Bug 1383205 - Update transitionend properties of <option> elements on a deferred task. r=jaws
☠☠ backed out by 731889ddbd52 ☠ ☠
authorFelipe Gomes <felipc@gmail.com>
Fri, 28 Jul 2017 16:15:32 -0300
changeset 420561 5a6100bac2393e0eb99b7e0f4feeb3b806fde7f7
parent 420560 1955c9d3718617f9d37c689a7e845ef97e56abf3
child 420562 485ceaeda92239b569b49989845fdee594c3c0a9
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1383205
milestone56.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 1383205 - Update transitionend properties of <option> elements on a deferred task. r=jaws Also, we only care about the properties that we support and that are animatable, as the non-animatable ones do not generate transitionend events MozReview-Commit-ID: Aluf8gnAhbn
browser/base/content/test/forms/browser_selectpopup_colors.js
toolkit/modules/SelectContentHelper.jsm
--- a/browser/base/content/test/forms/browser_selectpopup_colors.js
+++ b/browser/base/content/test/forms/browser_selectpopup_colors.js
@@ -125,25 +125,34 @@ const SELECT_STYLE_OF_OPTION_CHANGES_AFT
   '  <option>{"color": "rgb(255, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
   '  <option selected="true">{"end": "true"}</option>' +
   "</select></body><scr" +
   "ipt>" +
   "  var select = document.getElementById('one');" +
   "  select.addEventListener('focus', () => select.style.color = 'red');" +
   "</script></html>";
 
-const SELECT_STYLE_OF_OPTION_CHANGES_AFTER_TRANSITIONEND =
+const SELECT_COLOR_OF_OPTION_CHANGES_AFTER_TRANSITIONEND =
   "<html><head><style>" +
   "  select { transition: all .1s; }" +
   "  select:focus { background-color: orange; }" +
   "</style></head><body><select id='one'>" +
   '  <option>{"color": "rgb(0, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
   '  <option selected="true">{"end": "true"}</option>' +
   "</select></body></html>";
 
+const SELECT_TEXTSHADOW_OF_OPTION_CHANGES_AFTER_TRANSITIONEND =
+  "<html><head><style>" +
+  "  select { transition: all .1s; }" +
+  "  select:focus { text-shadow: 0 0 0 #303030; }" +
+  "</style></head><body><select id='one'>" +
+  '  <option>{"text-shadow": "none"}</option>' +
+  '  <option selected="true">{"end": "true"}</option>' +
+  "</select></body></html>";
+
 const SELECT_TRANSPARENT_COLOR_WITH_TEXT_SHADOW =
   "<html><head><style>" +
   "  select { color: transparent; text-shadow: 0 0 0 #303030; }" +
   "</style></head><body><select id='one'>" +
   '  <option>{"color": "rgba(0, 0, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)", "textShadow": "rgb(48, 48, 48) 0px 0px 0px"}</option>' +
   '  <option selected="true">{"end": "true"}</option>' +
   "</select></body></html>";
 
@@ -401,27 +410,39 @@ add_task(async function test_style_of_op
     waitForComputedStyle: {
       property: "color",
       value: "rgb(255, 0, 0)"
     }
   };
   await testSelectColors(SELECT_STYLE_OF_OPTION_CHANGES_AFTER_FOCUS_EVENT, 2, options);
 });
 
-add_task(async function test_style_of_options_is_dependent_on_transitionend() {
+add_task(async function test_color_of_options_is_dependent_on_transitionend() {
   let options = {
     selectColor: "rgb(0, 0, 0)",
     selectBgColor: "rgb(255, 165, 0)",
     waitForComputedStyle: {
       property: "background-image",
       value: "linear-gradient(rgb(255, 165, 0), rgb(255, 165, 0))"
     }
   };
 
-  await testSelectColors(SELECT_STYLE_OF_OPTION_CHANGES_AFTER_TRANSITIONEND, 2, options);
+  await testSelectColors(SELECT_COLOR_OF_OPTION_CHANGES_AFTER_TRANSITIONEND, 2, options);
+});
+
+add_task(async function test_textshadow_of_options_is_dependent_on_transitionend() {
+  let options = {
+    skipSelectColorTest: true,
+    waitForComputedStyle: {
+      property: "text-shadow",
+      value: "rgb(48, 48, 48) 0px 0px 0px"
+    }
+  };
+
+  await testSelectColors(SELECT_TEXTSHADOW_OF_OPTION_CHANGES_AFTER_TRANSITIONEND, 2, options);
 });
 
 add_task(async function test_transparent_color_with_text_shadow() {
   let options = {
     selectColor: "rgba(0, 0, 0, 0)",
     selectTextShadow: "rgb(48, 48, 48) 0px 0px 0px",
     selectBgColor: "rgb(255, 255, 255)"
   };
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -15,16 +15,22 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 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
 
+const SUPPORTED_PROPERTIES = [
+  "color",
+  "background-color",
+  "text-shadow",
+];
+
 // 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;
 
 this.EXPORTED_SYMBOLS = [
   "SelectContentHelper"
@@ -354,17 +360,19 @@ this.SelectContentHelper.prototype = {
       }
       case "mozhidedropdown":
         if (this.element === event.target) {
           this.global.sendAsyncMessage("Forms:HideDropDown", {});
           this.uninit();
         }
         break;
       case "transitionend":
-        this._update();
+        if (SUPPORTED_PROPERTIES.includes(event.propertyName)) {
+          this._updateTimer.arm();
+        }
         break;
     }
   }
 
 }
 
 function getComputedStyles(element) {
   return element.ownerGlobal.getComputedStyle(element);
@@ -385,16 +393,20 @@ function buildOptionListForChildren(node
         tagName == "OPTGROUP" ? child.getAttribute("label")
                               : child.text;
       if (textContent == null) {
         textContent = "";
       }
 
       let cs = getComputedStyles(child);
 
+      // Note: If you add any more CSS properties support here,
+      // please add the property name to the SUPPORTED_PROPERTIES
+      // list so that the menu can be correctly updated when CSS
+      // transitions are used.
       let info = {
         index: child.index,
         tagName,
         textContent,
         disabled: child.disabled,
         display: cs.display,
         // We need to do this for every option element as each one can have
         // an individual style set for direction