Skip to content
This repository has been archived by the owner on Sep 9, 2022. It is now read-only.

Blocking scripts should display noscript tags #574

Closed
anmarmansur opened this issue Jan 21, 2015 · 18 comments
Closed

Blocking scripts should display noscript tags #574

anmarmansur opened this issue Jan 21, 2015 · 18 comments

Comments

@anmarmansur
Copy link

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 tags.

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.

@lewisje
Copy link

lewisje commented Jan 22, 2015

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.

@anmarmansur
Copy link
Author

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
Copy link
Contributor

gorhill commented Jan 22, 2015

@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.

@chrisaljoudi
Copy link
Contributor

@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 a tracking.js script 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?

@chrisaljoudi
Copy link
Contributor

@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).

@anmarmansur
Copy link
Author

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;
}

@chrisaljoudi
Copy link
Contributor

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;
}

@anmarmansur
Copy link
Author

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.

@lewisje
Copy link

lewisje commented Jan 23, 2015

@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?

@anmarmansur
Copy link
Author

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    "    

@gorhill
Copy link
Contributor

gorhill commented Jan 23, 2015

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.

@quinncomendant
Copy link

+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.

@lewisje
Copy link

lewisje commented Sep 14, 2015

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.

@bzbarsky
Copy link

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.

@bzbarsky
Copy link

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.

@gorhill
Copy link
Contributor

gorhill commented Nov 15, 2017

@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: gorhill/uBlock#308. I would like to understand what you are referring to with:

setting allowJavascript on a docshell

What WebExtensions API are you referring to?

@bzbarsky
Copy link

I'll follow up in gorhill/uBlock#308

@bzbarsky
Copy link

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants