Bug 1294502 - Move AutoCompletePopup implementation for content to browser-content.js so that non-e10s can use it in a later patch. r?MattN draft
authorMike Conley <mconley@mozilla.com>
Thu, 28 Jul 2016 14:18:50 -0400
changeset 402661 f995d01b1002617d87464aef294140a09e47bb71
parent 402660 dc05739755333892f9166321a10778c0c4089ff8
child 402662 bd718bff1bbc06461e00c85008ac6a04132ba142
push id26721
push usermconley@mozilla.com
push dateThu, 18 Aug 2016 15:51:49 +0000
reviewersMattN
bugs1294502
milestone51.0a1
Bug 1294502 - Move AutoCompletePopup implementation for content to browser-content.js so that non-e10s can use it in a later patch. r?MattN MozReview-Commit-ID: 2fB4M3lqpLK
toolkit/content/browser-child.js
toolkit/content/browser-content.js
toolkit/content/widgets/browser.xml
toolkit/content/widgets/remote-browser.xml
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -583,92 +583,16 @@ addMessageListener("NetworkPrioritizer:A
 
 addMessageListener("NetworkPrioritizer:SetPriority", (msg) => {
   let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
   let loadGroup = webNav.QueryInterface(Ci.nsIDocumentLoader)
                         .loadGroup.QueryInterface(Ci.nsISupportsPriority);
   loadGroup.priority = msg.data.priority;
 });
 
-var AutoCompletePopup = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup]),
-
-  init: function() {
-    // Hook up the form fill autocomplete controller.
-    let controller = Cc["@mozilla.org/satchel/form-fill-controller;1"]
-                       .getService(Ci.nsIFormFillController);
-
-    controller.attachToBrowser(docShell, this.QueryInterface(Ci.nsIAutoCompletePopup));
-
-    this._input = null;
-    this._popupOpen = false;
-
-    addMessageListener("FormAutoComplete:HandleEnter", message => {
-      this.selectedIndex = message.data.selectedIndex;
-
-      let controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
-                  getService(Components.interfaces.nsIAutoCompleteController);
-      controller.handleEnter(message.data.isPopupSelection);
-    });
-
-    addEventListener("unload", function() {
-      AutoCompletePopup.destroy();
-    });
-  },
-
-  destroy: function() {
-    let controller = Cc["@mozilla.org/satchel/form-fill-controller;1"]
-                       .getService(Ci.nsIFormFillController);
-
-    controller.detachFromBrowser(docShell);
-  },
-
-  get input () { return this._input; },
-  get overrideValue () { return null; },
-  set selectedIndex (index) { },
-  get selectedIndex () {
-    // selectedIndex getter must be synchronous because we need the
-    // correct value when the controller is in controller::HandleEnter.
-    // We can't easily just let the parent inform us the new value every
-    // time it changes because not every action that can change the
-    // selectedIndex is trivial to catch (e.g. moving the mouse over the
-    // list).
-    return sendSyncMessage("FormAutoComplete:GetSelectedIndex", {});
-  },
-  get popupOpen () {
-    return this._popupOpen;
-  },
-
-  openAutocompletePopup: function (input, element) {
-    if (!this._popupOpen) {
-      // The search itself normally opens the popup itself, but in some cases,
-      // nsAutoCompleteController tries to use cached results so notify our
-      // popup to reuse the last results.
-      sendAsyncMessage("FormAutoComplete:MaybeOpenPopup", {});
-    }
-    this._input = input;
-    this._popupOpen = true;
-  },
-
-  closePopup: function () {
-    this._popupOpen = false;
-    sendAsyncMessage("FormAutoComplete:ClosePopup", {});
-  },
-
-  invalidate: function () {
-  },
-
-  selectBy: function(reverse, page) {
-    this._index = sendSyncMessage("FormAutoComplete:SelectBy", {
-      reverse: reverse,
-      page: page
-    });
-  }
-}
-
 addMessageListener("InPermitUnload", msg => {
   let inPermitUnload = docShell.contentViewer && docShell.contentViewer.inPermitUnload;
   sendAsyncMessage("InPermitUnload", {id: msg.data.id, inPermitUnload});
 });
 
 addMessageListener("PermitUnload", msg => {
   sendAsyncMessage("PermitUnload", {id: msg.data.id, kind: "start"});
 
@@ -681,14 +605,8 @@ addMessageListener("PermitUnload", msg =
 });
 
 // We may not get any responses to Browser:Init if the browser element
 // is torn down too quickly.
 var outerWindowID = content.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIDOMWindowUtils)
                            .outerWindowID;
 sendAsyncMessage("Browser:Init", {outerWindowID: outerWindowID});
-addMessageListener("Browser:InitReceived", function onInitReceived(msg) {
-  removeMessageListener("Browser:InitReceived", onInitReceived);
-  if (msg.data.initPopup) {
-    AutoCompletePopup.init();
-  }
-});
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -1377,8 +1377,98 @@ addEventListener("MozApplicationManifest
     uri: doc.documentURI,
     characterSet: doc.characterSet,
     manifest: doc.documentElement.getAttribute("manifest"),
     principal: doc.nodePrincipal,
   };
   sendAsyncMessage("MozApplicationManifest", info);
 }, false);
 
+let AutoCompletePopup = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup]),
+
+  _connected: false,
+  init: function() {
+    // We need to wait for a content viewer to be available
+    // before we can attach our AutoCompletePopup handler,
+    // since nsFormFillController assumes one will exist
+    // when we call attachToBrowser.
+    let onDCL = () => {
+      removeEventListener("DOMContentLoaded", onDCL);
+      // Hook up the form fill autocomplete controller.
+      let controller = Cc["@mozilla.org/satchel/form-fill-controller;1"]
+                         .getService(Ci.nsIFormFillController);
+      controller.attachToBrowser(docShell,
+                                 this.QueryInterface(Ci.nsIAutoCompletePopup));
+      this._connected = true;
+    };
+    addEventListener("DOMContentLoaded", onDCL);
+
+    this._input = null;
+    this._popupOpen = false;
+
+    addMessageListener("FormAutoComplete:HandleEnter", message => {
+      this.selectedIndex = message.data.selectedIndex;
+
+      let controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
+                  getService(Components.interfaces.nsIAutoCompleteController);
+      controller.handleEnter(message.data.isPopupSelection);
+    });
+
+    addEventListener("unload", function() {
+      AutoCompletePopup.destroy();
+    });
+  },
+
+  destroy: function() {
+    if (this._connected) {
+      let controller = Cc["@mozilla.org/satchel/form-fill-controller;1"]
+                         .getService(Ci.nsIFormFillController);
+
+      controller.detachFromBrowser(docShell);
+      this._connected = false;
+    }
+  },
+
+  get input () { return this._input; },
+  get overrideValue () { return null; },
+  set selectedIndex (index) { },
+  get selectedIndex () {
+    // selectedIndex getter must be synchronous because we need the
+    // correct value when the controller is in controller::HandleEnter.
+    // We can't easily just let the parent inform us the new value every
+    // time it changes because not every action that can change the
+    // selectedIndex is trivial to catch (e.g. moving the mouse over the
+    // list).
+    return sendSyncMessage("FormAutoComplete:GetSelectedIndex", {});
+  },
+  get popupOpen () {
+    return this._popupOpen;
+  },
+
+  openAutocompletePopup: function (input, element) {
+    if (!this._popupOpen) {
+      // The search itself normally opens the popup itself, but in some cases,
+      // nsAutoCompleteController tries to use cached results so notify our
+      // popup to reuse the last results.
+      sendAsyncMessage("FormAutoComplete:MaybeOpenPopup", {});
+    }
+    this._input = input;
+    this._popupOpen = true;
+  },
+
+  closePopup: function () {
+    this._popupOpen = false;
+    sendAsyncMessage("FormAutoComplete:ClosePopup", {});
+  },
+
+  invalidate: function () {
+  },
+
+  selectBy: function(reverse, page) {
+    this._index = sendSyncMessage("FormAutoComplete:SelectBy", {
+      reverse: reverse,
+      page: page
+    });
+  }
+}
+
+AutoCompletePopup.init();
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -258,16 +258,20 @@
           let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
           if (!frameLoader)
             return null;
           this._loadContext = frameLoader.loadContext;
           return this._loadContext;
         ]]></getter>
       </property>
 
+      <property name="autoCompletePopup"
+                onget="return document.getElementById(this.getAttribute('autocompletepopup'))"
+                readonly="true"/>
+
       <property name="docShellIsActive">
         <getter>
           <![CDATA[
             return this.docShell && this.docShell.isActive;
           ]]>
         </getter>
         <setter>
           <![CDATA[
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -238,20 +238,16 @@
 
       <field name="_innerWindowID">null</field>
       <property name="innerWindowID">
         <getter><![CDATA[
           return this._innerWindowID;
         ]]></getter>
       </property>
 
-      <property name="autoCompletePopup"
-                onget="return document.getElementById(this.getAttribute('autocompletepopup'))"
-                readonly="true"/>
-
       <property name="docShellIsActive">
         <getter>
           <![CDATA[
             let {frameLoader} = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
             return frameLoader.tabParent.docShellIsActive;
           ]]>
         </getter>
         <setter>
@@ -447,19 +443,16 @@
 
       <method name="receiveMessage">
         <parameter name="aMessage"/>
         <body><![CDATA[
           let data = aMessage.data;
           switch (aMessage.name) {
             case "Browser:Init":
               this._outerWindowID = data.outerWindowID;
-              this.messageManager.sendAsyncMessage("Browser:InitReceived", {
-                initPopup: this.autoCompletePopup != null,
-              });
               break;
             case "DOMTitleChanged":
               this._contentTitle = data.title;
               break;
             case "ImageDocumentLoaded":
               this._imageDocument = {
                 width: data.width,
                 height: data.height