+++ /dev/null
-///////////////////////////////////////////////////////////////////////////////\r
-// The FeedUpdateBroker class implements a simple RSS fetcher and parser.\r
-\r
-// Constructor.\r
-function FeedUpdateBroker() {\r
- this.httpReq = null;\r
- this.callback = null;\r
-}\r
-\r
-// Fetches a feed from the specified URL and calls the callback when the feed\r
-// has been fetched and parsed, or if the process results in an error.\r
-FeedUpdateBroker.prototype.fetchFeed = function(feedURL, callback) {\r
- // remember callback\r
- this.callback = callback;\r
- \r
- // create new XML HTTP request
-
- //netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\r
- this.httpReq = new Ajax();\r
- \r
- // set callback\r
- var self = this;\r
- this.httpReq.onreadystatechange = function() { self.readyStateChanged(); };\r
-\r
- // append the current time after the URL to bypass caches\r
- var fullURL = feedURL;\r
- if (fullURL.indexOf("?") == -1) {\r
- fullURL += "?";\r
- } else {\r
- fullURL += "&";\r
- }\r
- fullURL += "nocache=" + (new Date().getTime());\r
- \r
- // initiate the request\r
- this.httpReq.open("GET", fullURL, true);\r
- this.httpReq.send(null);\r
-}\r
-\r
-// Callback for ready-state change events in the XML HTTP request.\r
-FeedUpdateBroker.prototype.readyStateChanged = function() {\r
- // complete request?\r
- if (this.httpReq.readyState == 4) {\r
- // attempt to get response status\r
- var responseStatus = null;\r
- try {\r
- responseStatus = this.httpReq.status;\r
- } catch (noStatusException) {}\r
- \r
- // handle the response and call the registered callback\r
- this.callback.call(this, this.handleResponse(responseStatus, this.httpReq.responseXML));\r
- }\r
-}\r
-\r
-// Handles a completed response.\r
-FeedUpdateBroker.prototype.handleResponse = function(responseStatus, xmlDoc) {\r
- if (((responseStatus == 200)||(responseStatus == 0)) && xmlDoc != null) {\r
- // node ref for iterating\r
- var node;\r
- \r
- // get last modified time - default to current time\r
- var lastModified = new Date().getTime();\r
- var channelElements = xmlDoc.getElementsByTagName("channel");\r
- if (channelElements.length > 0) {\r
- node = channelElements[0].firstChild;\r
- while (node != null) {\r
- if (node.nodeType == Node.ELEMENT_NODE) {\r
- if (node.nodeName == "pubDate" ||\r
- node.nodeName == "lastBuildDate" ||\r
- node.nodeName == "dc:date") {\r
- lastModified = this.getTextOfNode(node);\r
- break;\r
- }\r
- }\r
- node = node.nextSibling;\r
- }\r
- }\r
- \r
- // init feed items array\r
- var items = [];\r
- \r
- // we got the feed XML so now we'll parse it\r
- var itemElements = xmlDoc.getElementsByTagName("item");\r
- for (var i = 0; i < itemElements.length; i++) {\r
- // iterate through child nodes of this item and gather\r
- // all the data we need for a feed item\r
- var title = null;\r
- var date = null;\r
- var description = null;\r
- var url = null;\r
- \r
- node = itemElements[i].firstChild;\r
- while (node != null) {\r
- if (node.nodeType == Node.ELEMENT_NODE) {\r
- if (node.nodeName == "title") {\r
- // item title\r
- title = this.getTextOfNode(node);\r
- } else if (node.nodeName == "pubDate" || node.nodeName == "dc:date") {\r
- // item publishing date\r
- date = this.getTextOfNode(node);\r
- } else if (node.nodeName == "description") {\r
- // item description\r
- description = this.getTextOfNode(node);\r
- } else if (node.nodeName == "link") {\r
- // link URL\r
- url = this.getTextOfNode(node);\r
- }\r
- }\r
- node = node.nextSibling;\r
- }\r
- \r
- // create the item and add to the items array\r
- items.push({ title: title, date: date, description: description, url: url });\r
- }\r
- \r
- // update was completed successfully\r
- return { status: "ok", lastModified: lastModified, items: items };\r
- } else {\r
- // update failed\r
- return { status: "error" };\r
- }\r
-}\r
-\r
-// Returns the text of a node.\r
-FeedUpdateBroker.prototype.getTextOfNode = function(node) {\r
- var buf = "";\r
- \r
- // iterate through all child elements and collect all text to the buffer\r
- var child = node.firstChild;\r
- while (child != null) {\r
- if (child.nodeType == Node.TEXT_NODE || child.nodeType == Node.CDATA_SECTION_NODE) {\r
- // append text to buffer\r
- if (buf != "") {\r
- buf += " ";\r
- }\r
- buf += child.nodeValue;\r
- }\r
- child = child.nextSibling;\r
- }\r
- \r
- // strip all tags from the buffer\r
- var strippedBuf = "";\r
- var textStartPos = -1;\r
- var tagBalance = 0;\r
- \r
- // iterate through the text and append all text to the stripped buffer\r
- // that is at a tag balance of 0\r
- for (pos = 0; pos < buf.length; pos++) {\r
- var c = buf.charAt(pos);\r
- if (c == '<') {\r
- // entering a tag\r
- if (tagBalance == 0 && textStartPos != -1) {\r
- // everything up to here was valid text\r
- strippedBuf += buf.substring(textStartPos, pos);\r
- textStartPos = -1;\r
- }\r
- tagBalance++;\r
- } else if (c == '>') {\r
- // leaving a tag\r
- tagBalance--;\r
- textStartPos = -1;\r
- } else if (tagBalance == 0 && textStartPos == -1) {\r
- // first char of text\r
- textStartPos = pos;\r
- }\r
- }\r
- \r
- // add remaining text - if any\r
- if (tagBalance == 0 && textStartPos != -1) {\r
- strippedBuf += buf.substring(textStartPos, pos);\r
- }\r
- \r
- return strippedBuf;\r
-}\r