aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhackademix <giorgio@maone.net>2019-04-30 13:31:49 +0200
committerhackademix <giorgio@maone.net>2019-04-30 13:31:49 +0200
commit21175a8267aae9d88652fac832a90266d5484cd5 (patch)
tree3811aa55d0021c7b8eba0fe43c2880c6a954f53a
parent65c68a4839a05bb8aa24a0444964fa8241bc8673 (diff)
Display NOSCRIPT elements when scripts are blocked or the data-librejs-display attribute is present.
-rw-r--r--main_background.js64
-rw-r--r--test/spec/LibreJSSpec.js24
2 files changed, 77 insertions, 11 deletions
diff --git a/main_background.js b/main_background.js
index f9e7521..0a1a2e9 100644
--- a/main_background.js
+++ b/main_background.js
@@ -938,16 +938,55 @@ function doc2HTML(doc) {
}
/**
-* Removes noscript tags with name "librejs-path" leaving the inner content to load.
+* Shortcut to create a correctly namespaced DOM HTML elements
*/
-function remove_noscripts(html_doc){
- for(var i = 0; i < html_doc.getElementsByName("librejs-path").length; i++){
- if(html_doc.getElementsByName("librejs-path")[i].tagName == "NOSCRIPT"){
- html_doc.getElementsByName("librejs-path")[i].outerHTML = html_doc.getElementsByName("librejs-path")[i].innerHTML;
- }
- }
+function createHTMLElement(doc, name) {
+ return doc.createElementNS("http://www.w3.org/1999/xhtml", name);
+}
- return doc2HTML(html_doc);
+/**
+* Replace any element with a span having the same content (useful to force
+* NOSCRIPT elements to visible the same way as NoScript and uBlock do)
+*/
+function forceElement(doc, element) {
+ let replacement = createHTMLElement(doc, "span");
+ replacement.innerHTML = element.innerHTML;
+ element.replaceWith(replacement);
+ return replacement;
+}
+
+/**
+* Forces displaying any element having the "data-librejs-display" attribute and
+* <noscript> elements on pages where LibreJS disabled inline scripts (unless
+* they have the "data-librejs-nodisplay" attribute).
+*/
+function forceNoscriptElements(doc) {
+ let shown = 0;
+ // inspired by NoScript's onScriptDisabled.js
+ for (let noscript of doc.querySelectorAll("noscript:not([data-librejs-nodisplay])")) {
+ let replacement = forceElement(doc, noscript);
+ // emulate meta-refresh
+ let meta = replacement.querySelector('meta[http-equiv="refresh"]');
+ if (meta) {
+ refresh = true;
+ doc.head.appendChild(meta);
+ }
+ shown++;
+ }
+ return shown;
+}
+/**
+* Forces displaying any element having the "data-librejs-display" attribute and
+* <noscript> elements on pages where LibreJS disabled inline scripts (unless
+* they have the "data-librejs-nodisplay" attribute).
+*/
+function showConditionalElements(doc) {
+ let shown = 0;
+ for (let element of document.querySelectorAll("[data-librejs-display]")) {
+ forceElement(doc, element);
+ shown++;
+ }
+ return shown;
}
/**
@@ -1113,10 +1152,13 @@ async function editHtml(html, documentUrl, tabId, frameId, whitelisted){
}
}
}
+
+ modified = showConditionalElements(html_doc) > 0 || modified;
if (modified) {
- return modifiedInline
- ? await remove_noscripts(html_doc)
- : doc2HTML(html_doc);
+ if (modifiedInline) {
+ forceNoscriptElements(html_doc);
+ }
+ return doc2HTML(html_doc);
}
}
return null;
diff --git a/test/spec/LibreJSSpec.js b/test/spec/LibreJSSpec.js
index 43f37a7..8d4aebe 100644
--- a/test/spec/LibreJSSpec.js
+++ b/test/spec/LibreJSSpec.js
@@ -222,6 +222,30 @@ describe("LibreJS' components", () => {
expect(processed).toContain(trivialAsUrl);
expect(processed).not.toContain(nontrivialAsUrl);
});
+
+ it("should force displaying NOSCRIPT elements (except those with @data-librejs-nodisplay) where scripts have been blocked", async () => {
+ let noscriptContent = "I'm NOSCRIPT content";
+ let asNoscript = `<noscript>${noscriptContent}</noscript>`;
+ let asNodisplay = `<noscript data-librejs-nodisplay>${noscriptContent}</noscript>`;
+ let asSpan = `<span>${noscriptContent}</span>`;
+ let page = addToBody(addToBody(nontrivialInHtml, asNoscript), asNodisplay);
+ let processed = await processHtml(page);
+ expect(processed).not.toContain(asNoscript);
+ expect(processed).toContain(asSpan);
+ expect(processed).not.toContain(asNodisplay);
+ });
+
+ it("should always force displaying @data-librejs-display elements", async () => {
+ let content = "I'm FORCED content";
+ let asDisplay = `<span data-librejs-display>${content}</span>`;
+ let asSpan = `<span>${content}</span>`;
+ for (let page of [nontrivialInHtml, "<body></body>"]) {
+ page = addToBody(page, asDisplay);
+ let processed = await processHtml(page);
+ expect(processed).not.toContain(asDisplay);
+ expect(processed).not.toContain(asSpan);
+ }
+ });
});
describe("The external (Web Labels) license checker", () => {