зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1387682 - Screenshots missing when thumbnailer Promise is garbage collected. r=ursula
Properly clean up on unload from newTab.js to release strong references in the background thumbnailer. MozReview-Commit-ID: IJNSYjwKUW3 --HG-- extra : rebase_source : c0d9b87ee6b8dd7f3b57f4c3a89fe9a2e324f1a9
This commit is contained in:
Родитель
efd355d4d2
Коммит
51d9e20da8
|
@ -19,8 +19,14 @@ var gPage = {
|
|||
// Add ourselves to the list of pages to receive notifications.
|
||||
gAllPages.register(this);
|
||||
|
||||
// Listen for 'unload' to unregister this page.
|
||||
addEventListener("unload", this, false);
|
||||
// Listen for 'unload' to unregister this page. Save a promise that can be
|
||||
// passed to others to know when to clean up, e.g., background thumbnails.
|
||||
this.unloadingPromise = new Promise(resolve => {
|
||||
addEventListener("unload", () => {
|
||||
resolve();
|
||||
this._handleUnloadEvent();
|
||||
});
|
||||
});
|
||||
|
||||
// XXX bug 991111 - Not all click events are correctly triggered when
|
||||
// listening from xhtml nodes -- in particular middle clicks on sites, so
|
||||
|
@ -189,9 +195,6 @@ var gPage = {
|
|||
case "load":
|
||||
this.onPageVisibleAndLoaded();
|
||||
break;
|
||||
case "unload":
|
||||
this._handleUnloadEvent();
|
||||
break;
|
||||
case "click":
|
||||
let {button, target} = aEvent;
|
||||
// Go up ancestors until we find a Site or not
|
||||
|
|
|
@ -168,7 +168,8 @@ Site.prototype = {
|
|||
*/
|
||||
captureIfMissing: function Site_captureIfMissing() {
|
||||
if (!document.hidden && !this.link.imageURI) {
|
||||
BackgroundPageThumbs.captureIfMissing(this.url);
|
||||
const {unloadingPromise} = gPage;
|
||||
BackgroundPageThumbs.captureIfMissing(this.url, {unloadingPromise});
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -6,4 +6,3 @@ support-files =
|
|||
[browser_as_load_location.js]
|
||||
[browser_as_render.js]
|
||||
[browser_getScreenshots.js]
|
||||
skip-if=true # issue 2851
|
||||
|
|
|
@ -91,6 +91,8 @@ const BackgroundPageThumbs = {
|
|||
* @param url The URL to capture.
|
||||
* @param options An optional object that configures the capture. See
|
||||
* capture() for description.
|
||||
* unloadingPromise This option is resolved when the calling context is
|
||||
* unloading, so things can be cleaned up to avoid leak.
|
||||
* @return {Promise} A Promise that resolves when this task completes
|
||||
*/
|
||||
async captureIfMissing(url, options = {}) {
|
||||
|
@ -105,28 +107,34 @@ const BackgroundPageThumbs = {
|
|||
return url;
|
||||
}
|
||||
let thumbPromise = new Promise((resolve, reject) => {
|
||||
let observer = {
|
||||
observe(subject, topic, data) { // jshint ignore:line
|
||||
if (data === url) {
|
||||
switch (topic) {
|
||||
case "page-thumbnail:create":
|
||||
resolve();
|
||||
break;
|
||||
case "page-thumbnail:error":
|
||||
reject(new Error("page-thumbnail:error"));
|
||||
break;
|
||||
}
|
||||
Services.obs.removeObserver(observer, "page-thumbnail:create");
|
||||
Services.obs.removeObserver(observer, "page-thumbnail:error");
|
||||
let observe = (subject, topic, data) => {
|
||||
if (data === url) {
|
||||
switch (topic) {
|
||||
case "page-thumbnail:create":
|
||||
resolve();
|
||||
break;
|
||||
case "page-thumbnail:error":
|
||||
reject(new Error("page-thumbnail:error"));
|
||||
break;
|
||||
}
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference])
|
||||
cleanup();
|
||||
}
|
||||
};
|
||||
// Use weak references to avoid leaking in tests where the promise we
|
||||
// return is GC'ed before it has resolved.
|
||||
Services.obs.addObserver(observer, "page-thumbnail:create", true);
|
||||
Services.obs.addObserver(observer, "page-thumbnail:error", true);
|
||||
Services.obs.addObserver(observe, "page-thumbnail:create");
|
||||
Services.obs.addObserver(observe, "page-thumbnail:error");
|
||||
|
||||
// Make sure to clean up to avoid leaks by removing observers when
|
||||
// observed or when our caller is unloading
|
||||
function cleanup() {
|
||||
if (observe) {
|
||||
Services.obs.removeObserver(observe, "page-thumbnail:create");
|
||||
Services.obs.removeObserver(observe, "page-thumbnail:error");
|
||||
observe = null;
|
||||
}
|
||||
}
|
||||
if (options.unloadingPromise) {
|
||||
options.unloadingPromise.then(cleanup);
|
||||
}
|
||||
});
|
||||
try {
|
||||
this.capture(url, options);
|
||||
|
|
Загрузка…
Ссылка в новой задаче