| var DomHandler = require("domhandler"); | 
| var DomUtils = require("domutils"); | 
|   | 
| //TODO: make this a streamable handler | 
| function FeedHandler(callback, options) { | 
|     this.init(callback, options); | 
| } | 
|   | 
| require("inherits")(FeedHandler, DomHandler); | 
|   | 
| FeedHandler.prototype.init = DomHandler; | 
|   | 
| function getElements(what, where) { | 
|     return DomUtils.getElementsByTagName(what, where, true); | 
| } | 
| function getOneElement(what, where) { | 
|     return DomUtils.getElementsByTagName(what, where, true, 1)[0]; | 
| } | 
| function fetch(what, where, recurse) { | 
|     return DomUtils.getText( | 
|         DomUtils.getElementsByTagName(what, where, recurse, 1) | 
|     ).trim(); | 
| } | 
|   | 
| function addConditionally(obj, prop, what, where, recurse) { | 
|     var tmp = fetch(what, where, recurse); | 
|     if (tmp) obj[prop] = tmp; | 
| } | 
|   | 
| var isValidFeed = function(value) { | 
|     return value === "rss" || value === "feed" || value === "rdf:RDF"; | 
| }; | 
|   | 
| FeedHandler.prototype.onend = function() { | 
|     var feed = {}, | 
|         feedRoot = getOneElement(isValidFeed, this.dom), | 
|         tmp, | 
|         childs; | 
|   | 
|     if (feedRoot) { | 
|         if (feedRoot.name === "feed") { | 
|             childs = feedRoot.children; | 
|   | 
|             feed.type = "atom"; | 
|             addConditionally(feed, "id", "id", childs); | 
|             addConditionally(feed, "title", "title", childs); | 
|             if ( | 
|                 (tmp = getOneElement("link", childs)) && | 
|                 (tmp = tmp.attribs) && | 
|                 (tmp = tmp.href) | 
|             ) | 
|                 feed.link = tmp; | 
|             addConditionally(feed, "description", "subtitle", childs); | 
|             if ((tmp = fetch("updated", childs))) feed.updated = new Date(tmp); | 
|             addConditionally(feed, "author", "email", childs, true); | 
|   | 
|             feed.items = getElements("entry", childs).map(function(item) { | 
|                 var entry = {}, | 
|                     tmp; | 
|   | 
|                 item = item.children; | 
|   | 
|                 addConditionally(entry, "id", "id", item); | 
|                 addConditionally(entry, "title", "title", item); | 
|                 if ( | 
|                     (tmp = getOneElement("link", item)) && | 
|                     (tmp = tmp.attribs) && | 
|                     (tmp = tmp.href) | 
|                 ) | 
|                     entry.link = tmp; | 
|                 if ((tmp = fetch("summary", item) || fetch("content", item))) | 
|                     entry.description = tmp; | 
|                 if ((tmp = fetch("updated", item))) | 
|                     entry.pubDate = new Date(tmp); | 
|                 return entry; | 
|             }); | 
|         } else { | 
|             childs = getOneElement("channel", feedRoot.children).children; | 
|   | 
|             feed.type = feedRoot.name.substr(0, 3); | 
|             feed.id = ""; | 
|             addConditionally(feed, "title", "title", childs); | 
|             addConditionally(feed, "link", "link", childs); | 
|             addConditionally(feed, "description", "description", childs); | 
|             if ((tmp = fetch("lastBuildDate", childs))) | 
|                 feed.updated = new Date(tmp); | 
|             addConditionally(feed, "author", "managingEditor", childs, true); | 
|   | 
|             feed.items = getElements("item", feedRoot.children).map(function( | 
|                 item | 
|             ) { | 
|                 var entry = {}, | 
|                     tmp; | 
|   | 
|                 item = item.children; | 
|   | 
|                 addConditionally(entry, "id", "guid", item); | 
|                 addConditionally(entry, "title", "title", item); | 
|                 addConditionally(entry, "link", "link", item); | 
|                 addConditionally(entry, "description", "description", item); | 
|                 if ((tmp = fetch("pubDate", item))) | 
|                     entry.pubDate = new Date(tmp); | 
|                 return entry; | 
|             }); | 
|         } | 
|     } | 
|     this.dom = feed; | 
|     DomHandler.prototype._handleCallback.call( | 
|         this, | 
|         feedRoot ? null : Error("couldn't find root of feed") | 
|     ); | 
| }; | 
|   | 
| module.exports = FeedHandler; |