Open
Bug 958962
Opened 11 years ago
Updated 2 years ago
No way to consistently enable <NOSCRIPT> elements using Cu.blockScriptForGlobal() early (e.g. in "content-document-global-created" observer?)
Categories
(Core :: Layout, defect, P4)
Core
Layout
Tracking
()
NEW
People
(Reporter: ma1, Unassigned)
References
Details
I'm trying to use the Cu.blockScriptForGlobal() API to block inline scripts on some pages, by calling it at the earliest chance (which I believe is in a "content-document-global-created" observer callback).
Unfortunately, this appear to not consistently trigger "scripts disabled" parsing mode, i.e. <NOSCRIPT> elements are kept usually hidden, probably because the change in script allowance status happens too late (even though it couldn't happen earlier, at least using this technique).
Is there anything that can be done to let this approach work as expected, i.e. the page parsing/rendering being consistent with the scripting status?
In order to reproduce, just run the following code in a browser-environment scratchpad:
let TOPIC = "content-document-global-created";
if (window.noscriptObserver) try {
Services.obs.removeObserver(window.noscriptObserver, TOPIC);
} catch(e) {}
Services.obs.addObserver(window.noscriptObserver = {
observe: function(subject, topic, data) {
Cu.blockScriptForGlobal(subject);
}
}, TOPIC, false);
content.location = 'data:text/html,<body><style>.status:after { content: "disabled" }</style><script>document.write("<style>.status:after { content: \\"ENABLED\\" }</style>")</script><div class="status">JavaScript status: </div><noscript><noscript> element shown.</noscript></body>';
Reporter | ||
Updated•11 years ago
|
OS: Windows 7 → All
Hardware: x86_64 → All
Comment 1•11 years ago
|
||
Yeah I don't know if this technique will work - the document is probably already at least somewhat parsed at this point. Boris?
Flags: needinfo?(bzbarsky)
Comment 2•11 years ago
|
||
I wouldn't think so; we fire that observer notification from OnStartRequest, essentially, before we feed any data into the parser.
I'll take a look into what's going on here.
Comment 4•11 years ago
|
||
This isn't a parsing problem at all. It's a pure styling issue.
In particular, we set up the preference stylesheet with a stack like so:
#0 PresShell::SetPrefNoScriptRule (this=0x1499e0000) at nsPresShell.cpp:1339
#1 0x000000010668110b in PresShell::SetPreferenceStyleRules (this=0x1499e0000, aForceReflow=false) at nsPresShell.cpp:1253
#2 0x000000010667f65a in PresShell::Init (this=0x1499e0000, aDocument=0x1236d5800, aPresContext=0x1237ce000, aViewManager=0x1132b1f40, aStyleSet=0x121fe8c00, aCompatMode=eCompatibility_NavQuirks) at nsPresShell.cpp:821
#3 0x0000000105c7fd8f in nsDocument::doCreateShell (this=0x1236d5800, aContext=0x1237ce000, aViewManager=0x1132b1f40, aStyleSet=0x121fe8c00, aCompatMode=eCompatibility_NavQuirks) at nsDocument.cpp:3507
#4 0x00000001060c4275 in nsHTMLDocument::CreateShell (this=0x1236d5800, aContext=0x1237ce000, aViewManager=0x1132b1f40, aStyleSet=0x121fe8c00) at nsHTMLDocument.cpp:287
#5 0x0000000106667963 in nsDocumentViewer::InitPresentationStuff (this=0x149817370, aDoInitialReflow=false) at nsDocumentViewer.cpp:653
#6 0x0000000106667725 in nsDocumentViewer::InitInternal (this=0x149817370, aParentWidget=0x0, aState=0x0, aBounds=@0x7fff5fbfbad8, aDoCreation=true, aNeedMakeCX=true, aForceSetNewDocument=true) at nsDocumentViewer.cpp:904
but the "content-document-global-created" is dispatched via a scriptblocker that comes off the stack at the end of InitInternal, so _after_ that's happened. And when blockScriptForGlobal() does its thing, it doesn't tell the presshell to update its styles. So while the document is parsed just fine the <noscript> has display:none styles applied to it.
I wonder whether we can just delay creating the preference stylesheet until after we've fired DOMWindowCreated. But of course we could have consumers of that that depend on it being set up.... :(
Flags: needinfo?(bzbarsky)
Comment 5•11 years ago
|
||
I mean, as a workaround you could apply a stylesheet to the document that changes the style on <noscript> to be display:initial or something...
Updated•11 years ago
|
Component: HTML: Parser → Layout
Reporter | ||
Comment 6•11 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #5)
> I mean, as a workaround you could apply a stylesheet to the document that
> changes the style on <noscript> to be display:initial or something...
Yep,I had figured this out yesterday and released a work-around with a similar approach.
Can you see any problematic side effect or performance issue in the following code called synchronously from the observer callback (thus before any DOM node has been added yet)?
<SNIPPET>
let ss = DOMUtils.getAllStyleSheets(subject.document)
// reverse loop because the preference stylesheet is almost always the last one
for (let j = ss.length; j-- > 0;) {
let s = ss[j];
if(s.href === "about:PreferenceStyleSheet") {
let rules = s.cssRules;
// skip 1st & 2nd, as they are HTML & SVG namespaces
for (let j = 2, len = rules.length; j < len; j++) {
let r = rules[j];
if (r.cssText === "noscript { display: none ! important; }") {
s.deleteRule(j);
break;
}
}
break;
}
}
</SNIPPET>
Still, having the preference stylesheet applied after "content-document-global-created" and getting rid of this ugly hack would be nice :)
Comment 7•11 years ago
|
||
Hmm. I think that should work, yes.
Updated•11 years ago
|
Priority: -- → P4
(In reply to Giorgio Maone [:mao] from comment #0)
> I'm trying to use the Cu.blockScriptForGlobal() API to block inline scripts
> on some pages, by calling it at the earliest chance (which I believe is in a
> "content-document-global-created" observer callback).
Shouldn't docshell.allowJavascript = false before navigation have the same effect?
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•