Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
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 */ |