layout/style/Loader.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/style/Loader.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,527 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/* loading of CSS style sheets using the network APIs */
    1.10 +
    1.11 +#ifndef mozilla_css_Loader_h
    1.12 +#define mozilla_css_Loader_h
    1.13 +
    1.14 +#include "nsIPrincipal.h"
    1.15 +#include "nsAString.h"
    1.16 +#include "nsAutoPtr.h"
    1.17 +#include "nsCompatibility.h"
    1.18 +#include "nsDataHashtable.h"
    1.19 +#include "nsInterfaceHashtable.h"
    1.20 +#include "nsRefPtrHashtable.h"
    1.21 +#include "nsTArray.h"
    1.22 +#include "nsTObserverArray.h"
    1.23 +#include "nsURIHashKey.h"
    1.24 +#include "mozilla/Attributes.h"
    1.25 +#include "mozilla/CORSMode.h"
    1.26 +#include "mozilla/MemoryReporting.h"
    1.27 +
    1.28 +class nsIAtom;
    1.29 +class nsICSSLoaderObserver;
    1.30 +class nsCSSStyleSheet;
    1.31 +class nsIContent;
    1.32 +class nsIDocument;
    1.33 +class nsCSSParser;
    1.34 +class nsMediaList;
    1.35 +class nsIStyleSheetLinkingElement;
    1.36 +class nsCycleCollectionTraversalCallback;
    1.37 +
    1.38 +namespace mozilla {
    1.39 +namespace dom {
    1.40 +class Element;
    1.41 +}
    1.42 +}
    1.43 +
    1.44 +namespace mozilla {
    1.45 +
    1.46 +class URIPrincipalAndCORSModeHashKey : public nsURIHashKey
    1.47 +{
    1.48 +public:
    1.49 +  typedef URIPrincipalAndCORSModeHashKey* KeyType;
    1.50 +  typedef const URIPrincipalAndCORSModeHashKey* KeyTypePointer;
    1.51 +
    1.52 +  URIPrincipalAndCORSModeHashKey(const URIPrincipalAndCORSModeHashKey* aKey)
    1.53 +    : nsURIHashKey(aKey->mKey), mPrincipal(aKey->mPrincipal),
    1.54 +      mCORSMode(aKey->mCORSMode)
    1.55 +  {
    1.56 +    MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey);
    1.57 +  }
    1.58 +  URIPrincipalAndCORSModeHashKey(nsIURI* aURI, nsIPrincipal* aPrincipal,
    1.59 +                                 CORSMode aCORSMode)
    1.60 +    : nsURIHashKey(aURI), mPrincipal(aPrincipal), mCORSMode(aCORSMode)
    1.61 +  {
    1.62 +    MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey);
    1.63 +  }
    1.64 +  URIPrincipalAndCORSModeHashKey(const URIPrincipalAndCORSModeHashKey& toCopy)
    1.65 +    : nsURIHashKey(toCopy), mPrincipal(toCopy.mPrincipal),
    1.66 +      mCORSMode(toCopy.mCORSMode)
    1.67 +  {
    1.68 +    MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey);
    1.69 +  }
    1.70 +  ~URIPrincipalAndCORSModeHashKey()
    1.71 +  {
    1.72 +    MOZ_COUNT_DTOR(URIPrincipalAndCORSModeHashKey);
    1.73 +  }
    1.74 +
    1.75 +  URIPrincipalAndCORSModeHashKey* GetKey() const {
    1.76 +    return const_cast<URIPrincipalAndCORSModeHashKey*>(this);
    1.77 +  }
    1.78 +  const URIPrincipalAndCORSModeHashKey* GetKeyPointer() const { return this; }
    1.79 +
    1.80 +  bool KeyEquals(const URIPrincipalAndCORSModeHashKey* aKey) const {
    1.81 +    if (!nsURIHashKey::KeyEquals(aKey->mKey)) {
    1.82 +      return false;
    1.83 +    }
    1.84 +
    1.85 +    if (!mPrincipal != !aKey->mPrincipal) {
    1.86 +      // One or the other has a principal, but not both... not equal
    1.87 +      return false;
    1.88 +    }
    1.89 +
    1.90 +    if (mCORSMode != aKey->mCORSMode) {
    1.91 +      // Different CORS modes; we don't match
    1.92 +      return false;
    1.93 +    }
    1.94 +
    1.95 +    bool eq;
    1.96 +    return !mPrincipal ||
    1.97 +      (NS_SUCCEEDED(mPrincipal->Equals(aKey->mPrincipal, &eq)) && eq);
    1.98 +  }
    1.99 +
   1.100 +  static const URIPrincipalAndCORSModeHashKey*
   1.101 +  KeyToPointer(URIPrincipalAndCORSModeHashKey* aKey) { return aKey; }
   1.102 +  static PLDHashNumber HashKey(const URIPrincipalAndCORSModeHashKey* aKey) {
   1.103 +    return nsURIHashKey::HashKey(aKey->mKey);
   1.104 +  }
   1.105 +
   1.106 +  nsIURI* GetURI() const { return nsURIHashKey::GetKey(); }
   1.107 +
   1.108 +  enum { ALLOW_MEMMOVE = true };
   1.109 +
   1.110 +protected:
   1.111 +  nsCOMPtr<nsIPrincipal> mPrincipal;
   1.112 +  CORSMode mCORSMode;
   1.113 +};
   1.114 +
   1.115 +
   1.116 +
   1.117 +namespace css {
   1.118 +
   1.119 +class SheetLoadData;
   1.120 +class ImportRule;
   1.121 +
   1.122 +/***********************************************************************
   1.123 + * Enum that describes the state of the sheet returned by CreateSheet. *
   1.124 + ***********************************************************************/
   1.125 +enum StyleSheetState {
   1.126 +  eSheetStateUnknown = 0,
   1.127 +  eSheetNeedsParser,
   1.128 +  eSheetPending,
   1.129 +  eSheetLoading,
   1.130 +  eSheetComplete
   1.131 +};
   1.132 +
   1.133 +class Loader MOZ_FINAL {
   1.134 +public:
   1.135 +  Loader();
   1.136 +  Loader(nsIDocument*);
   1.137 +
   1.138 + private:
   1.139 +  // Private destructor, to discourage deletion outside of Release():
   1.140 +  ~Loader();
   1.141 +
   1.142 + public:
   1.143 +  NS_INLINE_DECL_REFCOUNTING(Loader)
   1.144 +
   1.145 +  void DropDocumentReference(); // notification that doc is going away
   1.146 +
   1.147 +  void SetCompatibilityMode(nsCompatibility aCompatMode)
   1.148 +  { mCompatMode = aCompatMode; }
   1.149 +  nsCompatibility GetCompatibilityMode() { return mCompatMode; }
   1.150 +  nsresult SetPreferredSheet(const nsAString& aTitle);
   1.151 +
   1.152 +  // XXXbz sort out what the deal is with events!  When should they fire?
   1.153 +
   1.154 +  /**
   1.155 +   * Load an inline style sheet.  If a successful result is returned and
   1.156 +   * *aCompleted is false, then aObserver is guaranteed to be notified
   1.157 +   * asynchronously once the sheet is marked complete.  If an error is
   1.158 +   * returned, or if *aCompleted is true, aObserver will not be notified.  In
   1.159 +   * addition to parsing the sheet, this method will insert it into the
   1.160 +   * stylesheet list of this CSSLoader's document.
   1.161 +   *
   1.162 +   * @param aElement the element linking to the stylesheet.  This must not be
   1.163 +   *                 null and must implement nsIStyleSheetLinkingElement.
   1.164 +   * @param aBuffer the stylesheet data
   1.165 +   * @param aLineNumber the line number at which the stylesheet data started.
   1.166 +   * @param aTitle the title of the sheet.
   1.167 +   * @param aMedia the media string for the sheet.
   1.168 +   * @param aObserver the observer to notify when the load completes.
   1.169 +   *        May be null.
   1.170 +   * @param [out] aCompleted whether parsing of the sheet completed.
   1.171 +   * @param [out] aIsAlternate whether the stylesheet ended up being an
   1.172 +   *        alternate sheet.
   1.173 +   */
   1.174 +  nsresult LoadInlineStyle(nsIContent* aElement,
   1.175 +                           const nsAString& aBuffer,
   1.176 +                           uint32_t aLineNumber,
   1.177 +                           const nsAString& aTitle,
   1.178 +                           const nsAString& aMedia,
   1.179 +                           mozilla::dom::Element* aScopeElement,
   1.180 +                           nsICSSLoaderObserver* aObserver,
   1.181 +                           bool* aCompleted,
   1.182 +                           bool* aIsAlternate);
   1.183 +
   1.184 +  /**
   1.185 +   * Load a linked (document) stylesheet.  If a successful result is returned,
   1.186 +   * aObserver is guaranteed to be notified asynchronously once the sheet is
   1.187 +   * loaded and marked complete.  If an error is returned, aObserver will not
   1.188 +   * be notified.  In addition to loading the sheet, this method will insert it
   1.189 +   * into the stylesheet list of this CSSLoader's document.
   1.190 +   *
   1.191 +   * @param aElement the element linking to the the stylesheet.  May be null.
   1.192 +   * @param aURL the URL of the sheet.
   1.193 +   * @param aTitle the title of the sheet.
   1.194 +   * @param aMedia the media string for the sheet.
   1.195 +   * @param aHasAlternateRel whether the rel for this link included
   1.196 +   *        "alternate".
   1.197 +   * @param aCORSMode the CORS mode for this load.
   1.198 +   * @param aObserver the observer to notify when the load completes.
   1.199 +   *                  May be null.
   1.200 +   * @param [out] aIsAlternate whether the stylesheet actually ended up beinga
   1.201 +   *        an alternate sheet.  Note that this need not match
   1.202 +   *        aHasAlternateRel.
   1.203 +   */
   1.204 +  nsresult LoadStyleLink(nsIContent* aElement,
   1.205 +                         nsIURI* aURL,
   1.206 +                         const nsAString& aTitle,
   1.207 +                         const nsAString& aMedia,
   1.208 +                         bool aHasAlternateRel,
   1.209 +                         CORSMode aCORSMode,
   1.210 +                         nsICSSLoaderObserver* aObserver,
   1.211 +                         bool* aIsAlternate);
   1.212 +
   1.213 +  /**
   1.214 +   * Load a child (@import-ed) style sheet.  In addition to loading the sheet,
   1.215 +   * this method will insert it into the child sheet list of aParentSheet.  If
   1.216 +   * there is no sheet currently being parsed and the child sheet is not
   1.217 +   * complete when this method returns, then when the child sheet becomes
   1.218 +   * complete aParentSheet will be QIed to nsICSSLoaderObserver and
   1.219 +   * asynchronously notified, just like for LoadStyleLink.  Note that if the
   1.220 +   * child sheet is already complete when this method returns, no
   1.221 +   * nsICSSLoaderObserver notification will be sent.
   1.222 +   *
   1.223 +   * @param aParentSheet the parent of this child sheet
   1.224 +   * @param aURL the URL of the child sheet
   1.225 +   * @param aMedia the already-parsed media list for the child sheet
   1.226 +   * @param aRule the @import rule importing this child.  This is used to
   1.227 +   *              properly order the child sheet list of aParentSheet.
   1.228 +   */
   1.229 +  nsresult LoadChildSheet(nsCSSStyleSheet* aParentSheet,
   1.230 +                          nsIURI* aURL,
   1.231 +                          nsMediaList* aMedia,
   1.232 +                          ImportRule* aRule);
   1.233 +
   1.234 +  /**
   1.235 +   * Synchronously load and return the stylesheet at aURL.  Any child sheets
   1.236 +   * will also be loaded synchronously.  Note that synchronous loads over some
   1.237 +   * protocols may involve spinning up a new event loop, so use of this method
   1.238 +   * does NOT guarantee not receiving any events before the sheet loads.  This
   1.239 +   * method can be used to load sheets not associated with a document.
   1.240 +   *
   1.241 +   * @param aURL the URL of the sheet to load
   1.242 +   * @param aEnableUnsafeRules whether unsafe rules are enabled for this
   1.243 +   * sheet load
   1.244 +   * Unsafe rules are rules that can violate key Gecko invariants if misused.
   1.245 +   * In particular, most anonymous box pseudoelements must be very carefully
   1.246 +   * styled or we will have severe problems. Therefore unsafe rules should
   1.247 +   * never be enabled for stylesheets controlled by untrusted sites; preferably
   1.248 +   * unsafe rules should only be enabled for agent sheets.
   1.249 +   * @param aUseSystemPrincipal if true, give the resulting sheet the system
   1.250 +   * principal no matter where it's being loaded from.
   1.251 +   * @param [out] aSheet the loaded, complete sheet.
   1.252 +   *
   1.253 +   * NOTE: At the moment, this method assumes the sheet will be UTF-8, but
   1.254 +   * ideally it would allow arbitrary encodings.  Callers should NOT depend on
   1.255 +   * non-UTF8 sheets being treated as UTF-8 by this method.
   1.256 +   *
   1.257 +   * NOTE: A successful return from this method doesn't indicate anything about
   1.258 +   * whether the data could be parsed as CSS and doesn't indicate anything
   1.259 +   * about the status of child sheets of the returned sheet.
   1.260 +   */
   1.261 +  nsresult LoadSheetSync(nsIURI* aURL, bool aEnableUnsafeRules,
   1.262 +                         bool aUseSystemPrincipal,
   1.263 +                         nsCSSStyleSheet** aSheet);
   1.264 +
   1.265 +  /**
   1.266 +   * As above, but aUseSystemPrincipal and aEnableUnsafeRules are assumed false.
   1.267 +   */
   1.268 +  nsresult LoadSheetSync(nsIURI* aURL, nsCSSStyleSheet** aSheet) {
   1.269 +    return LoadSheetSync(aURL, false, false, aSheet);
   1.270 +  }
   1.271 +
   1.272 +  /**
   1.273 +   * Asynchronously load the stylesheet at aURL.  If a successful result is
   1.274 +   * returned, aObserver is guaranteed to be notified asynchronously once the
   1.275 +   * sheet is loaded and marked complete.  This method can be used to load
   1.276 +   * sheets not associated with a document.
   1.277 +   *
   1.278 +   * @param aURL the URL of the sheet to load
   1.279 +   * @param aOriginPrincipal the principal to use for security checks.  This
   1.280 +   *                         can be null to indicate that these checks should
   1.281 +   *                         be skipped.
   1.282 +   * @param aCharset the encoding to use for converting the sheet data
   1.283 +   *        from bytes to Unicode.  May be empty to indicate that the
   1.284 +   *        charset of the CSSLoader's document should be used.  This
   1.285 +   *        is only used if neither the network transport nor the
   1.286 +   *        sheet itself indicate an encoding.
   1.287 +   * @param aObserver the observer to notify when the load completes.
   1.288 +   *                  Must not be null.
   1.289 +   * @param [out] aSheet the sheet to load. Note that the sheet may well
   1.290 +   *              not be loaded by the time this method returns.
   1.291 +   */
   1.292 +  nsresult LoadSheet(nsIURI* aURL,
   1.293 +                     nsIPrincipal* aOriginPrincipal,
   1.294 +                     const nsCString& aCharset,
   1.295 +                     nsICSSLoaderObserver* aObserver,
   1.296 +                     nsCSSStyleSheet** aSheet);
   1.297 +
   1.298 +  /**
   1.299 +   * Same as above, to be used when the caller doesn't care about the
   1.300 +   * not-yet-loaded sheet.
   1.301 +   */
   1.302 +  nsresult LoadSheet(nsIURI* aURL,
   1.303 +                     nsIPrincipal* aOriginPrincipal,
   1.304 +                     const nsCString& aCharset,
   1.305 +                     nsICSSLoaderObserver* aObserver,
   1.306 +                     CORSMode aCORSMode = CORS_NONE);
   1.307 +
   1.308 +  /**
   1.309 +   * Stop loading all sheets.  All nsICSSLoaderObservers involved will be
   1.310 +   * notified with NS_BINDING_ABORTED as the status, possibly synchronously.
   1.311 +   */
   1.312 +  nsresult Stop(void);
   1.313 +
   1.314 +  /**
   1.315 +   * nsresult Loader::StopLoadingSheet(nsIURI* aURL), which notifies the
   1.316 +   * nsICSSLoaderObserver with NS_BINDING_ABORTED, was removed in Bug 556446.
   1.317 +   * It can be found in revision 2c44a32052ad.
   1.318 +   */
   1.319 +
   1.320 +  /**
   1.321 +   * Whether the loader is enabled or not.
   1.322 +   * When disabled, processing of new styles is disabled and an attempt
   1.323 +   * to do so will fail with a return code of
   1.324 +   * NS_ERROR_NOT_AVAILABLE. Note that this DOES NOT disable
   1.325 +   * currently loading styles or already processed styles.
   1.326 +   */
   1.327 +  bool GetEnabled() { return mEnabled; }
   1.328 +  void SetEnabled(bool aEnabled) { mEnabled = aEnabled; }
   1.329 +
   1.330 +  /**
   1.331 +   * Get the document we live for. May return null.
   1.332 +   */
   1.333 +  nsIDocument* GetDocument() const { return mDocument; }
   1.334 +
   1.335 +  /**
   1.336 +   * Return true if this loader has pending loads (ones that would send
   1.337 +   * notifications to an nsICSSLoaderObserver attached to this loader).
   1.338 +   * If called from inside nsICSSLoaderObserver::StyleSheetLoaded, this will
   1.339 +   * return false if and only if that is the last StyleSheetLoaded
   1.340 +   * notification the CSSLoader knows it's going to send.  In other words, if
   1.341 +   * two sheets load at once (via load coalescing, e.g.), HasPendingLoads()
   1.342 +   * will return true during notification for the first one, and false
   1.343 +   * during notification for the second one.
   1.344 +   */
   1.345 +  bool HasPendingLoads();
   1.346 +
   1.347 +  /**
   1.348 +   * Add an observer to this loader.  The observer will be notified
   1.349 +   * for all loads that would have notified their own observers (even
   1.350 +   * if those loads don't have observers attached to them).
   1.351 +   * Load-specific observers will be notified before generic
   1.352 +   * observers.  The loader holds a reference to the observer.
   1.353 +   *
   1.354 +   * aObserver must not be null.
   1.355 +   */
   1.356 +  nsresult AddObserver(nsICSSLoaderObserver* aObserver);
   1.357 +
   1.358 +  /**
   1.359 +   * Remove an observer added via AddObserver.
   1.360 +   */
   1.361 +  void RemoveObserver(nsICSSLoaderObserver* aObserver);
   1.362 +
   1.363 +  // These interfaces are public only for the benefit of static functions
   1.364 +  // within nsCSSLoader.cpp.
   1.365 +
   1.366 +  // IsAlternate can change our currently selected style set if none
   1.367 +  // is selected and aHasAlternateRel is false.
   1.368 +  bool IsAlternate(const nsAString& aTitle, bool aHasAlternateRel);
   1.369 +
   1.370 +  typedef nsTArray<nsRefPtr<SheetLoadData> > LoadDataArray;
   1.371 +
   1.372 +  // Traverse the cached stylesheets we're holding on to.  This should
   1.373 +  // only be called from the document that owns this loader.
   1.374 +  void TraverseCachedSheets(nsCycleCollectionTraversalCallback& cb);
   1.375 +
   1.376 +  // Unlink the cached stylesheets we're holding on to.  Again, this
   1.377 +  // should only be called from the document that owns this loader.
   1.378 +  void UnlinkCachedSheets();
   1.379 +
   1.380 +  // Measure our size.
   1.381 +  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   1.382 +
   1.383 +  // Marks all the sheets at the given URI obsolete, and removes them from the
   1.384 +  // cache.
   1.385 +  nsresult ObsoleteSheet(nsIURI* aURI);
   1.386 +
   1.387 +private:
   1.388 +  friend class SheetLoadData;
   1.389 +
   1.390 +  static PLDHashOperator
   1.391 +  RemoveEntriesWithURI(URIPrincipalAndCORSModeHashKey* aKey,
   1.392 +                       nsRefPtr<nsCSSStyleSheet> &aSheet,
   1.393 +                       void* aUserData);
   1.394 +
   1.395 +  // Note: null aSourcePrincipal indicates that the content policy and
   1.396 +  // CheckLoadURI checks should be skipped.
   1.397 +  nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
   1.398 +                            nsIURI* aTargetURI,
   1.399 +                            nsISupports* aContext);
   1.400 +
   1.401 +
   1.402 +  // For inline style, the aURI param is null, but the aLinkingContent
   1.403 +  // must be non-null then.  The loader principal must never be null
   1.404 +  // if aURI is not null.
   1.405 +  // *aIsAlternate is set based on aTitle and aHasAlternateRel.
   1.406 +  nsresult CreateSheet(nsIURI* aURI,
   1.407 +                       nsIContent* aLinkingContent,
   1.408 +                       nsIPrincipal* aLoaderPrincipal,
   1.409 +                       CORSMode aCORSMode,
   1.410 +                       bool aSyncLoad,
   1.411 +                       bool aHasAlternateRel,
   1.412 +                       const nsAString& aTitle,
   1.413 +                       StyleSheetState& aSheetState,
   1.414 +                       bool *aIsAlternate,
   1.415 +                       nsCSSStyleSheet** aSheet);
   1.416 +
   1.417 +  // Pass in either a media string or the nsMediaList from the
   1.418 +  // CSSParser.  Don't pass both.
   1.419 +  // This method will set the sheet's enabled state based on isAlternate
   1.420 +  void PrepareSheet(nsCSSStyleSheet* aSheet,
   1.421 +                    const nsAString& aTitle,
   1.422 +                    const nsAString& aMediaString,
   1.423 +                    nsMediaList* aMediaList,
   1.424 +                    dom::Element* aScopeElement,
   1.425 +                    bool isAlternate);
   1.426 +
   1.427 +  nsresult InsertSheetInDoc(nsCSSStyleSheet* aSheet,
   1.428 +                            nsIContent* aLinkingContent,
   1.429 +                            nsIDocument* aDocument);
   1.430 +
   1.431 +  nsresult InsertChildSheet(nsCSSStyleSheet* aSheet,
   1.432 +                            nsCSSStyleSheet* aParentSheet,
   1.433 +                            ImportRule* aParentRule);
   1.434 +
   1.435 +  nsresult InternalLoadNonDocumentSheet(nsIURI* aURL,
   1.436 +                                        bool aAllowUnsafeRules,
   1.437 +                                        bool aUseSystemPrincipal,
   1.438 +                                        nsIPrincipal* aOriginPrincipal,
   1.439 +                                        const nsCString& aCharset,
   1.440 +                                        nsCSSStyleSheet** aSheet,
   1.441 +                                        nsICSSLoaderObserver* aObserver,
   1.442 +                                        CORSMode aCORSMode = CORS_NONE);
   1.443 +
   1.444 +  // Post a load event for aObserver to be notified about aSheet.  The
   1.445 +  // notification will be sent with status NS_OK unless the load event is
   1.446 +  // canceled at some point (in which case it will be sent with
   1.447 +  // NS_BINDING_ABORTED).  aWasAlternate indicates the state when the load was
   1.448 +  // initiated, not the state at some later time.  aURI should be the URI the
   1.449 +  // sheet was loaded from (may be null for inline sheets).  aElement is the
   1.450 +  // owning element for this sheet.
   1.451 +  nsresult PostLoadEvent(nsIURI* aURI,
   1.452 +                         nsCSSStyleSheet* aSheet,
   1.453 +                         nsICSSLoaderObserver* aObserver,
   1.454 +                         bool aWasAlternate,
   1.455 +                         nsIStyleSheetLinkingElement* aElement);
   1.456 +
   1.457 +  // Start the loads of all the sheets in mPendingDatas
   1.458 +  void StartAlternateLoads();
   1.459 +
   1.460 +  // Handle an event posted by PostLoadEvent
   1.461 +  void HandleLoadEvent(SheetLoadData* aEvent);
   1.462 +
   1.463 +  // Note: LoadSheet is responsible for releasing aLoadData and setting the
   1.464 +  // sheet to complete on failure.
   1.465 +  nsresult LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState);
   1.466 +
   1.467 +  // Parse the stylesheet in aLoadData.  The sheet data comes from aInput.
   1.468 +  // Set aCompleted to true if the parse finished, false otherwise (e.g. if the
   1.469 +  // sheet had an @import).  If aCompleted is true when this returns, then
   1.470 +  // ParseSheet also called SheetComplete on aLoadData.
   1.471 +  nsresult ParseSheet(const nsAString& aInput,
   1.472 +                      SheetLoadData* aLoadData,
   1.473 +                      bool& aCompleted);
   1.474 +
   1.475 +  // The load of the sheet in aLoadData is done, one way or another.  Do final
   1.476 +  // cleanup, including releasing aLoadData.
   1.477 +  void SheetComplete(SheetLoadData* aLoadData, nsresult aStatus);
   1.478 +
   1.479 +  // The guts of SheetComplete.  This may be called recursively on parent datas
   1.480 +  // or datas that had glommed on to a single load.  The array is there so load
   1.481 +  // datas whose observers need to be notified can be added to it.
   1.482 +  void DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus,
   1.483 +                       LoadDataArray& aDatasToNotify);
   1.484 +
   1.485 +  struct Sheets {
   1.486 +    nsRefPtrHashtable<URIPrincipalAndCORSModeHashKey, nsCSSStyleSheet>
   1.487 +                      mCompleteSheets;
   1.488 +    nsDataHashtable<URIPrincipalAndCORSModeHashKey, SheetLoadData*>
   1.489 +                      mLoadingDatas; // weak refs
   1.490 +    nsDataHashtable<URIPrincipalAndCORSModeHashKey, SheetLoadData*>
   1.491 +                      mPendingDatas; // weak refs
   1.492 +  };
   1.493 +  nsAutoPtr<Sheets> mSheets;
   1.494 +
   1.495 +  // We're not likely to have many levels of @import...  But likely to have
   1.496 +  // some.  Allocate some storage, what the hell.
   1.497 +  nsAutoTArray<SheetLoadData*, 8> mParsingDatas;
   1.498 +
   1.499 +  // The array of posted stylesheet loaded events (SheetLoadDatas) we have.
   1.500 +  // Note that these are rare.
   1.501 +  LoadDataArray     mPostedEvents;
   1.502 +
   1.503 +  // Our array of "global" observers
   1.504 +  // XXXbz these are strong refs; should we be cycle collecting CSS loaders?
   1.505 +  nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver> > mObservers;
   1.506 +
   1.507 +  // the load data needs access to the document...
   1.508 +  nsIDocument*      mDocument;  // the document we live for
   1.509 +
   1.510 +
   1.511 +  // Number of datas still waiting to be notified on if we're notifying on a
   1.512 +  // whole bunch at once (e.g. in one of the stop methods).  This is used to
   1.513 +  // make sure that HasPendingLoads() won't return false until we're notifying
   1.514 +  // on the last data we're working with.
   1.515 +  uint32_t          mDatasToNotifyOn;
   1.516 +
   1.517 +  nsCompatibility   mCompatMode;
   1.518 +  nsString          mPreferredSheet;  // title of preferred sheet
   1.519 +
   1.520 +  bool              mEnabled; // is enabled to load new styles
   1.521 +
   1.522 +#ifdef DEBUG
   1.523 +  bool              mSyncCallback;
   1.524 +#endif
   1.525 +};
   1.526 +
   1.527 +} // namespace css
   1.528 +} // namespace mozilla
   1.529 +
   1.530 +#endif /* mozilla_css_Loader_h */

mercurial