Bug 1946764 - Support non-boolean media query prefs via -moz-pref(). r=firefox-style-system-reviewers,desktop-theme-reviewers,settings-reviewers,tabbrowser-reviewers,places-reviewers,sidebar-reviewers,urlbar-reviewers,firefox-ai-ml-reviewers,dao,mconley,dshin,mak

Allow querying int and string prefs too via functional syntax:

```
@media -moz-pref("pref-name", <value>) {
```

No argument means the pref exists and has a non-zero/false/empty value.
Unfortunately stylelint is still unhappy with this so we need to keep
the annoying comments...

Differential Revision: https://phabricator.services.mozilla.com/D237275
This commit is contained in:
Emilio Cobos Álvarez
2025-02-12 12:14:42 +00:00
parent faa30a7240
commit c67d8c9c9c
34 changed files with 293 additions and 122 deletions

View File

@@ -66,7 +66,7 @@ body {
z-index: 1;
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.revamp") {
@media not -moz-pref("sidebar.revamp") {
display: none;
}
}

View File

@@ -3,7 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.verticalTabs") {
@media -moz-pref("sidebar.verticalTabs") {
:host {
--button-size-icon: var(--tab-min-height);
--button-min-height: var(--button-size-icon);
@@ -24,7 +24,7 @@
padding-inline: 0;
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.verticalTabs") {
@media -moz-pref("sidebar.verticalTabs") {
:host([expanded]) & {
/* TODO: Should this be some other pixel value between 5/6? Need to be careful of Linux where font size is larger */
--tab-pinned-horizontal-count: 5;

View File

@@ -49,7 +49,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "widget.gtk.rounded-bottom-corners.enabled") {
@media -moz-pref("widget.gtk.rounded-bottom-corners.enabled") {
#navigator-toolbox {
/* The body clip below covers this. */
border-radius: 0;
@@ -101,7 +101,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.experimental.expandTextOnFocus") {
@media -moz-pref("browser.urlbar.experimental.expandTextOnFocus") {
#urlbar[breakout-extend] {
font-size: 1.14em;
}
@@ -116,7 +116,7 @@
/* Content area */
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.revamp") {
@media not -moz-pref("sidebar.revamp") {
.sidebar-splitter {
appearance: none;
width: 6px;
@@ -205,7 +205,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "widget.gtk.non-native-titlebar-buttons.enabled") {
@media -moz-pref("widget.gtk.non-native-titlebar-buttons.enabled") {
/* When using lightweight themes, use our own buttons since native ones might
* assume a native background in order to be visible. */
:root[lwtheme] & {

View File

@@ -9,7 +9,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.theme.native-theme") {
@media -moz-pref("browser.theme.native-theme") {
@media not (prefers-contrast) {
:root:not([lwtheme]) {
@media (prefers-color-scheme: light) {
@@ -125,7 +125,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.experimental.expandTextOnFocus") {
@media -moz-pref("browser.urlbar.experimental.expandTextOnFocus") {
#urlbar[breakout-extend] {
font-size: 1.36em;
}

View File

@@ -41,7 +41,7 @@
--chrome-content-separator-color: light-dark(rgba(0,0,0,.3), rgba(255,255,255,.3));
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.revamp") {
@media not -moz-pref("sidebar.revamp") {
&:not([lwtheme]) {
--chrome-content-separator-color: ThreeDShadow;
}
@@ -77,7 +77,7 @@
* transparencies in order to look more native.
*/
/* stylelint-disable-next-line media-query-no-invalid */
@media not ((prefers-contrast) or (-moz-bool-pref: "browser.theme.native-theme")) {
@media not ((prefers-contrast) or -moz-pref("browser.theme.native-theme")) {
:root:not([lwtheme]) {
--color-accent-primary: light-dark(rgb(0, 97, 224), rgb(0, 221, 255));
--button-text-color-primary: light-dark(rgb(251, 251, 254), rgb(43, 42, 51));
@@ -107,7 +107,7 @@
--tabs-navbar-separator-style: none;
/* stylelint-disable-next-line media-query-no-invalid */
@media not ((-moz-windows-mica) or ((-moz-windows-accent-color-in-titlebar) and (-moz-bool-pref: "browser.theme.windows.accent-color-in-tabs.enabled"))) {
@media not ((-moz-windows-mica) or ((-moz-windows-accent-color-in-titlebar) and -moz-pref("browser.theme.windows.accent-color-in-tabs.enabled"))) {
--toolbox-bgcolor: light-dark(rgb(240, 240, 244), rgb(28, 27, 34));
--toolbox-textcolor: light-dark(rgb(21, 20, 26), rgb(251, 251, 254));
--toolbox-bgcolor-inactive: var(--toolbox-bgcolor);
@@ -143,7 +143,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.revamp") {
@media not -moz-pref("sidebar.revamp") {
--chrome-content-separator-color: light-dark(rgb(204, 204, 204), hsl(240, 5%, 5%));
}

View File

@@ -52,7 +52,7 @@ body {
min-height: 120px;
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.verticalTabs") {
@media -moz-pref("sidebar.verticalTabs") {
min-width: 732px;
@media (-moz-platform: macos) {
@@ -192,7 +192,7 @@ body {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-platform: macos) and (-moz-bool-pref: "browser.theme.native-theme") {
@media (-moz-platform: macos) and -moz-pref("browser.theme.native-theme") {
/* Don't make the toolbox vibrant when in full-screen. macOS fullscreen has a
* native titlebar outside of the window (revealed on hover) anyways. */
:root[customtitlebar]:not([lwtheme], [macOSNativeFullscreen]) & {
@@ -222,7 +222,7 @@ body {
color: inherit;
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.verticalTabs") {
@media not -moz-pref("sidebar.verticalTabs") {
&:not(.browser-titlebar) {
background-color: var(--toolbar-bgcolor);
color: var(--toolbar-color);
@@ -305,7 +305,7 @@ body {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.verticalTabs") {
@media -moz-pref("sidebar.verticalTabs") {
&[type="pre-tabs"], &[type="post-tabs"] {
display: none;
}
@@ -415,7 +415,7 @@ body {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.verticalTabs") {
@media not -moz-pref("sidebar.verticalTabs") {
#vertical-spacer {
display: none;
}

View File

@@ -909,7 +909,7 @@ toolbarbutton[constrain-size="true"][cui-areatype="panel"] > .toolbarbutton-badg
}
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "identity.fxaccounts.toolbar.defaultVisible") {
@media not -moz-pref("identity.fxaccounts.toolbar.defaultVisible") {
/* Hide the FxA toolbar button when its in the nav-bar, until in use */
&[fxastatus="not_configured"] #widget-overflow-list > #fxa-toolbar-menu-button,
&[fxastatus="not_configured"] #nav-bar-customization-target > #fxa-toolbar-menu-button {

View File

@@ -30,7 +30,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.searchModeSwitcher.featureGate") or (-moz-bool-pref: "browser.urlbar.scotchBonnet.enableOverride") {
@media -moz-pref("browser.urlbar.searchModeSwitcher.featureGate") or -moz-pref("browser.urlbar.scotchBonnet.enableOverride") {
#identity-box[pageproxystate="invalid"] {
display: none;
}
@@ -74,7 +74,7 @@
#urlbar-label-box {
margin-inline-end: 8px;
/* stylelint-disable-next-line media-query-no-invalid */
@media ((-moz-bool-pref: "browser.urlbar.searchModeSwitcher.featureGate") or (-moz-bool-pref: "browser.urlbar.scotchBonnet.enableOverride")) {
@media (-moz-pref("browser.urlbar.searchModeSwitcher.featureGate") or -moz-pref("browser.urlbar.scotchBonnet.enableOverride")) {
margin-inline-end: var(--urlbar-searchmodeswitcher-margin-inline-end);
}
}

View File

@@ -19,7 +19,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.revamp") {
@media not -moz-pref("sidebar.revamp") {
display: none;
}
}

View File

@@ -257,7 +257,7 @@ radio {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "browser.migrate.preferences-entrypoint.enabled") {
@media not -moz-pref("browser.migrate.preferences-entrypoint.enabled") {
#dataMigrationGroup {
display: none;
}

View File

@@ -89,7 +89,7 @@ p {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.privatebrowsing.felt-privacy-v1") {
@media -moz-pref("browser.privatebrowsing.felt-privacy-v1") {
.search-inner-wrapper {
height: 52px;
padding: 0;
@@ -251,7 +251,7 @@ p {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.privatebrowsing.felt-privacy-v1") {
@media -moz-pref("browser.privatebrowsing.felt-privacy-v1") {
.search-handoff-button,
.search-handoff-button:hover:not(.focused),
.search-handoff-button:active,
@@ -384,7 +384,7 @@ p {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.privatebrowsing.felt-privacy-v1") {
@media -moz-pref("browser.privatebrowsing.felt-privacy-v1") {
.info-border {
border-radius: 8px;
margin-top: 64px;
@@ -605,7 +605,7 @@ p {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.privatebrowsing.felt-privacy-v1") {
@media -moz-pref("browser.privatebrowsing.felt-privacy-v1") {
.promo.below-search.promo-visible {
margin-block: 0 25px;

View File

@@ -15,7 +15,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") {
@media -moz-pref("sidebar.revamp") {
min-width: 200px;
width: 340px;
padding-block-end: var(--space-small);
@@ -40,7 +40,7 @@
max-width: 75vw;
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.revamp") {
@media not -moz-pref("sidebar.revamp") {
background-color: var(--sidebar-background-color);
color: var(--sidebar-text-color);
/* Note that with sidebar.revamp we apply the --sidebar-background-color to the
@@ -65,7 +65,7 @@
flex: 1;
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") {
@media -moz-pref("sidebar.revamp") {
border-radius: var(--border-radius-medium);
box-shadow: var(--content-area-shadow);
border: 0.5px solid var(--sidebar-border-color);
@@ -81,7 +81,7 @@
z-index: var(--browser-area-z-index-sidebar-splitter);
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") or (not (-moz-platform: linux)) {
@media -moz-pref("sidebar.revamp") or (not (-moz-platform: linux)) {
/* We don't let the splitter overlap the sidebar on Linux since the sidebar's
scrollbar is too narrow on Linux. */
appearance: none;
@@ -102,7 +102,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") {
@media -moz-pref("sidebar.revamp") {
--splitter-width: 4px;
transition: background-color 0.5s ease-in-out;
border-style: none;
@@ -116,7 +116,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.verticalTabs") {
@media not -moz-pref("sidebar.verticalTabs") {
&#sidebar-launcher-splitter {
display: none;
}

View File

@@ -19,7 +19,7 @@
--tabpanel-background-color: #25003e !important;
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.privatebrowsing.felt-privacy-v1") {
@media -moz-pref("browser.privatebrowsing.felt-privacy-v1") {
--tabpanel-background-color: linear-gradient(45deg, #722291 0%, #45278D 50%, #393473 100%) !important;
}
}
@@ -29,13 +29,13 @@
border-bottom: 0.01px solid var(--chrome-content-separator-color);
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") {
@media -moz-pref("sidebar.revamp") {
/* This reserves space for the content area outline */
border-bottom-color: var(--toolbar-bgcolor);
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.verticalTabs") {
@media -moz-pref("sidebar.verticalTabs") {
border-bottom-style: none;
}
}
@@ -72,18 +72,18 @@
margin: 0;
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") {
@media -moz-pref("sidebar.revamp") {
outline: 0.01px solid var(--chrome-content-separator-color);
box-shadow: var(--content-area-shadow);
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp.round-content-area") {
@media -moz-pref("sidebar.revamp.round-content-area") {
:root:not([inDOMFullscreen]) &[sidebar-shown] {
overflow: clip;
border-start-end-radius: var(--border-radius-medium);
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.position_start") {
@media -moz-pref("sidebar.position_start") {
border-start-start-radius: var(--border-radius-medium);
border-start-end-radius: 0;
}
@@ -192,7 +192,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.tabs.hideStatusPanel") {
@media -moz-pref("browser.tabs.hideStatusPanel") {
visibility: hidden;
}
}

View File

@@ -109,7 +109,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.verticalTabs") {
@media -moz-pref("sidebar.verticalTabs") {
:root {
--tab-min-height: max(32px, calc(var(--tab-label-line-height) * 1em));
--tab-block-margin: 2px;
@@ -444,7 +444,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.tabs.fadeOutUnloadedTabs") {
@media -moz-pref("browser.tabs.fadeOutUnloadedTabs") {
&[pending] {
opacity: 0.5;
/* Fade the favicon out */
@@ -793,7 +793,7 @@
/* Tab Groups */
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.verticalTabs") {
@media not -moz-pref("sidebar.verticalTabs") {
/*
* .tab-group-line needs to span the drop shadows + space between tabs in the
* same tab group so that the whole tab group appears to be underlined by an
@@ -845,7 +845,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.verticalTabs") {
@media -moz-pref("sidebar.verticalTabs") {
tab-group {
flex-direction: column;
position: relative;
@@ -883,7 +883,7 @@
transition: var(--tab-dragover-transition);
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.verticalTabs") {
@media not -moz-pref("sidebar.verticalTabs") {
position: relative;
/*
@@ -1405,7 +1405,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.expandOnHover") {
@media -moz-pref("sidebar.expandOnHover") {
/* Tab close button when the sidebar is collapsed should
not be shown when expand on hover is enabled because once
you hover over the launcher to use the button, the launcher

View File

@@ -190,7 +190,7 @@
#sidebar-button {
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "sidebar.revamp") {
@media not -moz-pref("sidebar.revamp") {
list-style-image: url("chrome://browser/skin/sidebars-right.svg");
&:-moz-locale-dir(ltr):not([positionend]),
@@ -200,11 +200,11 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.revamp") {
@media -moz-pref("sidebar.revamp") {
list-style-image: url("chrome://browser/skin/sidebar-collapsed-right.svg");
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.verticalTabs") {
@media -moz-pref("sidebar.verticalTabs") {
&:hover {
list-style-image: url("chrome://browser/skin/sidebar-expanded-right.svg");
}
@@ -223,7 +223,7 @@
list-style-image: url("chrome://browser/skin/sidebar-collapsed.svg");
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "sidebar.verticalTabs") {
@media -moz-pref("sidebar.verticalTabs") {
&:hover {
list-style-image: url("chrome://browser/skin/sidebar-expanded.svg");
}

View File

@@ -29,7 +29,7 @@
/* When rich suggestions are enabled the urlbar identity icon is given extra padding to
* align the results and urlbar text */
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.richSuggestions.featureGate") {
@media -moz-pref("browser.urlbar.richSuggestions.featureGate") {
#identity-box[pageproxystate="invalid"] > .identity-box-button {
padding-inline: calc(6px + var(--urlbar-icon-padding));
}
@@ -1146,8 +1146,8 @@ moz-input-box > menupopup .context-menu-add-engine > .menu-iconic-left::after {
}
/* stylelint-disable media-query-no-invalid */
@media (not (-moz-bool-pref: "browser.urlbar.searchModeSwitcher.featureGate")) and
(not (-moz-bool-pref: "browser.urlbar.scotchBonnet.enableOverride")) {
@media (not -moz-pref("browser.urlbar.searchModeSwitcher.featureGate")) and
(not -moz-pref("browser.urlbar.scotchBonnet.enableOverride")) {
display: none;
}
/* stylelint-enable media-query-no-invalid */
@@ -1172,7 +1172,7 @@ moz-input-box > menupopup .context-menu-add-engine > .menu-iconic-left::after {
display: none;
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.searchModeSwitcher.featureGate") or (-moz-bool-pref: "browser.urlbar.scotchBonnet.enableOverride") {
@media -moz-pref("browser.urlbar.searchModeSwitcher.featureGate") or -moz-pref("browser.urlbar.scotchBonnet.enableOverride") {
#urlbar[searchmode] & {
display: inline-flex;
}
@@ -1232,13 +1232,13 @@ moz-input-box > menupopup .context-menu-add-engine > .menu-iconic-left::after {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.searchModeSwitcher.featureGate") or (-moz-bool-pref: "browser.urlbar.scotchBonnet.enableOverride") {
@media -moz-pref("browser.urlbar.searchModeSwitcher.featureGate") or -moz-pref("browser.urlbar.scotchBonnet.enableOverride") {
#urlbar[searchmode] > .urlbar-input-container > #urlbar-search-mode-indicator {
display: none;
}
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "browser.urlbar.unifiedSearchButton.always") {
@media not -moz-pref("browser.urlbar.unifiedSearchButton.always") {
#urlbar-searchmode-switcher {
background-color: var(--urlbar-box-bgcolor);
#urlbar:not([unifiedsearchbutton-available]) > .urlbar-input-container > & {

View File

@@ -72,7 +72,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.richSuggestions.featureGate") {
@media -moz-pref("browser.urlbar.richSuggestions.featureGate") {
--urlbarView-favicon-margin-start: calc((var(--urlbarView-rich-suggestion-default-icon-size) - var(--urlbarView-favicon-width)) / 2);
--urlbarView-favicon-margin-end: calc(var(--urlbar-icon-padding) + var(--identity-box-margin-inline) + ((var(--urlbarView-rich-suggestion-default-icon-size) - var(--urlbarView-favicon-width)) / 2));
}
@@ -120,7 +120,7 @@
/* Align icons that are smaller than the default rich suggestion icon size
(28px) with default-size rich suggestion icons. */
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.richSuggestions.featureGate") {
@media -moz-pref("browser.urlbar.richSuggestions.featureGate") {
&:not([rich-suggestion]),
&[rich-suggestion][icon-size="16"] {
--urlbarView-icon-margin-start: var(--urlbarView-favicon-margin-start);
@@ -672,7 +672,7 @@
font-size: var(--urlbarView-small-font-size);
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "browser.urlbar.scotchBonnet.enableOverride") {
@media not -moz-pref("browser.urlbar.scotchBonnet.enableOverride") {
/* This targets both rich and non-rich results, so not using the child selector here. */
.urlbarView-row:not(:hover, [selected], [sponsored]) & {
color: var(--urlbarView-action-color);
@@ -739,7 +739,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "browser.urlbar.scotchBonnet.enableOverride") {
@media not -moz-pref("browser.urlbar.scotchBonnet.enableOverride") {
color: var(--urlbar-box-text-color);
background-color: var(--urlbar-box-focus-bgcolor);
@@ -749,7 +749,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.scotchBonnet.enableOverride") {
@media -moz-pref("browser.urlbar.scotchBonnet.enableOverride") {
-moz-context-properties: fill, fill-opacity;
padding-inline-start: calc(var(--urlbarView-favicon-width) + 8px);
background-image: url("chrome://browser/content/firefoxview/view-opentabs.svg");
@@ -770,7 +770,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media not (-moz-bool-pref: "browser.urlbar.scotchBonnet.enableOverride") {
@media not -moz-pref("browser.urlbar.scotchBonnet.enableOverride") {
&:is([selected], :hover) > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-action {
color: var(--urlbarView-result-button-selected-color);
background-color: var(--urlbarView-result-button-selected-background-color);

View File

@@ -34,7 +34,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-windows-mica) or (-moz-bool-pref: "browser.theme.windows.accent-color-in-tabs.enabled") {
@media (-moz-windows-mica) or -moz-pref("browser.theme.windows.accent-color-in-tabs.enabled") {
&:not([lwtheme]) #TabsToolbar {
/* These colors match the Linux/HCM default button colors. We need to
* override these on the tabs toolbar because the accent color is
@@ -286,7 +286,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.urlbar.experimental.expandTextOnFocus") {
@media -moz-pref("browser.urlbar.experimental.expandTextOnFocus") {
#urlbar[breakout-extend] {
font-size: 1.25em;
}

View File

@@ -304,7 +304,7 @@ semantics > :not(:first-child) {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "mathml.legacy_mathvariant_attribute.disabled") {
@media -moz-pref("mathml.legacy_mathvariant_attribute.disabled") {
/* Implement MathML Core's automatic italic on mi.
https://w3c.github.io/mathml-core/#the-mathvariant-attribute */
mi {

View File

@@ -11,7 +11,7 @@
background: green;
}
@media (-moz-bool-pref: "testing.supports.moz-bool-pref") {
@media -moz-pref("testing.supports.moz-bool-pref") {
.enabled {
background: green;
}

View File

@@ -1572,34 +1572,79 @@ const nsTArray<Element*>* Gecko_ShadowRoot_GetElementsWithId(
return aShadowRoot->GetAllElementsForId(aId);
}
bool Gecko_ComputeBoolPrefMediaQuery(nsAtom* aPref) {
static StyleComputedMozPrefFeatureValue GetPrefValue(const nsCString& aPref) {
using Value = StyleComputedMozPrefFeatureValue;
switch (Preferences::GetType(aPref.get())) {
case nsIPrefBranch::PREF_STRING: {
nsAutoString value;
Preferences::GetString(aPref.get(), value);
return Value::String(StyleAtomString{NS_Atomize(value)});
}
case nsIPrefBranch::PREF_INT:
return Value::Integer(Preferences::GetInt(aPref.get(), 0));
case nsIPrefBranch::PREF_BOOL: {
auto value = Preferences::GetBool(aPref.get(), false)
? StyleBoolValue::True
: StyleBoolValue::False;
return Value::Boolean(value);
}
case nsIPrefBranch::PREF_INVALID:
default:
break;
}
return StyleComputedMozPrefFeatureValue::None();
}
bool Gecko_EvalMozPrefFeature(nsAtom* aPref,
const StyleComputedMozPrefFeatureValue* aValue) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aValue);
using Value = StyleComputedMozPrefFeatureValue;
using PrefMap = nsTHashMap<RefPtr<nsAtom>, Value>;
// This map leaks until shutdown, but that's fine, all the values are
// controlled by us so it's not expected to be big.
static StaticAutoPtr<nsTHashMap<RefPtr<nsAtom>, bool>> sRegisteredPrefs;
static StaticAutoPtr<PrefMap> sRegisteredPrefs;
if (!sRegisteredPrefs) {
if (PastShutdownPhase(ShutdownPhase::XPCOMShutdownFinal)) {
// Styling doesn't really matter much at this point, don't bother.
return false;
}
sRegisteredPrefs = new nsTHashMap<RefPtr<nsAtom>, bool>();
sRegisteredPrefs = new PrefMap();
ClearOnShutdown(&sRegisteredPrefs);
}
return sRegisteredPrefs->LookupOrInsertWith(aPref, [&] {
const auto& value = sRegisteredPrefs->LookupOrInsertWith(aPref, [&] {
nsAutoAtomCString prefName(aPref);
Preferences::RegisterCallback(
[](const char* aPrefName, void*) {
nsDependentCString name(aPrefName);
if (sRegisteredPrefs) {
RefPtr<nsAtom> name = NS_Atomize(nsDependentCString(aPrefName));
sRegisteredPrefs->InsertOrUpdate(name,
Preferences::GetBool(aPrefName));
RefPtr<nsAtom> nameAtom = NS_Atomize(name);
sRegisteredPrefs->InsertOrUpdate(nameAtom, GetPrefValue(name));
}
LookAndFeel::NotifyChangedAllWindows(
widget::ThemeChangeKind::MediaQueriesOnly);
},
prefName);
return Preferences::GetBool(prefName.get());
return GetPrefValue(prefName);
});
if (aValue->IsNone()) {
// For a non-specified query, we return true if the pref is not false, zero,
// empty or invalid
switch (value.tag) {
case Value::Tag::None:
return false;
case Value::Tag::Boolean:
return value.AsBoolean() == StyleBoolValue::True;
case Value::Tag::Integer:
return value.AsInteger() != 0;
case Value::Tag::String:
return !value.AsString().AsAtom()->IsEmpty();
}
return false;
}
return value == *aValue;
}
bool Gecko_IsFontFormatSupported(StyleFontFaceSourceFormatKeyword aFormat) {

View File

@@ -550,7 +550,8 @@ const nsTArray<mozilla::dom::Element*>* Gecko_Document_GetElementsWithId(
const nsTArray<mozilla::dom::Element*>* Gecko_ShadowRoot_GetElementsWithId(
const mozilla::dom::ShadowRoot*, nsAtom* aId);
bool Gecko_ComputeBoolPrefMediaQuery(nsAtom*);
bool Gecko_EvalMozPrefFeature(nsAtom*,
const mozilla::StyleComputedMozPrefFeatureValue*);
// Check whether font format/tech is supported.
bool Gecko_IsFontFormatSupported(

View File

@@ -382,6 +382,7 @@ cbindgen-types = [
{ gecko = "StyleOffsetPathFunction", servo = "crate::values::computed::motion::OffsetPathFunction" },
{ gecko = "StyleGenericOffsetPath", servo = "crate::values::generics::motion::OffsetPath" },
{ gecko = "StyleGenericOffsetPathFunction", servo = "crate::values::generics::motion::OffsetPathFunction" },
{ gecko = "StyleComputedMozPrefFeatureValue", servo = "crate::queries::condition::ComputedMozPrefFeatureValue" },
{ gecko = "StyleMozTheme", servo = "crate::values::computed::ui::MozTheme" },
{ gecko = "StyleOffsetPosition", servo = "crate::values::computed::motion::OffsetPosition" },
{ gecko = "StyleOffsetRotate", servo = "crate::values::computed::motion::OffsetRotate" },

View File

@@ -206,7 +206,7 @@ h6 {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "layout.css.h1-in-section-ua-styles.enabled") {
@media -moz-pref("layout.css.h1-in-section-ua-styles.enabled") {
:is(article, aside, nav, section)
h1 {
margin-block: 0.83em;

View File

@@ -6,7 +6,7 @@
/* Rules required for style caching of anonymous content scrollbar parts */
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "layout.css.cached-scrollbar-styles.enabled") {
@media -moz-pref("layout.css.cached-scrollbar-styles.enabled") {
:is(scrollcorner, resizer, scrollbar, scrollbarbutton, slider):where(:-moz-native-anonymous) {
/* All scrollbar parts must not inherit any properties from the scrollable
* element (except for visibility and pointer-events), for the anonymous

View File

@@ -170,7 +170,7 @@
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "layout.css.always_underline_links") {
@media -moz-pref("layout.css.always_underline_links") {
:any-link {
text-decoration: underline !important;
}
@@ -514,7 +514,7 @@ parsererror|sourcetext {
/* Avoid exposing these keyframe names when view transitions are disabled */
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "dom.viewTransitions.enabled") {
@media -moz-pref("dom.viewTransitions.enabled") {
/* Default cross-fade transition */
@keyframes -ua-view-transition-fade-out {
to { opacity: 0; }

View File

@@ -19,7 +19,7 @@
margin: 0;
padding: 8px;
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "view_source.wrap_long_lines") {
@media -moz-pref("view_source.wrap_long_lines") {
white-space: pre-wrap;
word-wrap: break-word;
}
@@ -50,7 +50,7 @@ span[id]::before {
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "view_source.syntax_highlight") {
@media -moz-pref("view_source.syntax_highlight") {
.start-tag,
.end-tag {
color: light-dark(purple, #f55e5e);

View File

@@ -10,7 +10,7 @@ SimpleTest.waitForExplicitFinish();
function expect(q, shouldBeKnown) {
is(matchMedia(q).media, q, "Serialization should roundtrip");
is(matchMedia(`${q} or (not ${q})`).matches, shouldBeKnown, `Query should${shouldBeKnown ? "" : " not"} be known`);
is(matchMedia(`${q} or (not ${q})`).matches, shouldBeKnown, `${q} should${shouldBeKnown ? "" : " not"} be known`);
}
function expectKnown(q) {
@@ -21,6 +21,28 @@ function expectUnkown(q) {
expect(q, false);
}
function testMatches(q, shouldMatch = true) {
is(matchMedia(q).matches, shouldMatch, `${q} should match`);
}
async function testMozPref(q, prefName, value, otherValue) {
expectKnown(q);
await SpecialPowers.pushPrefEnv({
set:[[prefName, value]],
});
testMatches(q, true);
let mediaList = matchMedia(q);
let change = new Promise(r => {
mediaList.addEventListener("change", r, { once: true });
});
await SpecialPowers.pushPrefEnv({
set:[[prefName, otherValue]],
});
testMatches(q, false);
// Should change dynamically successfully.
await change;
}
// Test a toggle that should always match for `1` or `0`.
function testToggle(toggle) {
expectKnown(`(${toggle})`);
@@ -63,5 +85,13 @@ expectKnown("(forced-colors)");
expectUnkown("(-moz-platform: )");
SimpleTest.finish();
(async function() {
await testMozPref('-moz-pref("foo.bar.bool", true)', "foo.bar.bool", true, false);
await testMozPref('-moz-pref("foo.bar.bool")', "foo.bar.bool", true, false);
await testMozPref('-moz-pref("foo.bar.str", "foo")', "foo.bar.str", "foo", "bar");
await testMozPref('-moz-pref("foo.bar.str")', "foo.bar.str", "foo", "");
await testMozPref('-moz-pref("foo.bar.int", 1)', "foo.bar.int", 1, 2);
await testMozPref('-moz-pref("foo.bar.int")', "foo.bar.int", 1, 0);
SimpleTest.finish();
}());
</script>

View File

@@ -11,10 +11,8 @@ use crate::queries::feature::{AllowsRanges, Evaluator, FeatureFlags, QueryFeatur
use crate::queries::values::Orientation;
use crate::values::computed::{CSSPixelLength, Context, Ratio, Resolution};
use crate::values::specified::color::ForcedColors;
use crate::values::AtomString;
use app_units::Au;
use euclid::default::Size2D;
use selectors::kleene_value::KleeneValue;
fn device_size(device: &Device) -> Size2D<Au> {
let mut width = 0;
@@ -617,13 +615,6 @@ fn eval_moz_overlay_scrollbars(context: &Context) -> bool {
unsafe { bindings::Gecko_MediaFeatures_UseOverlayScrollbars(context.device().document()) }
}
fn eval_moz_bool_pref(_: &Context, pref: Option<&AtomString>) -> KleeneValue {
let Some(pref) = pref else {
return KleeneValue::False;
};
KleeneValue::from(unsafe { bindings::Gecko_ComputeBoolPrefMediaQuery(pref.as_ptr()) })
}
fn get_lnf_int(int_id: i32) -> i32 {
unsafe { bindings::Gecko_GetLookAndFeelInt(int_id) }
}
@@ -671,7 +662,7 @@ macro_rules! lnf_int_feature {
/// to support new types in these entries and (2) ensuring that either
/// nsPresContext::MediaFeatureValuesChanged is called when the value that
/// would be returned by the evaluator function could change.
pub static MEDIA_FEATURES: [QueryFeatureDescription; 61] = [
pub static MEDIA_FEATURES: [QueryFeatureDescription; 60] = [
feature!(
atom!("width"),
AllowsRanges::Yes,
@@ -936,12 +927,6 @@ pub static MEDIA_FEATURES: [QueryFeatureDescription; 61] = [
Evaluator::BoolInteger(eval_moz_overlay_scrollbars),
FeatureFlags::CHROME_AND_UA_ONLY,
),
feature!(
atom!("-moz-bool-pref"),
AllowsRanges::No,
Evaluator::String(eval_moz_bool_pref),
FeatureFlags::CHROME_AND_UA_ONLY,
),
lnf_int_feature!(
atom!("-moz-scrollbar-start-backward"),
ScrollArrowStyle,

View File

@@ -9,7 +9,7 @@
use super::{FeatureFlags, FeatureType, QueryFeatureExpression};
use crate::custom_properties;
use crate::values::computed;
use crate::values::{computed, AtomString};
use crate::{error_reporting::ContextualParseError, parser::ParserContext};
use cssparser::{Parser, SourcePosition, Token};
use selectors::kleene_value::KleeneValue;
@@ -107,6 +107,106 @@ impl StyleFeature {
}
}
/// A boolean value for a pref query.
#[derive(
Clone,
Debug,
MallocSizeOf,
PartialEq,
Eq,
Parse,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToShmem,
)]
#[repr(u8)]
#[allow(missing_docs)]
pub enum BoolValue {
False,
True,
}
/// Simple values we support for -moz-pref(). We don't want to deal with calc() and other
/// shenanigans for now.
#[derive(
Clone,
Debug,
Eq,
MallocSizeOf,
Parse,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToShmem,
)]
#[repr(u8)]
pub enum MozPrefFeatureValue<I> {
/// No pref value, implicitly bool, but also used to represent missing prefs.
#[css(skip)]
None,
/// A bool value.
Boolean(BoolValue),
/// An integer value, useful for int prefs.
Integer(I),
/// A string pref value.
String(crate::values::AtomString),
}
type SpecifiedMozPrefFeatureValue = MozPrefFeatureValue<crate::values::specified::Integer>;
/// The computed -moz-pref() value.
pub type ComputedMozPrefFeatureValue = MozPrefFeatureValue<crate::values::computed::Integer>;
/// A custom -moz-pref(<name>, <value>) query feature.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
pub struct MozPrefFeature {
name: crate::values::AtomString,
value: SpecifiedMozPrefFeatureValue,
}
impl MozPrefFeature {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
feature_type: FeatureType,
) -> Result<Self, ParseError<'i>> {
use crate::parser::Parse;
if !context.chrome_rules_enabled() || feature_type != FeatureType::Media {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
}
let name = AtomString::parse(context, input)?;
let value = if input.try_parse(|i| i.expect_comma()).is_ok() {
SpecifiedMozPrefFeatureValue::parse(context, input)?
} else {
SpecifiedMozPrefFeatureValue::None
};
Ok(Self { name, value })
}
fn matches(&self, ctx: &computed::Context) -> KleeneValue {
use crate::values::computed::ToComputedValue;
let value = self.value.to_computed_value(ctx);
KleeneValue::from(unsafe {
crate::gecko_bindings::bindings::Gecko_EvalMozPrefFeature(self.name.as_ptr(), &value)
})
}
}
impl ToCss for MozPrefFeature {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
{
self.name.to_css(dest)?;
if !matches!(self.value, MozPrefFeatureValue::None) {
dest.write_str(", ")?;
self.value.to_css(dest)?;
}
Ok(())
}
}
/// Represents a condition.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
pub enum QueryCondition {
@@ -120,6 +220,8 @@ pub enum QueryCondition {
InParens(Box<QueryCondition>),
/// A <style> query.
Style(StyleFeature),
/// A -moz-pref() query.
MozPref(MozPrefFeature),
/// [ <function-token> <any-value>? ) ] | [ ( <any-value>? ) ]
GeneralEnclosed(String),
}
@@ -147,6 +249,11 @@ impl ToCss for QueryCondition {
c.to_css(dest)?;
dest.write_char(')')
},
QueryCondition::MozPref(ref c) => {
dest.write_str("-moz-pref(")?;
c.to_css(dest)?;
dest.write_char(')')
},
QueryCondition::Operation(ref list, op) => {
let mut iter = list.iter();
iter.next().unwrap().to_css(dest)?;
@@ -184,7 +291,8 @@ impl QueryCondition {
{
visitor(self);
match *self {
Self::Feature(..) | Self::GeneralEnclosed(..) | Self::Style(..) => {},
Self::Feature(..) | Self::GeneralEnclosed(..) | Self::Style(..) | Self::MozPref(..) => {
},
Self::Not(ref cond) => cond.visit(visitor),
Self::Operation(ref conds, _op) => {
for cond in conds.iter() {
@@ -330,13 +438,24 @@ impl QueryCondition {
}
},
Token::Function(ref name) => {
if name.eq_ignore_ascii_case("style") {
let feature = Self::try_parse_block(context, input, start, |input| {
StyleFeature::parse(context, input, feature_type)
});
if let Some(feature) = feature {
return Ok(Self::Style(feature));
}
match_ignore_ascii_case! { name,
"style" => {
let feature = Self::try_parse_block(context, input, start, |input| {
StyleFeature::parse(context, input, feature_type)
});
if let Some(feature) = feature {
return Ok(Self::Style(feature));
}
},
"-moz-pref" => {
let feature = Self::try_parse_block(context, input, start, |input| {
MozPrefFeature::parse(context, input, feature_type)
});
if let Some(feature) = feature {
return Ok(Self::MozPref(feature));
}
},
_ => {},
}
},
ref t => return Err(start_location.new_unexpected_token_error(t.clone())),
@@ -357,6 +476,7 @@ impl QueryCondition {
QueryCondition::InParens(ref c) => c.matches(context),
QueryCondition::Not(ref c) => !c.matches(context),
QueryCondition::Style(ref c) => c.matches(context),
QueryCondition::MozPref(ref c) => c.matches(context),
QueryCondition::Operation(ref conditions, op) => {
debug_assert!(!conditions.is_empty(), "We never create an empty op");
match op {

View File

@@ -6,7 +6,6 @@
use crate::parser::ParserContext;
use crate::values::computed::{self, CSSPixelLength, Ratio, Resolution};
use crate::values::AtomString;
use crate::Atom;
use cssparser::Parser;
use selectors::kleene_value::KleeneValue;
@@ -45,7 +44,6 @@ pub enum Evaluator {
OptionalNumberRatio(QueryFeatureGetter<Option<Ratio>>),
/// A resolution.
Resolution(QueryFeatureGetter<Resolution>),
String(fn(&computed::Context, Option<&AtomString>) -> KleeneValue),
/// A keyword value.
Enumerated {
/// The parser to get a discriminant given a string.

View File

@@ -11,7 +11,7 @@ use crate::parser::{Parse, ParserContext};
use crate::str::{starts_with_ignore_ascii_case, string_as_ascii_lowercase};
use crate::values::computed::{self, Ratio, ToComputedValue};
use crate::values::specified::{Integer, Length, Number, Resolution};
use crate::values::{AtomString, CSSFloat};
use crate::values::CSSFloat;
use crate::{Atom, Zero};
use cssparser::{Parser, Token};
use selectors::kleene_value::KleeneValue;
@@ -639,10 +639,6 @@ impl QueryFeatureExpression {
.map(|v| *expect!(Enumerated, v));
return evaluator(context, computed);
},
Evaluator::String(evaluator) => {
let string = self.kind.non_ranged_value().map(|v| expect!(String, v));
return evaluator(context, string);
},
Evaluator::BoolInteger(eval) => {
let computed = self
.kind
@@ -681,8 +677,6 @@ pub enum QueryExpressionValue {
/// An enumerated value, defined by the variant keyword table in the
/// feature's `mData` member.
Enumerated(KeywordDiscriminant),
/// An arbitrary ident value.
String(AtomString),
}
impl QueryExpressionValue {
@@ -701,7 +695,6 @@ impl QueryExpressionValue {
Evaluator::Enumerated { serializer, .. } => dest.write_str(&*serializer(value)),
_ => unreachable!(),
},
QueryExpressionValue::String(ref s) => s.to_css(dest),
}
}
@@ -739,9 +732,6 @@ impl QueryExpressionValue {
Evaluator::Resolution(..) => {
QueryExpressionValue::Resolution(Resolution::parse(context, input)?)
},
Evaluator::String(..) => {
QueryExpressionValue::String(input.expect_string()?.as_ref().into())
},
Evaluator::Enumerated { parser, .. } => {
QueryExpressionValue::Enumerated(parser(context, input)?)
},

View File

@@ -112,6 +112,7 @@ include = [
"FontVariantEastAsian",
"FontVariantLigatures",
"FontVariantNumeric",
"ComputedMozPrefFeatureValue",
"ComputedFontStretchRange",
"ComputedFontStyleDescriptor",
"ComputedFontWeightRange",

View File

@@ -156,7 +156,7 @@ button:disabled {
/* Felt Privacy v1 LARGER SCREEN! */
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "security.certerrors.felt-privacy-v1") {
@media -moz-pref("security.certerrors.felt-privacy-v1") {
.felt-privacy-body {
justify-content: start;
}