Bug 1117936 - If print preview throws in browser-content.js, make sure printUtils.js can handle the error. r=Mossop.
authorMike Conley <mconley@mozilla.com>
Tue, 06 Jan 2015 14:52:01 -0500
changeset 248733 9c4843953f64afe5e0c6d22f4ab854ca7d8fae1a
parent 248732 2035148cfa4df10737715c7d5188b35b265fbfa3
child 248734 bc1e8b764b5ceed15759bb2520bfbaabdad76df0
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop
bugs1117936
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1117936 - If print preview throws in browser-content.js, make sure printUtils.js can handle the error. r=Mossop. It's possible for docShell.printPreview.printPreview to throw (if we're attempting to print preview a XUL document, for example). If it throws, this can put printUtils.js in a funny state, since it's waiting to hear that print preview was successfully entered. This patch makes it possible for browser-content.js to inform the parent that printPreview failed, and for the parent to react appropriately.
toolkit/components/printing/content/printUtils.js
toolkit/content/browser-content.js
--- a/toolkit/components/printing/content/printUtils.js
+++ b/toolkit/components/printing/content/printUtils.js
@@ -446,16 +446,25 @@ var PrintUtils = {
 
     if (this._webProgressPP.value) {
       mm.addMessageListener("Printing:Preview:StateChange", this);
       mm.addMessageListener("Printing:Preview:ProgressChange", this);
     }
 
     let onEntered = (message) => {
       mm.removeMessageListener("Printing:PrintPreview:Entered", onEntered);
+
+      if (message.data.failed) {
+        // Something went wrong while putting the document into print preview
+        // mode. Bail out.
+        this._listener.onEnter();
+        this._listener.onExit();
+        return;
+      }
+
       // Stash the focused element so that we can return to it after exiting
       // print preview.
       gFocusedElement = document.commandDispatcher.focusedElement;
 
       let printPreviewTB = document.getElementById("print-preview-toolbar");
       if (printPreviewTB) {
         printPreviewTB.updateToolbar();
         ppBrowser.collapsed = false;
@@ -515,17 +524,17 @@ var PrintUtils = {
     let printPreviewTB = document.getElementById("print-preview-toolbar");
     this._listener.getNavToolbox().parentNode.removeChild(printPreviewTB);
 
     let fm = Components.classes["@mozilla.org/focus-manager;1"]
                        .getService(Components.interfaces.nsIFocusManager);
     if (gFocusedElement)
       fm.setFocus(gFocusedElement, fm.FLAG_NOSCROLL);
     else
-      window.content.focus();
+      this._sourceBrowser.focus();
     gFocusedElement = null;
 
     this._listener.onExit();
   },
 
   onKeyDownPP: function (aEvent)
   {
     // Esc exits the PP
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -411,27 +411,45 @@ let Printing = {
 
   enterPrintPreview(printSettings, contentWindow) {
     // Bug 1088070 - we should instantiate nsIPrintSettings here in the
     // content script instead of passing it down as a CPOW.
     if (Cu.isCrossProcessWrapper(printSettings)) {
       printSettings = null;
     }
 
+    // We'll call this whenever we've finished reflowing the document, or if
+    // we errored out while attempting to print preview (in which case, we'll
+    // notify the parent that we've failed).
+    let notifyEntered = (error) => {
+      removeEventListener("printPreviewUpdate", onPrintPreviewReady);
+      sendAsyncMessage("Printing:Preview:Entered", {
+        failed: !!error,
+      });
+    };
+
+    let onPrintPreviewReady = () => {
+      notifyEntered();
+    };
+
     // We have to wait for the print engine to finish reflowing all of the
     // documents and subdocuments before we can tell the parent to flip to
     // the print preview UI - otherwise, the print preview UI might ask for
     // information (like the number of pages in the document) before we have
     // our PresShells set up.
-    addEventListener("printPreviewUpdate", function onPrintPreviewReady() {
-      removeEventListener("printPreviewUpdate", onPrintPreviewReady);
-      sendAsyncMessage("Printing:Preview:Entered");
-    });
+    addEventListener("printPreviewUpdate", onPrintPreviewReady);
 
-    docShell.printPreview.printPreview(printSettings, contentWindow, this);
+    try {
+      docShell.printPreview.printPreview(printSettings, contentWindow, this);
+    } 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);
+    }
   },
 
   exitPrintPreview() {
     docShell.printPreview.exitPrintPreview();
   },
 
   print(printSettings, contentWindow) {
     // Bug 1088070 - we should instantiate nsIPrintSettings here in the