?? feed.js
字號:
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-# ***** BEGIN LICENSE BLOCK *****# Version: MPL 1.1/GPL 2.0/LGPL 2.1## The contents of this file are subject to the Mozilla Public License Version# 1.1 (the "License"); you may not use this file except in compliance with# the License. You may obtain a copy of the License at# http://www.mozilla.org/MPL/## Software distributed under the License is distributed on an "AS IS" basis,# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License# for the specific language governing rights and limitations under the# License.## The Original Code is the RSS Parsing Engine## The Initial Developer of the Original Code is# The Mozilla Foundation.# Portions created by the Initial Developer are Copyright (C) 2004# the Initial Developer. All Rights Reserved.## Contributor(s):## Alternatively, the contents of this file may be used under the terms of# either the GNU General Public License Version 2 or later (the "GPL"), or# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),# in which case the provisions of the GPL or the LGPL are applicable instead# of those above. If you wish to allow use of your version of this file only# under the terms of either the GPL or the LGPL, and not to allow others to# use your version of this file under the terms of the MPL, indicate your# decision by deleting the provisions above and replace them with the notice# and other provisions required by the GPL or the LGPL. If you do not delete# the provisions above, a recipient may use your version of this file under# the terms of any one of the MPL, the GPL or the LGPL.## ***** END LICENSE BLOCK ***** */// error codes used to inform the consumer about attempts to download a feedconst kNewsBlogSuccess = 0;const kNewsBlogInvalidFeed = 1; // usually means there was an error trying to parse the feed...const kNewsBlogRequestFailure = 2; // generic networking failure when trying to download the feed.const kNewsBlogFeedIsBusy = 3;const kNewsBlogNoNewItems = 4; // there are no new articles for this feed// Cache for all of the feeds currently being downloaded, indexed by URL, so the load event listener// can access the Feed objects after it finishes downloading the feed.var FeedCache = { mFeeds: new Array(), putFeed: function (aFeed) { this.mFeeds[this.normalizeHost(aFeed.url)] = aFeed; }, getFeed: function (aUrl) { return this.mFeeds[this.normalizeHost(aUrl)]; }, removeFeed: function (aUrl) { delete this.mFeeds[this.normalizeHost(aUrl)]; }, normalizeHost: function (aUrl) { var ioService = Components.classes["@mozilla.org/network/io-service;1"]. getService(Components.interfaces.nsIIOService); var normalizedUrl = ioService.newURI(aUrl, null, null); normalizedUrl.host = normalizedUrl.host.toLowerCase(); return normalizedUrl.spec; }};function Feed(aResource, aRSSServer) { this.resource = aResource.QueryInterface(Components.interfaces.nsIRDFResource); this.server = aRSSServer;}Feed.prototype = { description: null, author: null, request: null, server: null, downloadCallback: null, resource: null, items: new Array(), mFolder: null, get folder() { if (!this.mFolder) { try { this.mFolder = this.server.rootMsgFolder.getChildNamed(this.name); } catch (ex) {} } return this.mFolder; }, set folder (aFolder) { this.mFolder = aFolder; }, get name() { var name = this.title || this.description || this.url; if (!name) throw("couldn't compute feed name, as feed has no title, description, or URL."); // Make sure the feed name doesn't have any line breaks, since we're going // to use it as the name of the folder in the filesystem. This may not // be necessary, since Mozilla's mail code seems to handle other forbidden // characters in filenames and can probably handle these as well. name = name.replace(/[\n\r\t]+/g, " "); // Make sure the feed doesn't end in a period to work around bug 117840. name = name.replace(/\.+$/, ""); return name; }, download: function(aParseItems, aCallback) { this.downloadCallback = aCallback; // may be null // Whether or not to parse items when downloading and parsing the feed. // Defaults to true, but setting to false is useful for obtaining // just the title of the feed when the user subscribes to it. this.parseItems = aParseItems == null ? true : aParseItems ? true : false; // Before we do anything...make sure the url is an http url. This is just a sanity check // so we don't try opening mailto urls, imap urls, etc. that the user may have tried to subscribe to // as an rss feed.. var uri = Components.classes["@mozilla.org/network/standard-url;1"]. createInstance(Components.interfaces.nsIURI); uri.spec = this.url; if (!(uri.schemeIs("http") || uri.schemeIs("https"))) return this.onParseError(this); // simulate an invalid feed error // Before we try to download the feed, make sure we aren't already processing the feed // by looking up the url in our feed cache if (FeedCache.getFeed(this.url)) { if (this.downloadCallback) this.downloadCallback.downloaded(this, kNewsBlogFeedIsBusy); return ; // don't do anything, the feed is already in use } this.request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] .createInstance(Components.interfaces.nsIXMLHttpRequest); this.request.onprogress = this.onProgress; // must be set before calling .open this.request.open("GET", this.url, true); var lastModified = this.lastModified; if (lastModified) this.request.setRequestHeader("If-Modified-Since", lastModified); this.request.overrideMimeType("text/xml"); this.request.onload = this.onDownloaded; this.request.onerror = this.onDownloadError; FeedCache.putFeed(this); this.request.send(null); }, onDownloaded: function(aEvent) { var request = aEvent.target; var url = request.channel.originalURI.spec; debug(url + " downloaded"); var feed = FeedCache.getFeed(url); if (!feed) throw("error after downloading " + url + ": couldn't retrieve feed from request"); // if the request has a Last-Modified header on it, then go ahead and remember // that as a property on the feed so we can use it when making future requests. var lastModifiedHeader = request.getResponseHeader('Last-Modified'); if (lastModifiedHeader) this.lastModified = lastModifiedHeader; feed.parse(); // parse will asynchronously call the download callback when it is done }, onProgress: function(aEvent) { var request = aEvent.target; var url = request.channel.originalURI.spec; var feed = FeedCache.getFeed(url); if (feed.downloadCallback) feed.downloadCallback.onProgress(feed, aEvent.position, aEvent.totalSize); }, onDownloadError: function(aEvent) { var request = aEvent.target; var url = request.channel.originalURI.spec; var feed = FeedCache.getFeed(url); if (feed.downloadCallback) { // if the http status code is a 304, then the feed has not been modified since we last downloaded it. var error = kNewsBlogRequestFailure; try { if (request.status == 304) error = kNewsBlogNoNewItems; } catch (ex) {} feed.downloadCallback.downloaded(feed, error); } FeedCache.removeFeed(url); }, onParseError: function(aFeed) { if (aFeed && aFeed.downloadCallback) { if (aFeed.downloadCallback) aFeed.downloadCallback.downloaded(aFeed, aFeed.request && aFeed.request.status == 304 ? kNewsBlogNoNewItems : kNewsBlogInvalidFeed); FeedCache.removeFeed(aFeed.url); } }, get url() { var ds = getSubscriptionsDS(this.server); var url = ds.GetTarget(this.resource, DC_IDENTIFIER, true); if (url)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -