Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

// Many of the active-related test cases in this file came from
// active.window.js. However, we cannot test the "navigated away" non-active
// case right now due to https://github.com/whatwg/html/issues/3997.
test(t => {
const frame = document.body.appendChild(document.createElement("iframe")),
body = frame.contentDocument.body;
t.add_cleanup(() => frame.remove());
const div = body.appendChild(frame.contentDocument.createElement("div"));
div.addEventListener("click", t.unreached_func("element event listener not removed"));
frame.contentDocument.open();
div.click();
frame.contentDocument.close();
}, "Standard event listeners are to be removed");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe")),
body = frame.contentDocument.body;
t.add_cleanup(() => frame.remove());
frame.contentDocument.addEventListener("x", t.unreached_func("document event listener not removed"));
body.addEventListener("x", t.unreached_func("body event listener not removed"));
frame.contentDocument.open();
frame.contentDocument.dispatchEvent(new Event("x"));
body.dispatchEvent(new Event("x"));
frame.contentDocument.close();
}, "Custom event listeners are to be removed");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe")),
body = frame.contentDocument.body;
t.add_cleanup(() => frame.remove());
// Focus on the current window so that the frame's window is blurred.
window.focus();
assert_false(frame.contentDocument.hasFocus());
frame.contentWindow.addEventListener("focus", t.unreached_func("window event listener not removed"));
body.onfocus = t.unreached_func("body event listener not removed");
frame.contentDocument.open();
assert_equals(body.onfocus, null);
frame.contentWindow.focus();
frame.contentDocument.close();
}, "Standard event listeners are to be removed from Window");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
const childFrame = frame.contentDocument.querySelector("iframe");
const childWin = childFrame.contentWindow;
const childDoc = childFrame.contentDocument;
const childBody = childDoc.body;
// Right now childDoc is still fully active.
frame.onload = t.step_func_done(() => {
// Focus on the current window so that the frame's window is blurred.
window.focus();
// Now childDoc is still active but no longer fully active.
childWin.addEventListener("focus", t.unreached_func("window event listener not removed"));
childBody.onfocus = t.unreached_func("body event listener not removed");
childDoc.open();
assert_equals(childBody.onfocus, null);
// Now try to fire the focus event two different ways.
childWin.focus();
const focusEvent = new FocusEvent("focus");
childWin.dispatchEvent(focusEvent);
childDoc.close();
});
frame.src = "/common/blank.html";
});
frame.src = "resources/page-with-frame.html";
}, "Standard event listeners are to be removed from Window for an active but not fully active document");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
const win = frame.contentWindow;
const doc = frame.contentDocument;
const body = doc.body;
// Right now the frame is connected and it has an active document.
frame.remove();
win.addEventListener("focus", t.unreached_func("window event listener not removed"));
body.onfocus = t.unreached_func("body event listener not removed");
doc.open();
assert_equals(body.onfocus, null);
// Now try to fire the focus event two different ways.
win.focus();
const focusEvent = new FocusEvent("focus");
win.dispatchEvent(focusEvent);
doc.close();
}, "Standard event listeners are to be removed from Window for a non-active document that is the associated Document of a Window (frame is removed)");
test(t => {
let winHappened = 0;
const winListener = t.step_func(() => { winHappened++; });
window.addEventListener("focus", winListener);
t.add_cleanup(() => { window.removeEventListener("focus", winListener); });
let bodyHappened = 0;
const bodyListener = t.step_func(() => { bodyHappened++; });
document.body.onfocus = bodyListener;
t.add_cleanup(() => { document.body.onfocus = null; });
const doc = document.implementation.createHTMLDocument();
doc.open();
const focusEvent = new FocusEvent("focus");
window.dispatchEvent(focusEvent);
assert_equals(winHappened, 1);
assert_equals(bodyHappened, 1);
}, "Standard event listeners are NOT to be removed from Window for a Window-less document (createHTMLDocument)");
test(t => {
let winHappened = 0;
const winListener = t.step_func(() => { winHappened++; });
window.addEventListener("focus", winListener);
t.add_cleanup(() => { window.removeEventListener("focus", winListener); });
let bodyHappened = 0;
const bodyListener = t.step_func(() => { bodyHappened++; });
document.body.onfocus = bodyListener;
t.add_cleanup(() => { document.body.onfocus = null; });
const doc = new DOMParser().parseFromString("", "text/html");
doc.open();
const focusEvent = new FocusEvent("focus");
window.dispatchEvent(focusEvent);
assert_equals(winHappened, 1);
assert_equals(bodyHappened, 1);
}, "Standard event listeners are NOT to be removed from Window for a Window-less document (DOMParser)");
async_test(t => {
const xhr = new XMLHttpRequest();
xhr.onload = t.step_func_done(() => {
assert_equals(xhr.status, 200);
const doc = xhr.responseXML;
let winHappened = 0;
const winListener = t.step_func(() => { winHappened++; });
window.addEventListener("focus", winListener);
t.add_cleanup(() => { window.removeEventListener("focus", winListener); });
let bodyHappened = 0;
const bodyListener = t.step_func(() => { bodyHappened++; });
document.body.onfocus = bodyListener;
t.add_cleanup(() => { document.body.onfocus = null; });
doc.open();
const focusEvent = new FocusEvent("focus");
window.dispatchEvent(focusEvent);
assert_equals(winHappened, 1);
assert_equals(bodyHappened, 1);
});
xhr.responseType = "document";
xhr.open("GET", "resources/dummy.html");
xhr.send();
}, "Standard event listeners are NOT to be removed from Window for a Window-less document (XMLHttpRequest)");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.contentWindow.addEventListener("x", t.unreached_func("window event listener not removed"));
frame.contentDocument.open();
frame.contentWindow.dispatchEvent(new Event("x"));
frame.contentDocument.close();
}, "Custom event listeners are to be removed from Window");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
const childFrame = frame.contentDocument.querySelector("iframe");
const childDoc = childFrame.contentDocument;
const childWin = childFrame.contentWindow;
// Right now childDoc is still fully active.
frame.onload = t.step_func_done(() => {
// Now childDoc is still active but no longer fully active.
childWin.addEventListener("x", t.unreached_func("window event listener not removed"));
childDoc.open();
childWin.dispatchEvent(new Event("x"));
childDoc.close();
});
frame.src = "/common/blank.html";
});
frame.src = "resources/page-with-frame.html";
}, "Custom event listeners are to be removed from Window for an active but not fully active document");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
const win = frame.contentWindow;
const doc = frame.contentDocument;
// Right now the frame is connected and it has an active document.
frame.remove();
win.addEventListener("x", t.unreached_func("window event listener not removed"));
doc.open();
win.dispatchEvent(new Event("x"));
doc.close();
}, "Custom event listeners are to be removed from Window for a non-active document that is the associated Document of a Window (frame is removed)");
test(t => {
const doc = document.implementation.createHTMLDocument();
let happened = false;
window.addEventListener("createHTMLDocumentTest", t.step_func(() => { happened = true; }));
doc.open();
window.dispatchEvent(new Event("createHTMLDocumentTest"));
assert_true(happened);
}, "Custom event listeners are NOT to be removed from Window for a Window-less document (createHTMLDocument)");
test(t => {
const doc = new DOMParser().parseFromString("", "text/html");
let happened = false;
window.addEventListener("DOMParserTest", t.step_func(() => { happened = true; }));
doc.open();
window.dispatchEvent(new Event("DOMParserTest"));
assert_true(happened);
}, "Custom event listeners are NOT to be removed from Window for a Window-less document (DOMParser)");
async_test(t => {
const xhr = new XMLHttpRequest();
xhr.onload = t.step_func_done(() => {
assert_equals(xhr.status, 200);
const doc = xhr.responseXML;
let happened = false;
window.addEventListener("XHRTest", t.step_func(() => { happened = true; }));
doc.open();
window.dispatchEvent(new Event("XHRTest"));
assert_true(happened);
});
xhr.responseType = "document";
xhr.open("GET", "resources/dummy.html");
xhr.send();
}, "Custom event listeners are NOT to be removed from Window for a Window-less document (XMLHttpRequest)");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe")),
body = frame.contentDocument.body;
t.add_cleanup(() => frame.remove());
const div = body.appendChild(frame.contentDocument.createElement("div"));
div.onclick = t.unreached_func("element event listener not removed");
frame.contentDocument.open();
assert_equals(div.onclick, null);
const e = frame.contentDocument.createEvent("mouseevents")
e.initEvent("click", false, false);
div.dispatchEvent(e);
frame.contentDocument.close();
}, "IDL attribute event handlers are to be deactivated");
var thrower;
test(t => {
const frame = document.body.appendChild(document.createElement("iframe")),
body = frame.contentDocument.body;
t.add_cleanup(() => frame.remove());
const div = body.appendChild(frame.contentDocument.createElement("div"));
thrower = t.step_func(() => { throw new Error('element event listener not removed'); });
div.setAttribute("onclick", "parent.thrower()");
assert_not_equals(div.onclick, null);
frame.contentDocument.open();
assert_equals(div.getAttribute("onclick"), "parent.thrower()");
assert_equals(div.onclick, null);
const e = frame.contentDocument.createEvent("mouseevents")
e.initEvent("click", false, false);
div.dispatchEvent(e);
frame.contentDocument.close();
}, "Content attribute event handlers are to be deactivated");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
let once = false;
frame.contentDocument.addEventListener("x", () => {
frame.contentDocument.open();
once = true;
});
frame.contentDocument.addEventListener("x", t.unreached_func("second event listener not removed"));
frame.contentDocument.dispatchEvent(new Event("x"));
assert_true(once);
frame.contentDocument.close();
}, "Event listeners are to be removed with immediate effect");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe")),
shadow = frame.contentDocument.body.attachShadow({ mode: "closed" }),
shadowChild = shadow.appendChild(document.createElement("div")),
shadowShadow = shadowChild.attachShadow({ mode: "open" }),
nodes = [shadow, shadowChild, shadowShadow];
t.add_cleanup(() => frame.remove());
nodes.forEach(node => {
node.addEventListener("x", t.unreached_func(node + "'s event listener not removed"));
});
frame.contentDocument.open();
nodes.forEach(node => {
node.dispatchEvent(new Event("x"));
});
frame.contentDocument.close();
}, "Event listeners are to be removed from shadow trees as well");