зеркало из https://github.com/mozilla/pjs.git
First part of bug 340555, Toolkit feed parser needs nicer API. r=vlad
This commit is contained in:
Родитель
c4e0a524a9
Коммит
0ec7282d8d
|
@ -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 © 2000 O'Reilly & 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>
|
Загрузка…
Ссылка в новой задаче