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
--- 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);