layout/style/Loader.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /* loading of CSS style sheets using the network APIs */
michael@0 7
michael@0 8 #ifndef mozilla_css_Loader_h
michael@0 9 #define mozilla_css_Loader_h
michael@0 10
michael@0 11 #include "nsIPrincipal.h"
michael@0 12 #include "nsAString.h"
michael@0 13 #include "nsAutoPtr.h"
michael@0 14 #include "nsCompatibility.h"
michael@0 15 #include "nsDataHashtable.h"
michael@0 16 #include "nsInterfaceHashtable.h"
michael@0 17 #include "nsRefPtrHashtable.h"
michael@0 18 #include "nsTArray.h"
michael@0 19 #include "nsTObserverArray.h"
michael@0 20 #include "nsURIHashKey.h"
michael@0 21 #include "mozilla/Attributes.h"
michael@0 22 #include "mozilla/CORSMode.h"
michael@0 23 #include "mozilla/MemoryReporting.h"
michael@0 24
michael@0 25 class nsIAtom;
michael@0 26 class nsICSSLoaderObserver;
michael@0 27 class nsCSSStyleSheet;
michael@0 28 class nsIContent;
michael@0 29 class nsIDocument;
michael@0 30 class nsCSSParser;
michael@0 31 class nsMediaList;
michael@0 32 class nsIStyleSheetLinkingElement;
michael@0 33 class nsCycleCollectionTraversalCallback;
michael@0 34
michael@0 35 namespace mozilla {
michael@0 36 namespace dom {
michael@0 37 class Element;
michael@0 38 }
michael@0 39 }
michael@0 40
michael@0 41 namespace mozilla {
michael@0 42
michael@0 43 class URIPrincipalAndCORSModeHashKey : public nsURIHashKey
michael@0 44 {
michael@0 45 public:
michael@0 46 typedef URIPrincipalAndCORSModeHashKey* KeyType;
michael@0 47 typedef const URIPrincipalAndCORSModeHashKey* KeyTypePointer;
michael@0 48
michael@0 49 URIPrincipalAndCORSModeHashKey(const URIPrincipalAndCORSModeHashKey* aKey)
michael@0 50 : nsURIHashKey(aKey->mKey), mPrincipal(aKey->mPrincipal),
michael@0 51 mCORSMode(aKey->mCORSMode)
michael@0 52 {
michael@0 53 MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey);
michael@0 54 }
michael@0 55 URIPrincipalAndCORSModeHashKey(nsIURI* aURI, nsIPrincipal* aPrincipal,
michael@0 56 CORSMode aCORSMode)
michael@0 57 : nsURIHashKey(aURI), mPrincipal(aPrincipal), mCORSMode(aCORSMode)
michael@0 58 {
michael@0 59 MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey);
michael@0 60 }
michael@0 61 URIPrincipalAndCORSModeHashKey(const URIPrincipalAndCORSModeHashKey& toCopy)
michael@0 62 : nsURIHashKey(toCopy), mPrincipal(toCopy.mPrincipal),
michael@0 63 mCORSMode(toCopy.mCORSMode)
michael@0 64 {
michael@0 65 MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey);
michael@0 66 }
michael@0 67 ~URIPrincipalAndCORSModeHashKey()
michael@0 68 {
michael@0 69 MOZ_COUNT_DTOR(URIPrincipalAndCORSModeHashKey);
michael@0 70 }
michael@0 71
michael@0 72 URIPrincipalAndCORSModeHashKey* GetKey() const {
michael@0 73 return const_cast<URIPrincipalAndCORSModeHashKey*>(this);
michael@0 74 }
michael@0 75 const URIPrincipalAndCORSModeHashKey* GetKeyPointer() const { return this; }
michael@0 76
michael@0 77 bool KeyEquals(const URIPrincipalAndCORSModeHashKey* aKey) const {
michael@0 78 if (!nsURIHashKey::KeyEquals(aKey->mKey)) {
michael@0 79 return false;
michael@0 80 }
michael@0 81
michael@0 82 if (!mPrincipal != !aKey->mPrincipal) {
michael@0 83 // One or the other has a principal, but not both... not equal
michael@0 84 return false;
michael@0 85 }
michael@0 86
michael@0 87 if (mCORSMode != aKey->mCORSMode) {
michael@0 88 // Different CORS modes; we don't match
michael@0 89 return false;
michael@0 90 }
michael@0 91
michael@0 92 bool eq;
michael@0 93 return !mPrincipal ||
michael@0 94 (NS_SUCCEEDED(mPrincipal->Equals(aKey->mPrincipal, &eq)) && eq);
michael@0 95 }
michael@0 96
michael@0 97 static const URIPrincipalAndCORSModeHashKey*
michael@0 98 KeyToPointer(URIPrincipalAndCORSModeHashKey* aKey) { return aKey; }
michael@0 99 static PLDHashNumber HashKey(const URIPrincipalAndCORSModeHashKey* aKey) {
michael@0 100 return nsURIHashKey::HashKey(aKey->mKey);
michael@0 101 }
michael@0 102
michael@0 103 nsIURI* GetURI() const { return nsURIHashKey::GetKey(); }
michael@0 104
michael@0 105 enum { ALLOW_MEMMOVE = true };
michael@0 106
michael@0 107 protected:
michael@0 108 nsCOMPtr<nsIPrincipal> mPrincipal;
michael@0 109 CORSMode mCORSMode;
michael@0 110 };
michael@0 111
michael@0 112
michael@0 113
michael@0 114 namespace css {
michael@0 115
michael@0 116 class SheetLoadData;
michael@0 117 class ImportRule;
michael@0 118
michael@0 119 /***********************************************************************
michael@0 120 * Enum that describes the state of the sheet returned by CreateSheet. *
michael@0 121 ***********************************************************************/
michael@0 122 enum StyleSheetState {
michael@0 123 eSheetStateUnknown = 0,
michael@0 124 eSheetNeedsParser,
michael@0 125 eSheetPending,
michael@0 126 eSheetLoading,
michael@0 127 eSheetComplete
michael@0 128 };
michael@0 129
michael@0 130 class Loader MOZ_FINAL {
michael@0 131 public:
michael@0 132 Loader();
michael@0 133 Loader(nsIDocument*);
michael@0 134
michael@0 135 private:
michael@0 136 // Private destructor, to discourage deletion outside of Release():
michael@0 137 ~Loader();
michael@0 138
michael@0 139 public:
michael@0 140 NS_INLINE_DECL_REFCOUNTING(Loader)
michael@0 141
michael@0 142 void DropDocumentReference(); // notification that doc is going away
michael@0 143
michael@0 144 void SetCompatibilityMode(nsCompatibility aCompatMode)
michael@0 145 { mCompatMode = aCompatMode; }
michael@0 146 nsCompatibility GetCompatibilityMode() { return mCompatMode; }
michael@0 147 nsresult SetPreferredSheet(const nsAString& aTitle);
michael@0 148
michael@0 149 // XXXbz sort out what the deal is with events! When should they fire?
michael@0 150
michael@0 151 /**
michael@0 152 * Load an inline style sheet. If a successful result is returned and
michael@0 153 * *aCompleted is false, then aObserver is guaranteed to be notified
michael@0 154 * asynchronously once the sheet is marked complete. If an error is
michael@0 155 * returned, or if *aCompleted is true, aObserver will not be notified. In
michael@0 156 * addition to parsing the sheet, this method will insert it into the
michael@0 157 * stylesheet list of this CSSLoader's document.
michael@0 158 *
michael@0 159 * @param aElement the element linking to the stylesheet. This must not be
michael@0 160 * null and must implement nsIStyleSheetLinkingElement.
michael@0 161 * @param aBuffer the stylesheet data
michael@0 162 * @param aLineNumber the line number at which the stylesheet data started.
michael@0 163 * @param aTitle the title of the sheet.
michael@0 164 * @param aMedia the media string for the sheet.
michael@0 165 * @param aObserver the observer to notify when the load completes.
michael@0 166 * May be null.
michael@0 167 * @param [out] aCompleted whether parsing of the sheet completed.
michael@0 168 * @param [out] aIsAlternate whether the stylesheet ended up being an
michael@0 169 * alternate sheet.
michael@0 170 */
michael@0 171 nsresult LoadInlineStyle(nsIContent* aElement,
michael@0 172 const nsAString& aBuffer,
michael@0 173 uint32_t aLineNumber,
michael@0 174 const nsAString& aTitle,
michael@0 175 const nsAString& aMedia,
michael@0 176 mozilla::dom::Element* aScopeElement,
michael@0 177 nsICSSLoaderObserver* aObserver,
michael@0 178 bool* aCompleted,
michael@0 179 bool* aIsAlternate);
michael@0 180
michael@0 181 /**
michael@0 182 * Load a linked (document) stylesheet. If a successful result is returned,
michael@0 183 * aObserver is guaranteed to be notified asynchronously once the sheet is
michael@0 184 * loaded and marked complete. If an error is returned, aObserver will not
michael@0 185 * be notified. In addition to loading the sheet, this method will insert it
michael@0 186 * into the stylesheet list of this CSSLoader's document.
michael@0 187 *
michael@0 188 * @param aElement the element linking to the the stylesheet. May be null.
michael@0 189 * @param aURL the URL of the sheet.
michael@0 190 * @param aTitle the title of the sheet.
michael@0 191 * @param aMedia the media string for the sheet.
michael@0 192 * @param aHasAlternateRel whether the rel for this link included
michael@0 193 * "alternate".
michael@0 194 * @param aCORSMode the CORS mode for this load.
michael@0 195 * @param aObserver the observer to notify when the load completes.
michael@0 196 * May be null.
michael@0 197 * @param [out] aIsAlternate whether the stylesheet actually ended up beinga
michael@0 198 * an alternate sheet. Note that this need not match
michael@0 199 * aHasAlternateRel.
michael@0 200 */
michael@0 201 nsresult LoadStyleLink(nsIContent* aElement,
michael@0 202 nsIURI* aURL,
michael@0 203 const nsAString& aTitle,
michael@0 204 const nsAString& aMedia,
michael@0 205 bool aHasAlternateRel,
michael@0 206 CORSMode aCORSMode,
michael@0 207 nsICSSLoaderObserver* aObserver,
michael@0 208 bool* aIsAlternate);
michael@0 209
michael@0 210 /**
michael@0 211 * Load a child (@import-ed) style sheet. In addition to loading the sheet,
michael@0 212 * this method will insert it into the child sheet list of aParentSheet. If
michael@0 213 * there is no sheet currently being parsed and the child sheet is not
michael@0 214 * complete when this method returns, then when the child sheet becomes
michael@0 215 * complete aParentSheet will be QIed to nsICSSLoaderObserver and
michael@0 216 * asynchronously notified, just like for LoadStyleLink. Note that if the
michael@0 217 * child sheet is already complete when this method returns, no
michael@0 218 * nsICSSLoaderObserver notification will be sent.
michael@0 219 *
michael@0 220 * @param aParentSheet the parent of this child sheet
michael@0 221 * @param aURL the URL of the child sheet
michael@0 222 * @param aMedia the already-parsed media list for the child sheet
michael@0 223 * @param aRule the @import rule importing this child. This is used to
michael@0 224 * properly order the child sheet list of aParentSheet.
michael@0 225 */
michael@0 226 nsresult LoadChildSheet(nsCSSStyleSheet* aParentSheet,
michael@0 227 nsIURI* aURL,
michael@0 228 nsMediaList* aMedia,
michael@0 229 ImportRule* aRule);
michael@0 230
michael@0 231 /**
michael@0 232 * Synchronously load and return the stylesheet at aURL. Any child sheets
michael@0 233 * will also be loaded synchronously. Note that synchronous loads over some
michael@0 234 * protocols may involve spinning up a new event loop, so use of this method
michael@0 235 * does NOT guarantee not receiving any events before the sheet loads. This
michael@0 236 * method can be used to load sheets not associated with a document.
michael@0 237 *
michael@0 238 * @param aURL the URL of the sheet to load
michael@0 239 * @param aEnableUnsafeRules whether unsafe rules are enabled for this
michael@0 240 * sheet load
michael@0 241 * Unsafe rules are rules that can violate key Gecko invariants if misused.
michael@0 242 * In particular, most anonymous box pseudoelements must be very carefully
michael@0 243 * styled or we will have severe problems. Therefore unsafe rules should
michael@0 244 * never be enabled for stylesheets controlled by untrusted sites; preferably
michael@0 245 * unsafe rules should only be enabled for agent sheets.
michael@0 246 * @param aUseSystemPrincipal if true, give the resulting sheet the system
michael@0 247 * principal no matter where it's being loaded from.
michael@0 248 * @param [out] aSheet the loaded, complete sheet.
michael@0 249 *
michael@0 250 * NOTE: At the moment, this method assumes the sheet will be UTF-8, but
michael@0 251 * ideally it would allow arbitrary encodings. Callers should NOT depend on
michael@0 252 * non-UTF8 sheets being treated as UTF-8 by this method.
michael@0 253 *
michael@0 254 * NOTE: A successful return from this method doesn't indicate anything about
michael@0 255 * whether the data could be parsed as CSS and doesn't indicate anything
michael@0 256 * about the status of child sheets of the returned sheet.
michael@0 257 */
michael@0 258 nsresult LoadSheetSync(nsIURI* aURL, bool aEnableUnsafeRules,
michael@0 259 bool aUseSystemPrincipal,
michael@0 260 nsCSSStyleSheet** aSheet);
michael@0 261
michael@0 262 /**
michael@0 263 * As above, but aUseSystemPrincipal and aEnableUnsafeRules are assumed false.
michael@0 264 */
michael@0 265 nsresult LoadSheetSync(nsIURI* aURL, nsCSSStyleSheet** aSheet) {
michael@0 266 return LoadSheetSync(aURL, false, false, aSheet);
michael@0 267 }
michael@0 268
michael@0 269 /**
michael@0 270 * Asynchronously load the stylesheet at aURL. If a successful result is
michael@0 271 * returned, aObserver is guaranteed to be notified asynchronously once the
michael@0 272 * sheet is loaded and marked complete. This method can be used to load
michael@0 273 * sheets not associated with a document.
michael@0 274 *
michael@0 275 * @param aURL the URL of the sheet to load
michael@0 276 * @param aOriginPrincipal the principal to use for security checks. This
michael@0 277 * can be null to indicate that these checks should
michael@0 278 * be skipped.
michael@0 279 * @param aCharset the encoding to use for converting the sheet data
michael@0 280 * from bytes to Unicode. May be empty to indicate that the
michael@0 281 * charset of the CSSLoader's document should be used. This
michael@0 282 * is only used if neither the network transport nor the
michael@0 283 * sheet itself indicate an encoding.
michael@0 284 * @param aObserver the observer to notify when the load completes.
michael@0 285 * Must not be null.
michael@0 286 * @param [out] aSheet the sheet to load. Note that the sheet may well
michael@0 287 * not be loaded by the time this method returns.
michael@0 288 */
michael@0 289 nsresult LoadSheet(nsIURI* aURL,
michael@0 290 nsIPrincipal* aOriginPrincipal,
michael@0 291 const nsCString& aCharset,
michael@0 292 nsICSSLoaderObserver* aObserver,
michael@0 293 nsCSSStyleSheet** aSheet);
michael@0 294
michael@0 295 /**
michael@0 296 * Same as above, to be used when the caller doesn't care about the
michael@0 297 * not-yet-loaded sheet.
michael@0 298 */
michael@0 299 nsresult LoadSheet(nsIURI* aURL,
michael@0 300 nsIPrincipal* aOriginPrincipal,
michael@0 301 const nsCString& aCharset,
michael@0 302 nsICSSLoaderObserver* aObserver,
michael@0 303 CORSMode aCORSMode = CORS_NONE);
michael@0 304
michael@0 305 /**
michael@0 306 * Stop loading all sheets. All nsICSSLoaderObservers involved will be
michael@0 307 * notified with NS_BINDING_ABORTED as the status, possibly synchronously.
michael@0 308 */
michael@0 309 nsresult Stop(void);
michael@0 310
michael@0 311 /**
michael@0 312 * nsresult Loader::StopLoadingSheet(nsIURI* aURL), which notifies the
michael@0 313 * nsICSSLoaderObserver with NS_BINDING_ABORTED, was removed in Bug 556446.
michael@0 314 * It can be found in revision 2c44a32052ad.
michael@0 315 */
michael@0 316
michael@0 317 /**
michael@0 318 * Whether the loader is enabled or not.
michael@0 319 * When disabled, processing of new styles is disabled and an attempt
michael@0 320 * to do so will fail with a return code of
michael@0 321 * NS_ERROR_NOT_AVAILABLE. Note that this DOES NOT disable
michael@0 322 * currently loading styles or already processed styles.
michael@0 323 */
michael@0 324 bool GetEnabled() { return mEnabled; }
michael@0 325 void SetEnabled(bool aEnabled) { mEnabled = aEnabled; }
michael@0 326
michael@0 327 /**
michael@0 328 * Get the document we live for. May return null.
michael@0 329 */
michael@0 330 nsIDocument* GetDocument() const { return mDocument; }
michael@0 331
michael@0 332 /**
michael@0 333 * Return true if this loader has pending loads (ones that would send
michael@0 334 * notifications to an nsICSSLoaderObserver attached to this loader).
michael@0 335 * If called from inside nsICSSLoaderObserver::StyleSheetLoaded, this will
michael@0 336 * return false if and only if that is the last StyleSheetLoaded
michael@0 337 * notification the CSSLoader knows it's going to send. In other words, if
michael@0 338 * two sheets load at once (via load coalescing, e.g.), HasPendingLoads()
michael@0 339 * will return true during notification for the first one, and false
michael@0 340 * during notification for the second one.
michael@0 341 */
michael@0 342 bool HasPendingLoads();
michael@0 343
michael@0 344 /**
michael@0 345 * Add an observer to this loader. The observer will be notified
michael@0 346 * for all loads that would have notified their own observers (even
michael@0 347 * if those loads don't have observers attached to them).
michael@0 348 * Load-specific observers will be notified before generic
michael@0 349 * observers. The loader holds a reference to the observer.
michael@0 350 *
michael@0 351 * aObserver must not be null.
michael@0 352 */
michael@0 353 nsresult AddObserver(nsICSSLoaderObserver* aObserver);
michael@0 354
michael@0 355 /**
michael@0 356 * Remove an observer added via AddObserver.
michael@0 357 */
michael@0 358 void RemoveObserver(nsICSSLoaderObserver* aObserver);
michael@0 359
michael@0 360 // These interfaces are public only for the benefit of static functions
michael@0 361 // within nsCSSLoader.cpp.
michael@0 362
michael@0 363 // IsAlternate can change our currently selected style set if none
michael@0 364 // is selected and aHasAlternateRel is false.
michael@0 365 bool IsAlternate(const nsAString& aTitle, bool aHasAlternateRel);
michael@0 366
michael@0 367 typedef nsTArray<nsRefPtr<SheetLoadData> > LoadDataArray;
michael@0 368
michael@0 369 // Traverse the cached stylesheets we're holding on to. This should
michael@0 370 // only be called from the document that owns this loader.
michael@0 371 void TraverseCachedSheets(nsCycleCollectionTraversalCallback& cb);
michael@0 372
michael@0 373 // Unlink the cached stylesheets we're holding on to. Again, this
michael@0 374 // should only be called from the document that owns this loader.
michael@0 375 void UnlinkCachedSheets();
michael@0 376
michael@0 377 // Measure our size.
michael@0 378 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
michael@0 379
michael@0 380 // Marks all the sheets at the given URI obsolete, and removes them from the
michael@0 381 // cache.
michael@0 382 nsresult ObsoleteSheet(nsIURI* aURI);
michael@0 383
michael@0 384 private:
michael@0 385 friend class SheetLoadData;
michael@0 386
michael@0 387 static PLDHashOperator
michael@0 388 RemoveEntriesWithURI(URIPrincipalAndCORSModeHashKey* aKey,
michael@0 389 nsRefPtr<nsCSSStyleSheet> &aSheet,
michael@0 390 void* aUserData);
michael@0 391
michael@0 392 // Note: null aSourcePrincipal indicates that the content policy and
michael@0 393 // CheckLoadURI checks should be skipped.
michael@0 394 nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
michael@0 395 nsIURI* aTargetURI,
michael@0 396 nsISupports* aContext);
michael@0 397
michael@0 398
michael@0 399 // For inline style, the aURI param is null, but the aLinkingContent
michael@0 400 // must be non-null then. The loader principal must never be null
michael@0 401 // if aURI is not null.
michael@0 402 // *aIsAlternate is set based on aTitle and aHasAlternateRel.
michael@0 403 nsresult CreateSheet(nsIURI* aURI,
michael@0 404 nsIContent* aLinkingContent,
michael@0 405 nsIPrincipal* aLoaderPrincipal,
michael@0 406 CORSMode aCORSMode,
michael@0 407 bool aSyncLoad,
michael@0 408 bool aHasAlternateRel,
michael@0 409 const nsAString& aTitle,
michael@0 410 StyleSheetState& aSheetState,
michael@0 411 bool *aIsAlternate,
michael@0 412 nsCSSStyleSheet** aSheet);
michael@0 413
michael@0 414 // Pass in either a media string or the nsMediaList from the
michael@0 415 // CSSParser. Don't pass both.
michael@0 416 // This method will set the sheet's enabled state based on isAlternate
michael@0 417 void PrepareSheet(nsCSSStyleSheet* aSheet,
michael@0 418 const nsAString& aTitle,
michael@0 419 const nsAString& aMediaString,
michael@0 420 nsMediaList* aMediaList,
michael@0 421 dom::Element* aScopeElement,
michael@0 422 bool isAlternate);
michael@0 423
michael@0 424 nsresult InsertSheetInDoc(nsCSSStyleSheet* aSheet,
michael@0 425 nsIContent* aLinkingContent,
michael@0 426 nsIDocument* aDocument);
michael@0 427
michael@0 428 nsresult InsertChildSheet(nsCSSStyleSheet* aSheet,
michael@0 429 nsCSSStyleSheet* aParentSheet,
michael@0 430 ImportRule* aParentRule);
michael@0 431
michael@0 432 nsresult InternalLoadNonDocumentSheet(nsIURI* aURL,
michael@0 433 bool aAllowUnsafeRules,
michael@0 434 bool aUseSystemPrincipal,
michael@0 435 nsIPrincipal* aOriginPrincipal,
michael@0 436 const nsCString& aCharset,
michael@0 437 nsCSSStyleSheet** aSheet,
michael@0 438 nsICSSLoaderObserver* aObserver,
michael@0 439 CORSMode aCORSMode = CORS_NONE);
michael@0 440
michael@0 441 // Post a load event for aObserver to be notified about aSheet. The
michael@0 442 // notification will be sent with status NS_OK unless the load event is
michael@0 443 // canceled at some point (in which case it will be sent with
michael@0 444 // NS_BINDING_ABORTED). aWasAlternate indicates the state when the load was
michael@0 445 // initiated, not the state at some later time. aURI should be the URI the
michael@0 446 // sheet was loaded from (may be null for inline sheets). aElement is the
michael@0 447 // owning element for this sheet.
michael@0 448 nsresult PostLoadEvent(nsIURI* aURI,
michael@0 449 nsCSSStyleSheet* aSheet,
michael@0 450 nsICSSLoaderObserver* aObserver,
michael@0 451 bool aWasAlternate,
michael@0 452 nsIStyleSheetLinkingElement* aElement);
michael@0 453
michael@0 454 // Start the loads of all the sheets in mPendingDatas
michael@0 455 void StartAlternateLoads();
michael@0 456
michael@0 457 // Handle an event posted by PostLoadEvent
michael@0 458 void HandleLoadEvent(SheetLoadData* aEvent);
michael@0 459
michael@0 460 // Note: LoadSheet is responsible for releasing aLoadData and setting the
michael@0 461 // sheet to complete on failure.
michael@0 462 nsresult LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState);
michael@0 463
michael@0 464 // Parse the stylesheet in aLoadData. The sheet data comes from aInput.
michael@0 465 // Set aCompleted to true if the parse finished, false otherwise (e.g. if the
michael@0 466 // sheet had an @import). If aCompleted is true when this returns, then
michael@0 467 // ParseSheet also called SheetComplete on aLoadData.
michael@0 468 nsresult ParseSheet(const nsAString& aInput,
michael@0 469 SheetLoadData* aLoadData,
michael@0 470 bool& aCompleted);
michael@0 471
michael@0 472 // The load of the sheet in aLoadData is done, one way or another. Do final
michael@0 473 // cleanup, including releasing aLoadData.
michael@0 474 void SheetComplete(SheetLoadData* aLoadData, nsresult aStatus);
michael@0 475
michael@0 476 // The guts of SheetComplete. This may be called recursively on parent datas
michael@0 477 // or datas that had glommed on to a single load. The array is there so load
michael@0 478 // datas whose observers need to be notified can be added to it.
michael@0 479 void DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus,
michael@0 480 LoadDataArray& aDatasToNotify);
michael@0 481
michael@0 482 struct Sheets {
michael@0 483 nsRefPtrHashtable<URIPrincipalAndCORSModeHashKey, nsCSSStyleSheet>
michael@0 484 mCompleteSheets;
michael@0 485 nsDataHashtable<URIPrincipalAndCORSModeHashKey, SheetLoadData*>
michael@0 486 mLoadingDatas; // weak refs
michael@0 487 nsDataHashtable<URIPrincipalAndCORSModeHashKey, SheetLoadData*>
michael@0 488 mPendingDatas; // weak refs
michael@0 489 };
michael@0 490 nsAutoPtr<Sheets> mSheets;
michael@0 491
michael@0 492 // We're not likely to have many levels of @import... But likely to have
michael@0 493 // some. Allocate some storage, what the hell.
michael@0 494 nsAutoTArray<SheetLoadData*, 8> mParsingDatas;
michael@0 495
michael@0 496 // The array of posted stylesheet loaded events (SheetLoadDatas) we have.
michael@0 497 // Note that these are rare.
michael@0 498 LoadDataArray mPostedEvents;
michael@0 499
michael@0 500 // Our array of "global" observers
michael@0 501 // XXXbz these are strong refs; should we be cycle collecting CSS loaders?
michael@0 502 nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver> > mObservers;
michael@0 503
michael@0 504 // the load data needs access to the document...
michael@0 505 nsIDocument* mDocument; // the document we live for
michael@0 506
michael@0 507
michael@0 508 // Number of datas still waiting to be notified on if we're notifying on a
michael@0 509 // whole bunch at once (e.g. in one of the stop methods). This is used to
michael@0 510 // make sure that HasPendingLoads() won't return false until we're notifying
michael@0 511 // on the last data we're working with.
michael@0 512 uint32_t mDatasToNotifyOn;
michael@0 513
michael@0 514 nsCompatibility mCompatMode;
michael@0 515 nsString mPreferredSheet; // title of preferred sheet
michael@0 516
michael@0 517 bool mEnabled; // is enabled to load new styles
michael@0 518
michael@0 519 #ifdef DEBUG
michael@0 520 bool mSyncCallback;
michael@0 521 #endif
michael@0 522 };
michael@0 523
michael@0 524 } // namespace css
michael@0 525 } // namespace mozilla
michael@0 526
michael@0 527 #endif /* mozilla_css_Loader_h */

mercurial