Bug 1387580 - Some top sites never get screenshots of redirected pages. r?adw
MozReview-Commit-ID: IzmzXhGnPcH
--- a/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
+++ b/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
@@ -1,22 +1,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-env mozilla/frame-script */
-var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
Cu.importGlobalProperties(["Blob", "FileReader"]);
Cu.import("resource://gre/modules/PageThumbUtils.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
+// Let the page settle for this amount of milliseconds before capturing to allow
+// for any in-page changes or redirects.
+const SETTLE_WAIT_TIME = 2500;
+
const STATE_LOADING = 1;
const STATE_CAPTURING = 2;
const STATE_CANCELED = 3;
// NOTE: Copied from nsSandboxFlags.h
/**
* This flag prevents content from creating new auxiliary browsing contexts,
* e.g. using the target attribute, the window.open() method, or the
@@ -117,20 +121,33 @@ const backgroundPageThumbsContent = {
this._finishCurrentCapture();
delete this._currentCapture;
this._startNextCapture();
} else if (this._state == STATE_CANCELED) {
delete this._currentCapture;
this._startNextCapture();
}
} else if (this._state == STATE_LOADING &&
- Components.isSuccessCode(status)) {
- // The requested page has loaded. Capture it.
- this._state = STATE_CAPTURING;
- this._captureCurrentPage();
+ (Components.isSuccessCode(status) ||
+ status === Cr.NS_BINDING_ABORTED)) {
+ // The requested page has loaded or stopped/aborted, so capture the page
+ // soon but first let it settle in case of in-page redirects
+ if (this._captureTimer) {
+ // There was additional activity, so restart the wait timer
+ this._captureTimer.delay = SETTLE_WAIT_TIME;
+ } else {
+ // Stay in LOADING until we're actually ready to be CAPTURING
+ this._captureTimer =
+ Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this._captureTimer.init(() => {
+ this._state = STATE_CAPTURING;
+ this._captureCurrentPage();
+ delete this._captureTimer;
+ }, SETTLE_WAIT_TIME, Ci.nsITimer.TYPE_ONE_SHOT);
+ }
} else if (this._state != STATE_CANCELED) {
// Something went wrong. Cancel the capture. Loading about:blank
// while onStateChange is still on the stack does not actually stop
// the request if it redirects, so do it asyncly.
this._state = STATE_CANCELED;
if (!this._cancelTimer) {
this._cancelTimer =
Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);