Bug 1215893: [webext] Check capturing event listeners for the correct target. r=billm

This commit is contained in:
Kris Maglione 2015-11-14 23:30:52 -08:00
parent 382d2ffc3c
commit 891eeed2f4
6 changed files with 87 additions and 5 deletions

View File

@ -175,7 +175,10 @@ global.openPanel = (node, popupURL, extension) => {
GlobalManager.injectInDocShell(browser.docShell, extension, context);
browser.setAttribute("src", context.uri.spec);
let contentLoadListener = () => {
let contentLoadListener = event => {
if (event.target != browser.contentDocument) {
return;
}
browser.removeEventListener("load", contentLoadListener, true);
let contentViewer = browser.docShell.contentViewer;
@ -462,8 +465,8 @@ global.WindowListManager = {
},
handleEvent(event) {
event.currentTarget.removeEventListener(event.type, this);
let window = event.target.defaultView;
window.removeEventListener("load", this);
if (window.document.documentElement.getAttribute("windowtype") != "navigator:browser") {
return;
}

View File

@ -322,6 +322,9 @@ var GlobalManager = {
let eventHandler = docShell.chromeEventHandler;
let listener = event => {
if (event.target != docShell.contentViewer.DOMDocument) {
return;
}
eventHandler.removeEventListener("unload", listener);
context.unload();
};

View File

@ -330,7 +330,13 @@ var DocumentManager = {
},
handleEvent: function(event) {
let window = event.target.defaultView;
let window = event.currentTarget;
if (event.target != window.document) {
// We use capturing listeners so we have precedence over content script
// listeners, but only care about events targeted to the element we're
// listening on.
return;
}
window.removeEventListener(event.type, this, true);
// Need to check if we're still on the right page? Greasemonkey does this.

View File

@ -53,7 +53,11 @@ BackgroundPage.prototype = {
// TODO: Right now we run onStartup after the background page
// finishes. See if this is what Chrome does.
window.windowRoot.addEventListener("load", () => {
let loadListener = event => {
if (event.target != window.document) {
return;
}
event.currentTarget.removeEventListener("load", loadListener, true);
if (this.scripts) {
let doc = window.document;
for (let script of this.scripts) {
@ -74,7 +78,8 @@ BackgroundPage.prototype = {
if (this.extension.onStartup) {
this.extension.onStartup();
}
}, true);
};
window.windowRoot.addEventListener("load", loadListener, true);
},
shutdown() {

View File

@ -35,5 +35,6 @@ support-files =
[test_ext_bookmarks.html]
[test_ext_alarms.html]
[test_ext_background_window_properties.html]
[test_ext_background_sub_windows.html]
[test_ext_jsversion.html]
skip-if = e10s # Uses a console monitor which doesn't work from a content process. The code being tested doesn't run in a tab content process in any case.

View File

@ -0,0 +1,64 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for sub-frames of WebExtension background pages</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.8">
add_task(function* testBackgroundWindow() {
let extension = ExtensionTestUtils.loadExtension({
background: "new " + function() {
browser.test.log("background script executed");
browser.test.sendMessage("background-script-load");
let img = document.createElement("img");
img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
document.body.appendChild(img);
img.onload = () => {
browser.test.log("image loaded");
let iframe = document.createElement("iframe");
iframe.src = "about:blank?1";
iframe.onload = () => {
browser.test.log("iframe loaded");
setTimeout(() => {
browser.test.notifyPass("background sub-window test done");
}, 0);
};
document.body.appendChild(iframe);
};
},
});
info("extension loaded");
let loadCount = 0;
extension.onMessage("background-script-load", () => {
loadCount++;
});
yield extension.startup();
info("startup complete loaded");
yield extension.awaitFinish("background sub-window test done")
is(loadCount, 1, "background script loaded only once");
yield extension.unload();
});
</script>
</body>
</html>