Bug 1300784 - Combine non-e10s and e10s select dropdown implementations, preffed off. r=mconley
authorMichael <wrigh517@msu.edu>
Wed, 21 Dec 2016 11:09:39 -0500
changeset 328811 84e26201a8eee4e52274a690690c5ebc4bffe919
parent 328810 7c54af30e12bdb70a36fdd811e447b0c2f675b79
child 328812 d75cca55d82497c0f4df313f2daabe7e31b35258
push id85546
push userkwierso@gmail.com
push dateWed, 11 Jan 2017 02:36:30 +0000
treeherdermozilla-inbound@c5bce4cd684a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs1300784
milestone53.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 1300784 - Combine non-e10s and e10s select dropdown implementations, preffed off. r=mconley Patch by Michael Wright and Freddy (Junshan) Luo. MozReview-Commit-ID: G0CaZplABpC
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_selectpopup.js
layout/forms/nsListControlFrame.cpp
modules/libpref/init/all.js
toolkit/content/browser-content.js
toolkit/content/jar.mn
toolkit/content/widgets/browser.xml
toolkit/content/widgets/remote-browser.xml
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -387,17 +387,16 @@ skip-if = e10s && debug && os == "win" #
 [browser_save_video.js]
 [browser_save_video_frame.js]
 [browser_scope.js]
 [browser_contentSearchUI.js]
 support-files =
   contentSearchUI.html
   contentSearchUI.js
 [browser_selectpopup.js]
-run-if = e10s
 [browser_selectTabAtIndex.js]
 [browser_ssl_error_reports.js]
 [browser_star_hsts.js]
 [browser_subframe_favicons_not_used.js]
 [browser_syncui.js]
 skip-if = os == 'linux' # Bug 1304272
 [browser_tab_close_dependent_window.js]
 [browser_tabDrop.js]
--- a/browser/base/content/test/general/browser_selectpopup.js
+++ b/browser/base/content/test/general/browser_selectpopup.js
@@ -190,16 +190,24 @@ function* doSelectTests(contentType, dtd
   is((yield getChangeEvents()), isWindows ? 2 : 1, "Tab away from select with change - number of change events");
 
   is(selectPopup.lastChild.previousSibling.label, "Seven", "Spaces collapsed");
   is(selectPopup.lastChild.label, "\xA0\xA0Eight\xA0\xA0", "Non-breaking spaces not collapsed");
 
   yield BrowserTestUtils.removeTab(tab);
 }
 
+add_task(function* setup() {
+  yield SpecialPowers.pushPrefEnv({
+    "set": [
+      ["dom.select_popup_in_parent.enabled", true],
+    ]
+  });
+});
+
 add_task(function*() {
   yield doSelectTests("text/html", "");
 });
 
 add_task(function*() {
   yield doSelectTests("application/xhtml+xml", XHTML_DTD);
 });
 
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -113,16 +113,22 @@ nsListControlFrame::nsListControlFrame(n
 }
 
 //---------------------------------------------------------
 nsListControlFrame::~nsListControlFrame()
 {
   mComboboxFrame = nullptr;
 }
 
+static bool ShouldFireDropDownEvent() {
+  return (XRE_IsContentProcess() &&
+          Preferences::GetBool("browser.tabs.remote.desktopbehavior", false)) ||
+         Preferences::GetBool("dom.select_popup_in_parent.enabled", false);
+}
+
 // for Bug 47302 (remove this comment later)
 void
 nsListControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   // get the receiver interface from the browser button's content node
   ENSURE_TRUE(mContent);
 
   // Clear the frame pointer on our event listener, just in case the
@@ -136,18 +142,17 @@ nsListControlFrame::DestroyFrom(nsIFrame
                                       mEventListener, false);
   mContent->RemoveSystemEventListener(NS_LITERAL_STRING("mousedown"),
                                       mEventListener, false);
   mContent->RemoveSystemEventListener(NS_LITERAL_STRING("mouseup"),
                                       mEventListener, false);
   mContent->RemoveSystemEventListener(NS_LITERAL_STRING("mousemove"),
                                       mEventListener, false);
 
-  if (XRE_IsContentProcess() &&
-      Preferences::GetBool("browser.tabs.remote.desktopbehavior", false)) {
+  if (ShouldFireDropDownEvent()) {
     nsContentUtils::AddScriptRunner(
       new AsyncEventDispatcher(mContent,
                                NS_LITERAL_STRING("mozhidedropdown"), true,
                                true));
   }
 
   nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
   nsHTMLScrollFrame::DestroyFrom(aDestructRoot);
@@ -1784,18 +1789,17 @@ nsListControlFrame::GetIndexFromDOMEvent
   }
 
   return NS_ERROR_FAILURE;
 }
 
 static bool
 FireShowDropDownEvent(nsIContent* aContent, bool aShow, bool aIsSourceTouchEvent)
 {
-  if (XRE_IsContentProcess() &&
-      Preferences::GetBool("browser.tabs.remote.desktopbehavior", false)) {
+  if (ShouldFireDropDownEvent()) {
     nsString eventName;
     if (aShow) {
       eventName = aIsSourceTouchEvent ? NS_LITERAL_STRING("mozshowdropdown-sourcetouch") :
                                         NS_LITERAL_STRING("mozshowdropdown");
     } else {
       eventName = NS_LITERAL_STRING("mozhidedropdown");
     }
     nsContentUtils::DispatchChromeEvent(aContent->OwnerDoc(), aContent,
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -112,16 +112,17 @@ pref("offline-apps.quota.warn",        5
 // cache compression turned off for now - see bug #715198
 pref("browser.cache.compression_level", 0);
 
 // Don't show "Open with" option on download dialog if true.
 pref("browser.download.forbid_open_with", false);
 
 // Whether or not testing features are enabled.
 pref("dom.quotaManager.testing", false);
+pref("dom.select_popup_in_parent.enabled", false);
 
 // Whether or not indexedDB is enabled.
 pref("dom.indexedDB.enabled", true);
 // Whether or not indexedDB experimental features are enabled.
 pref("dom.indexedDB.experimental", false);
 // Enable indexedDB logging.
 pref("dom.indexedDB.logging.enabled", true);
 // Detailed output in log messages.
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -10,16 +10,18 @@ var Cr = Components.results;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
   "resource://gre/modules/ReaderMode.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
   "resource://gre/modules/BrowserUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "SelectContentHelper",
+  "resource://gre/modules/SelectContentHelper.jsm");
 
 var global = this;
 
 
 // Lazily load the finder code
 addMessageListener("Finder:Initialize", function() {
   let {RemoteFinderListener} = Cu.import("resource://gre/modules/RemoteFinder.jsm", {});
   new RemoteFinderListener(global);
@@ -1820,8 +1822,27 @@ let TelemetryScrollTracker = {
 
   shouldIgnorePage() {
     return content.location == "" ||
            content.location.protocol === "about:";
   }
 };
 
 TelemetryScrollTracker.init();
+
+addEventListener("mozshowdropdown", event => {
+  if (!event.isTrusted)
+    return;
+
+  if (!SelectContentHelper.open) {
+    new SelectContentHelper(event.target, {isOpenedViaTouch: false}, this);
+  }
+});
+
+addEventListener("mozshowdropdown-sourcetouch", event => {
+  if (!event.isTrusted)
+    return;
+
+  if (!SelectContentHelper.open) {
+    new SelectContentHelper(event.target, {isOpenedViaTouch: true}, this);
+  }
+});
+
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -57,17 +57,16 @@ toolkit.jar:
    content/global/filepicker.properties
    content/global/globalOverlay.js
    content/global/mozilla.xhtml
    content/global/process-content.js
    content/global/resetProfile.css
    content/global/resetProfile.js
    content/global/resetProfile.xul
    content/global/resetProfileProgress.xul
-   content/global/select-child.js
    content/global/TopLevelVideoDocument.js
    content/global/timepicker.xhtml
    content/global/treeUtils.js
    content/global/viewZoomOverlay.js
    content/global/bindings/autocomplete.xml    (widgets/autocomplete.xml)
    content/global/bindings/browser.xml         (widgets/browser.xml)
    content/global/bindings/button.xml          (widgets/button.xml)
    content/global/bindings/calendar.js         (widgets/calendar.js)
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -951,16 +951,22 @@
 
           if (this.messageManager) {
             this.messageManager.addMessageListener("PopupBlocking:UpdateBlockedPopups", this);
             this.messageManager.addMessageListener("Autoscroll:Start", this);
             this.messageManager.addMessageListener("Autoscroll:Cancel", this);
             this.messageManager.addMessageListener("AudioPlayback:Start", this);
             this.messageManager.addMessageListener("AudioPlayback:Stop", this);
             this.messageManager.addMessageListener("AudioPlayback:Block", this);
+
+            if (this.hasAttribute("selectmenulist")) {
+              this.messageManager.addMessageListener("Forms:ShowDropDown", this);
+              this.messageManager.addMessageListener("Forms:HideDropDown", this);
+            }
+
           }
         ]]>
       </constructor>
 
       <destructor>
         <![CDATA[
           this.destroy();
         ]]>
@@ -969,16 +975,21 @@
       <!-- This is necessary because the destructor doesn't always get called when
            we are removed from a tabbrowser. This will be explicitly called by tabbrowser.
 
            Note: this function is overriden in remote-browser.xml, so any clean-up that
            also applies to browser.isRemoteBrowser = true must be duplicated there. -->
       <method name="destroy">
         <body>
           <![CDATA[
+          // Make sure that any open select is closed.
+          if (this._selectParentHelper) {
+            let menulist = document.getElementById(this.getAttribute("selectmenulist"));
+            this._selectParentHelper.hide(menulist, this);
+          }
           if (this.mDestroyed)
             return;
           this.mDestroyed = true;
 
           if (this.docShell && this.webNavigation.sessionHistory) {
             var os = Components.classes["@mozilla.org/observer-service;1"]
                                .getService(Components.interfaces.nsIObserverService);
             try {
@@ -1040,16 +1051,37 @@
               this.audioPlaybackStarted();
               break;
             case "AudioPlayback:Stop":
               this.audioPlaybackStopped();
               break;
             case "AudioPlayback:Block":
               this.audioPlaybackBlocked();
               break;
+            case "Forms:ShowDropDown": {
+              if (!this._selectParentHelper) {
+                this._selectParentHelper =
+                  Cu.import("resource://gre/modules/SelectParentHelper.jsm", {}).SelectParentHelper;
+              }
+
+              let menulist = document.getElementById(this.getAttribute("selectmenulist"));
+              menulist.menupopup.style.direction = data.direction;
+              this._selectParentHelper.populate(menulist, data.options, data.selectedIndex, this._fullZoom);
+              this._selectParentHelper.open(this, menulist, data.rect, data.isOpenedViaTouch);
+              break;
+            }
+
+            case "Forms:HideDropDown": {
+              if (this._selectParentHelper) {
+                let menulist = document.getElementById(this.getAttribute("selectmenulist"));
+                this._selectParentHelper.hide(menulist, this);
+              }
+              break;
+            }
+
           }
           return undefined;
         ]]></body>
       </method>
 
       <method name="receiveMessage">
         <parameter name="aMessage"/>
         <body><![CDATA[
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -384,17 +384,16 @@
           this.messageManager.addMessageListener("DOMFullscreen:RequestExit", this);
           this.messageManager.addMessageListener("DOMFullscreen:RequestRollback", this);
           this.messageManager.addMessageListener("MozApplicationManifest", this);
           this.messageManager.loadFrameScript("chrome://global/content/browser-child.js", true);
 
           if (this.hasAttribute("selectmenulist")) {
             this.messageManager.addMessageListener("Forms:ShowDropDown", this);
             this.messageManager.addMessageListener("Forms:HideDropDown", this);
-            this.messageManager.loadFrameScript("chrome://global/content/select-child.js", true);
           }
 
           if (!this.hasAttribute("disablehistory")) {
             Services.obs.addObserver(this, "browser:purge-session-history", true);
           }
 
           let jsm = "resource://gre/modules/RemoteController.jsm";
           let RemoteController = Components.utils.import(jsm, {}).RemoteController;
@@ -495,24 +494,16 @@
 
             case "ZoomChangeUsingMouseWheel": {
               let event = document.createEvent("Events");
               event.initEvent("ZoomChangeUsingMouseWheel", true, false);
               this.dispatchEvent(event);
               break;
             }
 
-            case "Forms:HideDropDown": {
-              if (this._selectParentHelper) {
-                let menulist = document.getElementById(this.getAttribute("selectmenulist"));
-                this._selectParentHelper.hide(menulist, this);
-              }
-              break;
-            }
-
             case "DOMFullscreen:RequestExit": {
               let windowUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                                       .getInterface(Components.interfaces.nsIDOMWindowUtils);
               windowUtils.exitFullscreen();
               break;
             }
 
             case "DOMFullscreen:RequestRollback": {