Fix for bug 302121: Implements feedview feature for better display of RSS and Atom feed files. r=mconnor, approval1.8b4+=mconnor

This commit is contained in:
myk%mozilla.org 2005-08-02 03:29:11 +00:00
parent c92c490d44
commit 279d0f9608
19 changed files with 1197 additions and 0 deletions

View File

@ -388,3 +388,9 @@ pref("browser.display.screen_resolution", 96);
pref("browser.download.show_plugins_in_list", true);
pref("browser.download.hide_plugins_without_extensions", true);
pref("browser.feedview.articleLength", 50);
pref("browser.feedview.showBar", true);
pref("browser.feedview.showImage", true);
pref("browser.feedview.timerInterval", 0);
pref("browser.feedview.externalCSS", "");

View File

@ -872,6 +872,9 @@ function delayedStartup()
document.getElementById("textfieldDirection-separator").hidden = false;
document.getElementById("textfieldDirection-swap").hidden = false;
}
// Prepare to load feedview for feed files.
initFeedview();
}
function BrowserShutdown()

View File

@ -71,11 +71,14 @@
#include global-scripts.inc
<script type="application/x-javascript" src="chrome://global/content/contentAreaUtils.js"/>
<script type="application/x-javascript" src="chrome://browser/content/feedview/feedviewOverlay.js"/>
# All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the
# browser-sets.inc file for sharing with hiddenWindow.xul.
#include browser-sets.inc
<stringbundle id="bundle_feedview" src="chrome://browser/locale/feedview.properties"/>
<popupset id="mainPopupSet">
<popup id="backMenu"
position="after_start"

View File

@ -62,6 +62,7 @@ DIRS = \
shell \
sidebar \
build \
feedview \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,46 @@
#
# ***** 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 mozilla.org code.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1998
# 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 *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,216 @@
/* ***** 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 curLength;
var number ;
// Add the name of the feed to the title.
function setFeed() {
var title = document.getElementsByTagName("h1")[0].textContent;
document.title = document.getElementsByTagName("title")[0].textContent + " " + title;
}
// Try to get a Date() from a date string.
function xmlDate(In) {
In = In.replace('Z', '+00:00')
var D = In.replace(/^(\d{4})-(\d\d)-(\d\d)T([0-9:]*)([.0-9]*)(.)(\d\d):(\d\d)$/, '$1/$2/$3 $4 $6$7$8');
D = Date.parse(D);
D += 1000*RegExp.$5;
return new Date(D);
}
function setDate() {
// Find all items (div) in the htmlfeed.
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
// If the current div element has a date...
var d = divs[i].getAttribute("date");
if (d) {
// If it is an RFC... date -> first parse it...
// otherwise try the Date() constructor.
if (d.indexOf("T"))
d = xmlDate( d );
else
d = new Date( d );
// If the date could be parsed...
if (d instanceof Date) {
// XXX It would be nicer to say day = "Today" or "Yesterday".
var day = d.toGMTString();
day = day.substring(0, 11);
divs[i].getElementsByTagName("span")[0].textContent =
day + " @ " + lead(d.getHours()) + ":" + lead(d.getMinutes());
}
}
} // end of the divs loop
}
// XXX This function should not exist.
// It tries to fix as many special characters as posible.
function fixchars(txt) {
txt = txt.replace(/&nbsp;/g, " ");
txt = txt.replace(/&amp;/g, "&");
txt = txt.replace(/&gt;/g, ">");
txt = txt.replace(/&lt;/g, "<");
txt = txt.replace(/&quot;/g, "'");
txt = txt.replace(/&#8217;/g, "'");
txt = txt.replace(/&#8216;/g, "'");
txt = txt.replace(/&#8212;/g, "—");
txt = txt.replace(/&#33;/g, "!");
txt = txt.replace(/&#38;/g, "&");
txt = txt.replace(/&#39;/g, "'");
return txt;
}
// This function is called when the page is loaded and when the feeds are resized.
// maxLength: maximum length (in words) of the article, which can be set by the slider
// init: is this onload or not
function updateArticleLength(maxLength, init) {
// regex to get all the img tags
var img = /<img([^>]*)>/g;
var imgArr;
var im;
// sl: the slider element
var sl = document.getElementById("lengthSlider");
sl.setAttribute("curpos", maxLength);
// performance trick, don't know if it actually speeds up
if (maxLength == curLength) return;
curLength = maxLength;
var divs = document.getElementsByTagName("div");
// for each feed item (div) in the feedhtml
for (var i = 0; i < divs.length; i++) {
// if this is onload, set the title (the <a>) of each feed item
if (init) {
var title = divs[i].getElementsByTagName("a");
if (title.length > 0) { // just being safe
title = title[0];
title.textContent = fixchars(title.textContent);
// ...and remove all html tags from the title.
title.textContent = title.textContent.replace(/<([^>]*)>/g, "");
}
}
var txt = divs[i].getAttribute("description");
// If the item contains a description attribute, fill the <p> with it.
if (txt != null) {
txt = fixchars(txt);
// Replace all <br> and <p> by real breaks.
txt = txt.replace(/<br[^\>]*>/g, "\n");
txt = txt.replace(/<p[^\>]*>/g, "\n");
// If we have a description AND we are in onload
// find all images in the description and put them in an array
// before they are stripped as common html tags.
if (init) {
imgArr = new Array();
img.lastIndex = 0;
while ((im = img.exec(txt)) != null) {
var src = /\< *[img][^\>]*[src] *= *[\"\']{0,1}([^\"\'\ >]*)/i;
im[0] = im[0].replace('border=', ''); // fix somtin?
im[0] = im[0].replace('class=', ''); // fix somtin?
var imgsrc = src.exec(im[0]);
imgArr.push(imgsrc[1]);
}
// For each found image in the description create a new <img> tag
// and append it after the <p> with the description.
var o; // will be our new <img> tag
for (im=0; im < imgArr.length; im++) {
a = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
a.setAttribute("href", imgArr[im]);
o = document.createElementNS("http://www.w3.org/1999/xhtml", "img");
a.setAttribute("class", "image");
o.setAttribute("src", imgArr[im]);
a.appendChild(o);
divs[i].appendChild(a);
}
} // end:if (init)
// Kill all html.
txt = txt.replace(/<([^>]*)>/g, "");
/* split the description in words*/
var ar = txt.split(" ");
// performance... :)
if (maxLength == 0) txt = "";
if (maxLength < 100 && maxLength != 0) {
if (ar.length > maxLength) {
txt = "";
// append the number of words (maxLength)
for (var x = 0; x < maxLength ; x++) {
txt += ar[x] + " ";
}
txt += " ..." ;
}
}
// the <p> of the feeditem we are working with
var currentP = divs[i].getElementsByTagName("p")[0];
if (currentP != null) {
// Remove all previous elements from the parent <p>,
// which fill in the next lines of code.
for (var pc = currentP.childNodes.length; pc > 0; pc--)
currentP.removeChild(currentP.childNodes[0]);
// Split our description and for each line (which were
// actually <br> or <p>) of the description add a new <p>.
var p = txt.split("\n");
for (im = 0; im < p.length; im++) {
if (p != "") {
var a = document.createElementNS("http://www.w3.org/1999/xhtml", "p");
a.textContent = p[im];
currentP.appendChild(a);
}
}
} // end if (currentP != null)
} // end if (txt != null)
} // end for (i=0; i<divs.length; i++)
}
// leading zero function
function lead(In) {
if (In < 10)
return "0" + In;
else
return In;
}

View File

@ -0,0 +1,292 @@
<?xml version="1.0"?>
<!-- ***** 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) 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 LGPL or the GPL. 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 ***** -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:date="http://www.jclark.com/xt/java/java.util.Date"
xmlns:dc="http://purl.org/dc/elements/1.1/" version="1.0"
xmlns:atom03="http://purl.org/atom/ns#"
xmlns:atom10="http://www.w3.org/2005/Atom"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!--
These parameters are filled in by the overlay.js with processor.setParameter
The parameters are used in '<options id="options" ' so they can be accessed in the DOM from JS
- there should be an easier way getting the settings
-->
<xsl:param name="feedUrl"/>
<xsl:param name="feedDescription"/>
<xsl:param name="feedTitle"/>
<xsl:param name="lengthSliderLabel"/>
<xsl:param name="articleLength"/>
<xsl:param name="showBar"/>
<xsl:param name="showImage"/>
<xsl:param name="timerInterval"/>
<xsl:param name="externalCSS"/>
<xsl:output method="html" media-type="text/html"/>
<xsl:template match="/">
<html>
<head>
<link rel="alternate" type="application/rss+xml" title="Current Feed" href=""/>
<title>
<xsl:value-of select="$feedTitle"/>
</title>
<link rel="stylesheet" href="chrome://browser/skin/feedview/feedview.css"/>
<!-- The custom stylesheet from the settings-->
<link rel="stylesheet">
<xsl:attribute name="href">
<xsl:value-of select="$externalCSS"/>
</xsl:attribute>
</link>
<script type="application/x-javascript" src="chrome://browser/content/feedview/feedview.js"/>
</head>
<body>
<!-- Menu box -->
<div id="menubox">
<xsl:value-of select="$lengthSliderLabel"/>
<br/>
<table>
<tr id="lengthSwitcher">
<td>
<a onclick="javascript:updateArticleLength(100);">
<div style="height: 10px;"/>
</a>
</td>
<td>
<a onclick="javascript:updateArticleLength(300);">
<div style="margin-left: 8px; margin-right: 8px; height: 15px; "/>
</a>
</td>
<td>
<a onclick="javascript:updateArticleLength(900);">
<div style="height: 20px; "/>
</a>
</td>
</tr>
</table>
<xul:slider id="lengthSlider" style="width: 110px; " flex="1"
pageincrement="10" maxpos="100"
onmousemove="updateArticleLength(this.getAttribute('curpos'))"
onclick="updateArticleLength(this.getAttribute('curpos'))"
onmouseup="updateArticleLength(this.getAttribute('curpos'))">
<xsl:attribute name="curpos">
<xsl:value-of select="$articleLength"/>
</xsl:attribute>
<xul:thumb/>
</xul:slider>
<br/>
<br/>
<span id="number">
<xsl:value-of select="$feedDescription"/>
</span>
<br/>
<br/>
<span id="timerspan">Refresh in <span id="timevalue">
<xsl:value-of select="$timerInterval"/>
</span> seconds</span>
</div>
<!-- The options place holder -->
<options id="options" style="display:none">
<xsl:attribute name="showbar">
<xsl:value-of select="$showBar"/>
</xsl:attribute>
<xsl:attribute name="showimage">
<xsl:value-of select="$showImage"/>
</xsl:attribute>
<xsl:attribute name="timerinterval">
<xsl:value-of select="$timerInterval"/>
</xsl:attribute>
</options>
<xsl:apply-templates/>
<!-- Dynamic stuff -->
<script><![CDATA[
if (document.getElementById("options").getAttribute("showbar") != "true")
document.getElementById("menubox").style.display = "none";
var showImage = true;
if (document.getElementById("options").getAttribute("showimage") != "true")
showImage = false;
setDate();
updateArticleLength(document.getElementById("lengthSlider").getAttribute("curpos"), showImage);
setFeed();
var interval = document.getElementById("options").getAttribute("timerinterval");
// only needed for automatic refresh
function refresh() {
interval -= 1;
if (interval <= 0)
window.location.href = window.location.href;
else
document.getElementById("timevalue").textContent = interval;
setTimeout("refresh()", 1000);
}
// if there is no interval hide the ticker
if (interval > 0)
setTimeout("refresh()", 1000);
else
document.getElementById("timerspan").style.display = "none";
]]></script>
</body>
</html>
</xsl:template>
<!-- RSS RDF Support-->
<xsl:template name="a-element">
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:apply-templates select="*[local-name()='link']"/>
</xsl:attribute>
<xsl:value-of select="*[local-name()='title']"/>
</xsl:element>
</xsl:template>
<xsl:template match="*[local-name()='channel']">
<h1>
<xsl:call-template name="a-element"/>
</h1>
<!-- Following line for RSS .091 -->
<div id="articles">
<xsl:apply-templates select="*[local-name()='item']"/>
</div>
</xsl:template>
<xsl:template match="*[local-name()='image']"></xsl:template>
<xsl:template match="*[local-name()='textinput']"></xsl:template>
<xsl:template match="*[local-name()='item']">
<div class="article">
<xsl:attribute name="description">
<xsl:value-of select="*[local-name()='description']" />
</xsl:attribute>
<xsl:if test="dc:date">
<xsl:attribute name="date">
<xsl:value-of select="dc:date" />
</xsl:attribute>
</xsl:if>
<xsl:if test="*[local-name()='pubDate']">
<xsl:attribute name="date">
<xsl:value-of select="*[local-name()='pubDate']" />
</xsl:attribute>
</xsl:if>
<xsl:call-template name="a-element"/>
<span class="date"></span>
<p></p>
</div>
</xsl:template>
<!-- ATOM 0.3 SUPPORT-->
<xsl:template match="atom03:feed">
<h1>
<a href="{atom03:link[substring(@rel, 1, 8)!='service.']/@href}">
<xsl:value-of select="atom03:title"/>
</a>
</h1>
<div id="articles">
<xsl:apply-templates select="atom03:entry"/>
</div>
</xsl:template>
<xsl:template match="atom03:entry">
<div class="article">
<xsl:if test="atom03:issued">
<xsl:attribute name="date">
<xsl:value-of select="atom03:issued"/>
</xsl:attribute>
</xsl:if>
<xsl:attribute name="description">
<xsl:choose>
<xsl:when test="atom03:content">
<xsl:value-of select="atom03:content"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="atom03:summary"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<a href="{atom03:link[substring(@rel, 1, 8)!='service.']/@href}">
<xsl:value-of select="atom03:title"/>
</a>
<span class="date"/>
<p/>
</div>
</xsl:template>
<!-- ATOM 1.0 SUPPORT-->
<xsl:template match="atom10:feed">
<h1>
<a href="{atom10:link[substring(@rel, 1, 8)!='service.']/@href}">
<xsl:value-of select="atom10:title"/>
</a>
</h1>
<div id="articles">
<xsl:apply-templates select="atom10:entry"/>
</div>
</xsl:template>
<xsl:template match="atom10:entry">
<div class="article">
<xsl:if test="atom10:updated">
<xsl:attribute name="date">
<xsl:value-of select="atom10:updated"/>
</xsl:attribute>
</xsl:if>
<xsl:attribute name="description">
<xsl:choose>
<xsl:when test="atom10:content">
<xsl:value-of select="atom10:content"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="atom10:summary"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<a href="{atom10:link[substring(@rel, 1, 8)!='service.']/@href}">
<xsl:value-of select="atom10:title"/>
</a>
<span class="date"/>
<p/>
</div>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,200 @@
/* ***** 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);
}
}

View File

@ -0,0 +1,4 @@
browser.jar:
content/browser/feedview/feedviewOverlay.js (content/feedviewOverlay.js)
content/browser/feedview/feedview.xsl (content/feedview.xsl)
content/browser/feedview/feedview.js (content/feedview.js)

View File

@ -0,0 +1,39 @@
# ***** 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 (www.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 *****
title=Feed:
description=This feed contains %S articles.
lengthSliderLabel=Article length:

View File

@ -7,6 +7,7 @@
* locale/browser/browser.dtd (%chrome/browser/browser.dtd)
locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd)
locale/browser/browser.properties (%chrome/browser/browser.properties)
locale/browser/feedview.properties (%chrome/browser/feedview.properties)
locale/browser/metaData.dtd (%chrome/browser/metaData.dtd)
locale/browser/metaData.properties (%chrome/browser/metaData.properties)
locale/browser/openLocation.dtd (%chrome/browser/openLocation.dtd)

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

View File

@ -0,0 +1,190 @@
/* ***** 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 ***** */
feed, rss, rdf {
margin: 0;
padding: 0;
}
body {
padding: 30px;
margin: 0;
}
* {
font-family: arial;
}
p {
width: 70%;
color: #666;
font-size: 13px;
margin-bottom: 20px;
margin-top: 5px;
}
p > p {
width: 100%;
}
select {
color: #666;
font-size: 13px;
}
h1 {
font-weight: normal;
font-size: 27px;
margin: -30px;
margin-bottom: 30px;
padding: 12px;
padding-left: 28px;
background-image: url("chrome://browser/skin/feedview/itemSelected.png") !important;
}
div.article a {
color: #444;
text-decoration: none;
font-size: 16px;
font-weight: bold;
padding-right: 25px;
}
div.article a:visited {
-moz-opacity: 1;
background: url(chrome://browser/skin/feedview/check.png) no-repeat right;
}
.image:visited {
background: transparent !important;
}
h1 a {
text-decoration: none;
color: white;
}
span.date {
margin-left:30px;
font-size:14px ;
color: #ccc;
font-weight: bold;
}
span#number {
margin-left:0px;
display:inline;
font-size:13px;
}
#addLivemark {
display:none;
font-size: 12px;
font-weight: normal;
background: url(chrome://browser/skin/page-livemarks.png) no-repeat;
padding-left: 25px;
}
#lengthSwitcher {
display: none;
}
#lengthSwitcher td {
vertical-align:top;
}
#lengthSwitcher div {
width: 20px;
background: #bbb;
-moz-border-radius: 3px;
cursor: pointer;
-moz-opacity: 0.6;
}
#lengthSwitcher div:hover {
-moz-opacity: 1;
}
#switchdate {
cursor: pointer;
}
#lengthSlider {
background: #fff;
-moz-border-radius: 6px;
}
#menubox {
width:125px;
-moz-border-radius:4px;
position: absolute;
top: 40px;
right: 30px;
margin-top: 40px;
background: #eee; /*#f5f5f5; */
border: 1px solid #ddd;
padding: 10px 30px 15px 30px;
font-size: 12px; color: #aaa;
border-width: 0 1px 1px 0;
}
.image img {
max-height: 80px ;
border: 1px solid #ddd;
padding: 4px;
background: #fff;
margin: -13px 5px 18px 0px;
-moz-border-radius: 4px;
vertical-align: top;
}
thumb {
height: 15px ;
min-height: 15px ;
}
thumb * {
display:none;
}
item, entry, channel {
display: none;
}
p > p {
margin: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

View File

@ -43,6 +43,9 @@ classic.jar:
skin/classic/browser/bookmarks/livemark-item.png (bookmarks/livemark-item.png)
skin/classic/browser/bookmarks/folderarrow-hover.png (bookmarks/folderarrow-hover.png)
skin/classic/browser/bookmarks/folderarrow.png (bookmarks/folderarrow.png)
skin/classic/browser/feedview/feedview.css (feedview/feedview.css)
skin/classic/browser/feedview/check.png (feedview/check.png)
skin/classic/browser/feedview/itemSelected.png (feedview/itemSelected.png)
skin/classic/browser/preferences/Options.png (preferences/Options.png)
skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

View File

@ -0,0 +1,190 @@
/* ***** 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 ***** */
feed, rss, rdf {
margin: 0;
padding: 0;
}
body {
padding: 30px;
margin: 0;
}
* {
font-family: arial;
}
p {
width: 70%;
color: #666;
font-size: 13px;
margin-bottom: 20px;
margin-top: 5px;
}
p > p {
width: 100%;
}
select {
color: #666;
font-size: 13px;
}
h1 {
font-weight: normal;
font-size: 27px;
margin: -30px;
margin-bottom: 30px;
padding: 12px;
padding-left: 28px;
background-image: url("chrome://browser/skin/feedview/itemSelected.png") !important;
}
div.article a {
color: #444;
text-decoration: none;
font-size: 16px;
font-weight: bold;
padding-right: 25px;
}
div.article a:visited {
-moz-opacity: 1;
background: url(chrome://browser/skin/feedview/check.png) no-repeat right;
}
.image:visited {
background: transparent !important;
}
h1 a {
text-decoration: none;
color: white;
}
span.date {
margin-left:30px;
font-size:14px ;
color: #ccc;
font-weight: bold;
}
span#number {
margin-left:0px;
display:inline;
font-size:13px;
}
#addLivemark {
display:none;
font-size: 12px;
font-weight: normal;
background: url(chrome://browser/skin/page-livemarks.png) no-repeat;
padding-left: 25px;
}
#lengthSwitcher {
display: none;
}
#lengthSwitcher td {
vertical-align:top;
}
#lengthSwitcher div {
width: 20px;
background: #bbb;
-moz-border-radius: 3px;
cursor: pointer;
-moz-opacity: 0.6;
}
#lengthSwitcher div:hover {
-moz-opacity: 1;
}
#switchdate {
cursor: pointer;
}
#lengthSlider {
background: #fff;
-moz-border-radius: 6px;
}
#menubox {
width:125px;
-moz-border-radius:4px;
position: absolute;
top: 40px;
right: 30px;
margin-top: 40px;
background: #eee; /*#f5f5f5; */
border: 1px solid #ddd;
padding: 10px 30px 15px 30px;
font-size: 12px; color: #aaa;
border-width: 0 1px 1px 0;
}
.image img {
max-height: 80px ;
border: 1px solid #ddd;
padding: 4px;
background: #fff;
margin: -13px 5px 18px 0px;
-moz-border-radius: 4px;
vertical-align: top;
}
thumb {
height: 15px ;
min-height: 15px ;
}
thumb * {
display:none;
}
item, entry, channel {
display: none;
}
p > p {
margin: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

View File

@ -24,6 +24,9 @@ classic.jar:
skin/classic/browser/bookmarks/addBookmark.css (bookmarks/addBookmark.css)
skin/classic/browser/bookmarks/bookmarksManager.css (bookmarks/bookmarksManager.css)
skin/classic/browser/bookmarks/Bookmarks-toolbar.png (bookmarks/Bookmarks-toolbar.png)
skin/classic/browser/feedview/feedview.css (feedview/feedview.css)
skin/classic/browser/feedview/check.png (feedview/check.png)
skin/classic/browser/feedview/itemSelected.png (feedview/itemSelected.png)
skin/classic/browser/preferences/Options.png (preferences/Options.png)
skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
icon.png