mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1782623 - Set select color-scheme based on child background. r=dholbert
This makes us use light or dark select popups on supported platforms based on the background of the select element, which allows us to use the right scrollbar color. Depends on D153424 Differential Revision: https://phabricator.services.mozilla.com/D153425
This commit is contained in:
parent
f6eb8c21a5
commit
4fc9841344
@ -107,7 +107,7 @@ const gSelects = {
|
||||
" option { color: white; }" +
|
||||
"</style></head>" +
|
||||
"<body><select id='one'>" +
|
||||
' <option>{"color": "rgb(255, 255, 255)", "backgroundColor": "rgb(0, 0, 0)"}</option>' +
|
||||
' <option>{"colorScheme": "dark", "color": "rgb(255, 255, 255)", "backgroundColor": "rgb(0, 0, 0)"}</option>' +
|
||||
' <option selected="true">{"end": "true"}</option>' +
|
||||
"</select></body></html>",
|
||||
|
||||
@ -231,8 +231,8 @@ const gSelects = {
|
||||
select { background-color: #fff; }
|
||||
option { color: #2b2b2b; background-color: #fff; }
|
||||
</style></head><body><select id='one'>
|
||||
<option>{"color": "rgb(43, 43, 43)", "backgroundColor": "rgb(255, 255, 255)"}</option>
|
||||
<option>{"color": "rgb(43, 43, 43)", "backgroundColor": "rgb(255, 255, 255)"}</option>
|
||||
<option>{"colorScheme": "light", "color": "rgb(43, 43, 43)", "backgroundColor": "rgb(255, 255, 255)"}</option>
|
||||
<option>{"colorScheme": "light", "color": "rgb(43, 43, 43)", "backgroundColor": "rgb(255, 255, 255)"}</option>
|
||||
<option selected="true">{"end": "true"}</option>
|
||||
</select></body></html>
|
||||
`,
|
||||
@ -298,6 +298,7 @@ function computeLabels(tab) {
|
||||
let any = false;
|
||||
for (let color of Object.keys(expected)) {
|
||||
if (
|
||||
color != "colorScheme" &&
|
||||
color.toLowerCase().includes("color") &&
|
||||
!expected[color].startsWith("rgb")
|
||||
) {
|
||||
@ -719,7 +720,6 @@ add_task(
|
||||
'#ContentSelectDropdown .ContentSelectDropdown-item-1:not([_moz-menuactive="true"])',
|
||||
"#ContentSelectDropdown .ContentSelectDropdown-item-2",
|
||||
'#ContentSelectDropdown .ContentSelectDropdown-item-2:not([_moz-menuactive="true"])',
|
||||
"#ContentSelectDropdown > menupopup",
|
||||
'#ContentSelectDropdown > menupopup > :is(menuitem, menucaption):not([_moz-menuactive="true"])',
|
||||
'#ContentSelectDropdown > menupopup > :is(menuitem, menucaption)[_moz-menuactive="true"]',
|
||||
].sort();
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "mozilla/ipc/UtilityProcessHost.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "IOActivityMonitor.h"
|
||||
#include "nsNativeTheme.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozJSModuleLoader.h"
|
||||
#include "mozilla/ProfilerLabels.h"
|
||||
@ -1707,4 +1708,13 @@ void ChromeUtils::GetFormAutofillConfidences(
|
||||
FormAutofillNative::GetFormAutofillConfidences(aGlobal, aElements, aResults,
|
||||
aRv);
|
||||
}
|
||||
|
||||
bool ChromeUtils::IsDarkBackground(GlobalObject&, Element& aElement) {
|
||||
nsIFrame* f = aElement.GetPrimaryFrame(FlushType::Frames);
|
||||
if (!f) {
|
||||
return false;
|
||||
}
|
||||
return nsNativeTheme::IsDarkBackground(f);
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
@ -276,6 +276,8 @@ class ChromeUtils {
|
||||
static void GetFormAutofillConfidences(
|
||||
GlobalObject& aGlobal, const Sequence<OwningNonNull<Element>>& aElements,
|
||||
nsTArray<FormAutofillConfidences>& aResults, ErrorResult& aRv);
|
||||
|
||||
static bool IsDarkBackground(GlobalObject&, Element&);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -632,6 +632,11 @@ partial namespace ChromeUtils {
|
||||
|
||||
[Throws]
|
||||
sequence<FormAutofillConfidences> getFormAutofillConfidences(sequence<Element> elements);
|
||||
|
||||
/**
|
||||
* Returns whether the background of the element is dark.
|
||||
*/
|
||||
boolean isDarkBackground(Element element);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -130,6 +130,7 @@ SelectContentHelper.prototype = {
|
||||
options,
|
||||
rect,
|
||||
selectedIndex: this.element.selectedIndex,
|
||||
isDarkBackground: ChromeUtils.isDarkBackground(this.element),
|
||||
style: supportedStyles(computedStyles, SUPPORTED_SELECT_PROPERTIES),
|
||||
defaultStyle: supportedStyles(defaultStyles, SUPPORTED_SELECT_PROPERTIES),
|
||||
});
|
||||
|
@ -84,6 +84,7 @@ var SelectParentHelper = {
|
||||
* @param {Array<Object>} uniqueItemStyles
|
||||
* @param {Number} selectedIndex
|
||||
* @param {Number} zoom
|
||||
* @param {Boolean} isDarkBackground
|
||||
* @param {Object} uaStyle
|
||||
* @param {Object} selectStyle
|
||||
*/
|
||||
@ -93,18 +94,24 @@ var SelectParentHelper = {
|
||||
uniqueItemStyles,
|
||||
selectedIndex,
|
||||
zoom,
|
||||
isDarkBackground,
|
||||
uaStyle,
|
||||
selectStyle
|
||||
) {
|
||||
let doc = menulist.ownerDocument;
|
||||
|
||||
// Clear the current contents of the popup
|
||||
menulist.menupopup.textContent = "";
|
||||
let menupopup = menulist.menupopup;
|
||||
menupopup.textContent = "";
|
||||
|
||||
let stylesheet = menulist.querySelector("#ContentSelectDropdownStylesheet");
|
||||
if (stylesheet) {
|
||||
stylesheet.remove();
|
||||
}
|
||||
|
||||
menupopup.setAttribute("style", "");
|
||||
menupopup.style.colorScheme = isDarkBackground ? "dark" : "light";
|
||||
|
||||
stylesheet = doc.createElementNS("http://www.w3.org/1999/xhtml", "style");
|
||||
stylesheet.setAttribute("id", "ContentSelectDropdownStylesheet");
|
||||
stylesheet.hidden = true;
|
||||
@ -140,7 +147,6 @@ var SelectParentHelper = {
|
||||
);
|
||||
}
|
||||
|
||||
let addedRule = false;
|
||||
for (let property of SUPPORTED_SELECT_PROPERTIES) {
|
||||
let shouldSkip = (function() {
|
||||
if (property == "direction") {
|
||||
@ -160,10 +166,6 @@ var SelectParentHelper = {
|
||||
if (shouldSkip) {
|
||||
continue;
|
||||
}
|
||||
if (!addedRule) {
|
||||
sheet.insertRule("#ContentSelectDropdown > menupopup {}", 0);
|
||||
addedRule = true;
|
||||
}
|
||||
let value = selectStyle[property];
|
||||
if (property == "scrollbar-width") {
|
||||
// This needs to actually apply to the relevant scrollbox, because
|
||||
@ -173,7 +175,7 @@ var SelectParentHelper = {
|
||||
if (property == "color") {
|
||||
property = "--panel-color";
|
||||
}
|
||||
sheet.cssRules[0].style.setProperty(property, value);
|
||||
menupopup.style.setProperty(property, value);
|
||||
}
|
||||
// Some webpages set the <select> backgroundColor to transparent,
|
||||
// but they don't intend to change the popup to transparent.
|
||||
@ -182,19 +184,18 @@ var SelectParentHelper = {
|
||||
// We intentionally use the parsed color to prevent color
|
||||
// values like `url(..)` being injected into the
|
||||
// `background-image` property.
|
||||
let parsedColor = sheet.cssRules[0].style["background-color"];
|
||||
sheet.cssRules[0].style.setProperty(
|
||||
let parsedColor = menupopup.style.backgroundColor;
|
||||
menupopup.style.setProperty(
|
||||
"--content-select-background-image",
|
||||
`linear-gradient(${parsedColor}, ${parsedColor})`
|
||||
);
|
||||
// Always drop the background color to avoid messing with the custom
|
||||
// shadow on Windows 10 styling.
|
||||
sheet.cssRules[0].style["background-color"] = "";
|
||||
menupopup.style.backgroundColor = "";
|
||||
// If the background is set, we also make sure we set the color, to
|
||||
// prevent contrast issues.
|
||||
sheet.cssRules[0].style.setProperty("--panel-color", selectStyle.color);
|
||||
}
|
||||
if (addedRule) {
|
||||
menupopup.style.setProperty("--panel-color", selectStyle.color);
|
||||
|
||||
sheet.insertRule(
|
||||
`#ContentSelectDropdown > menupopup > :is(menuitem, menucaption):not([_moz-menuactive="true"]) {
|
||||
color: inherit;
|
||||
@ -436,6 +437,7 @@ var SelectParentHelper = {
|
||||
options.uniqueStyles,
|
||||
selectedIndex,
|
||||
this._currentZoom,
|
||||
msg.data.isDarkBackground,
|
||||
msg.data.defaultStyle,
|
||||
msg.data.style
|
||||
);
|
||||
@ -785,6 +787,7 @@ class SelectParent extends JSWindowActorParent {
|
||||
// We only want to apply the full zoom. The text zoom is already
|
||||
// applied in the font-size.
|
||||
this.manager.browsingContext.fullZoom,
|
||||
data.isDarkBackground,
|
||||
data.defaultStyle,
|
||||
data.style
|
||||
);
|
||||
|
@ -23,9 +23,6 @@ menupopup {
|
||||
appearance: auto;
|
||||
-moz-default-appearance: menupopup;
|
||||
|
||||
/* Native menus are always light */
|
||||
color-scheme: light;
|
||||
|
||||
/* We set the background-color / border here so that it doesn't interfere with native styling. */
|
||||
background-color: Menu;
|
||||
border: 1px solid ThreeDShadow;
|
||||
@ -38,7 +35,6 @@ menupopup {
|
||||
menupopup {
|
||||
/* Disable the default appearance so we can override the native styling. */
|
||||
appearance: none;
|
||||
color-scheme: unset;
|
||||
|
||||
/* Prevent any background or border around the outside of the shadow. */
|
||||
background-color: transparent;
|
||||
@ -124,6 +120,11 @@ menulist > menupopup {
|
||||
}
|
||||
|
||||
@media not (-moz-windows-non-native-menus) {
|
||||
menupopup {
|
||||
/* Native menus are always light */
|
||||
color-scheme: light !important;
|
||||
}
|
||||
|
||||
/* For Win10, the popup itself needs to have a transparent background because
|
||||
otherwise the background color would appear behind the drop shadow. */
|
||||
menulist > menupopup {
|
||||
|
Loading…
Reference in New Issue
Block a user