Version 0.1.2

This commit is contained in:
Fabio Manganiello 2023-01-18 19:07:04 +01:00
parent cb8c201b95
commit d32b0243d8
5 changed files with 114 additions and 25 deletions

View file

@ -11,7 +11,7 @@ import commonjs from '@rollup/plugin-commonjs';
import replace from '@rollup/plugin-replace';
import postcss from 'rollup-plugin-postcss';
import alias from 'rollup-plugin-alias';
import _dotenv from 'dotenv/config';
// import _dotenv from 'dotenv/config';
import path from "path";
export default {

View file

@ -1,8 +1,69 @@
import browser from 'webextension-polyfill';
let awaitingResponse = false
const onFeedDownloaded = (req: XMLHttpRequest) => {
return async () => {
awaitingResponse = false
if (req.status >= 400) {
console.error(
`Could not load URL feed: ${req.responseURL}: ` +
`${req.status}: ${req.statusText}`
)
return
}
const [tab] = await browser.tabs.query({
active: true,
currentWindow: true
})
if (!tab || tab.id === -1)
return
await browser.tabs.sendMessage(
tab.id, {
type: 'renderFeed',
document: req.responseText
}
)
}
}
const renderFeed = (url: string) => {
awaitingResponse = true
const req = new XMLHttpRequest()
req.onload = onFeedDownloaded(req)
req.open('GET', url)
req.responseType = 'text'
req.send()
}
browser.webNavigation.onCompleted.addListener(
async (event: {tabId: string;}) => {
async (event: {tabId: Number}) => {
const { tabId } = event
await browser.tabs.sendMessage(tabId, {type: 'renderFeed'})
}
)
browser.webRequest.onHeadersReceived.addListener(
async (event: {
url: string,
responseHeaders: Array<{name: string, value: string}>
}) => {
if (awaitingResponse)
return
const {url, responseHeaders} = event
const contentType = responseHeaders.find(
h => h.name.toLowerCase() === 'content-type'
)?.value || ''
if (contentType.startsWith('application/rss+xml'))
renderFeed(url)
},
{urls: ['<all_urls>']},
['blocking', 'responseHeaders']
)

View file

@ -103,9 +103,9 @@ const parseFeed = (channel: Element) => {
}
}
const getFeedRoot = () => {
const getFeedRoot = (): HTMLElement | null => {
const xmlDoc = document.documentElement
if (xmlDoc.tagName === 'rss')
if (xmlDoc.tagName.toLowerCase() === 'rss')
return xmlDoc
// Chrome-based browsers may wrap the XML into an HTML view
@ -116,28 +116,31 @@ const getFeedRoot = () => {
// For some ugly reasons, some RSS feeds are rendered inside of a <pre> in a normal HTML DOM
const preElements = document.getElementsByTagName('pre')
if (preElements.length !== 1)
return
return null
const text = preElements[0].innerText
return preElements[0]
}
const textToDOM = (text: string) => {
const parser = new DOMParser()
let innerXmlDoc = null
let xmlDoc = null
try {
// @ts-ignore
innerXmlDoc = parser.parseFromString(text, 'text/xml')
xmlDoc = parser.parseFromString(text, 'text/xml')
} catch (e) { }
if (!innerXmlDoc)
if (!xmlDoc)
return
// @ts-ignore
const root = innerXmlDoc.documentElement
if (root.tagName === 'rss')
const root = xmlDoc.documentElement
if (root.tagName.toLowerCase() === 'rss')
return root
}
const renderFeed = () => {
const xmlDoc = getFeedRoot()
const renderFeed = (text: string) => {
const xmlDoc = text?.length ? textToDOM(text) : getFeedRoot()
if (!xmlDoc)
// Not an RSS feed
return
@ -154,7 +157,7 @@ const extractFeedUrl = () => {
const links = Array.from(document.getElementsByTagName('link'))
.filter((link) =>
link.getAttribute('rel') === 'alternate' &&
link.getAttribute('type') === 'application/rss+xml'
link.getAttribute('type')?.startsWith('application/rss+xml')
)
if (!links.length)
@ -171,10 +174,20 @@ const extractFeedUrl = () => {
return link.length ? link : null
}
browser.runtime.onMessage.addListener(async (message: {type: Object}) => {
browser.runtime.onMessage.addListener(
async (
message: {
type: Object,
url: string,
document: string,
}
) => {
if (message.type === 'renderFeed')
return renderFeed()
return renderFeed(message.document)
if (message.type === 'extractFeedUrl')
return extractFeedUrl()
})
console.warn(`Received unknown message type: ${message.type}`)
}
)

View file

@ -1,7 +1,7 @@
{
"name": "RSS Viewer",
"description": "An easy way to render RSS feeds directly in your browser",
"version": "0.1.1",
"version": "0.1.2",
"manifest_version": 2,
"browser_action": {
"default_title": "Feed Viewer",
@ -26,6 +26,11 @@
"viewer/index.html"
],
"permissions": [
"activeTab", "storage", "<all_urls>", "webNavigation"
"activeTab",
"storage",
"<all_urls>",
"webNavigation",
"webRequest",
"webRequestBlocking"
]
}

View file

@ -64,6 +64,10 @@ export default {
</script>
<style lang="scss" scoped>
.feed {
font-family: -apple-system, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Open Sans", "Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
header {
padding: 0.5em;
box-shadow: 1px 1px 1px 1px #b7b7b7;
@ -153,9 +157,15 @@ main {
}
.content {
display: flex;
flex-direction: column;
padding: 1em;
font-size: 1.25em;
font-family: sans-serif;
.description {
max-width: 45em;
text-align: justify;
}
}
}
}