annotate js/background.js @ 14:376a0e415bba

Properly handle non-text content in Atom feed elements The title, subtitle, summary and content elements of Atom feeds can all have non-text content. When parsing title and subtitle elements HTML and XHTML content will be stripped of any markup in order to keep it simple. In summary and content elements markup will be preserved. Element content of any other type as well as remote content in content elements will be ignored.
author Guido Berhoerster <guido+feed-preview@berhoerster.name>
date Mon, 10 Dec 2018 16:38:11 +0100
parents a4590add4901
children a59d322e5826
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':
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
135 break;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
136 default:
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
137 // non-XML media type
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
138 return {};
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
139 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
140 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
141 `media type: ${contentType.mediaType}\n`,
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
142 `charset: ${contentType.charset}`);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
143
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
144 let decoder;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
145 try {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
146 decoder = new TextDecoder(contentType.charset);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
147 } catch (e) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
148 if (e instanceof RangeError) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
149 // unsupported charset
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
150 return {};
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
151 } else {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
152 throw e;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
153 }
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 let encoder = new TextEncoder();
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
156 let inputText = '';
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
157 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
158 filter.addEventListener('data', ev => {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
159 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
160 });
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
161 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
162 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
163 filter.write(encoder.encode(result));
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
164 filter.close();
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
165 });
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 details.responseHeaders[contentTypeIndex] = {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
168 name: 'Content-Type',
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
169 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
170 };
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
171
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
172 return {responseHeaders: details.responseHeaders};
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
173 },
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
174 {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
175 ['blocking', 'responseHeaders']);
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
176
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
177 browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
178 let tab = sender.tab;
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
179 if (typeof tab !== 'undefined') {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
180 // content script sending feeds
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
181 tabsFeeds.set(tab.id, request);
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
182 browser.pageAction.show(tab.id);
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
183 } else {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
184 // popup querying feeds
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
185 sendResponse(tabsFeeds.get(request));
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
186 }
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
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
189 browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
190 if (typeof changeInfo.url === 'undefined') {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
191 // filter out updates which do not change the URL
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
192 return;
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
193 }
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 // 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
196 // 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
197 browser.pageAction.hide(tabId);
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
198
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
199 // 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
200 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
201 browser.tabs.executeScript(tabId, {
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
202 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
203 });
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
204 tabsFeedPreviews.delete(tabId);
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
205 }
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
206 });
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 browser.tabs.onRemoved.addListener((tabId, removeInfo) => {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
209 tabsFeeds.delete(tabId);
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
210 tabsFeedPreviews.delete(tabId);
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
211 });
11
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
212
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
213 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
214 if (details.reason === 'install' ||
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
215 (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
216 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
217 let feedReadersSet =
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
218 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
219 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
220 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
221 feedReaders.push(feedReader);
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
222 }
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 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
225 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
226 }
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
227 });