Mercurial > addons > firefox-addons > feed-preview
comparison js/background.js @ 10:ff5e5e3eba32
Implement feed subscription for web-based feed readers
Add options page for configuring web-based feed readers which allow for
subscribing to feeds via GET requests.
Track tabs containing feed previews and inject a content script which
retrieves the configured feed readers and keeps them in sync.
author | Guido Berhoerster <guido+feed-preview@berhoerster.name> |
---|---|
date | Fri, 07 Dec 2018 23:00:41 +0100 |
parents | 5d7c13e998e9 |
children | a4590add4901 |
comparison
equal
deleted
inserted
replaced
9:fcd65cf3f634 | 10:ff5e5e3eba32 |
---|---|
15 '<rss', | 15 '<rss', |
16 '<feed', | 16 '<feed', |
17 ...Object.values(feedParser.XMLNS) | 17 ...Object.values(feedParser.XMLNS) |
18 ]; | 18 ]; |
19 var tabsFeeds = new Map(); | 19 var tabsFeeds = new Map(); |
20 var tabsFeedPreviews = new Map(); | |
20 var fetchingFeedPreview = fetch('web_resources/feed-preview.xhtml') | 21 var fetchingFeedPreview = fetch('web_resources/feed-preview.xhtml') |
21 .then(response => response.text()); | 22 .then(response => response.text()); |
22 | 23 |
23 function parseContentType(header) { | 24 function parseContentType(header) { |
24 let contentType = { | 25 let contentType = { |
36 } | 37 } |
37 | 38 |
38 return contentType; | 39 return contentType; |
39 } | 40 } |
40 | 41 |
41 async function handleFeed(inputText, url) { | 42 async function handleFeed(inputText, tabId, url) { |
42 // fast-path: eliminate XML documents which cannot be Atom nor RSS feeds | 43 // fast-path: eliminate XML documents which cannot be Atom nor RSS feeds |
43 let inputTextStart = inputText.substring(0, 512); | 44 let inputTextStart = inputText.substring(0, 512); |
44 if (!FEED_MAGIC.some(element => inputTextStart.includes(element))) { | 45 if (!FEED_MAGIC.some(element => inputTextStart.includes(element))) { |
45 return inputText; | 46 return inputText; |
46 } | 47 } |
56 return inputText; | 57 return inputText; |
57 } | 58 } |
58 throw e; | 59 throw e; |
59 } | 60 } |
60 console.log(`parsed feed ${url}:\n`, feed); | 61 console.log(`parsed feed ${url}:\n`, feed); |
62 | |
63 // mark this feed preview for content script injection | |
64 tabsFeedPreviews.set(tabId, url); | |
61 | 65 |
62 // render the preview document | 66 // render the preview document |
63 let feedPreviewDocument = new DOMParser() | 67 let feedPreviewDocument = new DOMParser() |
64 .parseFromString(await fetchingFeedPreview, 'text/html'); | 68 .parseFromString(await fetchingFeedPreview, 'text/html'); |
65 renderFeedPreview(feedPreviewDocument, feed); | 69 renderFeedPreview(feedPreviewDocument, feed); |
116 let filter = browser.webRequest.filterResponseData(details.requestId); | 120 let filter = browser.webRequest.filterResponseData(details.requestId); |
117 filter.addEventListener('data', ev => { | 121 filter.addEventListener('data', ev => { |
118 inputText += decoder.decode(ev.data, {stream: true}); | 122 inputText += decoder.decode(ev.data, {stream: true}); |
119 }); | 123 }); |
120 filter.addEventListener('stop', async ev => { | 124 filter.addEventListener('stop', async ev => { |
121 let result = await handleFeed(inputText, details.url); | 125 let result = await handleFeed(inputText, details.tabId, details.url); |
122 filter.write(encoder.encode(result)); | 126 filter.write(encoder.encode(result)); |
123 filter.close(); | 127 filter.close(); |
124 }); | 128 }); |
125 | 129 |
126 details.responseHeaders[contentTypeIndex] = { | 130 details.responseHeaders[contentTypeIndex] = { |
143 // popup querying feeds | 147 // popup querying feeds |
144 sendResponse(tabsFeeds.get(request)); | 148 sendResponse(tabsFeeds.get(request)); |
145 } | 149 } |
146 }); | 150 }); |
147 | 151 |
148 browser.tabs.onUpdated.addListener((id, changeInfo, tab) => { | 152 browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { |
149 if (typeof changeInfo.url === 'undefined') { | 153 if (typeof changeInfo.url === 'undefined') { |
150 // filter out updates which do not change the URL | 154 // filter out updates which do not change the URL |
151 return; | 155 return; |
152 } | 156 } |
153 | 157 |
154 // hide the page action when the URL changes since it is no longer valid, | 158 // hide the page action when the URL changes since it is no longer valid, |
155 // it will be shown again if the content script detects a feed | 159 // it will be shown again if the content script detects a feed |
156 browser.pageAction.hide(tab.id); | 160 browser.pageAction.hide(tabId); |
161 | |
162 // inject content script once if the requested URL is a feed preview | |
163 if (tabsFeedPreviews.get(tabId) === changeInfo.url) { | |
164 browser.tabs.executeScript(tabId, { | |
165 file: 'content_scripts/feed-readers.js' | |
166 }); | |
167 tabsFeedPreviews.delete(tabId); | |
168 } | |
157 }); | 169 }); |
158 | 170 |
159 browser.tabs.onRemoved.addListener((tabId, removeInfo) => { | 171 browser.tabs.onRemoved.addListener((tabId, removeInfo) => { |
160 tabsFeeds.delete(tabId); | 172 tabsFeeds.delete(tabId); |
173 tabsFeedPreviews.delete(tabId); | |
161 }); | 174 }); |