Skip to content

Commit

Permalink
Bug 1180525. Run callbacks whose window is no longer current as long …
Browse files Browse the repository at this point in the history
…as its document is the active document in the browsing context. r=bholley

The distinction only matters when document.open() makes a different
window current without changing the active document.
  • Loading branch information
bzbarsky committed Jul 7, 2015
1 parent e94b7b7 commit 9c31c02
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 43 deletions.
14 changes: 11 additions & 3 deletions dom/base/test/test_bug372964-2.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,17 @@
event = ifr.contentDocument.createEvent("Events");
event.initEvent("foo", true, true);
xhr.dispatchEvent(event);
is(eventCount, 1,
"Shouldn't have handled an event because the context has changed");
SimpleTest.finish();
is(eventCount, 2,
"Should have handled the event because open()/close() keep the active document");
ifr.onload = function() {
event = ifr.contentDocument.createEvent("Events");
event.initEvent("foo", true, true);
xhr.dispatchEvent(event);
is(eventCount, 2,
"Shouldn't have handled an event because the context has changed");
SimpleTest.finish();
};
ifr.contentWindow.location = "about:blank";
}

SimpleTest.waitForExplicitFinish();
Expand Down
13 changes: 6 additions & 7 deletions dom/bindings/CallbackObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,13 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
nsGlobalWindow* win =
aIsJSImplementedWebIDL ? nullptr : xpc::WindowGlobalOrNull(realCallback);
if (win) {
// Make sure that if this is a window it's the current inner, since the
// nsIScriptContext and hence JSContext are associated with the outer
// window. Which means that if someone holds on to a function from a
// now-unloaded document we'd have the new document as the script entry
// point...
// Make sure that if this is a window it has an active document, since
// the nsIScriptContext and hence JSContext are associated with the
// outer window. Which means that if someone holds on to a function
// from a now-unloaded document we'd have the new document as the
// script entry point...
MOZ_ASSERT(win->IsInnerWindow());
nsPIDOMWindow* outer = win->GetOuterWindow();
if (!outer || win != outer->GetCurrentInnerWindow()) {
if (!win->HasActiveDocument()) {
// Just bail out from here
return;
}
Expand Down
1 change: 1 addition & 0 deletions dom/bindings/test/mochitest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ skip-if = debug == false
[test_bug1041646.html]
[test_bug1123875.html]
[test_barewordGetsWindow.html]
[test_callback_across_document_open.html]
[test_callback_default_thisval.html]
[test_cloneAndImportNode.html]
[test_defineProperty.html]
Expand Down
21 changes: 21 additions & 0 deletions dom/bindings/test/test_callback_across_document_open.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test for callback invocation for a callback that comes from a
no-longer-current window that still has an active document.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<iframe srcdoc='<script>function f() { parent.callCount++; }</script>'></iframe>
<script>
var callCount = 0;
var t = async_test("A test of callback invocation in a no-longer-current window with a still-active document");
window.addEventListener("load", t.step_func_done(function() {
var d = document.createElement("div");
d.addEventListener("xyz", frames[0].f);
frames[0].document.open();
frames[0].document.write("All gone");
frames[0].document.close();
d.dispatchEvent(new Event("xyz"));
assert_equals(callCount, 1, "Callback should have been called");
}));
</script>

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@
<body>

<div id="log">FAILED (This TC requires JavaScript enabled)</div>
<iframe id="myFrame"></iframe>

<script>
var t = async_test(undefined, {timeout:3500});
onload = t.step_func(function() {
document.open();
document.write("<title> scheduler: parser-created defer script after document load</title><script src='/resources/testharness.js'><\/script><script src='/resources/testharnessreport.js'><\/script><script src='testlib/testlib.js'><\/script><script>var t=async_test()<\/script><div id=log></div><script defer src='data:text/javascript,t.done();'><\/script>");
document.close();
setTimeout(t.step_func(function() {assert_unreached()}, 500));
var doc = document.getElementById("myFrame").contentDocument;
var win = document.getElementById("myFrame").contentWindow;
doc.open();
doc.write("<title> scheduler: parser-created defer script after document load</title><script src='/resources/testharness.js'><\/script><script src='/resources/testharnessreport.js'><\/script><script src='testlib/testlib.js'><\/script><script>var t=async_test()<\/script><div id=log></div><script defer src='data:text/javascript,parent.t.done();'><\/script>");
doc.close();
})
</script>
</body></html>
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@
<body>

<div id="log">FAILED (This TC requires JavaScript enabled)</div>
<iframe id="myFrame"></iframe>

<script>
var t = async_test();
onload = t.step_func(
function() {
document.open();
document.write("<title> scheduler: defer script after initial onload event</title><script src='/resources/testharness.js'><\/script><script src='/resources/testharnessreport.js'><\/script><script src='testlib/testlib.js'><\/script><div id='log'>document.written content</div><script>log('inline script #1'); t = async_test();<\/script><script src='scripts/include-1.js'><\/script><script defer src='scripts/include-2.js'><\/script>");
document.close();
var doc = document.getElementById("myFrame").contentDocument;
var win = document.getElementById("myFrame").contentWindow;
doc.open();
doc.write("<title> scheduler: defer script after initial onload event</title><script src='/resources/testharness.js'><\/script><script src='/resources/testharnessreport.js'><\/script><script src='testlib/testlib.js'><\/script><div id='log'>document.written content</div><script>log('inline script #1'); t = async_test();<\/script><script src='scripts/include-1.js'><\/script><script defer src='scripts/include-2.js'><\/script>");
doc.close();
//Note that the *window* object has changed but the *global scope* of the script has not.
window.setTimeout(
win.setTimeout(
function() {
window.t.step(
function() {
window.assert_array_equals(window.eventOrder, ['inline script #1', 'external script #1', 'external script #2']);
window.assert_array_equals(win.eventOrder, ['inline script #1', 'external script #1', 'external script #2']);
window.t.done();
})}, 1000);
});
Expand Down

0 comments on commit 9c31c02

Please sign in to comment.