Bug 1117936 - If print preview throws in browser-content.js, make sure printUtils.js can handle the error. r=Mossop, a=sledru
authorMike Conley <mconley@mozilla.com>
Tue, 06 Jan 2015 14:52:01 -0500
changeset 242880 2fd253435fe4
parent 242879 5d185a7d03b5
child 242881 ee9df2674663
push id4328
push userryanvm@gmail.com
push date2015-01-15 22:26 +0000
treeherdermozilla-beta@c8031be76a86 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop, sledru
bugs1117936
milestone36.0
Bug 1117936 - If print preview throws in browser-content.js, make sure printUtils.js can handle the error. r=Mossop, a=sledru 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;
@@ -516,17 +525,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