Bug 1358815 - update pdfjs for async-created findbar, r?bdahl draft
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Tue, 13 Mar 2018 11:52:56 +0000
changeset 768315 5d0a3265a9b7f8065f291278e707551d2539a194
parent 768052 e21e416d7c2a7a30b4091dc453f17f56525ef2bc
push id102843
push usergijskruitbosch@gmail.com
push dateThu, 15 Mar 2018 23:54:21 +0000
reviewersbdahl
bugs1358815
milestone61.0a1
Bug 1358815 - update pdfjs for async-created findbar, r?bdahl MozReview-Commit-ID: Byr5B4yAzfx
browser/extensions/pdfjs/content/PdfStreamConverter.jsm
browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
browser/extensions/pdfjs/content/PdfjsContentUtils.jsm
browser/extensions/pdfjs/test/browser_pdfjs_main.js
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
+++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
@@ -43,39 +43,16 @@ ChromeUtils.defineModuleGetter(this, "Pd
 
 Cu.importGlobalProperties(["XMLHttpRequest"]);
 
 var Svc = {};
 XPCOMUtils.defineLazyServiceGetter(Svc, "mime",
                                    "@mozilla.org/mime;1",
                                    "nsIMIMEService");
 
-function getContainingBrowser(domWindow) {
-  return domWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                  .getInterface(Ci.nsIWebNavigation)
-                  .QueryInterface(Ci.nsIDocShell)
-                  .chromeEventHandler;
-}
-
-function getFindBar(domWindow) {
-  if (PdfjsContentUtils.isRemote) {
-    throw new Error("FindBar is not accessible from the content process.");
-  }
-  try {
-    var browser = getContainingBrowser(domWindow);
-    var tabbrowser = browser.getTabBrowser();
-    var tab = tabbrowser.getTabForBrowser(browser);
-    return tabbrowser.getFindBar(tab);
-  } catch (e) {
-    // Suppress errors for PDF files opened in the bookmark sidebar, see
-    // https://bugzilla.mozilla.org/show_bug.cgi?id=1248959.
-    return null;
-  }
-}
-
 function getBoolPref(pref, def) {
   try {
     return Services.prefs.getBoolPref(pref);
   } catch (ex) {
     return def;
   }
 }
 
@@ -330,28 +307,17 @@ class ChromeActions {
     } catch (e) {
       log("Unable to retrieve localized strings: " + e);
       return "null";
     }
   }
 
   supportsIntegratedFind() {
     // Integrated find is only supported when we're not in a frame
-    if (this.domWindow.frameElement !== null) {
-      return false;
-    }
-
-    // ... and we are in a child process
-    if (PdfjsContentUtils.isRemote) {
-      return true;
-    }
-
-    // ... or when the new find events code exists.
-    var findBar = getFindBar(this.domWindow);
-    return !!findBar && ("updateControlState" in findBar);
+    return this.domWindow.frameElement === null;
   }
 
   supportsDocumentFonts() {
     var prefBrowser = getIntPref("browser.display.use_document_fonts", 1);
     var prefGfx = getBoolPref("gfx.downloadable_fonts.enabled", true);
     return (!!prefBrowser && prefGfx);
   }
 
--- a/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
+++ b/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
@@ -173,30 +173,39 @@ var PdfjsChromeUtils = {
     }
     return undefined;
   },
 
   /*
    * Internal
    */
 
-  _findbarFromMessage(aMsg) {
+  _updateControlState(aMsg) {
+    let data = aMsg.data;
     let browser = aMsg.target;
     let tabbrowser = browser.getTabBrowser();
     let tab = tabbrowser.getTabForBrowser(browser);
-    return tabbrowser.getFindBar(tab);
-  },
-
-  _updateControlState(aMsg) {
-    let data = aMsg.data;
-    this._findbarFromMessage(aMsg)
-        .updateControlState(data.result, data.findPrevious);
+    tabbrowser.getFindBar(tab).then(fb => {
+      if (!fb) {
+        // The tab or window closed.
+        return;
+      }
+      fb.updateControlState(data.result, data.findPrevious);
+    });
   },
 
   handleEvent(aEvent) {
+    // Handle the tab find initialized event specially:
+    if (aEvent.type == "TabFindInitialized") {
+      let browser = aEvent.target.linkedBrowser;
+      this._hookupEventListeners(browser);
+      aEvent.target.removeEventListener(aEvent.type, this);
+      return;
+    }
+
     // To avoid forwarding the message as a CPOW, create a structured cloneable
     // version of the event for both performance, and ease of usage, reasons.
     let type = aEvent.type;
     let detail = {
       query: aEvent.detail.query,
       caseSensitive: aEvent.detail.caseSensitive,
       highlightAll: aEvent.detail.highlightAll,
       findPrevious: aEvent.detail.findPrevious,
@@ -224,37 +233,58 @@ var PdfjsChromeUtils = {
       throw new Error("FindEventManager was bound 2nd time " +
                       "without unbinding it first.");
     }
 
     // Since this jsm is global, we need to store all the browsers
     // we have to forward the messages for.
     this._browsers.add(browser);
 
-    // And we need to start listening to find events.
-    for (var i = 0; i < this._types.length; i++) {
-      var type = this._types[i];
-      this._findbarFromMessage(aMsg)
-          .addEventListener(type, this, true);
+    this._hookupEventListeners(browser);
+  },
+
+  /**
+   * Either hook up all the find event listeners if a findbar exists,
+   * or listen for a find bar being created and hook up event listeners
+   * when it does get created.
+   */
+  _hookupEventListeners(aBrowser) {
+    let tabbrowser = aBrowser.getTabBrowser();
+    let tab = tabbrowser.getTabForBrowser(aBrowser);
+    let findbar = tabbrowser.getCachedFindBar(tab);
+    if (findbar) {
+      // And we need to start listening to find events.
+      for (var i = 0; i < this._types.length; i++) {
+        var type = this._types[i];
+        findbar.addEventListener(type, this, true);
+      }
+    } else {
+      tab.addEventListener("TabFindInitialized", this);
     }
+    return !!findbar;
   },
 
   _removeEventListener(aMsg) {
     let browser = aMsg.target;
     if (!this._browsers.has(browser)) {
       throw new Error("FindEventManager was unbound without binding it first.");
     }
 
     this._browsers.delete(browser);
 
-    // No reason to listen to find events any longer.
-    for (var i = 0; i < this._types.length; i++) {
-      var type = this._types[i];
-      this._findbarFromMessage(aMsg)
-          .removeEventListener(type, this, true);
+    let tabbrowser = browser.getTabBrowser();
+    let tab = tabbrowser.getTabForBrowser(browser);
+    tab.removeEventListener("TabFindInitialized", this);
+    let findbar = tabbrowser.getCachedFindBar(tab);
+    if (findbar) {
+      // No reason to listen to find events any longer.
+      for (var i = 0; i < this._types.length; i++) {
+        var type = this._types[i];
+        findbar.removeEventListener(type, this, true);
+      }
     }
   },
 
   _ensurePreferenceAllowed(aPrefName) {
     let unPrefixedName = aPrefName.split(PREF_PREFIX + ".");
     if (unPrefixedName[0] !== "" ||
         !this._allowedPrefNames.includes(unPrefixedName[1])) {
       let msg = "\"" + aPrefName + "\" " +
--- a/browser/extensions/pdfjs/content/PdfjsContentUtils.jsm
+++ b/browser/extensions/pdfjs/content/PdfjsContentUtils.jsm
@@ -21,21 +21,16 @@ ChromeUtils.import("resource://gre/modul
 
 var PdfjsContentUtils = {
   _mm: null,
 
   /*
    * Public API
    */
 
-  get isRemote() {
-    return (Services.appinfo.processType ===
-            Services.appinfo.PROCESS_TYPE_CONTENT);
-  },
-
   init() {
     // child *process* mm, or when loaded into the parent for in-content
     // support the psuedo child process mm 'child PPMM'.
     if (!this._mm) {
       this._mm = Services.cpmm;
       this._mm.addMessageListener("PDFJS:Child:updateSettings", this);
 
       Services.obs.addObserver(this, "quit-application");
--- a/browser/extensions/pdfjs/test/browser_pdfjs_main.js
+++ b/browser/extensions/pdfjs/test/browser_pdfjs_main.js
@@ -13,18 +13,16 @@ add_task(async function test() {
   is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally, "pdf handler defaults to internal");
 
   info("Pref action: " + handlerInfo.preferredAction);
 
   await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
     async function(newTabBrowser) {
       await waitForPdfJS(newTabBrowser, TESTROOT + "file_pdfjs_test.pdf");
 
-      ok(gBrowser.isFindBarInitialized(), "Browser FindBar initialized!");
-
       await ContentTask.spawn(newTabBrowser, null, async function() {
         // Overall sanity tests
         Assert.ok(content.document.querySelector("div#viewer"), "document content has viewer UI");
         Assert.ok("PDFJS" in content.wrappedJSObject, "window content has PDFJS object");
 
         // Sidebar: open
         var sidebar = content.document.querySelector("button#sidebarToggle"),
             outerContainer = content.document.querySelector("div#outerContainer");