Bug 1291078 - More closely mimic non-e10s order of events when choosing <select> elements in e10s mode. r?Enn draft
authorMike Conley <mconley@mozilla.com>
Tue, 02 Aug 2016 15:09:59 -0400
changeset 396384 ebb51ccb8339d21e512312dafc4da656bc157adf
parent 396350 331c4166a3a2df2d3a037107addef5d85cdc31b5
child 527186 529887f6f6ab814142f6a0bfd56434d3dc317b12
push id24983
push usermconley@mozilla.com
push dateWed, 03 Aug 2016 19:46:20 +0000
reviewersEnn
bugs1291078
milestone51.0a1
Bug 1291078 - More closely mimic non-e10s order of events when choosing <select> elements in e10s mode. r?Enn MozReview-Commit-ID: 4CkFUy1nLbo
browser/base/content/test/general/browser_selectpopup.js
toolkit/modules/SelectContentHelper.jsm
--- a/browser/base/content/test/general/browser_selectpopup.js
+++ b/browser/base/content/test/general/browser_selectpopup.js
@@ -315,36 +315,36 @@ add_task(function* test_event_order() {
         type: "change",
         cancelable: false,
         targetIsOption: false,
       },
     ];
 
     let expectedClick = [
       {
+        type: "mousedown",
+        cancelable: true,
+        targetIsOption: true,
+      },
+      {
+        type: "mouseup",
+        cancelable: true,
+        targetIsOption: true,
+      },
+      {
         type: "input",
         cancelable: false,
         targetIsOption: false,
       },
       {
         type: "change",
         cancelable: false,
         targetIsOption: false,
       },
       {
-        type: "mousedown",
-        cancelable: true,
-        targetIsOption: true,
-      },
-      {
-        type: "mouseup",
-        cancelable: true,
-        targetIsOption: true,
-      },
-      {
         type: "click",
         cancelable: true,
         targetIsOption: true,
       },
     ];
 
     for (let mode of ["enter", "click"]) {
       let expected = mode == "enter" ? expectedEnter : expectedClick;
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -115,44 +115,52 @@ this.SelectContentHelper.prototype = {
         this.element.selectedIndex = message.data.value;
         this.closedWithEnter = message.data.closedWithEnter;
         break;
 
       case "Forms:DismissedDropDown":
         let selectedOption = this.element.item(this.element.selectedIndex);
         if (this.initialSelection != selectedOption) {
           let win = this.element.ownerDocument.defaultView;
+          // For ordering of events, we're using non-e10s as our guide here,
+          // since the spec isn't exactly clear. In non-e10s, we fire:
+          // mousedown, mouseup, input, change, click if the user clicks
+          // on an element in the dropdown. If the user uses the keyboard
+          // to select an element in the dropdown, we only fire input and
+          // change events.
+          if (!this.closedWithEnter) {
+            const MOUSE_EVENTS = ["mousedown", "mouseup"];
+            for (let eventName of MOUSE_EVENTS) {
+              let mouseEvent = new win.MouseEvent(eventName, {
+                view: win,
+                bubbles: true,
+                cancelable: true,
+              });
+              selectedOption.dispatchEvent(mouseEvent);
+            }
+            DOMUtils.removeContentState(this.element, kStateActive);
+          }
+
           let inputEvent = new win.UIEvent("input", {
             bubbles: true,
           });
           this.element.dispatchEvent(inputEvent);
 
           let changeEvent = new win.Event("change", {
             bubbles: true,
           });
           this.element.dispatchEvent(changeEvent);
 
           if (!this.closedWithEnter) {
-            // Going for mostly-Blink parity here, which (at least on Windows)
-            // fires a mouseup and click event after each selection -
-            // even by keyboard. We're firing a mousedown too, since that
-            // seems to make more sense. Unfortunately, the spec on form
-            // control behaviours for these events is really not clear.
-            const MOUSE_EVENTS = ["mousedown", "mouseup", "click"];
-            for (let eventName of MOUSE_EVENTS) {
-              let mouseEvent = new win.MouseEvent(eventName, {
-                view: win,
-                bubbles: true,
-                cancelable: true,
-              });
-              selectedOption.dispatchEvent(mouseEvent);
-              if (eventName == "mouseup") {
-                DOMUtils.removeContentState(this.element, kStateActive);
-              }
-            }
+            let mouseEvent = new win.MouseEvent("click", {
+              view: win,
+              bubbles: true,
+              cancelable: true,
+            });
+            selectedOption.dispatchEvent(mouseEvent);
           }
         }
 
         this.uninit();
         break;
 
       case "Forms:MouseOver":
         DOMUtils.setContentState(this.element, kStateHover);