Bug 1348617 - Use the alpha channel of custom styled select backgrounds by applying the requested color on top of the system's background. r=mossop

This matches parity with Google Chrome Canary Version 59.0.3046.0 (Official Build) canary (64-bit).

MozReview-Commit-ID: 3rkhiFv8ezX

--HG--
extra : rebase_source : 3cb05e6c1e048bab4c7573bd050ea7477fc128fb
This commit is contained in:
Jared Wein 2017-03-21 10:51:40 -04:00
Родитель 130ff3a299
Коммит 2905dc199f
3 изменённых файлов: 51 добавлений и 12 удалений

Просмотреть файл

@ -60,6 +60,13 @@ const TRANSLUCENT_SELECT_BECOMES_OPAQUE =
' <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'>" +
@ -140,8 +147,33 @@ function* testSelectColors(select, itemCount, options) {
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");
@ -217,7 +249,7 @@ add_task(function* test_select_background_using_important() {
// 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)"
@ -225,6 +257,19 @@ add_task(function* test_translucent_select_becomes_opaque() {
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") {

Просмотреть файл

@ -142,13 +142,13 @@ this.SelectContentHelper.prototype = {
_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;

Просмотреть файл

@ -55,13 +55,7 @@ this.SelectParentHelper = {
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;