Bug 1323987 - Wait top level document to be loaded prior to entering print preview. r?mconley draft
authorMatheus Longaray <mlongaray@hp.com>
Wed, 25 Jan 2017 17:19:24 +0100
changeset 466235 63e2bc54ca861ed490ea4246902d1cb17f45d162
parent 466234 4edd530dd305ad6988f85602f763349351e2d195
child 543373 536047cf0f1333aac121c344609431acd2e74b1e
push id42843
push userbmo:mlongaray@hp.com
push dateWed, 25 Jan 2017 17:10:05 +0000
reviewersmconley
bugs1323987
milestone54.0a1
Bug 1323987 - Wait top level document to be loaded prior to entering print preview. r?mconley This patch fixes a raciness condition where nsDocShell has not finished redirecting to "about:printpreview" yet, and we try to QI current content viewer to nsIWebBrowserPrint. MozReview-Commit-ID: 4qaSI4jrHgW
toolkit/content/browser-content.js
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -539,17 +539,17 @@ var Printing = {
 
       content.document.head.innerHTML = "";
 
       // Set title of document
       content.document.title = article.title;
 
       // Set base URI of document. Print preview code will read this value to
       // populate the URL field in print settings so that it doesn't show
-      // "about:blank" as its URI.
+      // "about:printpreview" as its URI.
       let headBaseElement = content.document.createElement("base");
       headBaseElement.setAttribute("href", URL);
       content.document.head.appendChild(headBaseElement);
 
       // Create link element referencing aboutReader.css and append it to head
       let headStyleElement = content.document.createElement("link");
       headStyleElement.setAttribute("rel", "stylesheet");
       headStyleElement.setAttribute("href", "chrome://global/skin/aboutReader.css");
@@ -642,21 +642,39 @@ var Printing = {
     // our PresShells set up.
     addEventListener("printPreviewUpdate", onPrintPreviewReady);
 
     try {
       let printSettings = this.getPrintSettings();
 
       // If we happen to be on simplified mode, we need to set docURL in order
       // to generate header/footer content correctly, since simplified tab has
-      // "about:blank" as its URI.
+      // "about:printpreview" as its URI.
       if (printSettings && simplifiedMode)
         printSettings.docURL = contentWindow.document.baseURI;
 
-      docShell.printPreview.printPreview(printSettings, contentWindow, this);
+      // Bug 1323987 optimizes nsDocShell::GetPrintPreview() method so it can
+      // return its current content viewer QI'd to nsIWebBrowserPrint if it's
+      // already a blank one. Bug 1323987 also adds a new about: page for
+      // "about:printpreview" (new redirector that essentially aliases itself
+      // to "about:blank").
+      // These changes together can cause a raciness condition in nsDocShell::
+      // GetPrintPreview() if we access it and nsDocShell hasn't even finished
+      // the redirect yet. We solve this issue by checking if the current top
+      // level document has finished loading prior to entering on print preview
+      // mode, and if not, wait until it completes.
+      let print = content.QueryInterface(Ci.nsIInterfaceRequestor)
+                         .getInterface(Ci.nsIWebBrowserPrint);
+      if (print.doingPrintPreview || content.document.readyState == "complete") {
+        docShell.printPreview.printPreview(printSettings, contentWindow, this);
+      } else if (content.document.readyState != "complete") {
+        addEventListener("DOMContentLoaded", () => {
+          docShell.printPreview.printPreview(printSettings, contentWindow, this);
+        }, {once: true});
+      }
     } catch (error) {
       // This might fail if we, for example, attempt to print a XUL document.
       // In that case, we inform the parent to bail out of print preview.
       Components.utils.reportError(error);
       notifyEntered(error);
     }
   },
 
@@ -664,17 +682,17 @@ var Printing = {
     docShell.printPreview.exitPrintPreview();
   },
 
   print(contentWindow, simplifiedMode) {
     let printSettings = this.getPrintSettings();
 
     // If we happen to be on simplified mode, we need to set docURL in order
     // to generate header/footer content correctly, since simplified tab has
-    // "about:blank" as its URI.
+    // "about:printpreview" as its URI.
     if (printSettings && simplifiedMode) {
       printSettings.docURL = contentWindow.document.baseURI;
     }
 
     try {
       let print = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                                .getInterface(Ci.nsIWebBrowserPrint);