Bug 1291078 - Re-arrange events fired on <option> elements for e10s to match non-e10s. r=Enn, a=sylvestre
authorMike Conley <mconley@mozilla.com>
Wed, 03 Aug 2016 13:32:37 -0400
changeset 335699 e7d4b84c0ced
parent 335698 f0b7fef514f4
child 335700 909810e43190
push id1153
push usercbook@mozilla.com
push dateTue, 09 Aug 2016 07:12:04 +0000
treeherdermozilla-release@e7d4b84c0ced [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersEnn, sylvestre
bugs1291078
milestone48.0.1
Bug 1291078 - Re-arrange events fired on <option> elements for e10s to match non-e10s. r=Enn, a=sylvestre MozReview-Commit-ID: kYCFS51pvG
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
@@ -289,32 +289,32 @@ add_task(function* test_event_order() {
     yield openSelectPopup(selectPopup, true, "#one");
 
     let eventsPromise = ContentTask.spawn(browser, null, function*() {
       // According to https://html.spec.whatwg.org/#the-select-element,
       // we want to fire input, change, and then click events on the
       // <select> (in that order) when it has changed.
       let expected = [
         {
+          type: "mousedown",
+          cancelable: true,
+        },
+        {
+          type: "mouseup",
+          cancelable: true,
+        },
+        {
           type: "input",
           cancelable: false,
         },
         {
           type: "change",
           cancelable: false,
         },
         {
-          type: "mousedown",
-          cancelable: true,
-        },
-        {
-          type: "mouseup",
-          cancelable: true,
-        },
-        {
           type: "click",
           cancelable: true,
         },
       ];
 
       return new Promise((resolve) => {
         function onEvent(event) {
           select.removeEventListener(event.type, onEvent);
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -12,16 +12,17 @@ Cu.import("resource://gre/modules/XPCOMU
 
 XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
                                   "resource://gre/modules/BrowserUtils.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "DOMUtils",
                                    "@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
 XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask",
                                   "resource://gre/modules/DeferredTask.jsm");
 
+const kStateActive = 0x00000001; // NS_EVENT_STATE_ACTIVE
 const kStateHover = 0x00000004; // NS_EVENT_STATE_HOVER
 
 // A process global state for whether or not content thinks
 // that a <select> dropdown is open or not. This is managed
 // entirely within this module, and is read-only accessible
 // via SelectContentHelper.open.
 var gOpen = false;
 
@@ -112,40 +113,46 @@ this.SelectContentHelper.prototype = {
       case "Forms:SelectDropDownItem":
         this.element.selectedIndex = message.data.value;
         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.
+          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);
 
-          // 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);
-          }
+          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);
         break;