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: 9QEgJnWorTP
--- 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.indexOf(event.propertyName) != -1) {
+ 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