123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "nsLayoutStylesheetCache.h"
- #include "nsAppDirectoryServiceDefs.h"
- #include "mozilla/StyleSheetInlines.h"
- #include "mozilla/MemoryReporting.h"
- #include "mozilla/Preferences.h"
- #include "mozilla/StyleSheet.h"
- #include "mozilla/StyleSheetInlines.h"
- #include "mozilla/css/Loader.h"
- #include "mozilla/dom/SRIMetadata.h"
- #include "nsIConsoleService.h"
- #include "nsIFile.h"
- #include "nsNetUtil.h"
- #include "nsIObserverService.h"
- #include "nsServiceManagerUtils.h"
- #include "nsIXULRuntime.h"
- #include "nsPrintfCString.h"
- #include "nsXULAppAPI.h"
- using namespace mozilla;
- using namespace mozilla::css;
- static bool sNumberControlEnabled;
- #define NUMBER_CONTROL_PREF "dom.forms.number"
- NS_IMPL_ISUPPORTS(
- nsLayoutStylesheetCache, nsIObserver, nsIMemoryReporter)
- nsresult
- nsLayoutStylesheetCache::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData)
- {
- if (!strcmp(aTopic, "profile-before-change")) {
- mUserContentSheet = nullptr;
- mUserChromeSheet = nullptr;
- }
- else if (!strcmp(aTopic, "profile-do-change")) {
- InitFromProfile();
- }
- else if (strcmp(aTopic, "chrome-flush-skin-caches") == 0 ||
- strcmp(aTopic, "chrome-flush-caches") == 0) {
- mScrollbarsSheet = nullptr;
- mFormsSheet = nullptr;
- mNumberControlSheet = nullptr;
- }
- else {
- NS_NOTREACHED("Unexpected observer topic.");
- }
- return NS_OK;
- }
- StyleSheet*
- nsLayoutStylesheetCache::ScrollbarsSheet()
- {
- if (!mScrollbarsSheet) {
- // Scrollbars don't need access to unsafe rules
- LoadSheetURL("chrome://global/skin/scrollbars.css",
- &mScrollbarsSheet, eAuthorSheetFeatures, eCrash);
- }
- return mScrollbarsSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::FormsSheet()
- {
- if (!mFormsSheet) {
- // forms.css needs access to unsafe rules
- LoadSheetURL("resource://gre-resources/forms.css",
- &mFormsSheet, eAgentSheetFeatures, eCrash);
- }
- return mFormsSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::NumberControlSheet()
- {
- if (!sNumberControlEnabled) {
- return nullptr;
- }
- if (!mNumberControlSheet) {
- LoadSheetURL("resource://gre-resources/number-control.css",
- &mNumberControlSheet, eAgentSheetFeatures, eCrash);
- }
- return mNumberControlSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::UserContentSheet()
- {
- return mUserContentSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::UserChromeSheet()
- {
- return mUserChromeSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::UASheet()
- {
- if (!mUASheet) {
- LoadSheetURL("resource://gre-resources/ua.css",
- &mUASheet, eAgentSheetFeatures, eCrash);
- }
- return mUASheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::HTMLSheet()
- {
- if (!mHTMLSheet) {
- LoadSheetURL("resource://gre-resources/html.css",
- &mHTMLSheet, eAgentSheetFeatures, eCrash);
- }
- return mHTMLSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::MinimalXULSheet()
- {
- return mMinimalXULSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::XULSheet()
- {
- return mXULSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::QuirkSheet()
- {
- return mQuirkSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::SVGSheet()
- {
- return mSVGSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::MathMLSheet()
- {
- if (!mMathMLSheet) {
- LoadSheetURL("resource://gre-resources/mathml.css",
- &mMathMLSheet, eAgentSheetFeatures, eCrash);
- }
- return mMathMLSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::CounterStylesSheet()
- {
- return mCounterStylesSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::NoScriptSheet()
- {
- if (!mNoScriptSheet) {
- LoadSheetURL("resource://gre-resources/noscript.css",
- &mNoScriptSheet, eAgentSheetFeatures, eCrash);
- }
- return mNoScriptSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::NoFramesSheet()
- {
- if (!mNoFramesSheet) {
- LoadSheetURL("resource://gre-resources/noframes.css",
- &mNoFramesSheet, eAgentSheetFeatures, eCrash);
- }
- return mNoFramesSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::ChromePreferenceSheet(nsPresContext* aPresContext)
- {
- if (!mChromePreferenceSheet) {
- BuildPreferenceSheet(&mChromePreferenceSheet, aPresContext);
- }
- return mChromePreferenceSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::ContentPreferenceSheet(nsPresContext* aPresContext)
- {
- if (!mContentPreferenceSheet) {
- BuildPreferenceSheet(&mContentPreferenceSheet, aPresContext);
- }
- return mContentPreferenceSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::ContentEditableSheet()
- {
- if (!mContentEditableSheet) {
- LoadSheetURL("resource://gre/res/contenteditable.css",
- &mContentEditableSheet, eAgentSheetFeatures, eCrash);
- }
- return mContentEditableSheet;
- }
- StyleSheet*
- nsLayoutStylesheetCache::DesignModeSheet()
- {
- if (!mDesignModeSheet) {
- LoadSheetURL("resource://gre/res/designmode.css",
- &mDesignModeSheet, eAgentSheetFeatures, eCrash);
- }
- return mDesignModeSheet;
- }
- void
- nsLayoutStylesheetCache::Shutdown()
- {
- gCSSLoader_Gecko = nullptr;
- gCSSLoader_Servo = nullptr;
- gStyleCache_Gecko = nullptr;
- gStyleCache_Servo = nullptr;
- MOZ_ASSERT(!gUserContentSheetURL, "Got the URL but never used?");
- }
- void
- nsLayoutStylesheetCache::SetUserContentCSSURL(nsIURI* aURI)
- {
- MOZ_ASSERT(XRE_IsContentProcess(), "Only used in content processes.");
- gUserContentSheetURL = aURI;
- }
- MOZ_DEFINE_MALLOC_SIZE_OF(LayoutStylesheetCacheMallocSizeOf)
- NS_IMETHODIMP
- nsLayoutStylesheetCache::CollectReports(nsIHandleReportCallback* aHandleReport,
- nsISupports* aData, bool aAnonymize)
- {
- MOZ_COLLECT_REPORT(
- "explicit/layout/style-sheet-cache", KIND_HEAP, UNITS_BYTES,
- SizeOfIncludingThis(LayoutStylesheetCacheMallocSizeOf),
- "Memory used for some built-in style sheets.");
- return NS_OK;
- }
- size_t
- nsLayoutStylesheetCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
- {
- size_t n = aMallocSizeOf(this);
- #define MEASURE(s) n += s ? s->SizeOfIncludingThis(aMallocSizeOf) : 0;
- MEASURE(mChromePreferenceSheet);
- MEASURE(mContentEditableSheet);
- MEASURE(mContentPreferenceSheet);
- MEASURE(mCounterStylesSheet);
- MEASURE(mDesignModeSheet);
- MEASURE(mFormsSheet);
- MEASURE(mHTMLSheet);
- MEASURE(mMathMLSheet);
- MEASURE(mMinimalXULSheet);
- MEASURE(mNoFramesSheet);
- MEASURE(mNoScriptSheet);
- MEASURE(mNumberControlSheet);
- MEASURE(mQuirkSheet);
- MEASURE(mSVGSheet);
- MEASURE(mScrollbarsSheet);
- MEASURE(mUASheet);
- MEASURE(mUserChromeSheet);
- MEASURE(mUserContentSheet);
- MEASURE(mXULSheet);
- // Measurement of the following members may be added later if DMD finds it is
- // worthwhile:
- // - gCSSLoader_Gecko
- // - gCSSLoader_Servo
- return n;
- }
- nsLayoutStylesheetCache::nsLayoutStylesheetCache(StyleBackendType aType)
- : mBackendType(aType)
- {
- nsCOMPtr<nsIObserverService> obsSvc =
- mozilla::services::GetObserverService();
- NS_ASSERTION(obsSvc, "No global observer service?");
- if (obsSvc) {
- obsSvc->AddObserver(this, "profile-before-change", false);
- obsSvc->AddObserver(this, "profile-do-change", false);
- obsSvc->AddObserver(this, "chrome-flush-skin-caches", false);
- obsSvc->AddObserver(this, "chrome-flush-caches", false);
- }
- InitFromProfile();
- // And make sure that we load our UA sheets. No need to do this
- // per-profile, since they're profile-invariant.
- LoadSheetURL("resource://gre-resources/counterstyles.css",
- &mCounterStylesSheet, eAgentSheetFeatures, eCrash);
- LoadSheetURL("chrome://global/content/minimal-xul.css",
- &mMinimalXULSheet, eAgentSheetFeatures, eCrash);
- LoadSheetURL("resource://gre-resources/quirk.css",
- &mQuirkSheet, eAgentSheetFeatures, eCrash);
- LoadSheetURL("resource://gre/res/svg.css",
- &mSVGSheet, eAgentSheetFeatures, eCrash);
- LoadSheetURL("chrome://global/content/xul.css",
- &mXULSheet, eAgentSheetFeatures, eCrash);
- if (gUserContentSheetURL) {
- MOZ_ASSERT(XRE_IsContentProcess(), "Only used in content processes.");
- LoadSheet(gUserContentSheetURL, &mUserContentSheet, eUserSheetFeatures, eLogToConsole);
- gUserContentSheetURL = nullptr;
- }
- // The remaining sheets are created on-demand do to their use being rarer
- // (which helps save memory for Firefox OS apps) or because they need to
- // be re-loadable in DependentPrefChanged.
- }
- nsLayoutStylesheetCache::~nsLayoutStylesheetCache()
- {
- mozilla::UnregisterWeakMemoryReporter(this);
- }
- void
- nsLayoutStylesheetCache::InitMemoryReporter()
- {
- mozilla::RegisterWeakMemoryReporter(this);
- }
- /* static */ nsLayoutStylesheetCache*
- nsLayoutStylesheetCache::For(StyleBackendType aType)
- {
- MOZ_ASSERT(NS_IsMainThread());
- bool mustInit = !gStyleCache_Gecko && !gStyleCache_Servo;
- auto& cache = aType == StyleBackendType::Gecko ? gStyleCache_Gecko :
- gStyleCache_Servo;
- if (!cache) {
- cache = new nsLayoutStylesheetCache(aType);
- cache->InitMemoryReporter();
- }
- if (mustInit) {
- // Initialization that only needs to be done once for both
- // nsLayoutStylesheetCaches.
- Preferences::AddBoolVarCache(&sNumberControlEnabled, NUMBER_CONTROL_PREF,
- true);
- // For each pref that controls a CSS feature that a UA style sheet depends
- // on (such as a pref that enables a property that a UA style sheet uses),
- // register DependentPrefChanged as a callback to ensure that the relevant
- // style sheets will be re-parsed.
- // Preferences::RegisterCallback(&DependentPrefChanged,
- // "layout.css.example-pref.enabled");
- Preferences::RegisterCallback(&DependentPrefChanged,
- "layout.css.grid.enabled");
- Preferences::RegisterCallback(&DependentPrefChanged,
- "dom.details_element.enabled");
- }
- return cache;
- }
- void
- nsLayoutStylesheetCache::InitFromProfile()
- {
- nsCOMPtr<nsIXULRuntime> appInfo = do_GetService("@mozilla.org/xre/app-info;1");
- if (appInfo) {
- bool inSafeMode = false;
- appInfo->GetInSafeMode(&inSafeMode);
- if (inSafeMode)
- return;
- }
- nsCOMPtr<nsIFile> contentFile;
- nsCOMPtr<nsIFile> chromeFile;
- NS_GetSpecialDirectory(NS_APP_USER_CHROME_DIR,
- getter_AddRefs(contentFile));
- if (!contentFile) {
- // if we don't have a profile yet, that's OK!
- return;
- }
- contentFile->Clone(getter_AddRefs(chromeFile));
- if (!chromeFile) return;
- contentFile->Append(NS_LITERAL_STRING("userContent.css"));
- chromeFile->Append(NS_LITERAL_STRING("userChrome.css"));
- LoadSheetFile(contentFile, &mUserContentSheet, eUserSheetFeatures, eLogToConsole);
- LoadSheetFile(chromeFile, &mUserChromeSheet, eUserSheetFeatures, eLogToConsole);
- }
- void
- nsLayoutStylesheetCache::LoadSheetURL(const char* aURL,
- RefPtr<StyleSheet>* aSheet,
- SheetParsingMode aParsingMode,
- FailureAction aFailureAction)
- {
- nsCOMPtr<nsIURI> uri;
- NS_NewURI(getter_AddRefs(uri), aURL);
- LoadSheet(uri, aSheet, aParsingMode, aFailureAction);
- if (!aSheet) {
- NS_ERROR(nsPrintfCString("Could not load %s", aURL).get());
- }
- }
- void
- nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile,
- RefPtr<StyleSheet>* aSheet,
- SheetParsingMode aParsingMode,
- FailureAction aFailureAction)
- {
- bool exists = false;
- aFile->Exists(&exists);
- if (!exists) return;
- nsCOMPtr<nsIURI> uri;
- NS_NewFileURI(getter_AddRefs(uri), aFile);
- LoadSheet(uri, aSheet, aParsingMode, aFailureAction);
- }
- static void
- ErrorLoadingSheet(nsIURI* aURI, const char* aMsg, FailureAction aFailureAction)
- {
- nsPrintfCString errorMessage("%s loading built-in stylesheet '%s'",
- aMsg,
- aURI ? aURI->GetSpecOrDefault().get() : "");
- if (aFailureAction == eLogToConsole) {
- nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
- if (cs) {
- cs->LogStringMessage(NS_ConvertUTF8toUTF16(errorMessage).get());
- return;
- }
- }
- NS_RUNTIMEABORT(errorMessage.get());
- }
- void
- nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI,
- RefPtr<StyleSheet>* aSheet,
- SheetParsingMode aParsingMode,
- FailureAction aFailureAction)
- {
- if (!aURI) {
- ErrorLoadingSheet(aURI, "null URI", eCrash);
- return;
- }
- auto& loader = mBackendType == StyleBackendType::Gecko ?
- gCSSLoader_Gecko :
- gCSSLoader_Servo;
- if (!loader) {
- loader = new mozilla::css::Loader(mBackendType);
- if (!loader) {
- ErrorLoadingSheet(aURI, "no Loader", eCrash);
- return;
- }
- }
- nsresult rv = loader->LoadSheetSync(aURI, aParsingMode, true, aSheet);
- if (NS_FAILED(rv)) {
- ErrorLoadingSheet(aURI,
- nsPrintfCString("LoadSheetSync failed with error %x", rv).get(),
- aFailureAction);
- }
- }
- /* static */ void
- nsLayoutStylesheetCache::InvalidateSheet(RefPtr<StyleSheet>* aGeckoSheet,
- RefPtr<StyleSheet>* aServoSheet)
- {
- MOZ_ASSERT(gCSSLoader_Gecko || gCSSLoader_Servo,
- "pref changed before we loaded a sheet?");
- const bool gotGeckoSheet = aGeckoSheet && *aGeckoSheet;
- const bool gotServoSheet = aServoSheet && *aServoSheet;
- // Make sure sheets have the expected types
- MOZ_ASSERT(!gotGeckoSheet || (*aGeckoSheet)->IsGecko());
- MOZ_ASSERT(!gotServoSheet || (*aServoSheet)->IsServo());
- // Make sure the URIs match
- MOZ_ASSERT(!gotServoSheet || !gotGeckoSheet ||
- (*aGeckoSheet)->GetSheetURI() == (*aServoSheet)->GetSheetURI(),
- "Sheets passed should have the same URI");
- nsIURI* uri;
- if (gotGeckoSheet) {
- uri = (*aGeckoSheet)->GetSheetURI();
- } else if (gotServoSheet) {
- uri = (*aServoSheet)->GetSheetURI();
- } else {
- return;
- }
- if (gCSSLoader_Gecko) {
- gCSSLoader_Gecko->ObsoleteSheet(uri);
- }
- if (gCSSLoader_Servo) {
- gCSSLoader_Servo->ObsoleteSheet(uri);
- }
- if (gotGeckoSheet) {
- *aGeckoSheet = nullptr;
- }
- if (gotServoSheet) {
- *aServoSheet = nullptr;
- }
- }
- /* static */ void
- nsLayoutStylesheetCache::DependentPrefChanged(const char* aPref, void* aData)
- {
- MOZ_ASSERT(gStyleCache_Gecko || gStyleCache_Servo,
- "pref changed after shutdown?");
- // Cause any UA style sheets whose parsing depends on the value of prefs
- // to be re-parsed by dropping the sheet from gCSSLoader_{Gecko,Servo}'s cache
- // then setting our cached sheet pointer to null. This will only work for
- // sheets that are loaded lazily.
- #define INVALIDATE(sheet_) \
- InvalidateSheet(gStyleCache_Gecko ? &gStyleCache_Gecko->sheet_ : nullptr, \
- gStyleCache_Servo ? &gStyleCache_Servo->sheet_ : nullptr);
- INVALIDATE(mUASheet); // for layout.css.grid.enabled
- INVALIDATE(mHTMLSheet); // for dom.details_element.enabled
- #undef INVALIDATE
- }
- /* static */ void
- nsLayoutStylesheetCache::InvalidatePreferenceSheets()
- {
- if (gStyleCache_Gecko) {
- gStyleCache_Gecko->mContentPreferenceSheet = nullptr;
- gStyleCache_Gecko->mChromePreferenceSheet = nullptr;
- }
- if (gStyleCache_Servo) {
- gStyleCache_Servo->mContentPreferenceSheet = nullptr;
- gStyleCache_Servo->mChromePreferenceSheet = nullptr;
- }
- }
- void
- nsLayoutStylesheetCache::BuildPreferenceSheet(RefPtr<StyleSheet>* aSheet,
- nsPresContext* aPresContext)
- {
- if (mBackendType == StyleBackendType::Gecko) {
- *aSheet = new CSSStyleSheet(eAgentSheetFeatures, CORS_NONE,
- mozilla::net::RP_Default);
- } else {
- *aSheet = new ServoStyleSheet(eAgentSheetFeatures, CORS_NONE,
- mozilla::net::RP_Default, dom::SRIMetadata());
- }
- StyleSheet* sheet = *aSheet;
- nsCOMPtr<nsIURI> uri;
- NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nullptr);
- MOZ_ASSERT(uri, "URI creation shouldn't fail");
- sheet->SetURIs(uri, uri, uri);
- sheet->SetComplete();
- static const uint32_t kPreallocSize = 1024;
- nsString sheetText;
- sheetText.SetCapacity(kPreallocSize);
- #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();
- 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);
- 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();
- 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, "
- "input[type=\"submit\"]::-moz-focus-inner { "
- "padding: 1px 2px 1px 2px; "
- "border: %dpx %s transparent !important; }\n",
- focusRingWidth,
- focusRingStyle == 0 ? "solid" : "dotted");
- sheetText.AppendLiteral(
- "button:focus::-moz-focus-inner, "
- "input[type=\"reset\"]:focus::-moz-focus-inner, "
- "input[type=\"button\"]:focus::-moz-focus-inner, "
- "input[type=\"submit\"]:focus::-moz-focus-inner { "
- "border-color: ButtonText !important; }\n");
- }
- sheetText.AppendPrintf(
- "%s { outline: %dpx %s !important; %s}\n",
- focusRingOnAnything ?
- ":focus" :
- "*|*:link:focus, *|*:visited:focus",
- focusRingWidth,
- 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();
- 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 "
- "sheet without reallocation");
- if (sheet->IsGecko()) {
- sheet->AsGecko()->ReparseSheet(sheetText);
- } else {
- nsresult rv = sheet->AsServo()->ParseSheet(sheetText, uri, uri, nullptr, 0);
- // Parsing the about:PreferenceStyleSheet URI can only fail on OOM. If we
- // are OOM before we parsed any documents we might as well abort.
- MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
- }
- #undef NS_GET_R_G_B
- }
- mozilla::StaticRefPtr<nsLayoutStylesheetCache>
- nsLayoutStylesheetCache::gStyleCache_Gecko;
- mozilla::StaticRefPtr<nsLayoutStylesheetCache>
- nsLayoutStylesheetCache::gStyleCache_Servo;
- mozilla::StaticRefPtr<mozilla::css::Loader>
- nsLayoutStylesheetCache::gCSSLoader_Gecko;
- mozilla::StaticRefPtr<mozilla::css::Loader>
- nsLayoutStylesheetCache::gCSSLoader_Servo;
- mozilla::StaticRefPtr<nsIURI>
- nsLayoutStylesheetCache::gUserContentSheetURL;
|