[Bug 344389] feed parser doesn't expose guid/atom:id/rdf:about correctly. r=ben

This commit is contained in:
sayrer%gmail.com 2006-07-19 19:31:52 +00:00
parent 9a79b08c79
commit 3441890217
10 changed files with 233 additions and 17 deletions

View File

@ -45,14 +45,14 @@ interface nsIArray;
* but they have some divergent attributes and require
* different convenience methods.
*/
[scriptable, uuid(c7e65344-df1f-4a75-9615-d58357c1554b)]
[scriptable, uuid(b7e7b6b9-a461-4817-9003-3e6b9005945f)]
interface nsIFeedContainer : nsISupports
{
/**
* Many feeds contain an ID distinct from their URI, and
* entries have standard fields for this in all major formats.
*/
attribute AString identifier;
attribute AString id;
/**
* The baseURI for the Entry or Feed.

View File

@ -59,7 +59,12 @@ const XMLNS = "http://www.w3.org/XML/1998/namespace";
/***** Some general utils *****/
function strToURI(link, base) {
var base = base || null;
return gIoService.newURI(link, null, base);
try {
return gIoService.newURI(link, null, base);
}
catch(e) {
return null;
}
}
function isArray(a) {
@ -178,6 +183,19 @@ function bagHasKey(bag, key) {
}
}
function makePropGetter(key) {
return function FeedPropGetter(bag) {
try {
return value = bag.getProperty(key);
}
catch(e) {
}
return null;
}
}
/**
* XXX Thunderbird's W3C-DTF function
*
@ -325,6 +343,7 @@ function Feed() {
this._title = null;
this.items = [];
this.link = null;
this.id = null;
this.baseURI = null;
}
Feed.prototype = {
@ -349,6 +368,7 @@ Feed.prototype = {
_sub: ["description","dc:description","rss1:description",
"atom03:tagline","atom:subtitle"],
items: ["items","atom03_entries","entries"],
id: ["atom:id","rdf:about"],
_title: ["title","rss1:title", "atom03:title","atom:title"],
link: [["link",strToURI],["rss1:link",strToURI]],
categories: ["categories", "dc:subject"],
@ -390,7 +410,7 @@ Feed.prototype = {
}
}
},
QueryInterface: function Feed_QI(iid) {
if (iid.equals(Ci.nsIFeed) ||
iid.equals(Ci.nsIFeedContainer) ||
@ -407,6 +427,7 @@ function Entry() {
this.fields = Cc["@mozilla.org/hash-property-bag;1"].
createInstance(Ci.nsIWritablePropertyBag2);
this.link = null;
this.id = null;
this.baseURI = null;
}
@ -444,8 +465,10 @@ Entry.prototype = {
mediaContent: null,
searchLists: {
_title: ["title","rss1:title","atom03:title","atom:title"],
_title: ["title", "rss1:title", "atom03:title", "atom:title"],
link: [["link",strToURI],["rss1:link",strToURI]],
id: [["guid", makePropGetter("guid")], "rdf:about",
"atom03:id", "atom:id"],
_summary: ["description", "rss1:description", "dc:description",
"atom03:summary", "atom:summary"],
_content: ["content:encoded","atom03:content","atom:content"]
@ -453,9 +476,20 @@ Entry.prototype = {
normalize: function Entry_normalize() {
fieldsToObj(this, this.searchLists);
// Assign Atom link if needed
if (bagHasKey(this.fields, "links"))
this._atomLinksToURI();
// The link might be a guid w/ permalink=true
if (!this.link && bagHasKey(this.fields, "guid")) {
var guid = this.fields.getProperty("guid");
if (bagHasKey(guid, "isPermaLink")) {
var isPermaLink = new Boolean(guid.getProperty("isPermaLink"));
if (isPermaLink)
this.link = strToURI(guid.getProperty("guid"));
}
}
},
QueryInterface: function(iid) {
@ -1134,6 +1168,7 @@ FeedProcessor.prototype = {
this._state = "IN_" + elementInfo.fieldName.toUpperCase();
this._docVerified(elementInfo.feedVersion);
this._stack.push([this._feed, this._state]);
this._mapAttributes(this._feed, attributes);
}
else {
this._state = this._processComplexElement(elementInfo, attributes);
@ -1193,7 +1228,7 @@ FeedProcessor.prototype = {
function FP__processComplexElement(elementInfo, attributes) {
var obj, props, key, prefix;
// If the container is a feed or entry, it'll need to have its
// 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) {
@ -1208,15 +1243,7 @@ FeedProcessor.prototype = {
props = obj;
}
// Cycle through the attributes, and set our properties using the
// prefix:localNames we find in our namespace dictionary.
for (var i = 0; i < attributes.length; ++i) {
prefix = gNamespaces[attributes.getURI(i)] ?
gNamespaces[attributes.getURI(i)] + ":" : "";
key = prefix + attributes.getLocalName(i);
var val = attributes.getValue(i);
props.setPropertyAsAString(key, val);
}
this._mapAttributes(props, attributes);
// We should have a container/propertyBag that's had its
// attributes processed. Now we need to attach it to its
@ -1300,6 +1327,19 @@ FeedProcessor.prototype = {
container.replaceElementAt(element, container.length - 1, false);
},
_mapAttributes: function FP__mapAttributes(bag, attributes) {
// Cycle through the attributes, and set our properties using the
// prefix:localNames we find in our namespace dictionary.
for (var i = 0; i < attributes.length; ++i) {
prefix = gNamespaces[attributes.getURI(i)] ?
gNamespaces[attributes.getURI(i)] + ":" : "";
key = prefix + attributes.getLocalName(i);
var val = attributes.getValue(i);
bag.setPropertyAsAString(key, val);
}
},
// unknown element values are returned here. See startElement above
// for how this works.
returnFromExtHandler:

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: atom entry id
Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).id == "http://foo.example.com/hmm/ok,2006,07,11";
-->
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:foo="http://www.example.org"
foo:quux="quuux">
<title>hmm</title>
<author>
<email>hmm@example.com</email>
<name>foo</name>
</author>
<generator version="1.1" uri="http://example.org">Hmm</generator>
<author>
<email>bar@example.com</email>
<name>foo</name>
</author>
<rights type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><i>test</i> rights</div>
</rights>
<entry></entry>
<entry foo:bar="baz">
<title>test</title>
<id>http://foo.example.com/hmm/ok,2006,07,11</id>
</entry>
</feed>

View File

@ -2,7 +2,7 @@
<!--
Description: atom author name works
Expect: feed.fields.getProperty('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
Expect: feed.fields.getProperty('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6' && feed.id == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
-->
@ -24,4 +24,4 @@ Expect: feed.fields.getProperty('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-
<summary>Some text.</summary>
</entry>
</feed>
</feed>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Description: RSS1 feed w/ feed rdf:about
Expect: feed.id == 'http://www.xml.com/xml/news.rss'
-->
<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 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>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Description: RSS1 feed w/ item rdf:about
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).id == 'http://example.com/hmm'
-->
<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 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>
<!-- <dc:publisher>The O'Reilly Network</dc:publisher>
<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>
</item>
</rdf:RDF>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: item copes with bogus guid
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link == null;
-->
<rss version="2.0" >
<channel>
<item>
<enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" />
<author>jbb@dallas.example.com (Joe Bob Briggs)</author>
<comments>http://example.org</comments>
<title>test</title>
<guid isPermaLink="true">xorg</guid>
<category domain="foo">bar</category>
<description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
</channel>
</rss>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: item guid works
Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link.spec == 'http://www.example.org/';
-->
<rss version="2.0" >
<channel>
<item>
<enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" />
<author>jbb@dallas.example.com (Joe Bob Briggs)</author>
<title>test</title>
<guid isPermaLink="true">http://www.example.org/</guid>
<category domain="foo">bar</category>
<description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
</channel>
</rss>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: item guid works
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).id == 'asdf';
-->
<rss version="2.0" >
<channel>
<item>
<enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" />
<author>jbb@dallas.example.com (Joe Bob Briggs)</author>
<comments>http://example.org</comments>
<title>test</title>
<guid>asdf</guid>
<category domain="foo">bar</category>
<description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
</channel>
</rss>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: item prefers link to guid
Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == 'http://link.example.org/';
-->
<rss version="2.0" >
<channel>
<item>
<enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" />
<author>jbb@dallas.example.com (Joe Bob Briggs)</author>
<comments>http://example.org</comments>
<title>test</title>
<guid isPermaLink="true">http://www.example.org</guid>
<link>http://link.example.org/</link>
<category domain="foo">bar</category>
<description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
</channel>
</rss>