diff --git a/eslint/pack.js b/eslint/pack.js index 7fd6509d8..98a5f5e85 100644 --- a/eslint/pack.js +++ b/eslint/pack.js @@ -178,6 +178,10 @@ var packNonManifestExtensionFiles = function(zip, packedFileName) { return addImageFileToZip(zip, "ChapterStateNone.svg"); }).then(function () { return addImageFileToZip(zip, "ChapterStateSleeping.svg"); + }).then(function () { + return addImageFileToZip(zip, "FileEarmarkCheck.svg"); + }).then(function () { + return addImageFileToZip(zip, "FileEarmarkCheckFill.svg"); }).then(function () { return addCssFileToZip(zip, "default.css"); }).then(function () { @@ -212,6 +216,10 @@ var makeManifestForFirefox = function(data) { // fix permissions/host_permissions let permissions = manifest.permissions; permissions = permissions.filter(p => p != "scripting"); + // Add webRequestBlocking for Firefox + if (permissions.includes("webRequest") && !permissions.includes("webRequestBlocking")) { + permissions.push("webRequestBlocking"); + } manifest.permissions = permissions.concat(manifest.host_permissions); delete manifest.host_permissions; diff --git a/plugin/js/FootnoteExtractor.js b/plugin/js/FootnoteExtractor.js new file mode 100644 index 000000000..9d6956208 --- /dev/null +++ b/plugin/js/FootnoteExtractor.js @@ -0,0 +1,39 @@ +class FootnoteExtractor { + scriptElementsToFootnotes(dom) { + let indexedFootnotes = new Map(); + [...dom.querySelectorAll("script")] + .map(s => s.textContent) + .filter(s => s.includes("toolTips('.classtoolTips")) + .forEach(s => indexedFootnotes.set(this.getId(s), this.extractFootnoteText(s))); + + return this.getIdsUsedOnPage(dom) + .map(id => this.makeSpan(indexedFootnotes.get(id), dom)); + } + + getIdsUsedOnPage(dom) { + let extractId = (span) => [...span.classList] + .filter(s => s.startsWith("class"))[0]; + + return [...dom.querySelectorAll("span.tooltipsall")] + .map(extractId); + } + + getId(script) { + return this.extractSubstring(script, "toolTips('.", ",").replace("'", ""); + } + + makeSpan(content, dom) { + let span = dom.createElement("span"); + span.textContent = content; + return span; + } + + extractFootnoteText(content) { + return this.extractSubstring(content, "tt_store_content = \"", "\"; toolTips('"); + } + + extractSubstring(content, startTag, endTag) { + content = content.substring(content.indexOf(startTag) + startTag.length); + return content.substring(0, content.indexOf(endTag)); + } +} diff --git a/plugin/js/Parser.js b/plugin/js/Parser.js index 98b5440bd..6580553bd 100644 --- a/plugin/js/Parser.js +++ b/plugin/js/Parser.js @@ -369,10 +369,9 @@ class Parser { makeInformationEpubItem(dom) { let titleText = chrome.i18n.getMessage("informationPageTitle"); - let div = document.createElement("div"); let title = document.createElement("h1"); title.appendChild(document.createTextNode(titleText)); - div.appendChild(title); + let div = document.createElement("div"); let urlElement = document.createElement("p"); let bold = document.createElement("b"); bold.textContent = chrome.i18n.getMessage("tableOfContentsUrl"); @@ -381,7 +380,7 @@ class Parser { div.appendChild(urlElement); let infoDiv = document.createElement("div"); this.populateInfoDiv(infoDiv, dom); - let childNodes = [div, infoDiv]; + let childNodes = [title, div, infoDiv]; let chapter = { sourceUrl: this.state.chapterListUrl, title: titleText, diff --git a/plugin/js/Util.js b/plugin/js/Util.js index 2628fb385..4dc4cfebd 100644 --- a/plugin/js/Util.js +++ b/plugin/js/Util.js @@ -978,16 +978,16 @@ var util = (function () { } } - const replaceSemanticInlineStylesWithTags = function(element, removeLeftoverStyles = false) { + const replaceSemanticInlineStylesWithTags = function (element, removeLeftoverStyles = false) { if (element.hasAttribute("style")) { let styleText = element.getAttribute("style"); // Map of style patterns to their semantic HTML equivalents const styleToTag = [ - { regex: /font-style\s*:\s*(italic|oblique)\s*;/g, tag: "i" }, - { regex: /font-weight\s*:\s*(bold|[7-9]\d\d)\s*;/g, tag: "b" }, - { regex: /text-decoration\s*:\s*underline\s*;/g, tag: "u" }, - { regex: /text-decoration\s*:\s*line-through\s*;/g, tag: "s" } + { regex: /font-style\s*:\s*(italic|oblique)\s*;?/g, tag: "i" }, + { regex: /font-weight\s*:\s*(bold|[7-9]\d\d)\s*;?/g, tag: "b" }, + { regex: /text-decoration\s*:\s*underline\s*;?/g, tag: "u" }, + { regex: /text-decoration\s*:\s*line-through\s*;?/g, tag: "s" } ]; // Apply semantic tags and remove corresponding styles @@ -1001,7 +1001,7 @@ var util = (function () { } // Remove non-semantic font-weight - styleText = styleText.replace(/font-weight\s*:\s*(normal|[1-4]\d\d)\s*;/g, ""); + styleText = styleText.replace(/font-weight\s*:\s*(normal|[1-4]\d\d)\s*;?/g, ""); styleText = styleText.trim(); if (styleText && (!removeLeftoverStyles || /italic|bold|font-weight|underline|line-through/.test(styleText))) { @@ -1137,43 +1137,3 @@ var util = (function () { wrapInnerContentInTag: wrapInnerContentInTag }; })(); - -class FootnoteExtractor { - scriptElementsToFootnotes(dom) { - let indexedFootnotes = new Map(); - [...dom.querySelectorAll("script")] - .map(s => s.textContent) - .filter(s => s.includes("toolTips('.classtoolTips")) - .forEach(s => indexedFootnotes.set(this.getId(s), this.extractFootnoteText(s))); - - return this.getIdsUsedOnPage(dom) - .map(id => this.makeSpan(indexedFootnotes.get(id), dom)); - } - - getIdsUsedOnPage(dom) { - let extractId = (span) => [...span.classList] - .filter(s => s.startsWith("class"))[0]; - - return [...dom.querySelectorAll("span.tooltipsall")] - .map(extractId); - } - - getId(script) { - return this.extractSubstring(script, "toolTips('.", ",").replace("'", ""); - } - - makeSpan(content, dom) { - let span = dom.createElement("span"); - span.textContent = content; - return span; - } - - extractFootnoteText(content) { - return this.extractSubstring(content, "tt_store_content = \"", "\"; toolTips('"); - } - - extractSubstring(content, startTag, endTag) { - content = content.substring(content.indexOf(startTag) + startTag.length); - return content.substring(0, content.indexOf(endTag)); - } -} diff --git a/plugin/js/parsers/WordpressBaseParser.js b/plugin/js/parsers/WordpressBaseParser.js index b6dff194e..45c1975cc 100644 --- a/plugin/js/parsers/WordpressBaseParser.js +++ b/plugin/js/parsers/WordpressBaseParser.js @@ -18,6 +18,7 @@ parserFactory.register("skythewoodtl.com", function() { return new WordpressBase //dead url parserFactory.register("yoraikun.wordpress.com", function() { return new WordpressBaseParser() }); parserFactory.register("wanderertl130.id", function() { return new Wanderertl130Parser() }); +parserFactory.register("sasakitomyiano.wordpress.com", function() { return new WordpressBaseParser() }); parserFactory.registerRule( // return probability (0.0 to 1.0) web page is a Wordpress page @@ -29,7 +30,7 @@ parserFactory.registerRule( ); parserFactory.registerManualSelect( - "Wordpress", + "Wordpress", function() { return new WordpressBaseParser() } ); @@ -46,7 +47,9 @@ class WordpressBaseParser extends Parser { static findContentElement(dom) { return dom.querySelector("div.entry-content") || - dom.querySelector("div.post-content"); + dom.querySelector("div.post-content") || + dom.querySelector("ul.wp-block-post-template") || + dom.querySelector(".wp-block-cover__inner-container"); } // find the node(s) holding the story content @@ -65,7 +68,8 @@ class WordpressBaseParser extends Parser { dom.querySelector(".page-title") || dom.querySelector("header.post-title h1") || dom.querySelector(".post-title") || - dom.querySelector("#chapter-heading"); + dom.querySelector("#chapter-heading") || + dom.querySelector(".wp-block-post-title"); } findChapterTitle(dom) { diff --git a/plugin/manifest.json b/plugin/manifest.json index 4a6a1afb9..34622163c 100644 --- a/plugin/manifest.json +++ b/plugin/manifest.json @@ -10,7 +10,6 @@ "cookies", "downloads", "webRequest", - "webRequestBlocking", "declarativeNetRequest", "scripting", "storage", diff --git a/plugin/popup.html b/plugin/popup.html index e71de5510..0b94f024c 100644 --- a/plugin/popup.html +++ b/plugin/popup.html @@ -536,6 +536,7 @@