changeset 19:3fcd2209b39a

Add support for RSS 1.0 feeds
author Guido Berhoerster <guido+feed-preview@berhoerster.name>
date Thu, 13 Dec 2018 09:02:40 +0100
parents 15db49e77deb
children a6625fd9a30d
files js/feed-parser.js
diffstat 1 files changed, 23 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/js/feed-parser.js	Thu Dec 13 08:47:06 2018 +0100
+++ b/js/feed-parser.js	Thu Dec 13 09:02:40 2018 +0100
@@ -12,6 +12,7 @@
     ATOM03: 'http://purl.org/atom/ns#',
     ATOM10: 'http://www.w3.org/2005/Atom',
     RSS09: 'http://my.netscape.com/rdf/simple/0.9/',
+    RSS10: 'http://purl.org/rss/1.0/',
     XHTML: 'http://www.w3.org/1999/xhtml',
     PARSERERROR: 'http://www.mozilla.org/newlayout/xml/parsererror.xml'
 }
@@ -70,8 +71,10 @@
             return XMLNS.ATOM03;
         case 'atom':
             return XMLNS.ATOM10;
-        case 'rss':
+        case 'rss09':
             return XMLNS.RSS09;
+        case 'rss10':
+            return XMLNS.RSS10;
     }
     return null;
 }
@@ -214,6 +217,9 @@
         } else if (documentElement.localName.toLowerCase() === 'rdf' &&
                 documentElement.getAttribute('xmlns') === XMLNS.RSS09) {
             return ['rss', '0.9'];
+        } else if (documentElement.localName.toLowerCase() === 'rdf' &&
+                documentElement.getAttribute('xmlns') === XMLNS.RSS10) {
+            return ['rss', '1.0'];
         }
 
         return [undefined, undefined];
@@ -588,10 +594,10 @@
         return new Feed(this.url, {title, subtitle, logo, entries});
     }
 
-    parseRSS1Logo(imageElement) {
+    parseRSS1Logo(imageElement, nsPrefix) {
         let title;
         let urlElement = feedQueryXPath(this.document, imageElement,
-                './rss:url');
+                `./${nsPrefix}:url`);
         if (urlElement === null) {
             throw new TypeError('missing <url> element in <logo> element');
         }
@@ -601,7 +607,7 @@
         }
 
         let titleElement = feedQueryXPath(this.document, imageElement,
-                './rss:title');
+                `./${nsPrefix}:title`);
         if (titleElement !== null) {
             title = titleElement.textContent.trim();
         }
@@ -609,17 +615,17 @@
         return new FeedLogo(url, {title});
     }
 
-    parseRSS1Entry(itemElement) {
+    parseRSS1Entry(itemElement, nsPrefix) {
         let title;
         let link;
         let titleElement = feedQueryXPath(this.document, itemElement,
-                './rss:title');
+                `./${nsPrefix}:title`);
         if (titleElement !== null) {
             title = titleElement.textContent;
         }
 
         let linkElement = feedQueryXPath(this.document, itemElement,
-                './rss:link');
+                `./${nsPrefix}:link`);
         if (linkElement !== null) {
             link = parseURL(linkElement.textContent, this.url);
         }
@@ -627,29 +633,30 @@
         return new FeedEntry({title, link});
     }
 
-    parseRSS1Feed() {
+    parseRSS1Feed(version) {
+        let nsPrefix = version === '0.9' ? 'rss09' : 'rss10';
         let title;
         let subtitle;
         let logo;
         let entries = [];
         let documentElement = this.document.documentElement;
         let titleElement = feedQueryXPath(this.document, documentElement,
-                './rss:channel/rss:title');
+                `./${nsPrefix}:channel/${nsPrefix}:title`);
         if (titleElement !== null) {
             title = titleElement.textContent;
         }
 
         let descriptionElement = feedQueryXPath(this.document, documentElement,
-                './rss:channel/rss:description');
+                `./${nsPrefix}:channel/${nsPrefix}:description`);
         if (descriptionElement !== null) {
             subtitle = descriptionElement.textContent;
         }
 
         let imageElement = feedQueryXPath(this.document, documentElement,
-                './rss:image');
+                `./${nsPrefix}:image`);
         if (imageElement !== null) {
             try {
-                logo = this.parseRSS1Logo(imageElement);
+                logo = this.parseRSS1Logo(imageElement, nsPrefix);
             } catch (e) {
                 if (!(e instanceof TypeError)) {
                     throw e;
@@ -658,9 +665,9 @@
         }
 
         let itemElements = feedQueryXPathAll(this.document, documentElement,
-                './rss:item');
+                `./${nsPrefix}:item`);
         for (let itemElement of itemElements) {
-            let entry = this.parseRSS1Entry(itemElement);
+            let entry = this.parseRSS1Entry(itemElement, nsPrefix);
             if (typeof entry !== 'undefined') {
                 entries.push(entry);
             }
@@ -813,8 +820,8 @@
                 return this.parseAtomFeed();
             }
         } else if (type === 'rss') {
-            if (version === '0.9') {
-                return this.parseRSS1Feed();
+            if (version === '0.9' || version === '1.0') {
+                return this.parseRSS1Feed(version);
             } else {
                 return this.parseRSS2Feed();
             }