summaryrefslogtreecommitdiffstats
path: root/mobile/android/android-components/components/feature/readerview
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:43:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:43:14 +0000
commit8dd16259287f58f9273002717ec4d27e97127719 (patch)
tree3863e62a53829a84037444beab3abd4ed9dfc7d0 /mobile/android/android-components/components/feature/readerview
parentReleasing progress-linux version 126.0.1-1~progress7.99u1. (diff)
downloadfirefox-8dd16259287f58f9273002717ec4d27e97127719.tar.xz
firefox-8dd16259287f58f9273002717ec4d27e97127719.zip
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mobile/android/android-components/components/feature/readerview')
-rw-r--r--mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/manifest.template.json5
-rw-r--r--mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-background.js24
-rw-r--r--mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-content.js64
-rw-r--r--mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.html14
-rw-r--r--mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.js194
5 files changed, 167 insertions, 134 deletions
diff --git a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/manifest.template.json b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/manifest.template.json
index 616b2036eb..7eb8d17589 100644
--- a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/manifest.template.json
+++ b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/manifest.template.json
@@ -10,7 +10,10 @@
"content_scripts": [
{
"matches": ["<all_urls>"],
- "js": ["readability/readability-readerable-0.4.2.js", "readerview-content.js"],
+ "js": [
+ "readability/readability-readerable-0.4.2.js",
+ "readerview-content.js"
+ ],
"run_at": "document_idle"
}
],
diff --git a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-background.js b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-background.js
index 136e5e40e3..41e7b1f538 100644
--- a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-background.js
+++ b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-background.js
@@ -7,16 +7,16 @@
browser.runtime.onMessage.addListener(message => {
switch (message.action) {
- case 'addSerializedDoc':
- browser.storage.session.set({ [message.id]: message.doc });
- return Promise.resolve();
- case 'getSerializedDoc':
- return (async () => {
- let doc = await browser.storage.session.get(message.id);
- browser.storage.session.remove(message.id);
- return doc[message.id];
- })();
- default:
- console.error(`Received unsupported action ${message.action}`);
- }
+ case "addSerializedDoc":
+ browser.storage.session.set({ [message.id]: message.doc });
+ return Promise.resolve();
+ case "getSerializedDoc":
+ return (async () => {
+ let doc = await browser.storage.session.get(message.id);
+ browser.storage.session.remove(message.id);
+ return doc[message.id];
+ })();
+ default:
+ console.error(`Received unsupported action ${message.action}`);
+ }
});
diff --git a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-content.js b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-content.js
index 1d5859e793..cdcbe0434c 100644
--- a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-content.js
+++ b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-content.js
@@ -17,43 +17,53 @@ const blockedHosts = [
"pinterest.com",
"reddit.com",
"twitter.com",
- "youtube.com"
+ "youtube.com",
];
function isReaderable() {
- if (!supportedProtocols.includes(location.protocol)) {
- return false;
- }
+ if (!supportedProtocols.includes(location.protocol)) {
+ return false;
+ }
- if (blockedHosts.some(blockedHost => location.hostname.endsWith(blockedHost))) {
- return false;
- }
+ if (
+ blockedHosts.some(blockedHost => location.hostname.endsWith(blockedHost))
+ ) {
+ return false;
+ }
- if (location.pathname == "/") {
- return false;
- }
+ if (location.pathname == "/") {
+ return false;
+ }
- return isProbablyReaderable(document, _isNodeVisible);
+ return isProbablyReaderable(document, _isNodeVisible);
}
function _isNodeVisible(node) {
- return node.clientHeight > 0 && node.clientWidth > 0;
+ return node.clientHeight > 0 && node.clientWidth > 0;
}
function connectNativePort() {
let port = browser.runtime.connectNative("mozacReaderview");
- port.onMessage.addListener((message) => {
- switch (message.action) {
- case 'cachePage':
- let serializedDoc = new XMLSerializer().serializeToString(document);
- browser.runtime.sendMessage({action: "addSerializedDoc", doc: serializedDoc, id: message.id});
- break;
- case 'checkReaderState':
- port.postMessage({type: 'checkReaderState', baseUrl: browser.runtime.getURL("/"), readerable: isReaderable()});
- break;
- default:
- console.error(`Received unsupported action ${message.action}`);
- }
+ port.onMessage.addListener(message => {
+ switch (message.action) {
+ case "cachePage":
+ let serializedDoc = new XMLSerializer().serializeToString(document);
+ browser.runtime.sendMessage({
+ action: "addSerializedDoc",
+ doc: serializedDoc,
+ id: message.id,
+ });
+ break;
+ case "checkReaderState":
+ port.postMessage({
+ type: "checkReaderState",
+ baseUrl: browser.runtime.getURL("/"),
+ readerable: isReaderable(),
+ });
+ break;
+ default:
+ console.error(`Received unsupported action ${message.action}`);
+ }
});
return port;
@@ -65,11 +75,11 @@ let port = connectNativePort();
// do want to connect a new native port to trigger a new readerable check and
// apply the same logic (as on page load) in our feature class (e.g. updating the
// toolbar etc.)
-window.addEventListener("pageshow", (event) => {
- port = (port != null)? port : connectNativePort();
+window.addEventListener("pageshow", event => {
+ port = port != null ? port : connectNativePort();
});
-window.addEventListener("pagehide", (event) => {
+window.addEventListener("pagehide", event => {
port.disconnect();
port = null;
});
diff --git a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.html b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.html
index b09deb7811..99afab71a4 100644
--- a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.html
+++ b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.html
@@ -4,14 +4,14 @@
<html>
<head>
- <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
- <meta name="viewport" content="width=device-width; user-scalable=0" />
- <meta http-equiv="cache-control" content="no-store" />
+ <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
+ <meta name="viewport" content="width=device-width; user-scalable=0" />
+ <meta http-equiv="cache-control" content="no-store" />
- <link rel="stylesheet" href="readerview.css" />
+ <link rel="stylesheet" href="readerview.css" />
- <script src="readability/JSDOMParser-0.4.2.js"></script>
- <script src="readability/readability-0.4.2.js"></script>
- <script src="readerview.js"></script>
+ <script src="readability/JSDOMParser-0.4.2.js"></script>
+ <script src="readability/readability-0.4.2.js"></script>
+ <script src="readerview.js"></script>
</head>
</html>
diff --git a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.js b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.js
index 23b1f35250..ddea9218b0 100644
--- a/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.js
+++ b/mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.js
@@ -15,11 +15,10 @@ const preservedClasses = [
"visuallyhidden",
"wp-caption",
"wp-caption-text",
- "wp-smiley"
+ "wp-smiley",
];
class ReaderView {
-
static get MIN_FONT_SIZE() {
return 1;
}
@@ -37,18 +36,24 @@ class ReaderView {
* @param url the url of the article.
* @param options the fontSize, fontType and colorScheme to use.
*/
- show(doc, url, options = {fontSize: 4, fontType: "sans-serif", colorScheme: "light"}) {
- let result = new Readability(doc, {classesToPreserve: preservedClasses}).parse();
+ show(
+ doc,
+ url,
+ options = { fontSize: 4, fontType: "sans-serif", colorScheme: "light" }
+ ) {
+ let result = new Readability(doc, {
+ classesToPreserve: preservedClasses,
+ }).parse();
result.language = doc.documentElement.lang;
document.title = result.title;
let article = Object.assign(
result,
- {url: new URL(url)},
- {readingTime: this.getReadingTime(result.length, result.language)},
- {byline: this.getByline(result)},
- {dir: this.getTextDirection(result)},
- {title: this.getTitle(result)}
+ { url: new URL(url) },
+ { readingTime: this.getReadingTime(result.length, result.language) },
+ { byline: this.getByline(result) },
+ { dir: this.getTextDirection(result) },
+ { title: this.getTitle(result) }
);
document.body.outerHTML = this.createHtmlBody(article);
@@ -57,7 +62,7 @@ class ReaderView {
this.setFontType(options.fontType);
this.setColorScheme(options.colorScheme);
if (options.scrollY) {
- window.scrollTo({top: options.scrollY, left: 0, behavior: "instant"});
+ window.scrollTo({ top: options.scrollY, left: 0, behavior: "instant" });
}
}
@@ -68,7 +73,10 @@ class ReaderView {
* @param changeAmount e.g. +1, or -1.
*/
changeFontSize(changeAmount) {
- var size = Math.max(ReaderView.MIN_FONT_SIZE, Math.min(ReaderView.MAX_FONT_SIZE, this.fontSize + changeAmount));
+ var size = Math.max(
+ ReaderView.MIN_FONT_SIZE,
+ Math.min(ReaderView.MAX_FONT_SIZE, this.fontSize + changeAmount)
+ );
this.setFontSize(size);
}
@@ -79,7 +87,7 @@ class ReaderView {
* and ReaderView.MAX_FONT_SIZE.
*/
setFontSize(fontSize) {
- let size = (10 + 2 * fontSize) + "px";
+ let size = 10 + 2 * fontSize + "px";
let readerView = document.getElementById("mozac-readerview-container");
readerView.style.setProperty("font-size", size);
this.fontSize = fontSize;
@@ -108,8 +116,8 @@ class ReaderView {
* or sepia.
*/
setColorScheme(colorScheme) {
- if(!['light', 'sepia', 'dark'].includes(colorScheme)) {
- console.error(`Invalid color scheme specified: ${colorScheme}`)
+ if (!["light", "sepia", "dark"].includes(colorScheme)) {
+ console.error(`Invalid color scheme specified: ${colorScheme}`);
return;
}
@@ -152,7 +160,7 @@ class ReaderView {
</div>
</div>
</body>
- `
+ `;
}
/**
@@ -162,17 +170,21 @@ class ReaderView {
* @param optional language of the article, defaults to en.
*/
getReadingTime(length, lang = "en") {
- const [readingSpeed, readingSpeedLang] = this.getReadingSpeedForLanguage(lang);
+ const [readingSpeed, readingSpeedLang] =
+ this.getReadingSpeedForLanguage(lang);
const charactersPerMinuteLow = readingSpeed.cpm - readingSpeed.variance;
const charactersPerMinuteHigh = readingSpeed.cpm + readingSpeed.variance;
const readingTimeMinsSlow = Math.ceil(length / charactersPerMinuteLow);
- const readingTimeMinsFast = Math.ceil(length / charactersPerMinuteHigh);
+ const readingTimeMinsFast = Math.ceil(length / charactersPerMinuteHigh);
// Construct a localized and "humanized" reading time in minutes.
// If we have both a fast and slow reading time we'll show both e.g.
// "2 - 4 minutes", otherwise we'll just show "4 minutes".
try {
- var parts = new Intl.RelativeTimeFormat(readingSpeedLang).formatToParts(readingTimeMinsSlow, 'minute');
+ var parts = new Intl.RelativeTimeFormat(readingSpeedLang).formatToParts(
+ readingTimeMinsSlow,
+ "minute"
+ );
if (parts.length == 3) {
// No need to use part[0] which represents the literal "in".
var readingTime = parts[1].value; // reading time in minutes
@@ -183,8 +195,7 @@ class ReaderView {
}
return readingTimeString;
}
- }
- catch(error) {
+ } catch (error) {
console.error(`Failed to format reading time: ${error}`);
}
@@ -202,60 +213,62 @@ class ReaderView {
*/
getReadingSpeedForLanguage(lang) {
const readingSpeed = new Map([
- [ "en", {cpm: 987, variance: 118 } ],
- [ "ar", {cpm: 612, variance: 88 } ],
- [ "de", {cpm: 920, variance: 86 } ],
- [ "es", {cpm: 1025, variance: 127 } ],
- [ "fi", {cpm: 1078, variance: 121 } ],
- [ "fr", {cpm: 998, variance: 126 } ],
- [ "he", {cpm: 833, variance: 130 } ],
- [ "it", {cpm: 950, variance: 140 } ],
- [ "jw", {cpm: 357, variance: 56 } ],
- [ "nl", {cpm: 978, variance: 143 } ],
- [ "pl", {cpm: 916, variance: 126 } ],
- [ "pt", {cpm: 913, variance: 145 } ],
- [ "ru", {cpm: 986, variance: 175 } ],
- [ "sk", {cpm: 885, variance: 145 } ],
- [ "sv", {cpm: 917, variance: 156 } ],
- [ "tr", {cpm: 1054, variance: 156 } ],
- [ "zh", {cpm: 255, variance: 29 } ],
+ ["en", { cpm: 987, variance: 118 }],
+ ["ar", { cpm: 612, variance: 88 }],
+ ["de", { cpm: 920, variance: 86 }],
+ ["es", { cpm: 1025, variance: 127 }],
+ ["fi", { cpm: 1078, variance: 121 }],
+ ["fr", { cpm: 998, variance: 126 }],
+ ["he", { cpm: 833, variance: 130 }],
+ ["it", { cpm: 950, variance: 140 }],
+ ["jw", { cpm: 357, variance: 56 }],
+ ["nl", { cpm: 978, variance: 143 }],
+ ["pl", { cpm: 916, variance: 126 }],
+ ["pt", { cpm: 913, variance: 145 }],
+ ["ru", { cpm: 986, variance: 175 }],
+ ["sk", { cpm: 885, variance: 145 }],
+ ["sv", { cpm: 917, variance: 156 }],
+ ["tr", { cpm: 1054, variance: 156 }],
+ ["zh", { cpm: 255, variance: 29 }],
]);
- return readingSpeed.has(lang) ? [readingSpeed.get(lang), lang] : [readingSpeed.get("en"), "en"];
- }
-
- getByline(article) {
- return article.byline || "";
- }
-
- /**
- * Attempts to read the optional text direction from the article and uses
- * language mapping to detect rtl, if missing.
- */
- getTextDirection(article) {
- if (article.dir) {
- return article.dir;
- }
-
- if (["ar", "fa", "he", "ug", "ur"].includes(article.language)) {
- return "rtl";
- }
-
- return "ltr";
- }
-
- getTitle(article) {
- return article.title || "";
- }
-
- escapeHTML(text) {
- return text
- .replace(/\&/g, "&amp;")
- .replace(/\</g, "&lt;")
- .replace(/\>/g, "&gt;")
- .replace(/\"/g, "&quot;")
- .replace(/\'/g, "&#039;");
- }
+ return readingSpeed.has(lang)
+ ? [readingSpeed.get(lang), lang]
+ : [readingSpeed.get("en"), "en"];
+ }
+
+ getByline(article) {
+ return article.byline || "";
+ }
+
+ /**
+ * Attempts to read the optional text direction from the article and uses
+ * language mapping to detect rtl, if missing.
+ */
+ getTextDirection(article) {
+ if (article.dir) {
+ return article.dir;
+ }
+
+ if (["ar", "fa", "he", "ug", "ur"].includes(article.language)) {
+ return "rtl";
+ }
+
+ return "ltr";
+ }
+
+ getTitle(article) {
+ return article.title || "";
+ }
+
+ escapeHTML(text) {
+ return text
+ .replace(/\&/g, "&amp;")
+ .replace(/\</g, "&lt;")
+ .replace(/\>/g, "&gt;")
+ .replace(/\"/g, "&quot;")
+ .replace(/\'/g, "&#039;");
+ }
}
function fetchDocument(url) {
@@ -282,16 +295,16 @@ function fetchDocument(url) {
function getPreparedDocument(id, url) {
return new Promise((resolve, reject) => {
-
- browser.runtime.sendMessage({action: "getSerializedDoc", id: id}).then((serializedDoc) => {
+ browser.runtime
+ .sendMessage({ action: "getSerializedDoc", id: id })
+ .then(serializedDoc => {
if (serializedDoc) {
let doc = new JSDOMParser().parse(serializedDoc, url);
resolve(doc);
} else {
reject();
}
- }
- );
+ });
});
}
@@ -306,23 +319,26 @@ function connectNativePort() {
let baseUrl = browser.runtime.getURL("/");
let port = browser.runtime.connectNative("mozacReaderviewActive");
- port.onMessage.addListener((message) => {
+ port.onMessage.addListener(message => {
switch (message.action) {
- case 'show':
+ case "show":
async function showAsync(options) {
try {
let doc;
if (typeof Promise.any === "function") {
- doc = await Promise.any([fetchDocument(articleUrl), getPreparedDocument(id, articleUrl)]);
+ doc = await Promise.any([
+ fetchDocument(articleUrl),
+ getPreparedDocument(id, articleUrl),
+ ]);
} else {
try {
doc = await getPreparedDocument(id, articleUrl);
- } catch(e) {
+ } catch (e) {
doc = await fetchDocument(articleUrl);
}
}
readerView.show(doc, articleUrl, options);
- } catch(e) {
+ } catch (e) {
console.log(e);
// We weren't able to find the prepared document and also
// failed to fetch it. Let's load the original page which
@@ -332,19 +348,23 @@ function connectNativePort() {
}
showAsync(message.value);
break;
- case 'hide':
+ case "hide":
window.location.href = articleUrl;
- case 'setColorScheme':
+ case "setColorScheme":
readerView.setColorScheme(message.value.toLowerCase());
break;
- case 'changeFontSize':
+ case "changeFontSize":
readerView.changeFontSize(message.value);
break;
- case 'setFontType':
+ case "setFontType":
readerView.setFontType(message.value.toLowerCase());
break;
- case 'checkReaderState':
- port.postMessage({baseUrl: baseUrl, activeUrl: articleUrl, readerable: true});
+ case "checkReaderState":
+ port.postMessage({
+ baseUrl: baseUrl,
+ activeUrl: articleUrl,
+ readerable: true,
+ });
break;
default:
console.error(`Received invalid action ${message.action}`);