First part of bug 340555, Toolkit feed parser needs nicer API. r=vlad

This commit is contained in:
sayrer%gmail.com 2006-08-16 05:36:46 +00:00
Родитель c4e0a524a9
Коммит 0ec7282d8d
45 изменённых файлов: 938 добавлений и 110 удалений

Просмотреть файл

@ -52,6 +52,9 @@ XPIDLSRCS = nsIFeedProcessor.idl \
nsIFeedEntry.idl \
nsIFeedTextConstruct.idl \
nsIScriptableUnescapeHTML.idl \
nsIFeedElementBase.idl \
nsIFeedGenerator.idl \
nsIFeedPerson.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -39,12 +39,12 @@
#include "nsIFeedContainer.idl"
interface nsIArray;
interface nsIFeedGenerator;
/**
* An nsIFeed represents a single Atom or RSS feed.
*/
[scriptable, uuid(9472ff5b-10dc-4aed-a861-7619d7a4b5bf)]
[scriptable, uuid(330ae336-7b9b-4ca4-aa5f-681d884043bf)]
interface nsIFeed : nsIFeedContainer
{
/**
@ -82,6 +82,11 @@ interface nsIFeed : nsIFeedContainer
*/
attribute nsIWritablePropertyBag2 cloud;
/**
* Information about the software that produced the feed.
*/
attribute nsIFeedGenerator generator;
/**
* An image url and some metadata (as defined by RSS2).
*

Просмотреть файл

@ -34,7 +34,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIFeedElementBase.idl"
interface nsIURI;
interface nsIWritablePropertyBag2;
@ -46,8 +46,8 @@ interface nsIFeedTextConstruct;
* but they have some divergent attributes and require
* different convenience methods.
*/
[scriptable, uuid(56877da5-598b-41dd-bf3e-72fe713c7820)]
interface nsIFeedContainer : nsISupports
[scriptable, uuid(6f155937-011a-44ec-8833-b97917678aa4)]
interface nsIFeedContainer : nsIFeedElementBase
{
/**
* Many feeds contain an ID distinct from their URI, and
@ -55,11 +55,6 @@ interface nsIFeedContainer : nsISupports
*/
attribute AString id;
/**
* The baseURI for the Entry or Feed.
*/
attribute nsIURI baseURI;
/**
* The fields found in the document. Common Atom
* and RSS fields are normalized. This includes some namespaced
@ -94,7 +89,28 @@ interface nsIFeedContainer : nsISupports
attribute nsIArray categories;
/**
* Syncs a container's fields with its convience attributes.
* The rights or license associated with a feed or entry.
*/
attribute nsIFeedTextConstruct rights;
/**
* A list of nsIFeedPersons that authored the feed.
*/
attribute nsIArray authors;
/**
* A list of nsIFeedPersons that contributed to the feed.
*/
attribute nsIArray contributors;
/**
* The date the feed was updated, in RFC822 form. Parsable by JS
* and mail code.
*/
attribute AString updated;
/**
* Syncs a container's fields with its convenience attributes.
*/
void normalize();
};

Просмотреть файл

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 8; 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 mozilla.org code.
*
* The Initial Developer of the Original Code is the Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert Sayre <sayrer@gmail.com>
*
* 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 ***** */
#include "nsISupports.idl"
interface nsISAXAttributes;
interface nsIURI;
/**
* An nsIFeedGenerator represents the software used to create a feed.
*/
[scriptable, uuid(5215291e-fa0a-40c2-8ce7-e86cd1a1d3fa)]
interface nsIFeedElementBase : nsISupports
{
/**
* The attributes found on the element. Most interfaces provide convenience
* accessors for their standard fields, so this useful only when looking for
* an extension.
*/
attribute nsISAXAttributes attributes;
/**
* The baseURI for the Entry or Feed.
*/
attribute nsIURI baseURI;
};

Просмотреть файл

@ -44,7 +44,7 @@ interface nsIArray;
* and/or full-text content may be available, but callers will have to
* check both.
*/
[scriptable, uuid(364dc1e5-20fe-4315-bff7-33d2efcf2541)]
[scriptable, uuid(305ab161-d23d-44a0-89ce-f7c78683deec)]
interface nsIFeedEntry : nsIFeedContainer {
/**
@ -59,6 +59,12 @@ interface nsIFeedEntry : nsIFeedContainer {
*/
attribute nsIFeedTextConstruct summary;
/**
* The date the entry was published, in RFC822 form. Parsable by JS
* and mail code.
*/
attribute AString published;
/**
* Uses atom:content and content:encoded to provide
* a 'full text' view of an entry.

Просмотреть файл

@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 8; 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 mozilla.org code.
*
* The Initial Developer of the Original Code is the Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert Sayre <sayrer@gmail.com>
*
* 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 ***** */
#include "nsIFeedElementBase.idl"
interface nsIURI;
/**
* An nsIFeedGenerator represents the software used to create a feed.
*/
[scriptable, uuid(0fecd56b-bd92-481b-a486-b8d489cdd385)]
interface nsIFeedGenerator : nsIFeedElementBase
{
/**
* The name of the software.
*/
attribute AString agent;
/**
* The version of the software.
*/
attribute AString version;
/**
* A URI associated with the software.
*/
attribute nsIURI uri;
};

Просмотреть файл

@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 8; 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 mozilla.org code.
*
* The Initial Developer of the Original Code is the Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert Sayre <sayrer@gmail.com>
*
* 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 ***** */
#include "nsIFeedElementBase.idl"
interface nsIURI;
/**
* An nsIFeedPerson represents an author or contributor of a feed.
*/
[scriptable, uuid(29cbd45f-f2d3-4b28-b557-3ab7a61ecde4)]
interface nsIFeedPerson : nsIFeedElementBase
{
/**
* The name of the person.
*/
attribute AString name;
/**
* An email address associated with the person.
*/
attribute AString email;
/**
* A URI associated with the person (e.g. a homepage).
*/
attribute nsIURI uri;
};

Просмотреть файл

@ -184,6 +184,11 @@ function makePropGetter(key) {
* grok. For info, see
* http://lxr.mozilla.org/mozilla/source/js/src/jsdate.c#1526.
*/
const HOURS_TO_MINUTES = 60;
const MINUTES_TO_SECONDS = 60;
const SECONDS_TO_MILLISECONDS = 1000;
const MINUTES_TO_MILLISECONDS = MINUTES_TO_SECONDS * SECONDS_TO_MILLISECONDS;
const HOURS_TO_MILLISECONDS = HOURS_TO_MINUTES * MINUTES_TO_MILLISECONDS;
function W3CToIETFDate(dateString) {
var parts = dateString.match(/(\d\d\d\d)(-(\d\d))?(-(\d\d))?(T(\d\d):(\d\d)(:(\d\d)(\.(\d+))?)?(Z|([+-])(\d\d):(\d\d))?)?/);
@ -261,13 +266,16 @@ function W3CToIETFDate(dateString) {
}
// namespace map
const RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
var gNamespaces = {
"http://webns.net/mvcb/":"admin",
"http://backend.userland.com/rss":"",
"http://blogs.law.harvard.edu/tech/rss":"",
"http://www.w3.org/2005/Atom":"atom",
"http://purl.org/atom/ns#":"atom03",
"http://purl.org/rss/1.0/modules/content/":"content",
"http://purl.org/dc/elements/1.1/":"dc",
"http://purl.org/dc/terms/":"dcterms",
"http://www.w3.org/1999/02/22-rdf-syntax-ns#":"rdf",
"http://purl.org/rss/1.0/":"rss1",
"http://my.netscape.com/rdf/simple/0.9/":"rss1",
@ -276,25 +284,6 @@ var gNamespaces = {
"http://www.w3.org/XML/1998/namespace":"xml"
}
// lets us know to ignore extraneous attributes like
// <id foo:bar="baz">http://example.org</id>
var gKnownTextElements = ["title","link","description","language","copyright",
"managingEditor","webMaster","pubDate",
"lastBuildDate","docs","ttl","rating",
"rss1:title","rss1:link","rss1:description",
"rss1:url","rss1:name","dc:creator", "dc:subject",
"dc:description", "dc:publisher", "dc:contributor",
"dc:date", "dc:type", "dc:format", "dc:identifier",
"dc:source","dc:language","dc:relation",
"dc:coverage","dc:rights", "atom:id", "atom:name",
"atom:uri", "atom:content", "atom:email",
"atom:logo", "atom:published", "atom:updated",
"wfw:comment", "wfw:commentRss", "wiki:version",
"wiki:status", "wiki:importance","wiki:diff",
"wiki:history","content:encoded", "atom:icon",
"atom03:title", "atom03:summary", "atom03:content",
"atom03:tagline", "atom:title"];
function FeedResult() {}
FeedResult.prototype = {
bozo: false,
@ -320,10 +309,14 @@ FeedResult.prototype = {
function Feed() {
this.subtitle = null;
this.title = null;
this.items = [];
this.items = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
this.link = null;
this.id = null;
this.generator = null;
this.baseURI = null;
this.updated = null;
this.authors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
this.contributors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
}
Feed.prototype = {
@ -332,14 +325,20 @@ Feed.prototype = {
"atom03:tagline","atom:subtitle"],
items: ["items","atom03_entries","entries"],
id: ["atom:id","rdf:about"],
generator: ["generator"],
authors : ["authors"],
contributors: ["contributors"],
title: ["title","rss1:title", "atom03:title","atom:title"],
link: [["link",strToURI],["rss1:link",strToURI]],
categories: ["categories", "dc:subject"],
rights: ["atom03:rights","atom:rights"],
cloud: ["cloud"],
image: ["image", "rss1:image"],
textInput: ["textInput", "rss1:textinput"],
skipDays: ["skipDays"],
skipHours: ["skipHours"]
skipHours: ["skipHours"],
updated: ["pubDate", "atom03:modified", "dc:date", "dcterms:modified",
"atom:updated"]
},
normalize: function Feed_normalize() {
@ -348,7 +347,10 @@ Feed.prototype = {
this.skipDays = this.skipDays.getProperty("days");
if (this.skipHours)
this.skipHours = this.skipHours.getProperty("hours");
if (this.updated)
this.updated = dateParse(this.updated);
// Assign Atom link if needed
if (bagHasKey(this.fields, "links"))
this._atomLinksToURI();
@ -408,8 +410,12 @@ function Entry() {
this.link = null;
this.id = null;
this.baseURI = null;
this.updated = null;
this.published = null;
this.authors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
this.contributors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
}
Entry.prototype = {
fields: null,
enclosures: null,
@ -420,11 +426,17 @@ Entry.prototype = {
link: [["link",strToURI],["rss1:link",strToURI]],
id: [["guid", makePropGetter("guid")], "rdf:about",
"atom03:id", "atom:id"],
authors : ["authors"],
contributors: ["contributors"],
summary: ["description", "rss1:description", "dc:description",
"atom03:summary", "atom:summary"],
content: ["content:encoded","atom03:content","atom:content"]
content: ["content:encoded","atom03:content","atom:content"],
rights: ["atom03:rights","atom:rights"],
published: ["atom03:issued", "dcterms:issued", "atom:published"],
updated: ["pubDate", "atom03:modified", "dc:date", "dcterms:modified",
"atom:updated"]
},
normalize: function Entry_normalize() {
fieldsToObj(this, this.searchLists);
@ -444,6 +456,11 @@ Entry.prototype = {
this.link = strToURI(guid.getProperty("guid"));
}
if (this.updated)
this.updated = dateParse(this.updated);
if (this.published)
this.published = dateParse(this.published);
this._resetBagMembersToRawText([this.searchLists.content,
this.searchLists.summary,
this.searchLists.title]);
@ -507,6 +524,70 @@ TextConstruct.prototype = {
}
}
// Generator represents the software that produced the feed
function Generator() {
this.lang = null;
this.agent = null;
this.version = null;
this.uri = null;
// nsIFeedElementBase
this._attributes = null;
this.baseURI = null;
}
Generator.prototype = {
get attributes() {
return this._attributes;
},
set attributes(value) {
this._attributes = value;
this.version = this._attributes.getValueFromName("","version");
var uriAttribute = this._attributes.getValueFromName("","uri") ||
this._attributes.getValueFromName("","url");
this.uri = strToURI(uriAttribute, this.baseURI);
// RSS1
uriAttribute = this._attributes.getValueFromName(RDF_NS,"resource");
if (uriAttribute) {
this.agent = uriAttribute;
this.uri = strToURI(uriAttribute, this.baseURI);
}
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIFeedGenerator) ||
iid.equals(Ci.nsIFeedElementBase) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NOINTERFACE;
}
}
function Person() {
this.name = null;
this.uri = null;
this.email = null;
// nsIFeedElementBase
this.attributes = null;
this.baseURI = null;
}
Person.prototype = {
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIFeedPerson) ||
iid.equals(Ci.nsIFeedElementBase) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NOINTERFACE;
}
}
/**
* Map a list of fields into properties on a container.
*
@ -526,7 +607,7 @@ function fieldsToObj(container, fields) {
try {
prop = container.fields.getProperty(field);
}
catch(e) {
catch(e) {
}
if (prop) {
prop = isArray(props) ? props[1](prop) : prop;
@ -547,10 +628,10 @@ function LC(element) {
}
// TODO move these post-processor functions
//
// Handle atom:generator
// create a generator element
function atomGenerator(s, generator) {
generator.setPropertyAsAString("agent", trimString(s));
generator.QueryInterface(Ci.nsIFeedGenerator);
generator.agent = trimString(s);
return generator;
}
@ -573,23 +654,46 @@ function rssGuid(s, guid) {
//
// <author>lawyer@boyer.net (Lawyer Boyer)</author>
//
// or, delightfully, a field like this:
//
// <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
//
// We want to split this up and assign it to corresponding Atom
// fields.
//
function rssAuthor(s,author) {
author.QueryInterface(Ci.nsIWritablePropertyBag2);
var open = s.indexOf("(");
var close = s.indexOf(")");
var email = trimString(s.substring(0,open)) || null;
author.setPropertyAsAString("email", email);
var name = null;
if (open >= 0 && close > open)
name = trimString(s.substring(open+1,close));
author.setPropertyAsAString("name", name);
author.QueryInterface(Ci.nsIFeedPerson);
// check for RSS2 string format
var chars = trimString(s);
var matches = chars.match(/(.*)\((.*)\)/);
var emailCheck =
/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
if (matches) {
var match1 = trimString(matches[1]);
var match2 = trimString(matches[2]);
if (match2.indexOf("mailto:") == 0)
match2 = match2.substring(7);
if (emailCheck.test(match1)) {
author.email = match1;
author.name = match2;
}
else if (emailCheck.test(match2)) {
author.email = match2;
author.name = match1;
}
else {
// put it back together
author.name = match1 + " (" + match2 + ")";
}
}
else {
author.name = chars;
if (chars.indexOf('@'))
author.email = chars;
}
return author;
}
//
// skipHours and skipDays map to arrays, so we need to change the
// string to an nsISupports in order to stick it in there.
@ -741,9 +845,7 @@ XHTMLHandler.prototype = {
function ExtensionHandler(processor) {
this._buf = "";
this._depth = 0;
// Tracks whether the content model is something understandable
this._isSimple = true;
this._hasChildElements = false;
// The FeedProcessor
this._processor = processor;
@ -762,34 +864,29 @@ ExtensionHandler.prototype = {
},
startElement: function EH_startElement(uri, localName, qName, attrs) {
++this._depth;
var key = this._processor._prefixForNS(uri) + localName;
if (attrs.length > 0 && !arrayContains(gKnownTextElements, key))
this._isSimple = false;
var prefix = gNamespaces[uri] ? gNamespaces[uri] + ":" : "";
var key = prefix + localName;
if (this._depth == 1) {
this._uri = uri;
this._localName = localName;
this._qName = qName;
this._attrs = attrs;
}
else {
this._isSimple = false;
}
// if we descend into another element, we won't send text
this._hasChildElements = (this._depth > 1);
},
endElement: function EH_endElement(uri, localName, qName) {
--this._depth;
if (this._depth == 0) {
if (this._isSimple) {
this._processor.returnFromExtHandler(this._uri, this._localName,
trimString(this._buf),
this._attrs);
}
else {
this._processor.returnFromExtHandler(null,null,null);
}
var text = this._hasChildElements ? null : trimString(this._buf);
this._processor.returnFromExtHandler(this._uri, this._localName,
text, this._attrs);
}
},
characters: function EH_characters(data) {
if (this._isSimple)
if (!this._hasChildElements)
this._buf += data;
},
startPrefixMapping: function EH_startPrefixMapping() {
@ -797,7 +894,7 @@ ExtensionHandler.prototype = {
endPrefixMapping: function EH_endPrefixMapping() {
},
processingInstruction: function EH_processingInstruction() {
},
},
};
@ -892,16 +989,33 @@ function FeedProcessor() {
"IN_CHANNEL": {
"item": new ElementInfo("items", Cc[ENTRY_CONTRACTID], null, true),
"managingEditor": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"dc:creator": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"category": new ElementInfo("categories", null, rssCatTerm, true),
"cloud": new ElementInfo("cloud", null, null, false),
"image": new ElementInfo("image", null, null, false),
"textInput": new ElementInfo("textInput", null, null, false),
"skipDays": new ElementInfo("skipDays", null, null, false),
"skipHours": new ElementInfo("skipHours", null, null, false)
"skipHours": new ElementInfo("skipHours", null, null, false),
"generator": new ElementInfo("generator", Cc[GENERATOR_CONTRACTID],
atomGenerator, false),
},
"IN_ITEMS": {
"author": new ElementInfo("authors", null, rssAuthor, true),
"author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"dc:creator": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"category": new ElementInfo("categories", null, rssCatTerm, true),
"enclosure": new ElementInfo("enclosure", null, null, true),
"guid": new ElementInfo("guid", null, rssGuid, false)
@ -921,36 +1035,62 @@ function FeedProcessor() {
"rss1:channel": new FeedElementInfo("rdf_channel", "rss1"),
"rss1:image": new ElementInfo("image", null, null, false),
"rss1:textinput": new ElementInfo("textInput", null, null, false),
"rss1:item": new ElementInfo("items", Cc[ENTRY_CONTRACTID], null, true)
"rss1:item": new ElementInfo("items", Cc[ENTRY_CONTRACTID], null, true),
},
"IN_RDF_CHANNEL": {
"admin:generatorAgent": new ElementInfo("generator",
Cc[GENERATOR_CONTRACTID],
null, false),
"dc:creator": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
"dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
rssAuthor, true),
},
/********* ATOM 1.0 **********/
"IN_ATOM": {
"atom:author": new ElementInfo("author", null, null, true),
"atom:generator": new ElementInfo("generator", null,
"atom:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
null, true),
"atom:generator": new ElementInfo("generator", Cc[GENERATOR_CONTRACTID],
atomGenerator, false),
"atom:contributor": new ElementInfo("contributor", null, null, true),
"atom:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
null, true),
"atom:link": new ElementInfo("links", null, null, true),
"atom:entry": new ElementInfo("entries", Cc[ENTRY_CONTRACTID],
null, true)
},
"IN_ENTRIES": {
"atom:author": new ElementInfo("author", null, null, true),
"atom:contributor": new ElementInfo("contributor", null, null, true),
"atom:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
null, true),
"atom:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
null, true),
"atom:link": new ElementInfo("links", null, null, true),
},
/********* ATOM 0.3 **********/
"IN_ATOM03": {
"atom03:author": new ElementInfo("author", null, null, true),
"atom03:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
null, true),
"atom03:contributor": new ElementInfo("contributors",
Cc[PERSON_CONTRACTID],
null, true),
"atom03:link": new ElementInfo("links", null, null, true),
"atom03:entry": new ElementInfo("atom03_entries", Cc[ENTRY_CONTRACTID],
null, true)
null, true),
"atom03:generator": new ElementInfo("generator", Cc[GENERATOR_CONTRACTID],
atomGenerator, false),
},
"IN_ATOM03_ENTRIES": {
"atom03:author": new ElementInfo("author", null, null, true),
"atom03:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
null, true),
"atom03:contributor": new ElementInfo("contributors",
Cc[PERSON_CONTRACTID],
null, true),
"atom03:link": new ElementInfo("links", null, null, true),
"atom03:entry": new ElementInfo("atom03_entries", Cc[ENTRY_CONTRACTID],
null, true)
@ -1056,6 +1196,7 @@ FeedProcessor.prototype = {
// nsISAXContentHandler
startDocument: function FP_startDocument() {
//LOG("----------");
},
endDocument: function FP_endDocument() {
@ -1094,6 +1235,8 @@ FeedProcessor.prototype = {
++this._depth;
var elementInfo;
//LOG("<" + localName + ">");
// Check for xml:base
var base = attributes.getValueFromName(XMLNS, "base");
if (base) {
@ -1226,25 +1369,28 @@ FeedProcessor.prototype = {
// attributes and child elements.
_processComplexElement:
function FP__processComplexElement(elementInfo, attributes) {
var obj, props, key, prefix;
var obj, key, prefix;
// If the container is an entry/item, it'll need to have its
// more esoteric properties put in the 'fields' property bag, and set its
// parent.
if (elementInfo.containerClass) {
if (elementInfo.containerClass == Cc[ENTRY_CONTRACTID]) {
obj = elementInfo.containerClass.createInstance(Ci.nsIFeedEntry);
// Set the parent property of the entry.
obj.parent = this._result.doc;
obj.baseURI = this._xmlBaseStack[this._xmlBaseStack.length - 1];
props = obj.fields;
this._mapAttributes(obj.fields, attributes);
}
else if (elementInfo.containerClass) {
obj = elementInfo.containerClass.createInstance(Ci.nsIFeedElementBase);
obj.baseURI = this._xmlBaseStack[this._xmlBaseStack.length - 1];
obj.attributes = attributes; // just set the SAX attributes
}
else {
obj = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
props = obj;
this._mapAttributes(obj, attributes);
}
this._mapAttributes(props, attributes);
// We should have a container/propertyBag that's had its
// attributes processed. Now we need to attach it to its
// container.
@ -1319,7 +1465,7 @@ FeedProcessor.prototype = {
// If an nsIFeedContainer was on top of the stack,
// we need to normalize it
if (elementInfo.containerClass)
if (elementInfo.containerClass == Cc[ENTRY_CONTRACTID])
containerParent.normalize();
// If it's an array, re-set the last element
@ -1387,8 +1533,47 @@ FeedProcessor.prototype = {
// Grab the last element if it's an array
if (isIArray(container)) {
container = container.queryElementAt(container.length - 1,
Ci.nsIWritablePropertyBag2);
var contract = this._handlerStack[this._depth].containerClass;
// check if it's something specific, but not an entry
if (contract && contract != Cc[ENTRY_CONTRACTID]) {
var el = container.queryElementAt(container.length - 1,
Ci.nsIFeedElementBase);
// XXX there must be a way to flatten these interfaces
if (contract == Cc[PERSON_CONTRACTID])
el.QueryInterface(Ci.nsIFeedPerson);
else
return; // don't know about this interface
var propName = localName;
// synonyms
if ((uri == "" ||
(gNamespaces[uri].indexOf("atom") > -1) ||
(gNamespaces[uri].indexOf("rss") > -1)) &&
(propName == "url" || propName == "href"))
propName = "uri";
try {
if (el[propName] !== "undefined") {
var propValue = chars;
// convert URI-bearing values to an nsIURI
if (propName == "uri") {
var base = this._xmlBaseStack[this._xmlBaseStack.length - 1];
propValue = strToURI(chars, base);
}
el[propName] = propValue;
}
}
catch(e) {
// ignore XPConnect errors
}
// the rest of the function deals with entry- and feed-level stuff
return;
}
else {
container = container.queryElementAt(container.length - 1,
Ci.nsIWritablePropertyBag2);
}
}
// Make the buffer our new property
@ -1496,6 +1681,13 @@ const TEXTCONSTRUCT_CONTRACTID = "@mozilla.org/feed-textconstruct;1";
const TEXTCONSTRUCT_CLASSID =
Components.ID("{b992ddcd-3899-4320-9909-924b3e72c922}");
const TEXTCONSTRUCT_CLASSNAME = "Feed Text Construct";
const GENERATOR_CONTRACTID = "@mozilla.org/feed-generator;1";
const GENERATOR_CLASSID =
Components.ID("{414af362-9ad8-4296-898e-62247f25a20e}");
const GENERATOR_CLASSNAME = "Feed Generator";
const PERSON_CONTRACTID = "@mozilla.org/feed-person;1";
const PERSON_CLASSID = Components.ID("{95c963b7-20b2-11db-92f6-001422106990}");
const PERSON_CLASSNAME = "Feed Person";
function GenericComponentFactory(ctor) {
this._ctor = ctor;
@ -1545,6 +1737,10 @@ var Module = {
return new GenericComponentFactory(Entry);
if (cid.equals(TEXTCONSTRUCT_CLASSID))
return new GenericComponentFactory(TextConstruct);
if (cid.equals(GENERATOR_CLASSID))
return new GenericComponentFactory(Generator);
if (cid.equals(PERSON_CLASSID))
return new GenericComponentFactory(Person);
throw Cr.NS_ERROR_NO_INTERFACE;
},
@ -1566,6 +1762,12 @@ var Module = {
// Text Construct
cr.registerFactoryLocation(TEXTCONSTRUCT_CLASSID, TEXTCONSTRUCT_CLASSNAME,
TEXTCONSTRUCT_CONTRACTID, file, location, type);
// Generator
cr.registerFactoryLocation(GENERATOR_CLASSID, GENERATOR_CLASSNAME,
GENERATOR_CONTRACTID, file, location, type);
// Person
cr.registerFactoryLocation(PERSON_CLASSID, PERSON_CLASSNAME,
PERSON_CONTRACTID, file, location, type);
},
unregisterSelf: function(cm, location, type) {
@ -1580,6 +1782,10 @@ var Module = {
cr.unregisterFactoryLocation(ENTRY_CLASSID, location);
// Text Construct
cr.unregisterFactoryLocation(TEXTCONSTRUCT_CLASSID, location);
// Generator
cr.unregisterFactoryLocation(GENERATOR_CLASSID, location);
// Person
cr.unregisterFactoryLocation(PERSON_CLASSID, location);
},
canUnload: function(cm) {

Просмотреть файл

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: atom author name works
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe Entry';
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Atom-Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
<author>
<name>John Doe Entry</name>
</author>
</entry>
</feed>

Просмотреть файл

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: atom author name works
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).contributors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe Entry';
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Atom-Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
<contributor>
<name>John Doe Entry</name>
</contributor>
</entry>
</feed>

Просмотреть файл

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: atom published works
Expect: var entry = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry); entry.published == 'Tue, 09 Dec 2003 18:30:02 GMT'
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Atom-Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<published>2003-12-09T18:30:02Z</published>
<summary>Some text.</summary>
</entry>
</feed>

Просмотреть файл

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: atom entry rights works normalized
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).rights.plainText() == "test rights"
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> title</div>
</title>
<entry>
<rights type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> rights</div>
</rights>
</entry>
</feed>

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: atom updated works
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).updated == 'Sat, 13 Dec 2003 18:30:02 GMT'
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Atom-Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom author count works
Expect: var authors = feed.fields.getProperty('author'); authors.QueryInterface(Components.interfaces.nsIArray); authors.length == 1;
Expect: feed.authors.length == 1;
-->
<feed xmlns="http://www.w3.org/2005/Atom">

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom author count works
Expect: var authors = feed.fields.getProperty('author'); authors.QueryInterface(Components.interfaces.nsIArray); authors.length == 2;
Expect: feed.authors.length == 2
-->
<feed xmlns="http://www.w3.org/2005/Atom">

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom author name works
Expect: var authors = feed.fields.getProperty('author'); authors.QueryInterface(Components.interfaces.nsIArray); authors.queryElementAt(0, Components.interfaces.nsIPropertyBag).getProperty('atom:email')=='hmm@example.com';
Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).email=='hmm@example.com';
-->
<feed xmlns="http://www.w3.org/2005/Atom">

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom author name works
Expect: var authors = feed.fields.getProperty('author'); authors.QueryInterface(Components.interfaces.nsIArray); authors.queryElementAt(1, Components.interfaces.nsIPropertyBag).getProperty('atom:email')=='bar@example.com';
Expect: feed.authors.queryElementAt(1, Components.interfaces.nsIFeedPerson).email=='bar@example.com';
-->
<feed xmlns="http://www.w3.org/2005/Atom">

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom author name works
Expect: var authors = feed.fields.getProperty('author'); authors.QueryInterface(Components.interfaces.nsIArray); authors.queryElementAt(0, Components.interfaces.nsIPropertyBag).getProperty('atom:name')=='foo';
Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='foo';
-->
<feed xmlns="http://www.w3.org/2005/Atom">

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom author name works
Expect: var authors = feed.fields.getProperty('author'); authors.QueryInterface(Components.interfaces.nsIArray); authors.queryElementAt(0, Components.interfaces.nsIPropertyBag).getProperty('atom:name')=='John Doe';
Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe';
-->

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom author uri works
Expect: var authors = feed.fields.getProperty('author'); authors.QueryInterface(Components.interfaces.nsIArray); authors.queryElementAt(1, Components.interfaces.nsIPropertyBag).getProperty('atom:uri')=='http://example.com';
Expect: feed.authors.queryElementAt(1, Components.interfaces.nsIFeedPerson).uri.spec =='http://example.com/';
-->
<feed xmlns="http://www.w3.org/2005/Atom">
@ -15,6 +15,6 @@ Expect: var authors = feed.fields.getProperty('author'); authors.QueryInterface(
<author>
<email>bar@example.com</email>
<name>foo</name>
<uri>http://example.com</uri>
<uri>http://example.com/</uri>
</author>
</feed>

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom contributor uri works
Expect: var contributors = feed.fields.getProperty('contributor'); contributors.QueryInterface(Components.interfaces.nsIArray); contributors.queryElementAt(1, Components.interfaces.nsIPropertyBag).getProperty('atom:uri')=='http://example.com';
Expect: feed.contributors.queryElementAt(1, Components.interfaces.nsIFeedPerson).uri.spec=='http://example.com/';
-->
<feed xmlns="http://www.w3.org/2005/Atom">

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom generator works
Expect: var gen = feed.fields.getProperty('generator'); gen.QueryInterface(Components.interfaces.nsIPropertyBag2); gen.getProperty('agent') == 'Hmm';
Expect: feed.generator.agent == 'Hmm';
-->
<feed xmlns="http://www.w3.org/2005/Atom">

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom generator works
Expect: var gen = feed.fields.getProperty('generator'); gen.QueryInterface(Components.interfaces.nsIPropertyBag2); gen.getProperty('uri') == 'http://example.org';
Expect: feed.generator.uri.spec == 'http://example.org/';
-->
<feed xmlns="http://www.w3.org/2005/Atom">

Просмотреть файл

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: atom generator works
Expect: feed.generator.uri.spec == 'http://example.org/gen/';
-->
<feed xml:base="http://example.org/" xmlns="http://www.w3.org/2005/Atom">
<author>
<email>hmm@example.com</email>
<name>foo</name>
</author>
<generator uri="/gen/">Hmm</generator>
<author>
<email>bar@example.com</email>
<name>foo</name>
</author>
<title type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> title</div>
</title>
<rights type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><i>test</i> rights</div>
</rights>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><div><div>test</div> summary</div></div>
</summary>
</feed>

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: atom generator works
Expect: var gen = feed.fields.getProperty('generator'); gen.QueryInterface(Components.interfaces.nsIPropertyBag2); gen.getProperty('version') == '1.1';
Expect: feed.generator.version == "1.1"
-->
<feed xmlns="http://www.w3.org/2005/Atom">

Просмотреть файл

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: atom rights works normalized
Expect: feed.rights.plainText() == "test rights"
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> title</div>
</title>
<rights type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> rights</div>
</rights>
</feed>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: atom updated works
Expect: feed.updated == 'Sat, 13 Dec 2003 18:30:02 GMT'
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Atom-Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>

Просмотреть файл

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Description: RSS1 generator
Expect: feed.generator.agent == "http://Orchard.SourceForge.net/1.2/"
-->
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:admin="http://webns.net/mvcb/"
xmlns="http://purl.org/rss/1.0/">
<channel rdf:about="http://meerkat.oreillynet.com/?_fl=rss1.0">
<title>Meerkat</title>
<link>http://meerkat.oreillynet.com</link>
<description>Meerkat: An Open Wire Service</description>
<admin:errorReportsTo rdf:resource="mailto:channel-owner@acme.orgs"/>
<admin:generatorAgent rdf:resource="http://Orchard.SourceForge.net/1.2/"/>
<image rdf:resource="http://meerkat.oreillynet.com/icons/meerkat-powered.jpg" />
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://c.moreover.com/click/here.pl?r123" />
</rdf:Seq>
</items>
<textinput rdf:resource="http://meerkat.oreillynet.com/" />
</channel>
</rdf:RDF>

Просмотреть файл

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Description: RSS1 feed updated
Expect: feed.updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
-->
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:dc='http://purl.org/dc/elements/1.1/'>
<channel rdf:about="http://www.xml.com/xml/news.rss">
<title>Test</title>
<link>http://xml.com/pub</link>
<dc:description>another description</dc:description>
<dc:date>Sat, 07 Sep 2002 00:00:01 GMT</dc:date>
</channel>
<item rdf:about="http://example.com/hmm">
<title>XML: A Disruptive Technology</title>
<link>http://c.moreover.com/click/here.pl?r123</link>
<dc:description>
XML is placing increasingly heavy loads on the existing technical
infrastructure of the Internet.
</dc:description>
</item>
</rdf:RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Description: RSS1 feed updated
Expect: feed.updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
-->
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:dc='http://purl.org/dc/elements/1.1/'
xmlns:dcterms='http://purl.org/dc/terms/'>
<channel rdf:about="http://www.xml.com/xml/news.rss">
<title>Test</title>
<link>http://xml.com/pub</link>
<dc:description>another description</dc:description>
<dcterms:modified>Sat, 07 Sep 2002 00:00:01 GMT</dcterms:modified>
</channel>
<item rdf:about="http://example.com/hmm">
<title>XML: A Disruptive Technology</title>
<link>http://c.moreover.com/click/here.pl?r123</link>
<dc:description>
XML is placing increasingly heavy loads on the existing technical
infrastructure of the Internet.
</dc:description>
</item>
</rdf:RDF>

Просмотреть файл

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Description: RSS1 feed w/ item dc:description
Expect: var author = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).authors.queryElementAt(0, Components.interfaces.nsIFeedPerson); (author.name == "Simon St.Laurent" && author.email == "simonstl@simonstl.com")
-->
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:dc='http://purl.org/dc/elements/1.1/'>
<channel rdf:about="http://www.xml.com/xml/news.rss">
<title>Test</title>
<link>http://xml.com/pub</link>
<dc:description>another description</dc:description>
</channel>
<item>
<title>XML: A Disruptive Technology</title>
<link>http://c.moreover.com/click/here.pl?r123</link>
<dc:description>
XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet.
</dc:description>
<dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
<dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
<dc:subject>XML</dc:subject>
</item>
<item>
<dc:publisher>The O'Reilly Network</dc:publisher>
<dc:description>
XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet 2.
</dc:description>
<title>XML: A Disruptive Technology</title>
</item>
</rdf:RDF>

Просмотреть файл

@ -26,8 +26,8 @@ Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.
<dc:subject>XML</dc:subject>-->
</item>
<item>
<dc:publisher>The O'Reilly Network</dc:publisher>
<dc:description>
<dc:publisher>The O'Reilly Network</dc:publisher>
<dc:description>
XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet 2.
</dc:description>
<title>XML: A Disruptive Technology</title>

Просмотреть файл

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Description: RSS1 feed updated
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
-->
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:dc='http://purl.org/dc/elements/1.1/'
xmlns:dcterms='http://purl.org/dc/terms/'>
<channel rdf:about="http://www.xml.com/xml/news.rss">
<title>Test</title>
<link>http://xml.com/pub</link>
<dc:description>another description</dc:description>
<dcterms:modified>Sat, 07 Sep 2002 00:00:01 GMT</dcterms:modified>
</channel>
<item rdf:about="http://example.com/hmm">
<title>XML: A Disruptive Technology</title>
<link>http://c.moreover.com/click/here.pl?r123</link>
<dc:description>
XML is placing increasingly heavy loads on the existing technical
infrastructure of the Internet.
</dc:description>
<dcterms:modified>Sat, 07 Sep 2002 00:00:01 GMT</dcterms:modified>
</item>
</rdf:RDF>

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: channel copyright works
Expect: feed.fields.getProperty('dc:contributor') == 'them'
Expect: feed.contributors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name == 'them';
-->
<rss version="2.0" >

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: channel copyright works
Expect: feed.fields.getProperty('dc:creator') == 'me'
Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name == 'me'
-->
<rss version="2.0" >

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: channel generator works
Expect: feed.fields.getProperty('generator') == 'a generator used to make feeds'
Expect: feed.generator.agent == 'a generator used to make feeds'
-->
<rss version="2.0" >

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: channel managingEditor works
Expect: feed.fields.getProperty('managingEditor') == 'example@example.com'
Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).email == 'example@example.com'
-->
<rss version="2.0" >

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: channel managingEditor works
Expect: feed.fields.getProperty('managingEditor') == 'example@example.com'
Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).email == 'example@example.com'
-->
<rss version="2.0" >

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: channel pubDate works
Expect: feed.updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
-->
<rss version="2.0" >
<channel>
<pubDate>Sat, 07 Sep 2002 00:00:01 GMT</pubDate>
</channel>
</rss>

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: channel pubDate works
Expect: feed.updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
-->
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<dc:date>Sat, 07 Sep 2002 00:00:01 GMT</dc:date>
</channel>
</rss>

Просмотреть файл

@ -2,7 +2,7 @@
<!--
Description: item author works
Expect: var authors = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('authors'); authors.QueryInterface(Components.interfaces.nsIArray); var author = authors.queryElementAt(0, Components.interfaces.nsIPropertyBag); ((author.getProperty('name') == 'Joe Bob Briggs') && (author.getProperty('email') == 'jbb@dallas.example.com'));
Expect: var authors = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).authors; var author = authors.queryElementAt(0, Components.interfaces.nsIFeedPerson); ((author.name == 'Joe Bob Briggs'));
-->
<rss version="2.0" >

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: entry published works
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).published == 'Sat, 07 Sep 2002 00:00:01 GMT'
-->
<rss version="2.0" xmlns:dcterms="http://purl.org/dc/terms/">
<channel>
<item>
<dcterms:issued>Sat, 07 Sep 2002 00:00:01 GMT</dcterms:issued>
</item>
</channel>
</rss>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: channel pubDate works
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
-->
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<item>
<dc:date>Sat, 07 Sep 2002 00:00:01 GMT</dc:date>
</item>
</channel>
</rss>