201 lines
8.0 KiB
JavaScript
201 lines
8.0 KiB
JavaScript
/* ***** 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 Feedview for Firefox.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Tom Germeau <tom.germeau@epigoon.com>.
|
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
|
* 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 ***** */
|
|
|
|
|
|
var gFeedviewPrefs;
|
|
|
|
// The values to which these variables are initialized are just backups
|
|
// in case we can't get the actual values from the prefs service.
|
|
var gFeedviewPrefArticleLength = 50;
|
|
var gFeedviewPrefShowBar = true;
|
|
var gFeedviewPrefShowImage = true;
|
|
var gFeedviewPrefTimerInterval = 0;
|
|
var gFeedviewPrefExternalCSS = "";
|
|
|
|
var gFeedviewProcessor;
|
|
var gFeedviewStylesheet;
|
|
|
|
function initFeedview() {
|
|
try {
|
|
gFeedviewPrefs = Components.classes["@mozilla.org/preferences-service;1"]
|
|
.getService(Components.interfaces.nsIPrefService)
|
|
.getBranch("browser.feedview.");
|
|
|
|
gFeedviewPrefArticleLength = gFeedviewPrefs.getIntPref("articleLength");
|
|
gFeedviewPrefShowBar = gFeedviewPrefs.getBoolPref("showBar");
|
|
gFeedviewPrefShowImage = gFeedviewPrefs.getBoolPref("showImage");
|
|
gFeedviewPrefTimerInterval = gFeedviewPrefs.getIntPref("timerInterval");
|
|
gFeedviewPrefExternalCSS = gFeedviewPrefs.getCharPref("externalCSS");
|
|
}
|
|
catch (ex) {}
|
|
|
|
gFeedviewProcessor = new XSLTProcessor();
|
|
gFeedviewStylesheet = document.implementation.createDocument("", "", null);
|
|
gFeedviewStylesheet.addEventListener("load", onLoadFeedviewStylesheet, false);
|
|
gFeedviewStylesheet.load("chrome://browser/content/feedview/feedview.xsl");
|
|
|
|
window.addEventListener("load", maybeLoadFeedview, true);
|
|
}
|
|
|
|
function onLoadFeedviewStylesheet() {
|
|
gFeedviewProcessor.importStylesheet(gFeedviewStylesheet);
|
|
}
|
|
|
|
function feedviewIsFeed(doc) {
|
|
const ATOM_10_NS = "http://www.w3.org/2005/Atom";
|
|
const ATOM_03_NS = "http://purl.org/atom/ns#";
|
|
const RSS_10_NS = "http://purl.org/rss/1.0/";
|
|
const RSS_09_NS = "http://my.netscape.com/rdf/simple/0.9/";
|
|
const RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
|
|
|
|
var rootName = doc.localName;
|
|
var rootNS = doc.namespaceURI;
|
|
var channel;
|
|
|
|
// Atom feeds have a root "feed" element in one of two namespaces.
|
|
if (rootName == "feed" && (rootNS == ATOM_10_NS || rootNS == ATOM_03_NS))
|
|
return true;
|
|
|
|
// RSS 2.0, 0.92, and 0.91 feeds have a non-namespaced root "rss" element
|
|
// containing a non-namespaced "channel" child.
|
|
else if (rootName == "rss" && rootNS == null) {
|
|
channel = doc.getElementsByTagName('channel')[0];
|
|
if (channel && channel.parentNode == doc)
|
|
return true;
|
|
}
|
|
|
|
// RSS 1.0 and 0.9 feeds have a root "RDF" element in the RDF namespace
|
|
// and a "channel" child in the RSS 1.0 or 0.9 namespaces.
|
|
else if (rootName == "RDF" && rootNS == RDF_NS) {
|
|
channel = doc.getElementsByTagNameNS(RSS_10_NS, 'channel')[0]
|
|
|| doc.getElementsByTagNameNS(RSS_09_NS, 'channel')[0];
|
|
if (channel && channel.parentNode == doc)
|
|
return true;
|
|
}
|
|
|
|
// If it didn't match any criteria yet, it's probably not a feed,
|
|
// or perhaps it's a nonconformist feed. If you see a number of those
|
|
// and they match some pattern, add a check for that pattern here,
|
|
// making sure to specify the strictest check that matches that pattern
|
|
// to minimize false positives.
|
|
return false;
|
|
}
|
|
|
|
// Checks every document to see if it's a feed file, and transforms it if so.
|
|
function maybeLoadFeedview(evnt) {
|
|
// See if the document is XML. If not, it's definitely not a feed.
|
|
if (!(evnt.originalTarget instanceof XMLDocument))
|
|
return;
|
|
|
|
var dataXML = evnt.originalTarget;
|
|
|
|
// Make sure the document is loaded into one of the browser tabs.
|
|
// Otherwise, it might have been loaded as data by some application
|
|
// that expects it not to change, and we shouldn't break the app
|
|
// by changing the document.
|
|
var browser;
|
|
var browsers = document.getElementById('content').browsers;
|
|
for (var i = 0; i < browsers.length; i++) {
|
|
if (dataXML == browsers[i].contentDocument) {
|
|
browser = browsers[i];
|
|
break;
|
|
}
|
|
}
|
|
if (!browser)
|
|
return;
|
|
|
|
// See if the document we're dealing with is actually a feed.
|
|
if (!feedviewIsFeed(dataXML.documentElement))
|
|
return;
|
|
|
|
var ownerDocument = document.implementation.createDocument("", "", null);
|
|
|
|
var strbundle=document.getElementById("bundle_feedview");
|
|
|
|
gFeedviewProcessor.setParameter(null, "feedUrl", evnt.originalTarget.documentURI);
|
|
gFeedviewProcessor.setParameter(null, "feedTitle", strbundle.getString("title") );
|
|
// XXX This should be in a DTD.
|
|
gFeedviewProcessor.setParameter(null, "lengthSliderLabel", strbundle.getString("lengthSliderLabel"));
|
|
|
|
// XXX These are static values. Can I set them once and have the processor
|
|
// apply them every time I use it to transform a document?
|
|
gFeedviewProcessor.setParameter(null, "articleLength", gFeedviewPrefArticleLength);
|
|
gFeedviewProcessor.setParameter(null, "showBar", gFeedviewPrefShowBar);
|
|
gFeedviewProcessor.setParameter(null, "showImage", gFeedviewPrefShowImage);
|
|
gFeedviewProcessor.setParameter(null, "timerInterval", gFeedviewPrefTimerInterval);
|
|
gFeedviewProcessor.setParameter(null, "externalCSS", gFeedviewPrefExternalCSS );
|
|
|
|
// Get the length and give it to the description thingie.
|
|
var len = dataXML.getElementsByTagName("item").length;
|
|
if (len == 0)
|
|
len = dataXML.getElementsByTagName("entry").length;
|
|
gFeedviewProcessor.setParameter(null, "feedDescription", strbundle.getFormattedString("description", [len] ) );
|
|
|
|
var newFragment = gFeedviewProcessor.transformToFragment(dataXML, ownerDocument);
|
|
|
|
var oldLink = dataXML.documentElement.firstChild;
|
|
|
|
// XXX: it would be better if we could replace the documentElement..
|
|
// now the rdf/rss/feed tag remains , NOT good
|
|
dataXML.documentElement.replaceChild(newFragment, oldLink);
|
|
|
|
oldLink = dataXML.documentElement.firstChild.nextSibling;
|
|
|
|
// Kill all other child elements of the document element
|
|
// so only our transformed feed remains.
|
|
while (oldLink != null) {
|
|
oldLinkX = oldLink.nextSibling;
|
|
|
|
if (oldLinkX != null)
|
|
dataXML.documentElement.removeChild(oldLink);
|
|
|
|
oldLink = oldLinkX;
|
|
}
|
|
|
|
// Watch the article length slider so we can update the corresponding pref
|
|
// when it changes.
|
|
var slider = dataXML.getElementById('lengthSlider');
|
|
slider.addEventListener("mouseclick", updateFeedviewPrefArticleLength, false);
|
|
slider.addEventListener("mouseup", updateFeedviewPrefArticleLength, false);
|
|
}
|
|
|
|
function updateFeedviewPrefArticleLength(event) {
|
|
if (gFeedviewPrefArticleLength != event.target.getAttribute("curpos")) {
|
|
gFeedviewPrefArticleLength = event.target.getAttribute("curpos");
|
|
gFeedviewPrefs.setIntPref("articleLength", gFeedviewPrefArticleLength);
|
|
}
|
|
}
|