1 var DomHandler = require("domhandler");
2 var DomUtils = require("domutils");
4 //TODO: make this a streamable handler
5 function FeedHandler(callback, options) {
6 this.init(callback, options);
9 require("inherits")(FeedHandler, DomHandler);
11 FeedHandler.prototype.init = DomHandler;
13 function getElements(what, where) {
14 return DomUtils.getElementsByTagName(what, where, true);
16 function getOneElement(what, where) {
17 return DomUtils.getElementsByTagName(what, where, true, 1)[0];
19 function fetch(what, where, recurse) {
20 return DomUtils.getText(
21 DomUtils.getElementsByTagName(what, where, recurse, 1)
25 function addConditionally(obj, prop, what, where, recurse) {
26 var tmp = fetch(what, where, recurse);
27 if (tmp) obj[prop] = tmp;
30 var isValidFeed = function(value) {
31 return value === "rss" || value === "feed" || value === "rdf:RDF";
34 FeedHandler.prototype.onend = function() {
36 feedRoot = getOneElement(isValidFeed, this.dom),
41 if (feedRoot.name === "feed") {
42 childs = feedRoot.children;
45 addConditionally(feed, "id", "id", childs);
46 addConditionally(feed, "title", "title", childs);
48 (tmp = getOneElement("link", childs)) &&
49 (tmp = tmp.attribs) &&
53 addConditionally(feed, "description", "subtitle", childs);
54 if ((tmp = fetch("updated", childs))) feed.updated = new Date(tmp);
55 addConditionally(feed, "author", "email", childs, true);
57 feed.items = getElements("entry", childs).map(function(item) {
63 addConditionally(entry, "id", "id", item);
64 addConditionally(entry, "title", "title", item);
66 (tmp = getOneElement("link", item)) &&
67 (tmp = tmp.attribs) &&
71 if ((tmp = fetch("summary", item) || fetch("content", item)))
72 entry.description = tmp;
73 if ((tmp = fetch("updated", item)))
74 entry.pubDate = new Date(tmp);
78 childs = getOneElement("channel", feedRoot.children).children;
80 feed.type = feedRoot.name.substr(0, 3);
82 addConditionally(feed, "title", "title", childs);
83 addConditionally(feed, "link", "link", childs);
84 addConditionally(feed, "description", "description", childs);
85 if ((tmp = fetch("lastBuildDate", childs)))
86 feed.updated = new Date(tmp);
87 addConditionally(feed, "author", "managingEditor", childs, true);
89 feed.items = getElements("item", feedRoot.children).map(function(
97 addConditionally(entry, "id", "guid", item);
98 addConditionally(entry, "title", "title", item);
99 addConditionally(entry, "link", "link", item);
100 addConditionally(entry, "description", "description", item);
101 if ((tmp = fetch("pubDate", item)))
102 entry.pubDate = new Date(tmp);
108 DomHandler.prototype._handleCallback.call(
110 feedRoot ? null : Error("couldn't find root of feed")
114 module.exports = FeedHandler;