Bug 1355354 - Keep a reference to the progress listener to keep it from being gc'ed prematurely. r?mossop
MozReview-Commit-ID: A6WM1Bj3Z5L
--- a/browser/components/shell/HeadlessShell.jsm
+++ b/browser/components/shell/HeadlessShell.jsm
@@ -7,16 +7,20 @@
let EXPORTED_SYMBOLS = ["HeadlessShell"];
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/osfile.jsm");
const Ci = Components.interfaces;
+// Refrences to the progress listeners to keep them from being gc'ed
+// before they are called.
+const progressListeners = new Map();
+
function loadContentWindow(webNavigation, uri) {
return new Promise((resolve, reject) => {
webNavigation.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
let docShell = webNavigation.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell);
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebProgress);
let progressListener = {
@@ -26,24 +30,26 @@ function loadContentWindow(webNavigation
return;
}
// Ignore events that don't change the document
if (flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
return;
}
let contentWindow = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
+ progressListeners.delete(progressListener);
webProgress.removeProgressListener(progressListener);
contentWindow.addEventListener("load", (event) => {
resolve(contentWindow);
}, { once: true });
},
QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener",
"nsISupportsWeakReference"])
};
+ progressListeners.set(progressListener, progressListener);
webProgress.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
});
}
async function takeScreenshot(fullWidth, fullHeight, contentWidth, contentHeight, path, url) {
try {
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
--- a/widget/headless/tests/test_headless.js
+++ b/widget/headless/tests/test_headless.js
@@ -10,16 +10,20 @@ const server = new HttpServer();
server.registerDirectory("/", do_get_cwd());
server.start(-1);
const ROOT = `http://localhost:${server.identity.primaryPort}`;
const BASE = `${ROOT}/`;
const HEADLESS_URL = `${BASE}/headless.html`;
const HEADLESS_BUTTON_URL = `${BASE}/headless_button.html`;
registerCleanupFunction(() => { server.stop(() => {})});
+// Refrences to the progress listeners to keep them from being gc'ed
+// before they are called.
+const progressListeners = new Map();
+
function loadContentWindow(webNavigation, uri) {
return new Promise((resolve, reject) => {
webNavigation.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
let docShell = webNavigation.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell);
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebProgress);
let progressListener = {
@@ -32,23 +36,25 @@ function loadContentWindow(webNavigation
if (flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
return;
}
let docShell = webNavigation.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell);
let contentWindow = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
webProgress.removeProgressListener(progressListener);
+ progressListeners.delete(progressListener);
contentWindow.addEventListener("load", (event) => {
resolve(contentWindow);
}, { once: true });
},
QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener",
"nsISupportsWeakReference"])
};
+ progressListeners.set(progressListener, progressListener);
webProgress.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION);
});
}
add_task(async function test_snapshot() {
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
let webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);