layout/style/nsLayoutStylesheetCache.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "nsLayoutStylesheetCache.h"
michael@0 8
michael@0 9 #include "nsAppDirectoryServiceDefs.h"
michael@0 10 #include "mozilla/MemoryReporting.h"
michael@0 11 #include "mozilla/Preferences.h"
michael@0 12 #include "mozilla/css/Loader.h"
michael@0 13 #include "nsIFile.h"
michael@0 14 #include "nsNetUtil.h"
michael@0 15 #include "nsIObserverService.h"
michael@0 16 #include "nsServiceManagerUtils.h"
michael@0 17 #include "nsIXULRuntime.h"
michael@0 18 #include "nsCSSStyleSheet.h"
michael@0 19
michael@0 20 using namespace mozilla;
michael@0 21
michael@0 22 static bool sNumberControlEnabled;
michael@0 23
michael@0 24 #define NUMBER_CONTROL_PREF "dom.forms.number"
michael@0 25
michael@0 26 NS_IMPL_ISUPPORTS(
michael@0 27 nsLayoutStylesheetCache, nsIObserver, nsIMemoryReporter)
michael@0 28
michael@0 29 nsresult
michael@0 30 nsLayoutStylesheetCache::Observe(nsISupports* aSubject,
michael@0 31 const char* aTopic,
michael@0 32 const char16_t* aData)
michael@0 33 {
michael@0 34 if (!strcmp(aTopic, "profile-before-change")) {
michael@0 35 mUserContentSheet = nullptr;
michael@0 36 mUserChromeSheet = nullptr;
michael@0 37 }
michael@0 38 else if (!strcmp(aTopic, "profile-do-change")) {
michael@0 39 InitFromProfile();
michael@0 40 }
michael@0 41 else if (strcmp(aTopic, "chrome-flush-skin-caches") == 0 ||
michael@0 42 strcmp(aTopic, "chrome-flush-caches") == 0) {
michael@0 43 mScrollbarsSheet = nullptr;
michael@0 44 mFormsSheet = nullptr;
michael@0 45 mNumberControlSheet = nullptr;
michael@0 46 }
michael@0 47 else {
michael@0 48 NS_NOTREACHED("Unexpected observer topic.");
michael@0 49 }
michael@0 50 return NS_OK;
michael@0 51 }
michael@0 52
michael@0 53 nsCSSStyleSheet*
michael@0 54 nsLayoutStylesheetCache::ScrollbarsSheet()
michael@0 55 {
michael@0 56 EnsureGlobal();
michael@0 57 if (!gStyleCache)
michael@0 58 return nullptr;
michael@0 59
michael@0 60 if (!gStyleCache->mScrollbarsSheet) {
michael@0 61 nsCOMPtr<nsIURI> sheetURI;
michael@0 62 NS_NewURI(getter_AddRefs(sheetURI),
michael@0 63 NS_LITERAL_CSTRING("chrome://global/skin/scrollbars.css"));
michael@0 64
michael@0 65 // Scrollbars don't need access to unsafe rules
michael@0 66 if (sheetURI)
michael@0 67 LoadSheet(sheetURI, gStyleCache->mScrollbarsSheet, false);
michael@0 68 NS_ASSERTION(gStyleCache->mScrollbarsSheet, "Could not load scrollbars.css.");
michael@0 69 }
michael@0 70
michael@0 71 return gStyleCache->mScrollbarsSheet;
michael@0 72 }
michael@0 73
michael@0 74 nsCSSStyleSheet*
michael@0 75 nsLayoutStylesheetCache::FormsSheet()
michael@0 76 {
michael@0 77 EnsureGlobal();
michael@0 78 if (!gStyleCache)
michael@0 79 return nullptr;
michael@0 80
michael@0 81 if (!gStyleCache->mFormsSheet) {
michael@0 82 nsCOMPtr<nsIURI> sheetURI;
michael@0 83 NS_NewURI(getter_AddRefs(sheetURI),
michael@0 84 NS_LITERAL_CSTRING("resource://gre-resources/forms.css"));
michael@0 85
michael@0 86 // forms.css needs access to unsafe rules
michael@0 87 if (sheetURI)
michael@0 88 LoadSheet(sheetURI, gStyleCache->mFormsSheet, true);
michael@0 89
michael@0 90 NS_ASSERTION(gStyleCache->mFormsSheet, "Could not load forms.css.");
michael@0 91 }
michael@0 92
michael@0 93 return gStyleCache->mFormsSheet;
michael@0 94 }
michael@0 95
michael@0 96 nsCSSStyleSheet*
michael@0 97 nsLayoutStylesheetCache::NumberControlSheet()
michael@0 98 {
michael@0 99 EnsureGlobal();
michael@0 100 if (!gStyleCache)
michael@0 101 return nullptr;
michael@0 102
michael@0 103 if (!sNumberControlEnabled) {
michael@0 104 return nullptr;
michael@0 105 }
michael@0 106
michael@0 107 if (!gStyleCache->mNumberControlSheet) {
michael@0 108 nsCOMPtr<nsIURI> sheetURI;
michael@0 109 NS_NewURI(getter_AddRefs(sheetURI),
michael@0 110 NS_LITERAL_CSTRING("resource://gre-resources/number-control.css"));
michael@0 111
michael@0 112 if (sheetURI)
michael@0 113 LoadSheet(sheetURI, gStyleCache->mNumberControlSheet, false);
michael@0 114
michael@0 115 NS_ASSERTION(gStyleCache->mNumberControlSheet, "Could not load number-control.css");
michael@0 116 }
michael@0 117
michael@0 118 return gStyleCache->mNumberControlSheet;
michael@0 119 }
michael@0 120
michael@0 121 nsCSSStyleSheet*
michael@0 122 nsLayoutStylesheetCache::UserContentSheet()
michael@0 123 {
michael@0 124 EnsureGlobal();
michael@0 125 if (!gStyleCache)
michael@0 126 return nullptr;
michael@0 127
michael@0 128 return gStyleCache->mUserContentSheet;
michael@0 129 }
michael@0 130
michael@0 131 nsCSSStyleSheet*
michael@0 132 nsLayoutStylesheetCache::UserChromeSheet()
michael@0 133 {
michael@0 134 EnsureGlobal();
michael@0 135 if (!gStyleCache)
michael@0 136 return nullptr;
michael@0 137
michael@0 138 return gStyleCache->mUserChromeSheet;
michael@0 139 }
michael@0 140
michael@0 141 nsCSSStyleSheet*
michael@0 142 nsLayoutStylesheetCache::UASheet()
michael@0 143 {
michael@0 144 EnsureGlobal();
michael@0 145 if (!gStyleCache)
michael@0 146 return nullptr;
michael@0 147
michael@0 148 return gStyleCache->mUASheet;
michael@0 149 }
michael@0 150
michael@0 151 nsCSSStyleSheet*
michael@0 152 nsLayoutStylesheetCache::QuirkSheet()
michael@0 153 {
michael@0 154 EnsureGlobal();
michael@0 155 if (!gStyleCache)
michael@0 156 return nullptr;
michael@0 157
michael@0 158 return gStyleCache->mQuirkSheet;
michael@0 159 }
michael@0 160
michael@0 161 nsCSSStyleSheet*
michael@0 162 nsLayoutStylesheetCache::FullScreenOverrideSheet()
michael@0 163 {
michael@0 164 EnsureGlobal();
michael@0 165 if (!gStyleCache)
michael@0 166 return nullptr;
michael@0 167
michael@0 168 return gStyleCache->mFullScreenOverrideSheet;
michael@0 169 }
michael@0 170
michael@0 171 void
michael@0 172 nsLayoutStylesheetCache::Shutdown()
michael@0 173 {
michael@0 174 NS_IF_RELEASE(gCSSLoader);
michael@0 175 NS_IF_RELEASE(gStyleCache);
michael@0 176 }
michael@0 177
michael@0 178 MOZ_DEFINE_MALLOC_SIZE_OF(LayoutStylesheetCacheMallocSizeOf)
michael@0 179
michael@0 180 NS_IMETHODIMP
michael@0 181 nsLayoutStylesheetCache::CollectReports(nsIHandleReportCallback* aHandleReport,
michael@0 182 nsISupports* aData)
michael@0 183 {
michael@0 184 return MOZ_COLLECT_REPORT(
michael@0 185 "explicit/layout/style-sheet-cache", KIND_HEAP, UNITS_BYTES,
michael@0 186 SizeOfIncludingThis(LayoutStylesheetCacheMallocSizeOf),
michael@0 187 "Memory used for some built-in style sheets.");
michael@0 188 }
michael@0 189
michael@0 190
michael@0 191 size_t
michael@0 192 nsLayoutStylesheetCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 193 {
michael@0 194 size_t n = aMallocSizeOf(this);
michael@0 195
michael@0 196 #define MEASURE(s) n += s ? s->SizeOfIncludingThis(aMallocSizeOf) : 0;
michael@0 197
michael@0 198 MEASURE(mScrollbarsSheet);
michael@0 199 MEASURE(mFormsSheet);
michael@0 200 MEASURE(mNumberControlSheet);
michael@0 201 MEASURE(mUserContentSheet);
michael@0 202 MEASURE(mUserChromeSheet);
michael@0 203 MEASURE(mUASheet);
michael@0 204 MEASURE(mQuirkSheet);
michael@0 205 MEASURE(mFullScreenOverrideSheet);
michael@0 206
michael@0 207 // Measurement of the following members may be added later if DMD finds it is
michael@0 208 // worthwhile:
michael@0 209 // - gCSSLoader
michael@0 210
michael@0 211 return n;
michael@0 212 }
michael@0 213
michael@0 214 nsLayoutStylesheetCache::nsLayoutStylesheetCache()
michael@0 215 {
michael@0 216 nsCOMPtr<nsIObserverService> obsSvc =
michael@0 217 mozilla::services::GetObserverService();
michael@0 218 NS_ASSERTION(obsSvc, "No global observer service?");
michael@0 219
michael@0 220 if (obsSvc) {
michael@0 221 obsSvc->AddObserver(this, "profile-before-change", false);
michael@0 222 obsSvc->AddObserver(this, "profile-do-change", false);
michael@0 223 obsSvc->AddObserver(this, "chrome-flush-skin-caches", false);
michael@0 224 obsSvc->AddObserver(this, "chrome-flush-caches", false);
michael@0 225 }
michael@0 226
michael@0 227 InitFromProfile();
michael@0 228
michael@0 229 // And make sure that we load our UA sheets. No need to do this
michael@0 230 // per-profile, since they're profile-invariant.
michael@0 231 nsCOMPtr<nsIURI> uri;
michael@0 232 NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/ua.css");
michael@0 233 if (uri) {
michael@0 234 LoadSheet(uri, mUASheet, true);
michael@0 235 }
michael@0 236 NS_ASSERTION(mUASheet, "Could not load ua.css");
michael@0 237
michael@0 238 NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/quirk.css");
michael@0 239 if (uri) {
michael@0 240 LoadSheet(uri, mQuirkSheet, true);
michael@0 241 }
michael@0 242 NS_ASSERTION(mQuirkSheet, "Could not load quirk.css");
michael@0 243
michael@0 244 NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/full-screen-override.css");
michael@0 245 if (uri) {
michael@0 246 LoadSheet(uri, mFullScreenOverrideSheet, true);
michael@0 247 }
michael@0 248 NS_ASSERTION(mFullScreenOverrideSheet, "Could not load full-screen-override.css");
michael@0 249 }
michael@0 250
michael@0 251 nsLayoutStylesheetCache::~nsLayoutStylesheetCache()
michael@0 252 {
michael@0 253 mozilla::UnregisterWeakMemoryReporter(this);
michael@0 254 gStyleCache = nullptr;
michael@0 255 }
michael@0 256
michael@0 257 void
michael@0 258 nsLayoutStylesheetCache::InitMemoryReporter()
michael@0 259 {
michael@0 260 mozilla::RegisterWeakMemoryReporter(this);
michael@0 261 }
michael@0 262
michael@0 263 void
michael@0 264 nsLayoutStylesheetCache::EnsureGlobal()
michael@0 265 {
michael@0 266 if (gStyleCache) return;
michael@0 267
michael@0 268 gStyleCache = new nsLayoutStylesheetCache();
michael@0 269 if (!gStyleCache) return;
michael@0 270
michael@0 271 NS_ADDREF(gStyleCache);
michael@0 272
michael@0 273 gStyleCache->InitMemoryReporter();
michael@0 274
michael@0 275 Preferences::AddBoolVarCache(&sNumberControlEnabled, NUMBER_CONTROL_PREF,
michael@0 276 true);
michael@0 277 }
michael@0 278
michael@0 279 void
michael@0 280 nsLayoutStylesheetCache::InitFromProfile()
michael@0 281 {
michael@0 282 nsCOMPtr<nsIXULRuntime> appInfo = do_GetService("@mozilla.org/xre/app-info;1");
michael@0 283 if (appInfo) {
michael@0 284 bool inSafeMode = false;
michael@0 285 appInfo->GetInSafeMode(&inSafeMode);
michael@0 286 if (inSafeMode)
michael@0 287 return;
michael@0 288 }
michael@0 289 nsCOMPtr<nsIFile> contentFile;
michael@0 290 nsCOMPtr<nsIFile> chromeFile;
michael@0 291
michael@0 292 NS_GetSpecialDirectory(NS_APP_USER_CHROME_DIR,
michael@0 293 getter_AddRefs(contentFile));
michael@0 294 if (!contentFile) {
michael@0 295 // if we don't have a profile yet, that's OK!
michael@0 296 return;
michael@0 297 }
michael@0 298
michael@0 299 contentFile->Clone(getter_AddRefs(chromeFile));
michael@0 300 if (!chromeFile) return;
michael@0 301
michael@0 302 contentFile->Append(NS_LITERAL_STRING("userContent.css"));
michael@0 303 chromeFile->Append(NS_LITERAL_STRING("userChrome.css"));
michael@0 304
michael@0 305 LoadSheetFile(contentFile, mUserContentSheet);
michael@0 306 LoadSheetFile(chromeFile, mUserChromeSheet);
michael@0 307 }
michael@0 308
michael@0 309 void
michael@0 310 nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile, nsRefPtr<nsCSSStyleSheet> &aSheet)
michael@0 311 {
michael@0 312 bool exists = false;
michael@0 313 aFile->Exists(&exists);
michael@0 314
michael@0 315 if (!exists) return;
michael@0 316
michael@0 317 nsCOMPtr<nsIURI> uri;
michael@0 318 NS_NewFileURI(getter_AddRefs(uri), aFile);
michael@0 319
michael@0 320 LoadSheet(uri, aSheet, false);
michael@0 321 }
michael@0 322
michael@0 323 void
michael@0 324 nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI,
michael@0 325 nsRefPtr<nsCSSStyleSheet> &aSheet,
michael@0 326 bool aEnableUnsafeRules)
michael@0 327 {
michael@0 328 if (!aURI) {
michael@0 329 NS_ERROR("Null URI. Out of memory?");
michael@0 330 return;
michael@0 331 }
michael@0 332
michael@0 333 if (!gCSSLoader) {
michael@0 334 gCSSLoader = new mozilla::css::Loader();
michael@0 335 NS_IF_ADDREF(gCSSLoader);
michael@0 336 }
michael@0 337
michael@0 338 if (gCSSLoader) {
michael@0 339 gCSSLoader->LoadSheetSync(aURI, aEnableUnsafeRules, true,
michael@0 340 getter_AddRefs(aSheet));
michael@0 341 }
michael@0 342 }
michael@0 343
michael@0 344 nsLayoutStylesheetCache*
michael@0 345 nsLayoutStylesheetCache::gStyleCache = nullptr;
michael@0 346
michael@0 347 mozilla::css::Loader*
michael@0 348 nsLayoutStylesheetCache::gCSSLoader = nullptr;

mercurial