Bug 1349701 - Update the styles of <select> popups on focus. r=mossop, a=gchang
authorJared Wein <jwein@mozilla.com>
Thu, 23 Mar 2017 13:34:21 -0400
changeset 393321 94cfa175598827eceb9475a471ca3fe9a82a70f8
parent 393320 b305ba0b489ba2c9ac32c6896f9da68a24e10357
child 393322 a6ba68e32810d6e789683ed6abf605849a69d911
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmossop, gchang
bugs1349701
milestone54.0a2
Bug 1349701 - Update the styles of <select> popups on focus. r=mossop, a=gchang This patch also fixes a bug in our UpdateDropDown code where we weren't computing updated styles for <select> element, as well as another bug where we weren't passing the correct number of arguments to this.populate. MozReview-Commit-ID: 8LAeIliRXhZ
browser/base/content/test/forms/browser_selectpopup_colors.js
toolkit/modules/SelectContentHelper.jsm
toolkit/modules/SelectParentHelper.jsm
--- a/browser/base/content/test/forms/browser_selectpopup_colors.js
+++ b/browser/base/content/test/forms/browser_selectpopup_colors.js
@@ -86,16 +86,25 @@ const DISABLED_OPTGROUP_AND_OPTIONS =
   '    <option>{"color": "GrayText", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
   '    <option>{"color": "GrayText", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
   '    <option>{"color": "GrayText", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
   '    <option>{"color": "GrayText", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
   "  </optgroup>" +
   '  <option value="Two" selected="true">{"end": "true"}</option>' +
   "</select></body></html>";
 
+const SELECT_CHANGES_COLOR_ON_FOCUS =
+  "<html><head><style>" +
+  "  select:focus { background-color: orange; color: black; }" +
+  "</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>";
+
 function getSystemColor(color) {
   // Need to convert system color to RGB color.
   let textarea = document.createElementNS("http://www.w3.org/1999/xhtml", "textarea");
   textarea.style.color = color;
   return getComputedStyle(textarea).color;
 }
 
 function testOptionColors(index, item, menulist) {
@@ -274,8 +283,17 @@ add_task(function* test_disabled_optgrou
   // The colors used by this test are platform-specific.
   if (AppConstants.platform != "win") {
     return;
   }
 
   yield testSelectColors(DISABLED_OPTGROUP_AND_OPTIONS, 17,
                          {skipSelectColorTest: true});
 });
+
+add_task(function* test_disabled_optgroup_and_options() {
+  let options = {
+    selectColor: "rgb(0, 0, 0)",
+    selectBgColor: "rgb(255, 165, 0)"
+  };
+
+  yield testSelectColors(SELECT_CHANGES_COLOR_ON_FOCUS, 2, options);
+});
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -89,19 +89,21 @@ this.SelectContentHelper.prototype = {
     this._updateTimer.disarm();
     this._updateTimer = null;
     gOpen = false;
   },
 
   showDropDown() {
     this.element.openInParentProcess = true;
     let rect = this._getBoundingContentRect();
+    DOMUtils.addPseudoClassLock(this.element, ":focus");
     let computedStyles = getComputedStyles(this.element);
     this._selectBackgroundColor = computedStyles.backgroundColor;
     this._selectColor = computedStyles.color;
+    DOMUtils.clearPseudoClassLocks(this.element);
     this.global.sendAsyncMessage("Forms:ShowDropDown", {
       direction: computedStyles.direction,
       isOpenedViaTouch: this.isOpenedViaTouch,
       options: this._buildOptionList(),
       rect,
       selectedIndex: this.element.selectedIndex,
       selectBackgroundColor: this._selectBackgroundColor,
       selectColor: this._selectColor,
@@ -119,16 +121,24 @@ this.SelectContentHelper.prototype = {
 
   _buildOptionList() {
     return buildOptionListForChildren(this.element);
   },
 
   _update() {
     // The <select> was updated while the dropdown was open.
     // Let's send up a new list of options.
+    // Technically we might not need to set this pseudo-class
+    // during _update() since the element should organically
+    // have :focus, though it is here for belt-and-suspenders.
+    DOMUtils.addPseudoClassLock(this.element, ":focus");
+    let computedStyles = getComputedStyles(this.element);
+    this._selectBackgroundColor = computedStyles.backgroundColor;
+    this._selectColor = computedStyles.color;
+    DOMUtils.clearPseudoClassLocks(this.element);
     this.global.sendAsyncMessage("Forms:UpdateDropDown", {
       options: this._buildOptionList(),
       selectedIndex: this.element.selectedIndex,
       selectBackgroundColor: this._selectBackgroundColor,
       selectColor: this._selectColor,
       uaBackgroundColor: this.uaBackgroundColor,
       uaColor: this.uaColor,
       uaSelectBackgroundColor: this.uaSelectBackgroundColor,
--- a/toolkit/modules/SelectParentHelper.jsm
+++ b/toolkit/modules/SelectParentHelper.jsm
@@ -187,20 +187,23 @@ this.SelectParentHelper = {
       if (!currentMenulist || !currentBrowser) {
         return;
       }
 
       let options = msg.data.options;
       let selectedIndex = msg.data.selectedIndex;
       let uaBackgroundColor = msg.data.uaBackgroundColor;
       let uaColor = msg.data.uaColor;
+      let uaSelectBackgroundColor = msg.data.uaSelectBackgroundColor;
+      let uaSelectColor = msg.data.uaSelectColor;
       let selectBackgroundColor = msg.data.selectBackgroundColor;
       let selectColor = msg.data.selectColor;
       this.populate(currentMenulist, options, selectedIndex,
                     currentZoom, uaBackgroundColor, uaColor,
+                    uaSelectBackgroundColor, uaSelectColor,
                     selectBackgroundColor, selectColor);
     }
   },
 
   _registerListeners(browser, popup) {
     popup.addEventListener("command", this);
     popup.addEventListener("popuphidden", this);
     popup.addEventListener("mouseover", this);