--- a/browser/base/content/test/forms/browser_selectpopup_colors.js
+++ b/browser/base/content/test/forms/browser_selectpopup_colors.js
@@ -55,16 +55,23 @@ const GENERIC_OPTION_STYLED_AS_IMPORTANT
const TRANSLUCENT_SELECT_BECOMES_OPAQUE =
"<html><head>" +
"<body><select id='one' style='background-color: rgba(255,255,255,.55);'>" +
' <option value="One">{"color": "rgb(0, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
' <option value="Two" selected="true">{"end": "true"}</option>' +
"</select></body></html>";
+const TRANSLUCENT_SELECT_APPLIES_ON_BASE_COLOR =
+ "<html><head>" +
+ "<body><select id='one' style='background-color: rgba(255,0,0,.55);'>" +
+ ' <option value="One">{"color": "rgb(0, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
+ ' <option value="Two" selected="true">{"end": "true"}</option>' +
+ "</select></body></html>";
+
const DISABLED_OPTGROUP_AND_OPTIONS =
"<html><head>" +
"<body><select id='one'>" +
" <optgroup label='{\"color\": \"rgb(0, 0, 0)\", \"backgroundColor\": \"buttonface\"}'>" +
' <option disabled="">{"color": "GrayText", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
' <option>{"color": "rgb(0, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
' <option disabled="">{"color": "GrayText", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
' <option>{"color": "rgb(0, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
@@ -135,18 +142,43 @@ function* testSelectColors(select, itemC
is(selectPopup.parentNode.itemCount, itemCount, "Correct number of items");
let child = selectPopup.firstChild;
let idx = 1;
if (!options.skipSelectColorTest) {
is(getComputedStyle(selectPopup).color, options.selectColor,
"popup has expected foreground color");
- is(getComputedStyle(selectPopup).backgroundColor, options.selectBgColor,
- "popup has expected background color");
+
+ // Combine the select popup's backgroundColor and the
+ // backgroundImage color to get the color that is seen by
+ // the user.
+ let base = getComputedStyle(selectPopup).backgroundColor;
+ let [/* unused */, bR, bG, bB] =
+ base.match(/rgb\((\d+), (\d+), (\d+)\)/);
+ bR = parseInt(bR, 10);
+ bG = parseInt(bG, 10);
+ bB = parseInt(bB, 10);
+ let topCoat = getComputedStyle(selectPopup).backgroundImage;
+ if (topCoat == "none") {
+ is(`rgb(${bR}, ${bG}, ${bB})`, options.selectBgColor,
+ "popup has expected background color");
+ } else {
+ let [/* unused */, /* unused */, tR, tG, tB, tA] =
+ topCoat.match(/(rgba?\((\d+), (\d+), (\d+)(?:, (0\.\d+))?\)), \1/);
+ tR = parseInt(tR, 10);
+ tG = parseInt(tG, 10);
+ tB = parseInt(tB, 10);
+ tA = parseFloat(tA) || 1;
+ let actualR = Math.round(tR * tA + bR * (1 - tA));
+ let actualG = Math.round(tG * tA + bG * (1 - tA));
+ let actualB = Math.round(tB * tA + bB * (1 - tA));
+ is(`rgb(${actualR}, ${actualG}, ${actualB})`, options.selectBgColor,
+ "popup has expected background color");
+ }
}
ok(!child.selected, "The first child should not be selected");
while (child) {
testOptionColors(idx, child, menulist);
idx++;
child = child.nextSibling;
}
@@ -212,24 +244,37 @@ add_task(function* test_select_backgroun
});
// This test checks when a <select> element has a background set, and the
// options have their own background set which is equal to the default
// user-agent background color, but should be used because the select
// background color has been changed.
add_task(function* test_translucent_select_becomes_opaque() {
// The popup is requested to show a translucent background
- // but we force the alpha channel to 1 on the popup.
+ // but we apply the requested background color on the system's base color.
let options = {
selectColor: "rgb(0, 0, 0)",
selectBgColor: "rgb(255, 255, 255)"
};
yield testSelectColors(TRANSLUCENT_SELECT_BECOMES_OPAQUE, 2, options);
});
+// This test checks when a popup has a translucent background color,
+// and that the color painted to the screen of the translucent background
+// matches what the user expects.
+add_task(function* test_translucent_select_applies_on_base_color() {
+ // The popup is requested to show a translucent background
+ // but we apply the requested background color on the system's base color.
+ let options = {
+ selectColor: "rgb(0, 0, 0)",
+ selectBgColor: "rgb(255, 115, 115)"
+ };
+ yield testSelectColors(TRANSLUCENT_SELECT_APPLIES_ON_BASE_COLOR, 2, options);
+});
+
add_task(function* test_disabled_optgroup_and_options() {
// The colors used by this test are platform-specific.
if (AppConstants.platform != "win") {
return;
}
yield testSelectColors(DISABLED_OPTGROUP_AND_OPTIONS, 17,
{skipSelectColorTest: true});
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -137,23 +137,23 @@ this.SelectContentHelper.prototype = {
},
// Determine user agent background-color and color.
// This is used to skip applying the custom color if it matches
// the user agent values.
_calculateUAColors() {
let dummyOption = this.element.ownerDocument.createElement("option");
dummyOption.style.setProperty("color", "-moz-comboboxtext", "important");
- dummyOption.style.setProperty("backgroundColor", "-moz-combobox", "important");
+ dummyOption.style.setProperty("background-color", "-moz-combobox", "important");
let optionCS = this.element.ownerGlobal.getComputedStyle(dummyOption);
this._uaBackgroundColor = optionCS.backgroundColor;
this._uaColor = optionCS.color;
let dummySelect = this.element.ownerDocument.createElement("select");
dummySelect.style.setProperty("color", "-moz-fieldtext", "important");
- dummySelect.style.setProperty("backgroundColor", "-moz-field", "important");
+ dummySelect.style.setProperty("background-color", "-moz-field", "important");
let selectCS = this.element.ownerGlobal.getComputedStyle(dummySelect);
this._uaSelectBackgroundColor = selectCS.backgroundColor;
this._uaSelectColor = selectCS.color;
},
get uaBackgroundColor() {
if (!this._uaBackgroundColor) {
this._calculateUAColors();
--- a/toolkit/modules/SelectParentHelper.jsm
+++ b/toolkit/modules/SelectParentHelper.jsm
@@ -50,23 +50,17 @@ this.SelectParentHelper = {
let ruleBody = "";
// Some webpages set the <select> backgroundColor to transparent,
// but they don't intend to change the popup to transparent.
if (customStylingEnabled &&
selectBackgroundColor != uaSelectBackgroundColor &&
selectBackgroundColor != "rgba(0, 0, 0, 0)" &&
selectBackgroundColor != selectColor) {
- let rgba = selectBackgroundColor.match(/rgba\((\d+), (\d+), (\d+),/);
- if (rgba) {
- let [, r, g, b] = rgba;
- ruleBody = `background-color: rgb(${r}, ${g}, ${b});`;
- } else {
- ruleBody = `background-color: ${selectBackgroundColor};`;
- }
+ ruleBody = `background-image: linear-gradient(${selectBackgroundColor}, ${selectBackgroundColor});`;
usedSelectBackgroundColor = selectBackgroundColor;
} else {
usedSelectBackgroundColor = uaSelectBackgroundColor;
}
if (customStylingEnabled &&
selectColor != uaSelectColor &&
selectColor != selectBackgroundColor &&