tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Loader.h (26265B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /* loading of CSS style sheets using the network APIs */
      8 
      9 #ifndef mozilla_css_Loader_h
     10 #define mozilla_css_Loader_h
     11 
     12 #include <tuple>
     13 #include <utility>
     14 
     15 #include "mozilla/Attributes.h"
     16 #include "mozilla/CORSMode.h"
     17 #include "mozilla/MemoryReporting.h"
     18 #include "mozilla/SharedSubResourceCache.h"
     19 #include "mozilla/css/StylePreloadKind.h"
     20 #include "mozilla/dom/LinkStyle.h"
     21 #include "nsCompatibility.h"
     22 #include "nsCycleCollectionParticipant.h"
     23 #include "nsRefPtrHashtable.h"
     24 #include "nsStringFwd.h"
     25 #include "nsTArray.h"
     26 #include "nsTObserverArray.h"
     27 #include "nsURIHashKey.h"
     28 
     29 class nsICSSLoaderObserver;
     30 class nsIConsoleReportCollector;
     31 class nsIContent;
     32 class nsIPrincipal;
     33 
     34 namespace mozilla {
     35 
     36 class PreloadHashKey;
     37 class SharedStyleSheetCache;
     38 class SheetLoadDataHashKey;
     39 class StyleSheet;
     40 
     41 namespace dom {
     42 class DocGroup;
     43 class Element;
     44 enum class FetchPriority : uint8_t;
     45 }  // namespace dom
     46 
     47 // The load data for a <link> or @import style-sheet.
     48 //
     49 // This must contain all the state that affects CSS parsing.
     50 class SheetLoadDataHashKey : public PLDHashEntryHdr {
     51 public:
     52  using KeyType = const SheetLoadDataHashKey&;
     53  using KeyTypePointer = const SheetLoadDataHashKey*;
     54 
     55  explicit SheetLoadDataHashKey(const SheetLoadDataHashKey* aKey)
     56      : mURI(aKey->mURI),
     57        mLoaderPrincipal(aKey->mLoaderPrincipal),
     58        mPartitionPrincipal(aKey->mPartitionPrincipal),
     59        mEncodingGuess(aKey->mEncodingGuess),
     60        mCORSMode(aKey->mCORSMode),
     61        mParsingMode(aKey->mParsingMode),
     62        mCompatMode(aKey->mCompatMode),
     63        mSRIMetadata(aKey->mSRIMetadata),
     64        mIsLinkRelPreloadOrEarlyHint(aKey->mIsLinkRelPreloadOrEarlyHint) {
     65    MOZ_COUNT_CTOR(SheetLoadDataHashKey);
     66  }
     67 
     68  SheetLoadDataHashKey(nsIURI* aURI, nsIPrincipal* aLoaderPrincipal,
     69                       nsIPrincipal* aPartitionPrincipal,
     70                       NotNull<const Encoding*> aEncodingGuess,
     71                       CORSMode aCORSMode, css::SheetParsingMode aParsingMode,
     72                       nsCompatibility aCompatMode,
     73                       const dom::SRIMetadata& aSRIMetadata,
     74                       css::StylePreloadKind aPreloadKind)
     75      : mURI(aURI),
     76        mLoaderPrincipal(aLoaderPrincipal),
     77        mPartitionPrincipal(aPartitionPrincipal),
     78        mEncodingGuess(aEncodingGuess),
     79        mCORSMode(aCORSMode),
     80        mParsingMode(aParsingMode),
     81        mCompatMode(aCompatMode),
     82        mSRIMetadata(aSRIMetadata),
     83        mIsLinkRelPreloadOrEarlyHint(
     84            css::IsLinkRelPreloadOrEarlyHint(aPreloadKind)) {
     85    MOZ_ASSERT(aURI);
     86    MOZ_ASSERT(aLoaderPrincipal);
     87    MOZ_COUNT_CTOR(SheetLoadDataHashKey);
     88  }
     89 
     90  SheetLoadDataHashKey(SheetLoadDataHashKey&& toMove)
     91      : mURI(std::move(toMove.mURI)),
     92        mLoaderPrincipal(std::move(toMove.mLoaderPrincipal)),
     93        mPartitionPrincipal(std::move(toMove.mPartitionPrincipal)),
     94        mEncodingGuess(std::move(toMove.mEncodingGuess)),
     95        mCORSMode(std::move(toMove.mCORSMode)),
     96        mParsingMode(std::move(toMove.mParsingMode)),
     97        mCompatMode(std::move(toMove.mCompatMode)),
     98        mSRIMetadata(std::move(toMove.mSRIMetadata)),
     99        mIsLinkRelPreloadOrEarlyHint(
    100            std::move(toMove.mIsLinkRelPreloadOrEarlyHint)) {
    101    MOZ_COUNT_CTOR(SheetLoadDataHashKey);
    102  }
    103 
    104  explicit SheetLoadDataHashKey(const css::SheetLoadData&);
    105 
    106  MOZ_COUNTED_DTOR(SheetLoadDataHashKey)
    107 
    108  const SheetLoadDataHashKey& GetKey() const { return *this; }
    109  const SheetLoadDataHashKey* GetKeyPointer() const { return this; }
    110 
    111  bool KeyEquals(const SheetLoadDataHashKey* aKey) const {
    112    return KeyEquals(*aKey);
    113  }
    114 
    115  bool KeyEquals(const SheetLoadDataHashKey&) const;
    116 
    117  static const SheetLoadDataHashKey* KeyToPointer(
    118      const SheetLoadDataHashKey& aKey) {
    119    return &aKey;
    120  }
    121  static PLDHashNumber HashKey(const SheetLoadDataHashKey* aKey) {
    122    return nsURIHashKey::HashKey(aKey->mURI);
    123  }
    124 
    125  nsIURI* URI() const { return mURI; }
    126 
    127  nsIPrincipal* LoaderPrincipal() const { return mLoaderPrincipal; }
    128  nsIPrincipal* PartitionPrincipal() const { return mPartitionPrincipal; }
    129 
    130  css::SheetParsingMode ParsingMode() const { return mParsingMode; }
    131 
    132  enum { ALLOW_MEMMOVE = true };
    133 
    134 protected:
    135  const nsCOMPtr<nsIURI> mURI;
    136  const nsCOMPtr<nsIPrincipal> mLoaderPrincipal;
    137  const nsCOMPtr<nsIPrincipal> mPartitionPrincipal;
    138  // The encoding guess is the encoding the sheet would get if the request
    139  // didn't have any encoding information like @charset or a Content-Encoding
    140  // header.
    141  const NotNull<const Encoding*> mEncodingGuess;
    142  const CORSMode mCORSMode;
    143  const css::SheetParsingMode mParsingMode;
    144  const nsCompatibility mCompatMode;
    145  dom::SRIMetadata mSRIMetadata;
    146  const bool mIsLinkRelPreloadOrEarlyHint;
    147 };
    148 
    149 namespace css {
    150 
    151 class SheetLoadData;
    152 class ImportRule;
    153 
    154 /*********************
    155 * Style sheet reuse *
    156 *********************/
    157 
    158 class MOZ_RAII LoaderReusableStyleSheets {
    159 public:
    160  LoaderReusableStyleSheets() = default;
    161 
    162  /**
    163   * Look for a reusable sheet (see AddReusableSheet) matching the
    164   * given URL.  If found, set aResult, remove the reused sheet from
    165   * the internal list, and return true.  If not found, return false;
    166   * in this case, aResult is not modified.
    167   *
    168   * @param aURL the url to match
    169   * @param aResult [out] the style sheet which can be reused
    170   */
    171  bool FindReusableStyleSheet(nsIURI* aURL, RefPtr<StyleSheet>& aResult);
    172 
    173  /**
    174   * Indicate that a certain style sheet is available for reuse if its
    175   * URI matches the URI of an @import.  Sheets should be added in the
    176   * opposite order in which they are intended to be reused.
    177   *
    178   * @param aSheet the sheet which can be reused
    179   */
    180  void AddReusableSheet(StyleSheet* aSheet) {
    181    mReusableSheets.AppendElement(aSheet);
    182  }
    183 
    184 private:
    185  LoaderReusableStyleSheets(const LoaderReusableStyleSheets&) = delete;
    186  LoaderReusableStyleSheets& operator=(const LoaderReusableStyleSheets&) =
    187      delete;
    188 
    189  // The sheets that can be reused.
    190  nsTArray<RefPtr<StyleSheet>> mReusableSheets;
    191 };
    192 
    193 class Loader final {
    194  using ReferrerPolicy = dom::ReferrerPolicy;
    195 
    196 public:
    197  using Completed = dom::LinkStyle::Completed;
    198  using HasAlternateRel = dom::LinkStyle::HasAlternateRel;
    199  using IsAlternate = dom::LinkStyle::IsAlternate;
    200  using IsInline = dom::LinkStyle::IsInline;
    201  using IsExplicitlyEnabled = dom::LinkStyle::IsExplicitlyEnabled;
    202  using MediaMatched = dom::LinkStyle::MediaMatched;
    203  using LoadSheetResult = dom::LinkStyle::Update;
    204  using SheetInfo = dom::LinkStyle::SheetInfo;
    205 
    206  Loader();
    207  // aDocGroup is used for dispatching SheetLoadData in PostLoadEvent(). It
    208  // can be null if you want to use this constructor, and there's no
    209  // document when the Loader is constructed.
    210  explicit Loader(dom::DocGroup*);
    211  explicit Loader(dom::Document*);
    212 
    213 private:
    214  // Private destructor, to discourage deletion outside of Release():
    215  ~Loader();
    216 
    217 public:
    218  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Loader)
    219  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(Loader)
    220 
    221  void DropDocumentReference();  // notification that doc is going away
    222 
    223  void DeregisterFromSheetCache();
    224  void RegisterInSheetCache();
    225 
    226  void SetCompatibilityMode(nsCompatibility aCompatMode) {
    227    mDocumentCompatMode = aCompatMode;
    228  }
    229 
    230  using StylePreloadKind = css::StylePreloadKind;
    231 
    232  bool HasLoaded(const SheetLoadDataHashKey& aKey) const {
    233    return mLoadsPerformed.Contains(aKey);
    234  }
    235 
    236  void WillStartPendingLoad() {
    237    MOZ_DIAGNOSTIC_ASSERT(mPendingLoadCount, "Where did this load come from?");
    238    mPendingLoadCount--;
    239  }
    240 
    241  nsCompatibility CompatMode(StylePreloadKind aPreloadKind) const {
    242    if (css::ShouldAssumeStandardsMode(aPreloadKind)) {
    243      return eCompatibility_FullStandards;
    244    }
    245    return mDocumentCompatMode;
    246  }
    247 
    248  // TODO(emilio): Is the complexity of this method and carrying the titles
    249  // around worth it? The alternate sheets will load anyhow eventually...
    250  void DocumentStyleSheetSetChanged();
    251 
    252  // XXXbz sort out what the deal is with events!  When should they fire?
    253 
    254  /**
    255   * Load an inline style sheet.  If a successful result is returned and
    256   * result.WillNotify() is true, then aObserver is guaranteed to be notified
    257   * asynchronously once the sheet is marked complete.  If an error is
    258   * returned, or if result.WillNotify() is false, aObserver will not be
    259   * notified.  In addition to parsing the sheet, this method will insert it
    260   * into the stylesheet list of this CSSLoader's document.
    261   * @param aObserver the observer to notify when the load completes.
    262   *        May be null.
    263   * @param aBuffer the stylesheet data
    264   */
    265  Result<LoadSheetResult, nsresult> LoadInlineStyle(
    266      const SheetInfo&, const nsAString& aBuffer,
    267      nsICSSLoaderObserver* aObserver);
    268 
    269  /**
    270   * Load a linked (document) stylesheet.  If a successful result is returned,
    271   * aObserver is guaranteed to be notified asynchronously once the sheet is
    272   * loaded and marked complete, i.e., result.WillNotify() will always return
    273   * true.  If an error is returned, aObserver will not be notified.  In
    274   * addition to loading the sheet, this method will insert it into the
    275   * stylesheet list of this CSSLoader's document.
    276   * @param aObserver the observer to notify when the load completes.
    277   *                  May be null.
    278   */
    279  Result<LoadSheetResult, nsresult> LoadStyleLink(
    280      const SheetInfo&, nsICSSLoaderObserver* aObserver);
    281 
    282  /**
    283   * Load a child (@import-ed) style sheet.  In addition to loading the sheet,
    284   * this method will insert it into the child sheet list of aParentSheet.  If
    285   * there is no sheet currently being parsed and the child sheet is not
    286   * complete when this method returns, then when the child sheet becomes
    287   * complete aParentSheet will be QIed to nsICSSLoaderObserver and
    288   * asynchronously notified, just like for LoadStyleLink.  Note that if the
    289   * child sheet is already complete when this method returns, no
    290   * nsICSSLoaderObserver notification will be sent.
    291   *
    292   * @param aParentSheet the parent of this child sheet
    293   * @param aParentData the SheetLoadData corresponding to the load of the
    294   *                    parent sheet. May be null for @import rules inserted via
    295   *                    CSSOM.
    296   * @param aURL the URL of the child sheet
    297   * @param aMedia the already-parsed media list for the child sheet
    298   * @param aSavedSheets any saved style sheets which could be reused
    299   *              for this load
    300   */
    301  nsresult LoadChildSheet(StyleSheet& aParentSheet, SheetLoadData* aParentData,
    302                          nsIURI* aURL, dom::MediaList* aMedia,
    303                          LoaderReusableStyleSheets* aSavedSheets);
    304 
    305  /**
    306   * Called when we hit the internal memory cache with a complete stylesheet.
    307   */
    308  void DidHitCompleteSheetCache(const SheetLoadDataHashKey&,
    309                                const StyleUseCounters* aCounters);
    310 
    311  enum class UseSystemPrincipal { No, Yes };
    312 
    313  /**
    314   * Synchronously load and return the stylesheet at aURL.  Any child sheets
    315   * will also be loaded synchronously.  Note that synchronous loads over some
    316   * protocols may involve spinning up a new event loop, so use of this method
    317   * does NOT guarantee not receiving any events before the sheet loads.  This
    318   * method can be used to load sheets not associated with a document.
    319   *
    320   * @param aURL the URL of the sheet to load
    321   * @param aParsingMode the mode in which to parse the sheet
    322   *        (see comments at enum SheetParsingMode, above).
    323   * @param aUseSystemPrincipal if true, give the resulting sheet the system
    324   * principal no matter where it's being loaded from.
    325   *
    326   * NOTE: At the moment, this method assumes the sheet will be UTF-8, but
    327   * ideally it would allow arbitrary encodings.  Callers should NOT depend on
    328   * non-UTF8 sheets being treated as UTF-8 by this method.
    329   *
    330   * NOTE: A successful return from this method doesn't indicate anything about
    331   * whether the data could be parsed as CSS and doesn't indicate anything
    332   * about the status of child sheets of the returned sheet.
    333   */
    334  Result<RefPtr<StyleSheet>, nsresult> LoadSheetSync(
    335      nsIURI*, SheetParsingMode = eAuthorSheetFeatures,
    336      UseSystemPrincipal = UseSystemPrincipal::No);
    337 
    338  /**
    339   * Asynchronously load the stylesheet at aURL.  If a successful result is
    340   * returned, aObserver is guaranteed to be notified asynchronously once the
    341   * sheet is loaded and marked complete.  This method can be used to load
    342   * sheets not associated with a document.
    343   *
    344   * @param aURL the URL of the sheet to load
    345   * @param aParsingMode the mode in which to parse the sheet
    346   *        (see comments at enum SheetParsingMode, above).
    347   * @param aUseSystemPrincipal if true, give the resulting sheet the system
    348   * principal no matter where it's being loaded from.
    349   * @param aReferrerInfo referrer information of the sheet.
    350   * @param aObserver the observer to notify when the load completes.
    351   *                  Must not be null.
    352   * @param aEarlyHintPreloaderId to connect back to the early hint preload
    353   * channel. Null means no connect back should happen
    354   * @return the sheet to load. Note that the sheet may well not be loaded by
    355   * the time this method returns.
    356   *
    357   * NOTE: At the moment, this method assumes the sheet will be UTF-8, but
    358   * ideally it would allow arbitrary encodings.  Callers should NOT depend on
    359   * non-UTF8 sheets being treated as UTF-8 by this method.
    360   */
    361  Result<RefPtr<StyleSheet>, nsresult> LoadSheet(
    362      nsIURI* aURI, StylePreloadKind, const Encoding* aPreloadEncoding,
    363      nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver,
    364      uint64_t aEarlyHintPreloaderId, CORSMode aCORSMode,
    365      const nsAString& aNonce, const nsAString& aIntegrity,
    366      dom::FetchPriority aFetchPriority);
    367 
    368  /**
    369   * As above, but without caring for a couple things.
    370   * Only to be called by `PreloadedStyleSheet::PreloadAsync`.
    371   */
    372  Result<RefPtr<StyleSheet>, nsresult> LoadSheet(nsIURI*, SheetParsingMode,
    373                                                 UseSystemPrincipal,
    374                                                 nsICSSLoaderObserver*);
    375 
    376  /**
    377   * Stop loading all sheets.  All nsICSSLoaderObservers involved will be
    378   * notified with NS_BINDING_ABORTED as the status, possibly synchronously.
    379   */
    380  void Stop();
    381 
    382  /**
    383   * nsresult Loader::StopLoadingSheet(nsIURI* aURL), which notifies the
    384   * nsICSSLoaderObserver with NS_BINDING_ABORTED, was removed in Bug 556446.
    385   * It can be found in revision 2c44a32052ad.
    386   */
    387 
    388  /**
    389   * Whether the loader is enabled or not.
    390   * When disabled, processing of new styles is disabled and an attempt
    391   * to do so will fail with a return code of
    392   * NS_ERROR_NOT_AVAILABLE. Note that this DOES NOT disable
    393   * currently loading styles or already processed styles.
    394   */
    395  bool GetEnabled() { return mEnabled; }
    396  void SetEnabled(bool aEnabled) { mEnabled = aEnabled; }
    397 
    398  uint32_t ParsedSheetCount() const { return mParsedSheetCount; }
    399 
    400  /**
    401   * Get the document we live for. May return null.
    402   */
    403  dom::Document* GetDocument() const { return mDocument; }
    404 
    405  bool IsDocumentAssociated() const { return mIsDocumentAssociated; }
    406 
    407  /**
    408   * Return true if this loader has pending loads (ones that would send
    409   * notifications to an nsICSSLoaderObserver attached to this loader).
    410   * If called from inside nsICSSLoaderObserver::StyleSheetLoaded, this will
    411   * return false if and only if that is the last StyleSheetLoaded
    412   * notification the CSSLoader knows it's going to send.  In other words, if
    413   * two sheets load at once (via load coalescing, e.g.), HasPendingLoads()
    414   * will return true during notification for the first one, and false
    415   * during notification for the second one.
    416   */
    417  bool HasPendingLoads();
    418 
    419  /**
    420   * Add an observer to this loader.  The observer will be notified
    421   * for all loads that would have notified their own observers (even
    422   * if those loads don't have observers attached to them).
    423   * Load-specific observers will be notified before generic
    424   * observers.  The loader holds a reference to the observer.
    425   *
    426   * aObserver must not be null.
    427   */
    428  void AddObserver(nsICSSLoaderObserver* aObserver);
    429 
    430  /**
    431   * Remove an observer added via AddObserver.
    432   */
    433  void RemoveObserver(nsICSSLoaderObserver* aObserver);
    434 
    435  // These interfaces are public only for the benefit of static functions
    436  // within nsCSSLoader.cpp.
    437 
    438  // IsAlternateSheet can change our currently selected style set if none is
    439  // selected and aHasAlternateRel is false.
    440  IsAlternate IsAlternateSheet(const nsAString& aTitle, bool aHasAlternateRel);
    441 
    442  // Measure our size.
    443  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
    444 
    445  enum class SheetState : uint8_t {
    446    NeedsParser = 0,
    447    Pending,
    448    Loading,
    449    Complete
    450  };
    451 
    452  // The loader principal is the document's node principal, if this loader is
    453  // owned by a document, or the system principal otherwise.
    454  nsIPrincipal* LoaderPrincipal() const;
    455 
    456  // The partitioned principal is the document's partitioned principal, if this
    457  // loader is owned by a document, or the system principal otherwise.
    458  nsIPrincipal* PartitionedPrincipal() const;
    459 
    460  bool ShouldBypassCache() const;
    461 
    462  // Inserts a style sheet in a document or a ShadowRoot.
    463  void InsertSheetInTree(StyleSheet& aSheet);
    464 
    465  enum class PendingLoad { No, Yes };
    466 
    467 private:
    468  friend class mozilla::SharedStyleSheetCache;
    469  friend class SheetLoadData;
    470  friend class StreamLoader;
    471 
    472  enum class UsePreload : bool { No, Yes };
    473  enum class UseLoadGroup : bool { No, Yes };
    474 
    475  nsresult NewStyleSheetChannel(SheetLoadData& aLoadData, CORSMode aCorsMode,
    476                                UsePreload aUsePreload,
    477                                UseLoadGroup aUseLoadGroup,
    478                                nsIChannel** aOutChannel);
    479 
    480  // Only to be called by `LoadSheet`.
    481  [[nodiscard]] bool MaybeDeferLoad(SheetLoadData& aLoadData,
    482                                    SheetState aSheetState,
    483                                    PendingLoad aPendingLoad,
    484                                    const SheetLoadDataHashKey& aKey);
    485 
    486  // Only to be called by `LoadSheet`.
    487  bool MaybeCoalesceLoadAndNotifyOpen(SheetLoadData& aLoadData,
    488                                      SheetState aSheetState,
    489                                      const SheetLoadDataHashKey& aKey,
    490                                      const PreloadHashKey& aPreloadKey);
    491 
    492  // Only to be called by `LoadSheet`.
    493  [[nodiscard]] nsresult LoadSheetSyncInternal(SheetLoadData& aLoadData,
    494                                               SheetState aSheetState);
    495 
    496  void AdjustPriority(const SheetLoadData& aLoadData, nsIChannel* aChannel);
    497 
    498  // Only to be called by `LoadSheet`.
    499  [[nodiscard]] nsresult LoadSheetAsyncInternal(
    500      SheetLoadData& aLoadData, uint64_t aEarlyHintPreloaderId,
    501      const SheetLoadDataHashKey& aKey);
    502 
    503  // Helpers to conditionally block onload if mDocument is non-null.
    504  void IncrementOngoingLoadCountAndMaybeBlockOnload() {
    505    if (!mOngoingLoadCount++) {
    506      BlockOnload();
    507    }
    508  }
    509 
    510  void DecrementOngoingLoadCountAndMaybeUnblockOnload() {
    511    MOZ_DIAGNOSTIC_ASSERT(mOngoingLoadCount);
    512    MOZ_DIAGNOSTIC_ASSERT(mOngoingLoadCount > mPendingLoadCount);
    513    if (!--mOngoingLoadCount) {
    514      UnblockOnload(false);
    515    }
    516  }
    517 
    518  void BlockOnload();
    519  void UnblockOnload(bool aFireSync);
    520 
    521  nsresult CheckContentPolicy(nsIPrincipal* aLoadingPrincipal,
    522                              nsIPrincipal* aTriggeringPrincipal,
    523                              nsIURI* aTargetURI, nsINode* aRequestingNode,
    524                              const nsAString& aNonce, StylePreloadKind,
    525                              CORSMode aCORSMode, const nsAString& aIntegrity);
    526 
    527  bool MaybePutIntoLoadsPerformed(SheetLoadData& aLoadData);
    528 
    529 private:
    530  std::tuple<RefPtr<StyleSheet>, SheetState,
    531             RefPtr<SubResourceNetworkMetadataHolder>>
    532  CreateSheet(const SheetInfo& aInfo, css::SheetParsingMode aParsingMode,
    533              bool aSyncLoad, css::StylePreloadKind aPreloadKind) {
    534    nsIPrincipal* triggeringPrincipal = aInfo.mTriggeringPrincipal
    535                                            ? aInfo.mTriggeringPrincipal.get()
    536                                            : LoaderPrincipal();
    537    return CreateSheet(aInfo.mURI, aInfo.mContent, triggeringPrincipal,
    538                       aParsingMode, aInfo.mCORSMode,
    539                       /* aPreloadOrParentDataEncoding = */ nullptr,
    540                       aInfo.mIntegrity, aSyncLoad, aPreloadKind);
    541  }
    542 
    543  // For inline style, the aURI param is null, but the aLinkingContent
    544  // must be non-null then.  The loader principal must never be null
    545  // if aURI is not null.
    546  std::tuple<RefPtr<StyleSheet>, SheetState,
    547             RefPtr<SubResourceNetworkMetadataHolder>>
    548  CreateSheet(nsIURI* aURI, nsIContent* aLinkingContent,
    549              nsIPrincipal* aTriggeringPrincipal, css::SheetParsingMode,
    550              CORSMode, const Encoding* aPreloadOrParentDataEncoding,
    551              const nsAString& aIntegrity, bool aSyncLoad, StylePreloadKind);
    552 
    553  // Pass in either a media string or the MediaList from the CSSParser.  Don't
    554  // pass both.
    555  //
    556  // This method will set the sheet's enabled state based on IsAlternate and co.
    557  MediaMatched PrepareSheet(StyleSheet&, const nsAString& aTitle,
    558                            const nsAString& aMediaString, dom::MediaList*,
    559                            IsAlternate, IsExplicitlyEnabled);
    560 
    561  // Inserts a style sheet into a parent style sheet.
    562  void InsertChildSheet(StyleSheet& aSheet, StyleSheet& aParentSheet);
    563 
    564  Result<RefPtr<StyleSheet>, nsresult> InternalLoadNonDocumentSheet(
    565      nsIURI* aURL, StylePreloadKind, SheetParsingMode aParsingMode,
    566      UseSystemPrincipal, const Encoding* aPreloadEncoding,
    567      nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver,
    568      CORSMode aCORSMode, const nsAString& aNonce, const nsAString& aIntegrity,
    569      uint64_t aEarlyHintPreloaderId, dom::FetchPriority aFetchPriority);
    570 
    571  RefPtr<StyleSheet> LookupInlineSheetInCache(const nsAString&, nsIPrincipal*,
    572                                              nsIURI* aBaseURI);
    573 
    574  // Synchronously notify of a cached load data.
    575  void NotifyOfCachedLoad(RefPtr<SheetLoadData>);
    576 
    577  // Notify observers of a cached stylesheet being.
    578  void NotifyObserversForCachedSheet(SheetLoadData&);
    579 
    580  // Add the Performance API's Resource Timing entry for the cached load data.
    581  void AddPerformanceEntryForCachedSheet(SheetLoadData&);
    582 
    583  // Start the loads of all the sheets in mPendingDatas
    584  void StartDeferredLoads();
    585 
    586  // Note: LoadSheet is responsible for setting the sheet to complete on
    587  // failure.
    588  nsresult LoadSheet(SheetLoadData&, SheetState, uint64_t aEarlyHintPreloaderId,
    589                     PendingLoad = PendingLoad::No);
    590 
    591  enum class AllowAsyncParse {
    592    Yes,
    593    No,
    594  };
    595 
    596  // Parse the stylesheet in the load data.
    597  //
    598  // Returns whether the parse finished. It may not finish e.g. if the sheet had
    599  // an @import.
    600  //
    601  // If this function returns Completed::Yes, then ParseSheet also called
    602  // SheetComplete on aLoadData.
    603  Completed ParseSheet(const nsACString&, const RefPtr<SheetLoadDataHolder>&,
    604                       AllowAsyncParse);
    605 
    606  // The load of the sheet in the load data is done, one way or another.
    607  // Do final cleanup.
    608  void SheetComplete(SheetLoadData&, nsresult);
    609 
    610  // Notify observers on an individual data. This is different from
    611  // SheetComplete for loads that are shared.
    612  void NotifyObservers(SheetLoadData&, nsresult);
    613 
    614  // Mark the given SheetLoadData, as well as any of its siblings, parents, etc
    615  // transitively, as failed.  The idea is to mark as failed any load that was
    616  // directly or indirectly @importing the sheet this SheetLoadData represents.
    617  //
    618  // if aOnlyForLoader is non-null, then only loads for a given loader will be
    619  // marked as failing. This is useful to only cancel loads associated to a
    620  // given loader, in case they were marked as canceled.
    621  static void MarkLoadTreeFailed(SheetLoadData&,
    622                                 Loader* aOnlyForLoader = nullptr);
    623 
    624  // A shorthand to mark a possible link preload as used to supress "unused"
    625  // warning in the console.
    626  void MaybeNotifyPreloadUsed(SheetLoadData&);
    627 
    628  // A set with all the different loads we've done in a given document, for the
    629  // purpose of not posting duplicate performance entries for them.
    630  nsTHashtable<const SheetLoadDataHashKey> mLoadsPerformed;
    631 
    632  RefPtr<SharedStyleSheetCache> mSheets;
    633 
    634  // Our array of "global" observers
    635  nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver>> mObservers;
    636 
    637  // This reference is nulled by the Document in it's destructor through
    638  // DropDocumentReference().
    639  dom::Document* MOZ_NON_OWNING_REF mDocument;  // the document we live for
    640 
    641  // For dispatching events via DocGroup::Dispatch() when mDocument is nullptr.
    642  RefPtr<dom::DocGroup> mDocGroup;
    643 
    644  nsCompatibility mDocumentCompatMode;
    645 
    646  const nsCOMPtr<nsIConsoleReportCollector> mReporter;
    647 
    648  // Number of datas for asynchronous sheet loads still waiting to be notified.
    649  // This includes pending stylesheets whose load hasn't started yet but which
    650  // we need to, but not inline or constructable stylesheets, though the
    651  // constructable stylesheets bit may change, see bug 1642227.
    652  uint32_t mOngoingLoadCount = 0;
    653 
    654  // The number of sheets that have been deferred / are in a pending state.
    655  uint32_t mPendingLoadCount = 0;
    656 
    657  // The number of stylesheets that we have parsed, for testing purposes.
    658  Atomic<uint32_t, MemoryOrdering::Relaxed> mParsedSheetCount{0};
    659 
    660  bool mEnabled = true;
    661 
    662  // Whether we had a document at the point of creation.
    663  bool mIsDocumentAssociated = false;
    664 
    665 #ifdef DEBUG
    666  // Whether we're in a necko callback atm.
    667  bool mSyncCallback = false;
    668 #endif
    669 };
    670 
    671 }  // namespace css
    672 }  // namespace mozilla
    673 
    674 #endif /* mozilla_css_Loader_h */