annotate js/background.js @ 16:a59d322e5826

Support feeds served as text/xml
author Guido Berhoerster <guido+feed-preview@berhoerster.name>
date Wed, 12 Dec 2018 10:56:37 +0100
parents 376a0e415bba
children 688d75e554e0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
1 /*
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
2 * Copyright (C) 2018 Guido Berhoerster <guido+feed-preview@berhoerster.name>
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
3 *
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
4 * This Source Code Form is subject to the terms of the Mozilla Public
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
7 */
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
8
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
9 'use strict';
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
10
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
11 import * as feedParser from './feed-parser.js';
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
12 import {renderFeedPreview} from './feed-preview.js';
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
13
11
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
14 const FEED_READERS_PRESET = [
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
15 {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
16 title: 'Feedly',
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
17 urlTemplate: 'https://feedly.com/#subscription/feed/%s'
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
18 },
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
19 {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
20 title: 'FlowReader',
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
21 urlTemplate: 'https://www.flowreader.com/subscribe?url=%s'
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
22 },
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
23 {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
24 title: 'InoReader',
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
25 urlTemplate: 'https://www.inoreader.com/feed/%s'
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
26 },
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
27 {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
28 title: 'Kouio',
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
29 urlTemplate: 'https://kouio.com/subscribe?url=%s'
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
30 },
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
31 {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
32 title: 'My Yahoo',
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
33 urlTemplate: 'https://add.my.yahoo.com/rss?url=%s'
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
34 },
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
35 {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
36 title: 'Netvibes',
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
37 urlTemplate: 'https://www.netvibes.com/subscribe.php?url=%s'
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
38 },
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
39 {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
40 title: 'NewsBlur',
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
41 urlTemplate: 'https://www.newsblur.com/?url=%s'
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
42 },
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
43 {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
44 title: 'The Old Reader',
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
45 urlTemplate: 'https://theoldreader.com/feeds/subscribe?url=%s'
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
46 }
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
47 ];
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
48 const FEED_MAGIC = [
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
49 '<rss',
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
50 '<feed',
14
376a0e415bba Properly handle non-text content in Atom feed elements
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 11
diff changeset
51 feedParser.XMLNS.ATOM03,
376a0e415bba Properly handle non-text content in Atom feed elements
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 11
diff changeset
52 feedParser.XMLNS.ATOM10,
376a0e415bba Properly handle non-text content in Atom feed elements
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 11
diff changeset
53 feedParser.XMLNS.RSS09,
376a0e415bba Properly handle non-text content in Atom feed elements
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 11
diff changeset
54 feedParser.XMLNS.RSS10
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
55 ];
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
56 var tabsFeeds = new Map();
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
57 var tabsFeedPreviews = new Map();
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
58 var fetchingFeedPreview = fetch('web_resources/feed-preview.xhtml')
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
59 .then(response => response.text());
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
60
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
61 function parseContentType(header) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
62 let contentType = {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
63 mediaType: '',
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
64 charset: 'utf-8'
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
65 };
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
66 let parts = header.toLowerCase().split(';');
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
67 contentType.mediaType = parts.shift().trim();
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
68 for (let parameter of parts) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
69 let [, name, value, ] = parameter.trim().split(/([^=]+)="?([^"]*)"?/);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
70 if (name.toLowerCase() === 'charset') {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
71 contentType.charset = value.toLowerCase();
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
72 break;
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
73 }
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
74 }
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
75
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
76 return contentType;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
77 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
78
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
79 async function handleFeed(inputText, tabId, url) {
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
80 // fast-path: eliminate XML documents which cannot be Atom nor RSS feeds
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
81 let inputTextStart = inputText.substring(0, 512);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
82 if (!FEED_MAGIC.some(element => inputTextStart.includes(element))) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
83 return inputText;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
84 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
85
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
86 let feed;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
87 try {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
88 feed = (new feedParser.FeedParser).parseFromString(inputText, url);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
89 } catch (e) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
90 if (e instanceof feedParser.ParserError ||
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
91 e instanceof feedParser.UnsupportedFeedTypeError) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
92 // let the browser deal with non-well formed XML or XML documents
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
93 // which are not supported Atom or RSS feeds
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
94 return inputText;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
95 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
96 throw e;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
97 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
98 console.log(`parsed feed ${url}:\n`, feed);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
99
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
100 // mark this feed preview for content script injection
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
101 tabsFeedPreviews.set(tabId, url);
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
102
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
103 // render the preview document
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
104 let feedPreviewDocument = new DOMParser()
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
105 .parseFromString(await fetchingFeedPreview, 'text/html');
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
106 renderFeedPreview(feedPreviewDocument, feed);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
107
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
108 return new XMLSerializer().serializeToString(feedPreviewDocument);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
109 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
110
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
111 browser.webRequest.onHeadersReceived.addListener(details => {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
112 if (details.statusCode !== 200) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
113 return {};
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
114 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
115
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
116 let contentTypeIndex = details.responseHeaders.findIndex(header =>
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
117 header.name.toLowerCase() === 'content-type' &&
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
118 typeof header.value !== 'undefined');
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
119 if (contentTypeIndex < 0) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
120 // no Content-Type header found
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
121 return {};
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
122 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
123 let headerValue = details.responseHeaders[contentTypeIndex].value
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
124 let contentType = parseContentType(headerValue);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
125 // until content handlers become available to webextensions
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
126 // (https://bugzilla.mozilla.org/show_bug.cgi?id=1457500) intercept all
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
127 // responses and change the content type from application/atom+xml or
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
128 // application/rss+xml to application/xml which will then be probed for
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
129 // Atom or RSS content
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
130 switch (contentType.mediaType) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
131 case 'application/atom+xml':
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
132 case 'application/rss+xml':
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
133 case 'application/rdf+xml':
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
134 case 'application/xml':
16
a59d322e5826 Support feeds served as text/xml
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 14
diff changeset
135 case 'text/xml':
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
136 break;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
137 default:
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
138 // non-XML media type
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
139 return {};
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
140 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
141 console.log(`response is an XML document\n`,
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
142 `media type: ${contentType.mediaType}\n`,
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
143 `charset: ${contentType.charset}`);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
144
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
145 let decoder;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
146 try {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
147 decoder = new TextDecoder(contentType.charset);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
148 } catch (e) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
149 if (e instanceof RangeError) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
150 // unsupported charset
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
151 return {};
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
152 } else {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
153 throw e;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
154 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
155 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
156 let encoder = new TextEncoder();
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
157 let inputText = '';
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
158 let filter = browser.webRequest.filterResponseData(details.requestId);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
159 filter.addEventListener('data', ev => {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
160 inputText += decoder.decode(ev.data, {stream: true});
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
161 });
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
162 filter.addEventListener('stop', async ev => {
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
163 let result = await handleFeed(inputText, details.tabId, details.url);
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
164 filter.write(encoder.encode(result));
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
165 filter.close();
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
166 });
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
167
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
168 details.responseHeaders[contentTypeIndex] = {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
169 name: 'Content-Type',
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
170 value: `application/xml;charset=${contentType.charset}`
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
171 };
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
172
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
173 return {responseHeaders: details.responseHeaders};
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
174 },
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
175 {urls: ['http://*/*', 'https://*/*'], types: ['main_frame']},
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
176 ['blocking', 'responseHeaders']);
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
177
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
178 browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
179 let tab = sender.tab;
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
180 if (typeof tab !== 'undefined') {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
181 // content script sending feeds
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
182 tabsFeeds.set(tab.id, request);
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
183 browser.pageAction.show(tab.id);
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
184 } else {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
185 // popup querying feeds
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
186 sendResponse(tabsFeeds.get(request));
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
187 }
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
188 });
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
189
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
190 browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
191 if (typeof changeInfo.url === 'undefined') {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
192 // filter out updates which do not change the URL
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
193 return;
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
194 }
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
195
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
196 // hide the page action when the URL changes since it is no longer valid,
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
197 // it will be shown again if the content script detects a feed
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
198 browser.pageAction.hide(tabId);
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
199
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
200 // inject content script once if the requested URL is a feed preview
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
201 if (tabsFeedPreviews.get(tabId) === changeInfo.url) {
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
202 browser.tabs.executeScript(tabId, {
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
203 file: 'content_scripts/feed-readers.js'
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
204 });
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
205 tabsFeedPreviews.delete(tabId);
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
206 }
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
207 });
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
208
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
209 browser.tabs.onRemoved.addListener((tabId, removeInfo) => {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
210 tabsFeeds.delete(tabId);
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
211 tabsFeedPreviews.delete(tabId);
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
212 });
11
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
213
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
214 browser.runtime.onInstalled.addListener(async details => {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
215 if (details.reason === 'install' ||
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
216 (details.reason === 'update' && details.previousVersion < 2)) {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
217 let {feedReaders = []} = await browser.storage.sync.get('feedReaders');
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
218 let feedReadersSet =
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
219 new Set(feedReaders.map(feedReader => feedReader.urlTemplate));
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
220 for (let feedReader of FEED_READERS_PRESET) {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
221 if (!feedReadersSet.has(feedReader.urlTemplate)) {
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
222 feedReaders.push(feedReader);
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
223 }
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
224 }
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
225 console.log('set feedReaders to', feedReaders);
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
226 browser.storage.sync.set({feedReaders});
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
227 }
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
228 });