
Loading…
Blocking scripts should display noscript tags #574
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.
@gorhill some thoughts on why this might not be optimal:
The helpful part of this is being able to know when µBlock has blocked a script, and only if that removes desirable functionality (making the issue easier to diagnose).
In most cases I've come across,
<noscript>just usually holds a message telling the user to enable JavaScript.I don't want to see
<noscript>stuff if µBlock just happens to block atracking.jsscript that's not really relevant to the site I'm on (and won't affect the functionality).Not sure on this one: this potentially enables webpages to "figure out" whether scripts have been blocked where they couldn't have in the past.
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.
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 <noscript> tags.
If this is intentional, and if there is a benefit to continue to hide the page's <noscipt>, perhaps a user selectable behavior could be added.