Mercurial > addons > firefox-addons > feed-preview
view js/feed-preview.js @ 37:6bd8a649186d
Fix charset encoding in rewritten Content-Type header
The charset encoding in the rewritten Content-Type header must be UTF-8 since
that is what the original response body will be converted to. This fixes the
garbled text seen when viewing feeds using charset encodings other than UTF-8.
author | Guido Berhoerster <guido+feed-preview@berhoerster.name> |
---|---|
date | Mon, 01 Apr 2019 21:04:05 +0200 |
parents | 4492db3b277e |
children |
line wrap: on
line source
/* * Copyright (C) 2018 Guido Berhoerster <guido+feed-preview@berhoerster.name> * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 'use strict'; function formatFileSize(size) { const LIMITS_UNITS = new Map([ [1024 * 1024 * 1024, 'GiB'], [1024 * 1024, 'MiB'], [1024, 'KiB'], [0, 'B'] ]) for (let [limit, unit] of LIMITS_UNITS) { if (size >= limit) { return `${Number(size / limit).toFixed(1)} ${unit}`; } } return '? B'; } export function renderFeedPreview(feedPreviewDocument, feed, expandEntriesByDefault) { // inject XSL stylesheet which transforms XHTML to HTML allowing the use of // the HTML DOM let xslFilename = browser.runtime.getURL('web_resources/xhtml-to-html.xsl'); let xmlStylesheetNode = feedPreviewDocument.createProcessingInstruction('xml-stylesheet', `type="application/xslt+xml" href="${xslFilename}"`); feedPreviewDocument.firstChild.after(xmlStylesheetNode); feedPreviewDocument.querySelector('#default-stylesheet').href = browser.runtime.getURL('web_resources/style/feed-preview.css'); // link to the currently viewed feed in order to allow feed reader addons // to subscribe to it let feedLinkElement = feedPreviewDocument.querySelector('#feed-link'); feedLinkElement.href = feed.url; feedLinkElement.type = feed.type; feedPreviewDocument.querySelector('title').textContent = feed.title; feedPreviewDocument.querySelector('label[for="feed-reader-selection"]') .textContent = browser.i18n.getMessage('feedReaderSelectionLabel'); feedPreviewDocument.querySelector('[name="subscribe"]').textContent = browser.i18n.getMessage('subscribeButtonLabel'); feedPreviewDocument.querySelector('#feed-title').textContent = feed.title; feedPreviewDocument.querySelector('#feed-subtitle').textContent = feed.subtitle; if (typeof feed.logo !== 'undefined') { let feedLogoTemplate = feedPreviewDocument.querySelector('#feed-logo-template'); let logoNode = feedPreviewDocument.importNode(feedLogoTemplate.content, true); let imgElement = logoNode.querySelector('#feed-logo'); imgElement.setAttribute('src', feed.logo.url); imgElement.setAttribute('alt', feed.logo.title); feedPreviewDocument.querySelector('#feed-header').prepend(logoNode); } feedPreviewDocument.querySelector("#no-entries-hint").textContent = browser.i18n.getMessage('noEntriesHint'); let entryTemplateElement = feedPreviewDocument.querySelector('#entry-template'); let entryTitleTemplateElement = feedPreviewDocument.querySelector('#entry-title-template'); let entryTitleLinkedTemplateElement = feedPreviewDocument.querySelector('#entry-title-linked-template'); let entryFileListTemplateElement = feedPreviewDocument.querySelector('#entry-files-list-template'); let entryFileTemplateElement = feedPreviewDocument.querySelector('#entry-file-template'); for (let entry of feed.entries) { let entryNode = feedPreviewDocument.importNode(entryTemplateElement.content, true); entryNode.querySelector('details.entry').open = expandEntriesByDefault; let titleElement; let titleNode; if (typeof entry.link !== 'undefined') { titleNode = feedPreviewDocument .importNode(entryTitleLinkedTemplateElement.content, true); titleElement = titleNode.querySelector('.entry-link'); titleElement.href = entry.link; titleElement.title = entry.title; } else { titleNode = feedPreviewDocument .importNode(entryTitleTemplateElement.content, true); titleElement = titleNode.querySelector('.entry-title'); } titleElement.textContent = entry.title; entryNode.querySelector('.entry-header').prepend(titleNode); let timeElement = entryNode.querySelector('.entry-date > time'); timeElement.textContent = entry.date.toLocaleString(); let contentElement = entryNode.querySelector('.entry-content'); let contentDocument = new DOMParser().parseFromString(entry.content, 'text/html'); let stylesheetElement = contentDocument.createElement('link'); stylesheetElement.rel = 'stylesheet'; stylesheetElement.href = browser.runtime.getURL('web_resources/style/entry-content.css'); contentDocument.head.appendChild(stylesheetElement); // open links in a new tab rather than within the iframe for (let linkElement of contentDocument.links) { linkElement.target = '_blank'; } contentElement.srcdoc = new XMLSerializer() .serializeToString(contentDocument); contentElement.title = entry.title; if (entry.files.length > 0) { let fileListNode = feedPreviewDocument .importNode(entryFileListTemplateElement.content, true); fileListNode.querySelector('.entry-files-title').textContent = browser.i18n.getMessage('filesTitle'); let fileListElement = fileListNode.querySelector('.entry-files-list'); for (let file of entry.files) { let fileNode = feedPreviewDocument .importNode(entryFileTemplateElement.content, true); let fileLinkElement = fileNode.querySelector('.entry-file-link'); fileLinkElement.href = file.url; fileLinkElement.title = file.filename; fileLinkElement.textContent = file.filename; fileNode.querySelector('.entry-file-info').textContent = `(${file.type}, ${ formatFileSize(file.size)})`; fileListElement.appendChild(fileNode); } entryNode.querySelector('.entry').append(fileListNode); } feedPreviewDocument.body.append(entryNode); } }