author | Emilio Cobos Álvarez <emilio@crisal.io> |
Wed, 06 Mar 2019 21:34:30 +0000 | |
changeset 462727 | 2e2dd6d6d5762cd5a60acdb1f14efadf76dcf490 |
parent 462726 | 4a50be47adebd4c8f4fd2fb0171aa0c40d611921 |
child 462728 | 26ac004eeb4cc3876cf822e91ef25206586a1537 |
push id | 79820 |
push user | ealvarez@mozilla.com |
push date | Wed, 06 Mar 2019 21:35:14 +0000 |
treeherder | autoland@2e2dd6d6d576 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jwatt |
bugs | 1530193 |
milestone | 67.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -1439,29 +1439,23 @@ void nsIPresShell::UpdatePreferenceStyle return; } // Documents in chrome shells do not have any preference style rules applied. if (nsContentUtils::IsInChromeDocshell(mDocument)) { return; } - // We need to pass in mPresContext so that if the nsLayoutStylesheetCache - // needs to recreate the pref style sheet, it has somewhere to get the - // pref styling information from. All pres contexts for - // IsChromeOriginImage() == false will have the same pref styling information, - // and similarly for IsChromeOriginImage() == true, so it doesn't really - // matter which pres context we pass in when it does need to be recreated. - // (See nsPresContext::GetDocumentColorPreferences for how whether we - // are a chrome origin image affects some pref styling information.) + PreferenceSheet::EnsureInitialized(); auto cache = nsLayoutStylesheetCache::Singleton(); + RefPtr<StyleSheet> newPrefSheet = - mPresContext->IsChromeOriginImage() - ? cache->ChromePreferenceSheet(mPresContext) - : cache->ContentPreferenceSheet(mPresContext); + PreferenceSheet::ShouldUseChromePrefs(*mDocument) + ? cache->ChromePreferenceSheet() + : cache->ContentPreferenceSheet(); if (mPrefStyleSheet == newPrefSheet) { return; } RemovePreferenceStyles(); // NOTE(emilio): This sheet is added as an agent sheet, because we don't want
--- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -105,31 +105,16 @@ uint8_t gNotifySubDocInvalidationData; * of local invalidations of them and their descendant layers. * Pass a callback to ComputeDifferences to have these called. */ class ContainerLayerPresContext : public LayerUserData { public: nsPresContext* mPresContext; }; -nscolor nsPresContext::MakeColorPref(const nsString& aColor) { - ServoStyleSet* styleSet = mShell ? mShell->StyleSet() : nullptr; - - nscolor result; - bool ok = - ServoCSSParser::ComputeColor(styleSet, NS_RGB(0, 0, 0), aColor, &result); - - if (!ok) { - // Any better choices? - result = NS_RGB(0, 0, 0); - } - - return result; -} - bool nsPresContext::IsDOMPaintEventPending() { if (!mTransactions.IsEmpty()) { return true; } nsRootPresContext* drpc = GetRootPresContext(); if (drpc && drpc->mRefreshDriver->ViewManagerFlushIsPending()) { // Since we're promising that there will be a MozAfterPaint event @@ -167,44 +152,32 @@ nsPresContext::nsPresContext(dom::Docume mFullZoom(1.0), mOverrideDPPX(0.0), mLastFontInflationScreenSize(gfxSize(-1.0, -1.0)), mCurAppUnitsPerDevPixel(0), mAutoQualityMinFontSizePixelsPref(0), mPageSize(-1, -1), mPageScale(0.0), mPPScale(1.0f), - mDefaultColor(NS_RGBA(0, 0, 0, 0)), - mBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF)), - mLinkColor(NS_RGB(0x00, 0x00, 0xEE)), - mActiveLinkColor(NS_RGB(0xEE, 0x00, 0x00)), - mVisitedLinkColor(NS_RGB(0x55, 0x1A, 0x8B)), - mFocusBackgroundColor(mBackgroundColor), - mFocusTextColor(mDefaultColor), - mBodyTextColor(mDefaultColor), mViewportScrollOverrideElement(nullptr), mViewportScrollStyles(StyleOverflow::Auto, StyleOverflow::Auto), - mFocusRingWidth(1), mExistThrottledUpdates(false), // mImageAnimationMode is initialised below, in constructor body mImageAnimationModePref(imgIContainer::kNormalAnimMode), mInterruptChecksToSkip(0), mElementsRestyled(0), mFramesConstructed(0), mFramesReflowed(0), mInteractionTimeEnabled(true), mHasPendingInterrupt(false), mPendingInterruptFromTest(false), mInterruptsEnabled(false), mUseDocumentColors(true), - mUnderlineLinks(true), mSendAfterPaintToContent(false), mUseFocusColors(false), - mFocusRingOnAnything(false), - mFocusRingStyle(false), mDrawImageBackground(true), // always draw the background mDrawColorBackground(true), // mNeverAnimate is initialised below, in constructor body mPaginated(aType != eContext_Galley), mCanPaginatedScroll(false), mDoScaledTwips(true), mIsRootPaginatedDocument(false), mPrefBidiDirection(false), @@ -365,81 +338,37 @@ bool nsPresContext::IsChromeOriginImage( Document()->IsDocumentURISchemeChrome(); } void nsPresContext::GetDocumentColorPreferences() { // Make sure the preferences are initialized. In the normal run, // they would already be, because gfxPlatform would have been created, // but in some reference tests, that is not the case. gfxPrefs::GetSingleton(); - - int32_t useAccessibilityTheme = 0; - bool usePrefColors = true; + PreferenceSheet::EnsureInitialized(); + static int32_t sDocumentColorsSetting; static bool sDocumentColorsSettingPrefCached = false; if (!sDocumentColorsSettingPrefCached) { sDocumentColorsSettingPrefCached = true; Preferences::AddIntVarCache(&sDocumentColorsSetting, "browser.display.document_color_use", 0); } - if (IsChrome() || IsChromeOriginImage()) { - usePrefColors = false; - } else { - useAccessibilityTheme = - LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0); - usePrefColors = !useAccessibilityTheme; - } - if (usePrefColors) { - usePrefColors = - !Preferences::GetBool("browser.display.use_system_colors", false); - } - - if (nsContentUtils::UseStandinsForNativeColors()) { - // Once the |nsContentUtils::UseStandinsForNativeColors()| is true, - // use fixed color values instead of preferred colors and system colors. - mDefaultColor = LookAndFeel::GetColorUsingStandins( - LookAndFeel::eColorID_windowtext, NS_RGB(0x00, 0x00, 0x00)); - mBackgroundColor = LookAndFeel::GetColorUsingStandins( - LookAndFeel::eColorID_window, NS_RGB(0xff, 0xff, 0xff)); - } else if (usePrefColors) { - nsAutoString colorStr; - Preferences::GetString("browser.display.foreground_color", colorStr); - if (!colorStr.IsEmpty()) { - mDefaultColor = MakeColorPref(colorStr); - } - - colorStr.Truncate(); - Preferences::GetString("browser.display.background_color", colorStr); - if (!colorStr.IsEmpty()) { - mBackgroundColor = MakeColorPref(colorStr); - } - } else { - mDefaultColor = LookAndFeel::GetColor( - LookAndFeel::eColorID_WindowForeground, NS_RGB(0x00, 0x00, 0x00)); - mBackgroundColor = LookAndFeel::GetColor( - LookAndFeel::eColorID_WindowBackground, NS_RGB(0xFF, 0xFF, 0xFF)); - } - - // Wherever we got the default background color from, ensure it is - // opaque. - mBackgroundColor = - NS_ComposeColors(NS_RGB(0xFF, 0xFF, 0xFF), mBackgroundColor); - // Now deal with the pref: // 0 = default: always, except in high contrast mode // 1 = always // 2 = never if (sDocumentColorsSetting == 1 || mDocument->IsBeingUsedAsImage()) { mUseDocumentColors = true; } else if (sDocumentColorsSetting == 2) { mUseDocumentColors = IsChrome() || IsChromeOriginImage(); } else { - MOZ_ASSERT(!useAccessibilityTheme || !(IsChrome() || IsChromeOriginImage()), - "The accessibility theme should only be on for non-chrome"); + bool useAccessibilityTheme = + PreferenceSheet::UseAccessibilityTheme(IsChrome()); mUseDocumentColors = !useAccessibilityTheme; } } void nsPresContext::GetUserPreferences() { if (!GetPresShell()) { // No presshell means nothing to do here. We'll do this when we // get a presshell. @@ -450,67 +379,16 @@ void nsPresContext::GetUserPreferences() Preferences::GetInt("browser.display.auto_quality_min_font_size"); // * document colors GetDocumentColorPreferences(); mSendAfterPaintToContent = Preferences::GetBool( "dom.send_after_paint_to_content", mSendAfterPaintToContent); - // * link colors - mUnderlineLinks = - Preferences::GetBool("browser.underline_anchors", mUnderlineLinks); - - nsAutoString colorStr; - Preferences::GetString("browser.anchor_color", colorStr); - if (!colorStr.IsEmpty()) { - mLinkColor = MakeColorPref(colorStr); - } - - colorStr.Truncate(); - Preferences::GetString("browser.active_color", colorStr); - if (!colorStr.IsEmpty()) { - mActiveLinkColor = MakeColorPref(colorStr); - } - - colorStr.Truncate(); - Preferences::GetString("browser.visited_color", colorStr); - if (!colorStr.IsEmpty()) { - mVisitedLinkColor = MakeColorPref(colorStr); - } - - mUseFocusColors = - Preferences::GetBool("browser.display.use_focus_colors", mUseFocusColors); - - mFocusTextColor = mDefaultColor; - mFocusBackgroundColor = mBackgroundColor; - - colorStr.Truncate(); - Preferences::GetString("browser.display.focus_text_color", colorStr); - if (!colorStr.IsEmpty()) { - mFocusTextColor = MakeColorPref(colorStr); - } - - colorStr.Truncate(); - Preferences::GetString("browser.display.focus_background_color", colorStr); - if (!colorStr.IsEmpty()) { - mFocusBackgroundColor = MakeColorPref(colorStr); - } - - mFocusRingWidth = - Preferences::GetInt("browser.display.focus_ring_width", mFocusRingWidth); - - mFocusRingOnAnything = Preferences::GetBool( - "browser.display.focus_ring_on_anything", mFocusRingOnAnything); - - mFocusRingStyle = - Preferences::GetInt("browser.display.focus_ring_style", mFocusRingStyle); - - mBodyTextColor = mDefaultColor; - mPrefScrollbarSide = Preferences::GetInt("layout.scrollbar.side"); Document()->ResetLangPrefs(); // * image animation nsAutoCString animatePref; Preferences::GetCString("image.animation_mode", animatePref); if (animatePref.EqualsLiteral("normal")) @@ -633,16 +511,17 @@ void nsPresContext::PreferenceChanged(co // We will end up calling InvalidatePreferenceSheets one from each pres // context, but all it's doing is clearing its cached sheet pointers, so it // won't be wastefully recreating the sheet multiple times. // // The first pres context that has its pref changed runnable called will // be the one to cause the reconstruction of the pref style sheet. nsLayoutStylesheetCache::InvalidatePreferenceSheets(); + PreferenceSheet::Refresh(); DispatchPrefChangedRunnableIfNeeded(); if (prefName.EqualsLiteral("nglayout.debug.paint_flashing") || prefName.EqualsLiteral("nglayout.debug.paint_flashing_chrome")) { mPaintFlashingInitialized = false; return; } } @@ -1473,16 +1352,18 @@ void nsPresContext::SysColorChangedInter // Don't use the cached values for the system colors LookAndFeel::Refresh(); sLookAndFeelChanged = false; } // Invalidate cached '-moz-windows-accent-color-applies' media query: RefreshSystemMetrics(); + PreferenceSheet::Refresh(); + // Reset default background and foreground colors for the document since // they may be using system colors GetDocumentColorPreferences(); // The system color values are computed to colors in the style data, // so normal style data comparison is sufficient here. RebuildAllStyleData(nsChangeHint(0), nsRestyleHint(0)); }
--- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -8,16 +8,17 @@ #ifndef nsPresContext_h___ #define nsPresContext_h___ #include "mozilla/Attributes.h" #include "mozilla/MediaFeatureChange.h" #include "mozilla/NotNull.h" #include "mozilla/ScrollStyles.h" +#include "mozilla/PreferenceSheet.h" #include "mozilla/UniquePtr.h" #include "mozilla/WeakPtr.h" #include "nsColor.h" #include "nsCoord.h" #include "nsCOMPtr.h" #include "nsIPresShell.h" #include "nsIPresShellInlines.h" #include "nsRect.h" @@ -81,22 +82,16 @@ class ContainerLayer; class LayerManager; } // namespace layers namespace dom { class Document; class Element; } // namespace dom } // namespace mozilla -// supported values for cached bool types -// -// FIXME(emilio): We have StaticPrefs now, probably all of these should be -// migrated. -enum nsPresContext_CachedBoolPrefType { kPresContext_UnderlineLinks = 1 }; - // supported values for cached integer pref types enum nsPresContext_CachedIntPrefType { kPresContext_ScrollbarSide = 1, kPresContext_BidiDirection }; // IDs for the default variable and fixed fonts (not to be changed, see // nsFont.h) To be used for Get/SetDefaultFont(). The other IDs in nsFont.h are @@ -354,31 +349,16 @@ class nsPresContext : public nsISupports */ void EmulateMedium(const nsAString& aMediaType); /* * Restore the viewer's natural medium */ void StopEmulatingMedium(); - /** Get a cached boolean pref, by its type */ - // * - initially created for bugs 31816, 20760, 22963 - bool GetCachedBoolPref(nsPresContext_CachedBoolPrefType aPrefType) const { - // If called with a constant parameter, the compiler should optimize - // this switch statement away. - switch (aPrefType) { - case kPresContext_UnderlineLinks: - return mUnderlineLinks; - default: - NS_ERROR("Invalid arg passed to GetCachedBoolPref"); - } - - return false; - } - /** Get a cached integer pref, by its type */ // * - initially created for bugs 30910, 61883, 74186, 84398 int32_t GetCachedIntPref(nsPresContext_CachedIntPrefType aPrefType) const { // If called with a constant parameter, the compiler should optimize // this switch statement away. switch (aPrefType) { case kPresContext_ScrollbarSide: return mPrefScrollbarSide; @@ -386,38 +366,22 @@ class nsPresContext : public nsISupports return mPrefBidiDirection; default: NS_ERROR("invalid arg passed to GetCachedIntPref"); } return false; } - /** - * Get the default colors - */ - nscolor DefaultColor() const { return mDefaultColor; } - nscolor DefaultBackgroundColor() const { return mBackgroundColor; } - nscolor DefaultLinkColor() const { return mLinkColor; } - nscolor DefaultActiveLinkColor() const { return mActiveLinkColor; } - nscolor DefaultVisitedLinkColor() const { return mVisitedLinkColor; } - nscolor FocusBackgroundColor() const { return mFocusBackgroundColor; } - nscolor FocusTextColor() const { return mFocusTextColor; } - - /** - * Body text color, for use in quirks mode only. - */ - nscolor BodyTextColor() const { return mBodyTextColor; } - void SetBodyTextColor(nscolor aColor) { mBodyTextColor = aColor; } - - bool GetUseFocusColors() const { return mUseFocusColors; } - uint8_t FocusRingWidth() const { return mFocusRingWidth; } - bool GetFocusRingOnAnything() const { return mFocusRingOnAnything; } - uint8_t GetFocusRingStyle() const { return mFocusRingStyle; } - + const mozilla::PreferenceSheet::Prefs& PrefSheetPrefs() const { + return mozilla::PreferenceSheet::PrefsFor(*mDocument); + } + nscolor DefaultBackgroundColor() const { + return PrefSheetPrefs().mDefaultBackgroundColor; + } nsISupports* GetContainerWeak() const; nsIDocShell* GetDocShell() const; // XXX this are going to be replaced with set/get container void SetLinkHandler(nsILinkHandler* aHandler) { mLinkHandler = aHandler; } nsILinkHandler* GetLinkHandler() { return mLinkHandler; } @@ -1215,40 +1179,26 @@ class nsPresContext : public nsISupports mozilla::UniquePtr<gfxMissingFontRecorder> mMissingFonts; nsRect mVisibleArea; nsSize mPageSize; float mPageScale; float mPPScale; - nscolor mDefaultColor; - nscolor mBackgroundColor; - - nscolor mLinkColor; - nscolor mActiveLinkColor; - nscolor mVisitedLinkColor; - - nscolor mFocusBackgroundColor; - nscolor mFocusTextColor; - - nscolor mBodyTextColor; - // This is a non-owning pointer. May be null. If non-null, it's guaranteed to // be pointing to an element that's still alive, because we'll reset it in // UpdateViewportScrollStylesOverride() as part of the cleanup code when // this element is removed from the document. (For <body> and the root // element, this call happens in nsCSSFrameConstructor::ContentRemoved(). For // fullscreen elements, it happens in the fullscreen-specific cleanup invoked // by Element::UnbindFromTree().) mozilla::dom::Element* MOZ_NON_OWNING_REF mViewportScrollOverrideElement; ScrollStyles mViewportScrollStyles; - uint8_t mFocusRingWidth; - bool mExistThrottledUpdates; uint16_t mImageAnimationMode; uint16_t mImageAnimationModePref; uint32_t mInterruptChecksToSkip; // Counters for tests and tools that want to detect frame construction @@ -1273,17 +1223,16 @@ class nsPresContext : public nsISupports // last time we did a full style flush mozilla::TimeStamp mLastStyleUpdateForAllAnimations; unsigned mHasPendingInterrupt : 1; unsigned mPendingInterruptFromTest : 1; unsigned mInterruptsEnabled : 1; unsigned mUseDocumentColors : 1; - unsigned mUnderlineLinks : 1; unsigned mSendAfterPaintToContent : 1; unsigned mUseFocusColors : 1; unsigned mFocusRingOnAnything : 1; unsigned mFocusRingStyle : 1; unsigned mDrawImageBackground : 1; unsigned mDrawColorBackground : 1; unsigned mNeverAnimate : 1; unsigned mPaginated : 1; @@ -1342,18 +1291,16 @@ class nsPresContext : public nsISupports unsigned mInitialized : 1; #endif mozilla::Maybe<mozilla::MediaFeatureChange> mPendingMediaFeatureValuesChange; protected: virtual ~nsPresContext(); - nscolor MakeColorPref(const nsString& aColor); - void LastRelease(); #ifdef DEBUG private: friend struct nsAutoLayoutPhase; uint32_t mLayoutPhaseCount[eLayoutPhase_COUNT]; public:
--- a/layout/style/GeckoBindings.cpp +++ b/layout/style/GeckoBindings.cpp @@ -760,16 +760,20 @@ nsAtom* Gecko_GetXMLLangValue(RawGeckoEl RefPtr<nsAtom> atom = attr->GetAtomValue(); return atom.forget().take(); } Document::DocumentTheme Gecko_GetDocumentLWTheme(const Document* aDocument) { return aDocument->ThreadSafeGetDocumentLWTheme(); } +const PreferenceSheet::Prefs* Gecko_GetPrefSheetPrefs(const Document* aDoc) { + return &PreferenceSheet::PrefsFor(*aDoc); +} + bool Gecko_IsTableBorderNonzero(RawGeckoElementBorrowed aElement) { if (!aElement->IsHTMLElement(nsGkAtoms::table)) { return false; } const nsAttrValue* val = aElement->GetParsedAttr(nsGkAtoms::border); return val && (val->Type() != nsAttrValue::eInteger || val->GetIntegerValue() != 0); }
--- a/layout/style/GeckoBindings.h +++ b/layout/style/GeckoBindings.h @@ -12,16 +12,17 @@ #include <stdint.h> #include "mozilla/ServoTypes.h" #include "mozilla/ServoBindingTypes.h" #include "mozilla/css/DocumentMatchingFunction.h" #include "mozilla/css/SheetLoadData.h" #include "mozilla/EffectCompositor.h" #include "mozilla/ComputedTimingFunction.h" +#include "mozilla/PreferenceSheet.h" #include "nsCSSValue.h" #include "nsStyleStruct.h" class nsAtom; class nsIURI; class nsSimpleContentList; struct nsFont; @@ -133,16 +134,19 @@ bool Gecko_IsRootElement(RawGeckoElement bool Gecko_MatchLang(RawGeckoElementBorrowed element, nsAtom* override_lang, bool has_override_lang, const char16_t* value); nsAtom* Gecko_GetXMLLangValue(RawGeckoElementBorrowed element); mozilla::dom::Document::DocumentTheme Gecko_GetDocumentLWTheme( const mozilla::dom::Document*); +const mozilla::PreferenceSheet::Prefs* Gecko_GetPrefSheetPrefs( + const mozilla::dom::Document*); + bool Gecko_IsTableBorderNonzero(RawGeckoElementBorrowed element); bool Gecko_IsBrowserFrame(RawGeckoElementBorrowed element); // Attributes. #define SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_) \ nsAtom* prefix_##LangValue(implementor_ element); \ bool prefix_##HasAttr(implementor_ element, nsAtom* ns, nsAtom* name); \ bool prefix_##AttrEquals(implementor_ element, nsAtom* ns, nsAtom* name, \
new file mode 100644 --- /dev/null +++ b/layout/style/PreferenceSheet.cpp @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "PreferenceSheet.h" + +#include "ServoCSSParser.h" +#include "MainThreadUtils.h" +#include "mozilla/StaticPrefs.h" +#include "mozilla/LookAndFeel.h" +#include "mozilla/dom/Document.h" +#include "nsContentUtils.h" + +using mozilla::dom::Document; + +namespace mozilla { + +bool PreferenceSheet::sInitialized; +PreferenceSheet::Prefs PreferenceSheet::sContentPrefs; +PreferenceSheet::Prefs PreferenceSheet::sChromePrefs; + +static void GetColor(const char* aPrefName, nscolor& aColor) { + nsAutoString value; + Preferences::GetString(aPrefName, value); + if (value.IsEmpty()) { + return; + } + nscolor result; + if (!ServoCSSParser::ComputeColor(nullptr, NS_RGB(0, 0, 0), value, &result)) { + return; + } + aColor = result; +} + +bool PreferenceSheet::ShouldUseChromePrefs(const Document& aDoc) { + return aDoc.IsInChromeDocShell() || + (aDoc.IsBeingUsedAsImage() && aDoc.IsDocumentURISchemeChrome()); +} + +bool PreferenceSheet::UseAccessibilityTheme(bool aIsChrome) { + return !aIsChrome && + !!LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0); +} + +void PreferenceSheet::Prefs::Load(bool aIsChrome) { + *this = {}; + + mUnderlineLinks = StaticPrefs::browser_underline_anchors(); + + mUseFocusColors = StaticPrefs::browser_display_use_focus_colors(); + mFocusRingWidth = StaticPrefs::browser_display_focus_ring_width(); + mFocusRingStyle = StaticPrefs::browser_display_focus_ring_style(); + mFocusRingOnAnything = StaticPrefs::browser_display_focus_ring_on_anything(); + + const bool usePrefColors = !aIsChrome && !UseAccessibilityTheme(aIsChrome) && + !StaticPrefs::browser_display_use_system_colors(); + + if (nsContentUtils::UseStandinsForNativeColors()) { + mDefaultColor = LookAndFeel::GetColorUsingStandins( + LookAndFeel::eColorID_windowtext, mDefaultColor); + mDefaultBackgroundColor = LookAndFeel::GetColorUsingStandins( + LookAndFeel::eColorID_window, mDefaultBackgroundColor); + } else if (usePrefColors) { + GetColor("browser.display.background_color", mDefaultBackgroundColor); + GetColor("browser.display.foreground_color", mDefaultColor); + } else { + mDefaultColor = LookAndFeel::GetColor( + LookAndFeel::eColorID_WindowForeground, mDefaultColor); + mDefaultBackgroundColor = LookAndFeel::GetColor( + LookAndFeel::eColorID_WindowBackground, mDefaultBackgroundColor); + } + + GetColor("browser.anchor_color", mLinkColor); + GetColor("browser.active_color", mActiveLinkColor); + GetColor("browser.visited_color", mVisitedLinkColor); + + GetColor("browser.display.focus_text_color", mFocusTextColor); + GetColor("browser.display.focus_background_color", mFocusBackgroundColor); + + // Wherever we got the default background color from, ensure it is + // opaque. + mDefaultBackgroundColor = + NS_ComposeColors(NS_RGB(0xFF, 0xFF, 0xFF), mDefaultBackgroundColor); +} + +void PreferenceSheet::Initialize() { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!sInitialized); + + sInitialized = true; + + sContentPrefs.Load(false); + sChromePrefs.Load(true); +} + +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/layout/style/PreferenceSheet.h @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Some prefable colors for style system use */ + +#ifndef mozilla_ColorPreferences_h +#define mozilla_ColorPreferences_h + +#include "nsColor.h" + +namespace mozilla { + +namespace dom { +class Document; +} + +struct PreferenceSheet { + struct Prefs { + nscolor mLinkColor = NS_RGB(0x00, 0x00, 0xEE); + nscolor mActiveLinkColor = NS_RGB(0xEE, 0x00, 0x00); + nscolor mVisitedLinkColor = NS_RGB(0x55, 0x1A, 0x8B); + + nscolor mDefaultColor = NS_RGB(0, 0, 0); + nscolor mDefaultBackgroundColor = NS_RGB(0xFF, 0xFF, 0xFF); + + nscolor mLinkBackgroundColor = mDefaultBackgroundColor; + + nscolor mFocusTextColor = mDefaultColor; + nscolor mFocusBackgroundColor = mDefaultBackgroundColor; + + bool mUnderlineLinks = true; + bool mUseFocusColors = false; + uint8_t mFocusRingWidth = 1; + bool mFocusRingStyle = false; + bool mFocusRingOnAnything = false; + + void Load(bool aIsChrome); + }; + + static void EnsureInitialized() { + if (sInitialized) { + return; + } + Initialize(); + } + + static void Refresh() { + sInitialized = false; + EnsureInitialized(); + } + + static Prefs& ContentPrefs() { + MOZ_ASSERT(sInitialized); + return sContentPrefs; + } + + static Prefs& ChromePrefs() { + MOZ_ASSERT(sInitialized); + return sChromePrefs; + } + + static bool ShouldUseChromePrefs(const dom::Document&); + static bool UseAccessibilityTheme(bool aIsChrome); + static const Prefs& PrefsFor(const dom::Document& aDocument) { + return ShouldUseChromePrefs(aDocument) ? ChromePrefs() : ContentPrefs(); + } + + private: + static bool sInitialized; + static Prefs sContentPrefs; + static Prefs sChromePrefs; + + static void Initialize(); +}; + +} // namespace mozilla + +#endif
--- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -174,16 +174,17 @@ whitelist-types = [ "RawServoAnimationValueMap", # TODO(heycam): Handle this elsewhere. "mozilla::DeclarationBlockMutationClosure", "mozilla::AnimationPropertySegment", "mozilla::AnonymousCounterStyle", "mozilla::AtomArray", "mozilla::ComputedTiming", "mozilla::ComputedTimingFunction", "mozilla::ComputedTimingFunction::BeforeFlag", + "mozilla::PreferenceSheet", "mozilla::SeenPtrs", "mozilla::ServoElementSnapshot.*", "mozilla::ComputedStyle", "mozilla::StyleSheet", "mozilla::ServoStyleSheetInner", "mozilla::ServoStyleSetSizes", "mozilla::ServoTraversalStatistics", "mozilla::css::LoaderReusableStyleSheets", @@ -520,16 +521,17 @@ structs-types = [ "gfxFontFeature", "mozilla::gfx::FontVariation", "mozilla::DeclarationBlockMutationClosure", "nsAttrValue", "nsIContent", "nsINode", "Document", "Document_DocumentTheme", + "mozilla::PreferenceSheet_Prefs", "nsSimpleContentList", "mozilla::MediumFeaturesChangedResult", "RawGeckoAnimationPropertySegment", "RawGeckoComputedTiming", "RawGeckoCSSPropertyIDList", "RawGeckoDocument", "RawGeckoElement", "Element",
--- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -82,16 +82,17 @@ EXPORTS.mozilla += [ 'CSSPropFlags.h', 'DeclarationBlock.h', 'DocumentStyleRootIterator.h', 'GeckoBindings.h', 'LayerAnimationInfo.h', 'MappedDeclarations.h', 'MediaFeatureChange.h', 'PostTraversalTask.h', + 'PreferenceSheet.h', 'PreloadedStyleSheet.h', 'PseudoStyleType.h', 'RustCell.h', 'ServoArcTypeList.h', 'ServoBindings.h', 'ServoBindingTypes.h', 'ServoBoxedTypeList.h', 'ServoComputedData.h', @@ -206,16 +207,17 @@ UNIFIED_SOURCES += [ 'nsStyleCoord.cpp', 'nsStyleStruct.cpp', 'nsStyleTransformMatrix.cpp', 'nsStyleUtil.cpp', 'nsTransitionManager.cpp', 'PaintWorkletGlobalScope.cpp', 'PaintWorkletImpl.cpp', 'PostTraversalTask.cpp', + 'PreferenceSheet.cpp', 'PreloadedStyleSheet.cpp', 'PseudoStyleType.cpp', 'Rule.cpp', 'ServoCSSParser.cpp', 'ServoCSSRuleList.cpp', 'ServoElementSnapshot.cpp', 'ServoStyleSet.cpp', 'StreamLoader.cpp',
--- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -62,29 +62,29 @@ nsresult nsLayoutStylesheetCache::Observ StyleSheet* nsLayoutStylesheetCache::GetUserContentSheet() { return mUserContentSheet; } StyleSheet* nsLayoutStylesheetCache::GetUserChromeSheet() { return mUserChromeSheet; } -StyleSheet* nsLayoutStylesheetCache::ChromePreferenceSheet( - nsPresContext* aPresContext) { +StyleSheet* nsLayoutStylesheetCache::ChromePreferenceSheet() { if (!mChromePreferenceSheet) { - BuildPreferenceSheet(&mChromePreferenceSheet, aPresContext); + BuildPreferenceSheet(&mChromePreferenceSheet, + PreferenceSheet::ChromePrefs()); } return mChromePreferenceSheet; } -StyleSheet* nsLayoutStylesheetCache::ContentPreferenceSheet( - nsPresContext* aPresContext) { +StyleSheet* nsLayoutStylesheetCache::ContentPreferenceSheet() { if (!mContentPreferenceSheet) { - BuildPreferenceSheet(&mContentPreferenceSheet, aPresContext); + BuildPreferenceSheet(&mContentPreferenceSheet, + PreferenceSheet::ContentPrefs()); } return mContentPreferenceSheet; } void nsLayoutStylesheetCache::Shutdown() { gCSSLoader = nullptr; NS_WARNING_ASSERTION(!gStyleCache || !gUserContentSheetURL, @@ -315,17 +315,17 @@ void nsLayoutStylesheetCache::LoadSheet( void nsLayoutStylesheetCache::InvalidatePreferenceSheets() { if (gStyleCache) { gStyleCache->mContentPreferenceSheet = nullptr; gStyleCache->mChromePreferenceSheet = nullptr; } } void nsLayoutStylesheetCache::BuildPreferenceSheet( - RefPtr<StyleSheet>* aSheet, nsPresContext* aPresContext) { + RefPtr<StyleSheet>* aSheet, const PreferenceSheet::Prefs& aPrefs) { *aSheet = new StyleSheet(eAgentSheetFeatures, CORS_NONE, mozilla::net::RP_Unset, dom::SRIMetadata()); StyleSheet* sheet = *aSheet; nsCOMPtr<nsIURI> uri; NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nullptr); MOZ_ASSERT(uri, "URI creation shouldn't fail"); @@ -341,38 +341,37 @@ void nsLayoutStylesheetCache::BuildPrefe #define NS_GET_R_G_B(color_) \ NS_GET_R(color_), NS_GET_G(color_), NS_GET_B(color_) sheetText.AppendLiteral( "@namespace url(http://www.w3.org/1999/xhtml);\n" "@namespace svg url(http://www.w3.org/2000/svg);\n"); // Rules for link styling. - nscolor linkColor = aPresContext->DefaultLinkColor(); - nscolor activeColor = aPresContext->DefaultActiveLinkColor(); - nscolor visitedColor = aPresContext->DefaultVisitedLinkColor(); + nscolor linkColor = aPrefs.mLinkColor; + nscolor activeColor = aPrefs.mActiveLinkColor; + nscolor visitedColor = aPrefs.mVisitedLinkColor; sheetText.AppendPrintf( "*|*:link { color: #%02x%02x%02x; }\n" "*|*:any-link:active { color: #%02x%02x%02x; }\n" "*|*:visited { color: #%02x%02x%02x; }\n", NS_GET_R_G_B(linkColor), NS_GET_R_G_B(activeColor), NS_GET_R_G_B(visitedColor)); - bool underlineLinks = - aPresContext->GetCachedBoolPref(kPresContext_UnderlineLinks); + bool underlineLinks = aPrefs.mUnderlineLinks; sheetText.AppendPrintf("*|*:any-link%s { text-decoration: %s; }\n", underlineLinks ? ":not(svg|a)" : "", underlineLinks ? "underline" : "none"); // Rules for focus styling. - bool focusRingOnAnything = aPresContext->GetFocusRingOnAnything(); - uint8_t focusRingWidth = aPresContext->FocusRingWidth(); - uint8_t focusRingStyle = aPresContext->GetFocusRingStyle(); + bool focusRingOnAnything = aPrefs.mFocusRingOnAnything; + uint8_t focusRingWidth = aPrefs.mFocusRingWidth; + uint8_t focusRingStyle = aPrefs.mFocusRingStyle; if ((focusRingWidth != 1 && focusRingWidth <= 4) || focusRingOnAnything) { if (focusRingWidth != 1) { // If the focus ring width is different from the default, fix buttons // with rings. sheetText.AppendPrintf( "button::-moz-focus-inner, input[type=\"reset\"]::-moz-focus-inner, " "input[type=\"button\"]::-moz-focus-inner, " @@ -395,19 +394,19 @@ void nsLayoutStylesheetCache::BuildPrefe focusRingStyle == 0 ? // solid "solid -moz-mac-focusring" : "dotted WindowText", focusRingStyle == 0 ? // solid "-moz-outline-radius: 3px; outline-offset: 1px; " : ""); } - if (aPresContext->GetUseFocusColors()) { - nscolor focusText = aPresContext->FocusTextColor(); - nscolor focusBG = aPresContext->FocusBackgroundColor(); + if (aPrefs.mUseFocusColors) { + nscolor focusText = aPrefs.mFocusTextColor; + nscolor focusBG = aPrefs.mFocusBackgroundColor; sheetText.AppendPrintf( "*:focus, *:focus > font { color: #%02x%02x%02x !important; " "background-color: #%02x%02x%02x !important; }\n", NS_GET_R_G_B(focusText), NS_GET_R_G_B(focusBG)); } NS_ASSERTION(sheetText.Length() <= kPreallocSize, "kPreallocSize should be big enough to build preference style "
--- a/layout/style/nsLayoutStylesheetCache.h +++ b/layout/style/nsLayoutStylesheetCache.h @@ -6,16 +6,17 @@ #ifndef nsLayoutStylesheetCache_h__ #define nsLayoutStylesheetCache_h__ #include "nsIMemoryReporter.h" #include "nsIObserver.h" #include "mozilla/Attributes.h" #include "mozilla/MemoryReporting.h" +#include "mozilla/PreferenceSheet.h" #include "mozilla/NotNull.h" #include "mozilla/StaticPtr.h" #include "mozilla/css/Loader.h" class nsIFile; class nsIURI; namespace mozilla { @@ -41,18 +42,18 @@ class nsLayoutStylesheetCache final : pu #define STYLE_SHEET(identifier_, url_, lazy_) \ mozilla::NotNull<mozilla::StyleSheet*> identifier_##Sheet(); #include "mozilla/UserAgentStyleSheetList.h" #undef STYLE_SHEET mozilla::StyleSheet* GetUserContentSheet(); mozilla::StyleSheet* GetUserChromeSheet(); - mozilla::StyleSheet* ChromePreferenceSheet(nsPresContext* aPresContext); - mozilla::StyleSheet* ContentPreferenceSheet(nsPresContext* aPresContext); + mozilla::StyleSheet* ChromePreferenceSheet(); + mozilla::StyleSheet* ContentPreferenceSheet(); static void InvalidatePreferenceSheets(); static void Shutdown(); static void SetUserContentCSSURL(nsIURI* aURI); size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; @@ -68,17 +69,17 @@ class nsLayoutStylesheetCache final : pu mozilla::css::FailureAction aFailureAction); void LoadSheetFile(nsIFile* aFile, RefPtr<mozilla::StyleSheet>* aSheet, mozilla::css::SheetParsingMode aParsingMode, mozilla::css::FailureAction aFailureAction); void LoadSheet(nsIURI* aURI, RefPtr<mozilla::StyleSheet>* aSheet, mozilla::css::SheetParsingMode aParsingMode, mozilla::css::FailureAction aFailureAction); void BuildPreferenceSheet(RefPtr<mozilla::StyleSheet>* aSheet, - nsPresContext* aPresContext); + const mozilla::PreferenceSheet::Prefs&); static mozilla::StaticRefPtr<nsLayoutStylesheetCache> gStyleCache; static mozilla::StaticRefPtr<mozilla::css::Loader> gCSSLoader; static mozilla::StaticRefPtr<nsIURI> gUserContentSheetURL; #define STYLE_SHEET(identifier_, url_, lazy_) \ RefPtr<mozilla::StyleSheet> m##identifier_##Sheet; #include "mozilla/UserAgentStyleSheetList.h"
--- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -30,16 +30,17 @@ #include "imgIContainer.h" #include "CounterStyleManager.h" #include "mozilla/dom/AnimationEffectBinding.h" // for PlaybackDirection #include "mozilla/dom/DocGroup.h" #include "mozilla/dom/ImageTracker.h" #include "mozilla/CORSMode.h" #include "mozilla/ClearOnShutdown.h" +#include "mozilla/PreferenceSheet.h" #include "mozilla/Likely.h" #include "nsIURI.h" #include "mozilla/dom/Document.h" #include <algorithm> #include "ImageLoader.h" using namespace mozilla; using namespace mozilla::dom; @@ -1661,18 +1662,17 @@ nsChangeHint nsStyleTableBorder::CalcDif } } // -------------------- // nsStyleColor // static nscolor DefaultColor(const Document& aDocument) { - auto* pc = aDocument.GetPresContext(); - return pc ? pc->DefaultColor() : NS_RGB(0, 0, 0); + return PreferenceSheet::PrefsFor(aDocument).mDefaultColor; } nsStyleColor::nsStyleColor(const Document& aDocument) : mColor(DefaultColor(aDocument)) { MOZ_COUNT_CTOR(nsStyleColor); } nsStyleColor::nsStyleColor(const nsStyleColor& aSource)
--- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -549,16 +549,64 @@ VARCACHE_PREF( VARCACHE_PREF( "full-screen-api.unprefix.enabled", full_screen_api_unprefix_enabled, bool, true ) //--------------------------------------------------------------------------- +// Preference stylesheet prefs. +//--------------------------------------------------------------------------- + +VARCACHE_PREF( + "browser.display.focus_ring_on_anything", + browser_display_focus_ring_on_anything, + bool, false +) + +VARCACHE_PREF( + "browser.display.focus_ring_width", + browser_display_focus_ring_width, + uint32_t, 1 +) + +VARCACHE_PREF( + "browser.display.focus_ring_style", + browser_display_focus_ring_style, + bool, false +) + +VARCACHE_PREF( + "browser.display.use_system_colors", + browser_display_use_system_colors, + bool, true +) + +VARCACHE_PREF( + "browser.display.use_focus_colors", + browser_display_use_focus_colors, + bool, false +) + +VARCACHE_PREF( + "browser.underline_anchors", + browser_underline_anchors, + bool, true +) + +PREF("browser.display.foreground_color", String, "") +PREF("browser.display.background_color", String, "") +PREF("browser.display.focus_background_color", String, "") +PREF("browser.display.focus_text_color", String, "") +PREF("browser.anchor_color", String, "") +PREF("browser.active_color", String, "") +PREF("browser.visited_color", String, "") + +//--------------------------------------------------------------------------- // Graphics prefs //--------------------------------------------------------------------------- // In theory: 0 = never, 1 = quick, 2 = always, though we always just use it as // a bool! VARCACHE_PREF( "browser.display.use_document_fonts", browser_display_use_document_fonts,
--- a/servo/components/style/gecko/data.rs +++ b/servo/components/style/gecko/data.rs @@ -145,17 +145,17 @@ impl PerDocumentStyleData { /// Create a dummy `PerDocumentStyleData`. pub fn new(pres_context: RawGeckoPresContextBorrowed) -> Self { let device = Device::new(pres_context); // FIXME(emilio, tlin): How is this supposed to work with XBL? This is // right now not always honored, see bug 1405543... // // Should we just force XBL Stylists to be NoQuirks? - let quirks_mode = unsafe { (*device.pres_context().mDocument.mRawPtr).mCompatMode }; + let quirks_mode = device.document().mCompatMode; PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl { stylist: Stylist::new(device, quirks_mode.into()), })) } /// Get an immutable reference to this style data. pub fn borrow(&self) -> AtomicRef<PerDocumentStyleDataImpl> { @@ -186,18 +186,17 @@ impl PerDocumentStyleDataImpl { /// Get the default computed values for this document. pub fn default_computed_values(&self) -> &Arc<ComputedValues> { self.stylist.device().default_computed_values_arc() } /// Returns whether visited styles are enabled. #[inline] pub fn visited_styles_enabled(&self) -> bool { - let doc = self.stylist.device().pres_context().mDocument.mRawPtr; - unsafe { bindings::Gecko_VisitedStylesEnabled(doc) } + unsafe { bindings::Gecko_VisitedStylesEnabled(self.stylist.device().document()) } } /// Measure heap usage. pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) { self.stylist.add_size_of(ops, sizes); } }
--- a/servo/components/style/gecko/media_queries.rs +++ b/servo/components/style/gecko/media_queries.rs @@ -78,24 +78,24 @@ impl fmt::Debug for Device { unsafe impl Sync for Device {} unsafe impl Send for Device {} impl Device { /// Trivially constructs a new `Device`. pub fn new(pres_context: RawGeckoPresContextBorrowed) -> Self { assert!(!pres_context.is_null()); + let doc = unsafe { &*(*pres_context).mDocument.mRawPtr }; + let prefs = unsafe { &*bindings::Gecko_GetPrefSheetPrefs(doc) }; Device { pres_context, - default_values: ComputedValues::default_values(unsafe { - &*(*pres_context).mDocument.mRawPtr - }), + default_values: ComputedValues::default_values(doc), // FIXME(bz): Seems dubious? root_font_size: AtomicIsize::new(FontSize::medium().size().0 as isize), - body_text_color: AtomicUsize::new(unsafe { &*pres_context }.mDefaultColor as usize), + body_text_color: AtomicUsize::new(prefs.mDefaultColor as usize), used_root_font_size: AtomicBool::new(false), used_viewport_size: AtomicBool::new(false), environment: CssEnvironment, } } /// Get the relevant environment to resolve `env()` functions. #[inline] @@ -163,16 +163,22 @@ impl Device { } /// Gets the document pointer. #[inline] pub fn document(&self) -> &structs::Document { unsafe { &*self.pres_context().mDocument.mRawPtr } } + /// Gets the preference stylesheet prefs for our document. + #[inline] + pub fn pref_sheet_prefs(&self) -> &structs::PreferenceSheet_Prefs { + unsafe { &*bindings::Gecko_GetPrefSheetPrefs(self.document()) } + } + /// Recreates the default computed values. pub fn reset_computed_values(&mut self) { self.default_values = ComputedValues::default_values(self.document()); } /// Rebuild all the cached data. pub fn rebuild_cached_data(&mut self) { self.reset_computed_values(); @@ -238,17 +244,17 @@ impl Device { /// Returns whether document colors are enabled. pub fn use_document_colors(&self) -> bool { self.pres_context().mUseDocumentColors() != 0 } /// Returns the default background color. pub fn default_background_color(&self) -> RGBA { - convert_nscolor_to_rgba(self.pres_context().mBackgroundColor) + convert_nscolor_to_rgba(self.pref_sheet_prefs().mDefaultBackgroundColor) } /// Applies text zoom to a font-size or line-height value (see nsStyleFont::ZoomText). #[inline] pub fn zoom_text(&self, size: Au) -> Au { size.scale_by(self.pres_context().mEffectiveTextZoom) }
--- a/servo/components/style/gecko/wrapper.rs +++ b/servo/components/style/gecko/wrapper.rs @@ -1238,17 +1238,17 @@ impl<'le> TElement for GeckoElement<'le> #[inline] fn as_node(&self) -> Self::ConcreteNode { unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) } } fn owner_doc_matches_for_testing(&self, device: &Device) -> bool { self.as_node().owner_doc().0 as *const structs::Document == - device.pres_context().mDocument.mRawPtr + device.document() as *const _ } fn style_attribute(&self) -> Option<ArcBorrow<Locked<PropertyDeclarationBlock>>> { if !self.may_have_style_attribute() { return None; } let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) };
--- a/servo/components/style/values/specified/color.rs +++ b/servo/components/style/values/specified/color.rs @@ -345,23 +345,23 @@ impl Color { Color::Complex(ref complex) => Some(*complex), #[cfg(feature = "gecko")] Color::System(system) => _context .map(|context| convert_nscolor_to_computedcolor(system.to_computed_value(context))), #[cfg(feature = "gecko")] Color::Special(special) => { use self::gecko::SpecialColorKeyword as Keyword; _context.map(|context| { - let pres_context = context.device().pres_context(); + let prefs = context.device().pref_sheet_prefs(); convert_nscolor_to_computedcolor(match special { - Keyword::MozDefaultColor => pres_context.mDefaultColor, - Keyword::MozDefaultBackgroundColor => pres_context.mBackgroundColor, - Keyword::MozHyperlinktext => pres_context.mLinkColor, - Keyword::MozActivehyperlinktext => pres_context.mActiveLinkColor, - Keyword::MozVisitedhyperlinktext => pres_context.mVisitedLinkColor, + Keyword::MozDefaultColor => prefs.mDefaultColor, + Keyword::MozDefaultBackgroundColor => prefs.mDefaultBackgroundColor, + Keyword::MozHyperlinktext => prefs.mLinkColor, + Keyword::MozActivehyperlinktext => prefs.mActiveLinkColor, + Keyword::MozVisitedhyperlinktext => prefs.mVisitedLinkColor, }) }) }, #[cfg(feature = "gecko")] Color::InheritFromBodyQuirk => { _context.map(|context| ComputedColor::rgba(context.device().body_text_color())) }, }