Closed anmarmansur closed 2 years ago
If you're talking about dynamic filtering, blocking all scripts that run on a certain hostname, then I think this extension might need to use the contentSettings API like uMatrix does; then if it uses that API to disable scripts on that hostname, Chrome will parse noscript
elements as usual.
Yes, I am talking about dynamic filtering, but on Firefox not Chrome. I looked at a couple of Firefox extensions, NoScript and TabMixPlus, and the way they tell Firefox to parse a page's <noscript>
tags is as simple as setting the linkedBrowser.docShell.allowJavascript
property of the tab object to false
. That, however, is a tab-wide setting that will block all scripts on a page regardless of origin.
It appears that, on Firefox at least, there's no straightforward way to achieve this while maintaining the origin-specific granularity of blocking scripts, as the only way to get Firefox to parse <noscript>
tags is to block all scripts on a tab. Please, feel free to close this issue.
@lewisje
need to use the contentSettings API like uMatrix does
No, uMatrix does not do that.
The solution is simple: to transform <noscript>
into <div>
when inline script tags are blocked, just like uMatrix does.
@gorhill some thoughts on why this might not be optimal:
<noscript>
just usually holds a message telling the user to enable JavaScript.<noscript>
stuff if µBlock just happens to block a tracking.js
script that's not really relevant to the site I'm on (and won't affect the functionality).My own, humble suggestion would be to offer some visual indicator in the µBlock toolbar icon when one or more first-party scripts are blocked (an "asterisk" after the count, perhaps?). That gives the advantage of easier debugging/troubleshooting without the potential problems listed above.
What do you think?
@gorhill just another quick note (follow-up to comment above): if you do decide to show <noscript>
stuff on pages µBlock blocks a script, I think it'd be good to consider using a style injection instead of traversing the DOM.
In other words:
noscript {
display: block;
}
Inserting that should be much cheaper than looking for/replacing <noscript>
tags, offloading most of the work to the browser (which presumably knows how to efficiently select elements and modify how/whether they get rendered).
I thought of that too, but Firefox appears to have the following rule hardcoded in about:PreferenceStyleSheet
, and it takes precedence over anything you inject:
noscript {
display: none !important;
}
it takes precedence over anything you inject
Is that a conclusion, or something special that Firefox does? You can have !important
and that'll override it if it's just playing by CSS rules. If it's fully CSS-compliant and Firefox isn't hacking in some weird thing, being slightly more specific with the selector should be sufficient:
* > noscript {
display: block !important;
}
Well, it either takes precedence through some trickery, or the CSS rules are being ignored altogether, and the noscript
tags are forced hidden in the DOM. Either way, the result is the same, unless you disable scripting on a tab, noscript
tags are hidden. I might dig through the source code this weekend if I get a chance, out of curiosity and not hope of achieving anything mind you.
@gorhill I thought uMatrix might use contentSettings for more than just setting, as a baseline, a couple whitelists (whitelisting all scripts on URLs starting with http://
and https://
); I guess it wouldn't have worked to use contentSettings to granularly enforce cookie
and plugin
and image
and script
permissions, or else you would have done that.
@anmarmansur Did you try injecting that style block with !important
and still found that it was being overridden?
Yes, I did try injecting that style block with !important
among many other things. I also had a chance to take a quick look at the source code and found something interesting to support my assumption that noscript
CSS rules were being ignored: Gecko's HTML parser has a special class of tags, which it doesn't parse, but outputs their contents untouched as CDATA. Among those are script
, style
, and noscript
tags!
I immediately confirmed this in the browser by creating this simple HTML document:
...
<body>
<div>div 1</div>
<noscript>
<div>div 2</div>
<div>div 3</div>
</noscript>
</body>
...
And this is what the resulting DOM looks like:
...
BODY
#text
DIV
#text
#text
NOSCRIPT
#text
#text
Notice how the latter two div
tags are absent from the DOM. In fact, that #text
node under the NOSCRIPT
node contains the inner html unparsed complete with indentations and new lines:
"\n <div>div 2</div>\n <div>div 3</div>\n "
Yes the DOM won't parse noscript
if javascript is not disabled. There could be meta
tag in there for automatic redirection when javascript is disabled etc. It's why it is implemented the way it is in uMatrix.
+1 I would like to see the <noscript>
when all JS on the site is blocked. But if at least one JS is enabled, then <noscript>
should be hidden.
Unfortunately that can't be done: Apparently there is no way to have the browser think that scripting is disabled altogether just because every single script is blocked, and <noscript>
elements are parsed and displayed only if scripting is disabled.
That, however, is a tab-wide setting that will block all scripts on a page regardless of origin.
More precisely, setting allowJavascript on a docshell will by default inherit that same setting into its descendant docshells (iframes). One can directly set allowJavascript on those other docshells if desired if their script-enabled state should not match the parent.
and it takes precedence over anything you inject
Oh, and for this part: the preferences sheet is a user-level sheet. !important rules in it have hight precedence than any author-sheet rules. Having an extension add a user-level or ua-level sheet with a !important rule would allow overriding it.
@bzbarsky The repo here is dead since years. I was made aware of your comment from https://bugzilla.mozilla.org/show_bug.cgi?id=1392090#c5. The issue for (not abandonware) uBlock Origin is here: https://github.com/gorhill/uBlock/issues/308. I would like to understand what you are referring to with:
setting allowJavascript on a docshell
What WebExtensions API are you referring to?
I'll follow up in https://github.com/gorhill/uBlock/issues/308
What WebExtensions API are you referring to?
There might well not be a webextensions API for this. That part of my comment was in response to the earlier discussion in this issue, which was not in a webextensions context.
This might be specific to Firefox, as I don't use Chrome, but as it stands blocking scripts with uBlock will leave most websites unusable, while, for comparison, blocking scripts using the NoScript extension will not do so, because NoScript (I believe) tells the browser to parse and display the page's
If this is intentional, and if there is a benefit to continue to hide the page's, perhaps a user selectable behavior could be added.