Blame view

node_modules/htmlparser2/lib/FeedHandler.js 2.97 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  var index = require("./index.js"),
      DomHandler = index.DomHandler,
  	DomUtils = index.DomUtils;
  
  //TODO: make this a streamable handler
  function FeedHandler(callback, options){
  	this.init(callback, options);
  }
  
  require("util").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;
  				addConditionally(entry, "description", "summary", item);
  				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;