annotate js/background.js @ 46:586eebf8efb7

Work around race condition in feed reader subscription script execution browser.tabs.executeScript() should only run the script once the feed preview page is completely loaded but there seems to be a race condition where it is run too early resulting in disabled feed reader subscription.
author Guido Berhoerster <guido+feed-preview@berhoerster.name>
date Wed, 03 Jul 2019 15:51:36 +0200
parents 6bd8a649186d
children ede87e1004f9
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());
29
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
60 var feedPreviewOptions = {
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
61 expandEntries: false
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
62 };
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
63
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
64 function parseContentType(header) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
65 let contentType = {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
66 mediaType: '',
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
67 charset: 'utf-8'
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
68 };
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
69 let parts = header.toLowerCase().split(';');
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
70 contentType.mediaType = parts.shift().trim();
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
71 for (let parameter of parts) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
72 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
73 if (name.toLowerCase() === 'charset') {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
74 contentType.charset = value.toLowerCase();
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
75 break;
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
76 }
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
77 }
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
78
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
79 return contentType;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
80 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
81
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
82 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
83 // 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
84 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
85 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
86 return inputText;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
87 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
88
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
89 let feed;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
90 try {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
91 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
92 } catch (e) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
93 if (e instanceof feedParser.ParserError ||
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
94 e instanceof feedParser.UnsupportedFeedTypeError) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
95 // 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
96 // 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
97 return inputText;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
98 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
99 throw e;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
100 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
101 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
102
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
103 // 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
104 tabsFeedPreviews.set(tabId, url);
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
105
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
106 // render the preview document
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
107 let feedPreviewDocument = new DOMParser()
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
108 .parseFromString(await fetchingFeedPreview, 'text/html');
29
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
109 renderFeedPreview(feedPreviewDocument, feed,
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
110 feedPreviewOptions.expandEntries);
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
111
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
112 return new XMLSerializer().serializeToString(feedPreviewDocument);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
113 }
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 browser.webRequest.onHeadersReceived.addListener(details => {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
116 if (details.statusCode !== 200) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
117 return {};
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
118 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
119
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
120 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
121 header.name.toLowerCase() === 'content-type' &&
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
122 typeof header.value !== 'undefined');
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
123 if (contentTypeIndex < 0) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
124 // no Content-Type header found
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
125 return {};
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
126 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
127 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
128 let contentType = parseContentType(headerValue);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
129 // 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
130 // (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
131 // 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
132 // 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
133 // Atom or RSS content
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
134 switch (contentType.mediaType) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
135 case 'application/atom+xml':
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
136 case 'application/rss+xml':
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
137 case 'application/rdf+xml':
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
138 case 'application/xml':
16
a59d322e5826 Support feeds served as text/xml
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 14
diff changeset
139 case 'text/xml':
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
140 break;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
141 default:
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
142 // non-XML media type
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
143 return {};
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 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
146 `media type: ${contentType.mediaType}\n`,
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
147 `charset: ${contentType.charset}`);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
148
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
149 let decoder;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
150 try {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
151 decoder = new TextDecoder(contentType.charset);
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
152 } catch (e) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
153 if (e instanceof RangeError) {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
154 // unsupported charset
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
155 return {};
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
156 } else {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
157 throw e;
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
158 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
159 }
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
160 let encoder = new TextEncoder();
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
161 let inputText = '';
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
162 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
163 filter.addEventListener('data', ev => {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
164 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
165 });
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
166 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
167 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
168 filter.write(encoder.encode(result));
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
169 filter.close();
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
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
172 details.responseHeaders[contentTypeIndex] = {
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
173 name: 'Content-Type',
37
6bd8a649186d Fix charset encoding in rewritten Content-Type header
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 29
diff changeset
174 value: 'application/xml;charset=utf-8'
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
175 };
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
176
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
177 return {responseHeaders: details.responseHeaders};
6
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
178 },
5d7c13e998e9 Create feed previews using a stream filter
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 0
diff changeset
179 {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
180 ['blocking', 'responseHeaders']);
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
181
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
182 browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
183 let tab = sender.tab;
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
184 if (typeof tab !== 'undefined') {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
185 // content script sending feeds
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
186 tabsFeeds.set(tab.id, request);
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
187 browser.pageAction.show(tab.id);
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
188 } else {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
189 // popup querying feeds
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
190 sendResponse(tabsFeeds.get(request));
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
191 }
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
192 });
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
193
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
194 browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
46
586eebf8efb7 Work around race condition in feed reader subscription script execution
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 37
diff changeset
195 if (changeInfo.status !== 'complete') {
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
196 return;
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
197 }
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
198
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
199 // 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
200 // 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
201 browser.pageAction.hide(tabId);
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
202
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
203 // inject content script once if the requested URL is a feed preview
46
586eebf8efb7 Work around race condition in feed reader subscription script execution
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 37
diff changeset
204 if (tabsFeedPreviews.get(tabId) === tab.url) {
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
205 browser.tabs.executeScript(tabId, {
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
206 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
207 });
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
208 tabsFeedPreviews.delete(tabId);
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
209 }
46
586eebf8efb7 Work around race condition in feed reader subscription script execution
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 37
diff changeset
210 }, {properties: ["status"]});
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
211
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
212 browser.tabs.onRemoved.addListener((tabId, removeInfo) => {
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
213 tabsFeeds.delete(tabId);
10
ff5e5e3eba32 Implement feed subscription for web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 6
diff changeset
214 tabsFeedPreviews.delete(tabId);
0
bc5cc170163c Initial revision
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents:
diff changeset
215 });
11
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
216
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
217 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
218 if (details.reason === 'install' ||
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
219 (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
220 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
221 let feedReadersSet =
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
222 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
223 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
224 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
225 feedReaders.push(feedReader);
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 }
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
228 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
229 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
230 }
a4590add4901 Add preset with common web-based feed readers
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 10
diff changeset
231 });
29
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
232
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
233 browser.storage.sync.get('feedPreview').then(({feedPreview}) => {
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
234 if (typeof feedPreview !== 'undefined' &&
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
235 feedPreview === Object(feedPreview)) {
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
236 feedPreviewOptions.expandEntries = !!feedPreview.expandEntries;
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
237 }
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
238 });
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
239 browser.storage.onChanged.addListener((changes, areaName) => {
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
240 if (areaName !== 'sync' || typeof changes.feedPreview === 'undefined') {
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
241 return;
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
242 }
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
243
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
244 let newValue = changes.feedPreview.newValue;
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
245 if (typeof newValue !== 'undefined' && newValue === Object(newValue)) {
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
246 feedPreviewOptions.expandEntries = !!newValue.expandEntries;
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
247 }
688d75e554e0 Add option to expand feed entries by default
Guido Berhoerster <guido+feed-preview@berhoerster.name>
parents: 16
diff changeset
248 });