/* 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 "ZenStyleSheetCache.h" #include "nsAppDirectoryServiceDefs.h" #include "nsCOMPtr.h" #include "nsIFile.h" #include "nsNetUtil.h" #include "nsStyleSheetService.h" #include "mozilla/css/SheetParsingMode.h" #include "mozilla/GlobalStyleSheetCache.h" #define GET_MODS_FILE(chromeFile, err) \ NS_GetSpecialDirectory(NS_APP_USER_CHROME_DIR, getter_AddRefs(chromeFile)); \ if (!chromeFile) { \ return err; \ } \ chromeFile->Append(ZEN_MODS_FILENAME); namespace zen { using namespace mozilla; NS_IMPL_ISUPPORTS(ZenStyleSheetCache, nsISupports) auto ZenStyleSheetCache::GetModsSheet() -> StyleSheet* { if (mModsSheet) { // If the mods stylesheet is already loaded, return it. return mModsSheet; } nsCOMPtr chromeFile; GET_MODS_FILE(chromeFile, nullptr); // Create the mods stylesheet if it doesn't exist. bool exists; chromeFile->Exists(&exists); if (!exists) { nsresult rv = chromeFile->Create(nsIFile::NORMAL_FILE_TYPE, 0644); if (NS_FAILED(rv)) { return nullptr; } } LoadSheetFile(chromeFile, css::eUserSheetFeatures); return mModsSheet; } auto ZenStyleSheetCache::LoadSheetFile(nsIFile* aFile, css::SheetParsingMode aParsingMode) -> void { nsCOMPtr uri; NS_NewFileURI(getter_AddRefs(uri), aFile); if (!uri) { return; } auto loader = new mozilla::css::Loader; auto result = loader->LoadSheetSync(uri, aParsingMode, css::Loader::UseSystemPrincipal::Yes); if (MOZ_UNLIKELY(result.isErr())) { return; } mModsSheet = result.unwrapOr(nullptr); } /* static */ auto ZenStyleSheetCache::Singleton() -> ZenStyleSheetCache* { MOZ_ASSERT(NS_IsMainThread()); if (!gZenModsCache) { gZenModsCache = new ZenStyleSheetCache; } return gZenModsCache; } nsresult ZenStyleSheetCache::RebuildModsStylesheets(const nsACString& aContents) { // Re-parse the mods stylesheet. By doing so, we read // Once we have the data as a nsACString, we call ReparseSheet from the // StyleSheet class to re-parse the stylesheet. auto sheet = GetModsSheet(); if (!sheet) { return NS_ERROR_FAILURE; } ErrorResult aRv; sheet->ReparseSheet(aContents, aRv); if (auto sss = nsStyleSheetService::GetInstance()) { sss->ZenMarkStylesAsChanged(); } return aRv.StealNSResult(); } mozilla::StaticRefPtr ZenStyleSheetCache::gZenModsCache; } // namespace: zen