tor-browser

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

StyleSheet.h (22714B)


      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 #ifndef mozilla_StyleSheet_h
      8 #define mozilla_StyleSheet_h
      9 
     10 #include "mozilla/Assertions.h"
     11 #include "mozilla/CORSMode.h"
     12 #include "mozilla/MozPromise.h"
     13 #include "mozilla/RefPtr.h"
     14 #include "mozilla/ServoBindingTypes.h"
     15 #include "mozilla/ServoTypes.h"
     16 #include "mozilla/StaticPrefs_network.h"
     17 #include "mozilla/StyleSheetInfo.h"
     18 #include "mozilla/css/SheetParsingMode.h"
     19 #include "mozilla/dom/CSSStyleSheetBinding.h"
     20 #include "mozilla/dom/SRIMetadata.h"
     21 #include "nsICSSLoaderObserver.h"
     22 #include "nsIPrincipal.h"
     23 #include "nsProxyRelease.h"
     24 #include "nsStringFwd.h"
     25 #include "nsWrapperCache.h"
     26 
     27 class nsIGlobalObject;
     28 class nsINode;
     29 class nsIPrincipal;
     30 struct StyleLockedCssRules;
     31 class nsIReferrerInfo;
     32 
     33 namespace mozilla {
     34 
     35 class ServoCSSRuleList;
     36 class ServoStyleSet;
     37 class DeclarationBlock;
     38 
     39 using StyleSheetParsePromise = MozPromise</* Dummy */ bool,
     40                                          /* Dummy */ bool,
     41                                          /* IsExclusive = */ true>;
     42 
     43 enum class StyleRuleChangeKind : uint32_t;
     44 enum class StyleNonLocalUriDependency : uint8_t;
     45 
     46 struct StyleRuleChange {
     47  StyleRuleChange() = delete;
     48  MOZ_IMPLICIT StyleRuleChange(StyleRuleChangeKind aKind) : mKind(aKind) {}
     49  // Only relevant for Kind::*Declarations.
     50  StyleRuleChange(StyleRuleChangeKind aKind, const DeclarationBlock* aOldBlock,
     51                  const DeclarationBlock* aNewBlock)
     52      : mKind(aKind), mOldBlock(aOldBlock), mNewBlock(aNewBlock) {}
     53 
     54  const StyleRuleChangeKind mKind;
     55  // mOldBlock and mNewBlock can be the same object.
     56  const DeclarationBlock* const mOldBlock = nullptr;
     57  const DeclarationBlock* const mNewBlock = nullptr;
     58 };
     59 
     60 namespace css {
     61 class GroupRule;
     62 class Loader;
     63 class LoaderReusableStyleSheets;
     64 class Rule;
     65 class SheetLoadData;
     66 using SheetLoadDataHolder = nsMainThreadPtrHolder<SheetLoadData>;
     67 }  // namespace css
     68 
     69 namespace dom {
     70 class CSSImportRule;
     71 class CSSRuleList;
     72 class DocumentOrShadowRoot;
     73 class MediaList;
     74 class ShadowRoot;
     75 struct CSSStyleSheetInit;
     76 }  // namespace dom
     77 
     78 enum class StyleSheetState : uint8_t {
     79  // Whether the sheet is disabled. Sheets can be made disabled via CSSOM, or
     80  // via alternate links and such.
     81  Disabled = 1 << 0,
     82  // Whether the sheet is complete. The sheet is complete if it's finished
     83  // loading. See StyleSheet::SetComplete.
     84  Complete = 1 << 1,
     85  // Whether we've forced a unique inner. StyleSheet objects share an 'inner'
     86  // StyleSheetInfo object if they share URL, CORS mode, etc.
     87  //
     88  // See the Loader's `mCompleteSheets` and `mLoadingSheets`.
     89  ForcedUniqueInner = 1 << 2,
     90  // Whether this stylesheet has suffered any modification to the rules via
     91  // CSSOM.
     92  ModifiedRules = 1 << 3,
     93  // Same flag, but devtools clears it in some specific situations.
     94  //
     95  // Used to control whether devtools shows the rule in its authored form or
     96  // not.
     97  ModifiedRulesForDevtools = 1 << 4,
     98  // Whether modifications to the sheet are currently disallowed.
     99  // This flag is set during the async Replace() function to ensure
    100  // that the sheet is not modified until the promise is resolved.
    101  ModificationDisallowed = 1 << 5,
    102 };
    103 
    104 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StyleSheetState)
    105 
    106 class StyleSheet final : public nsICSSLoaderObserver, public nsWrapperCache {
    107  StyleSheet(const StyleSheet& aCopy, StyleSheet* aParentSheetToUse,
    108             dom::DocumentOrShadowRoot* aDocOrShadowRootToUse,
    109             dom::Document* aConstructorDocToUse);
    110 
    111  virtual ~StyleSheet();
    112 
    113  using State = StyleSheetState;
    114 
    115 public:
    116  StyleSheet(css::SheetParsingMode aParsingMode, CORSMode aCORSMode,
    117             const dom::SRIMetadata& aIntegrity);
    118 
    119  static already_AddRefed<StyleSheet> Constructor(const dom::GlobalObject&,
    120                                                  const dom::CSSStyleSheetInit&,
    121                                                  ErrorResult&);
    122 
    123  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    124  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(StyleSheet)
    125 
    126  static already_AddRefed<StyleSheet> CreateConstructedSheet(
    127      dom::Document& aConstructorDocument, nsIURI* aBaseURI,
    128      const dom::CSSStyleSheetInit& aOptions, ErrorResult& aError);
    129 
    130  already_AddRefed<StyleSheet> CreateEmptyChildSheet(
    131      already_AddRefed<dom::MediaList> aMediaList) const;
    132 
    133  bool HasRules() const;
    134 
    135  // Parses a stylesheet. The load data argument corresponds to the
    136  // SheetLoadData for this stylesheet.
    137  // NOTE: ParseSheet can run synchronously or asynchronously
    138  //       based on the result of `AllowParallelParse`
    139  RefPtr<StyleSheetParsePromise> ParseSheet(
    140      css::Loader&, const nsACString& aBytes,
    141      const RefPtr<css::SheetLoadDataHolder>& aLoadData);
    142 
    143  // Common code that needs to be called after servo finishes parsing. This is
    144  // shared between the parallel and sequential paths.
    145  void FinishAsyncParse(already_AddRefed<StyleStylesheetContents>);
    146 
    147  // Similar to `ParseSheet`, but guarantees that
    148  // parsing will be performed synchronously.
    149  // NOTE: ParseSheet can still run synchronously.
    150  //       This is not a strict alternative.
    151  //
    152  // The load data may be null sometimes.
    153  void ParseSheetSync(
    154      css::Loader* aLoader, const nsACString& aBytes,
    155      css::SheetLoadData* aLoadData,
    156      css::LoaderReusableStyleSheets* aReusableSheets = nullptr);
    157 
    158  void ReparseSheet(const nsACString& aInput, ErrorResult& aRv);
    159 
    160  const StyleStylesheetContents* RawContents() const {
    161    return Inner().mContents;
    162  }
    163 
    164  const StyleUseCounters* UseCounters() const;
    165  void PropagateUseCountersTo(dom::Document*) const;
    166 
    167  // Whether our original contents may be using relative URIs.
    168  StyleNonLocalUriDependency OriginalContentsUriDependency() const;
    169 
    170  URLExtraData* URLData() const { return mURLData.get(); }
    171 
    172  // nsICSSLoaderObserver interface
    173  NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasDeferred,
    174                              nsresult aStatus) final;
    175 
    176  // Internal GetCssRules methods which do not have security check and
    177  // completeness check.
    178  ServoCSSRuleList* GetCssRulesInternal();
    179 
    180  // Returns the stylesheet's Servo origin as a StyleOrigin value.
    181  StyleOrigin GetOrigin() const;
    182 
    183  void SetOwningNode(nsINode* aOwningNode) { mOwningNode = aOwningNode; }
    184 
    185  css::SheetParsingMode ParsingMode() const { return mParsingMode; }
    186  dom::CSSStyleSheetParsingMode ParsingModeDOM();
    187 
    188  /**
    189   * Whether the sheet is complete.
    190   */
    191  bool IsComplete() const { return bool(mState & State::Complete); }
    192 
    193  void SetComplete();
    194 
    195  void SetEnabled(bool aEnabled) { SetDisabled(!aEnabled); }
    196 
    197  // Whether the sheet is for an inline <style> element.
    198  bool IsInline() const { return !GetOriginalURI(); }
    199  /**
    200   * Get the URI this sheet was originally loaded from, if any. Can return null.
    201   */
    202  nsIURI* GetOriginalURI() const { return mOriginalSheetURI; }
    203  nsIURI* GetBaseURI() const;
    204 
    205  void SetURIs(nsIURI* aOriginalSheetURI, nsIURI* aBaseURI,
    206               nsIReferrerInfo* aReferrerInfo, nsIPrincipal* aPrincipal);
    207 
    208  void SetOriginClean(bool aValue) { Inner().mOriginClean = aValue; }
    209  bool IsOriginClean() const { return Inner().mOriginClean; }
    210 
    211  /**
    212   * Whether the sheet is applicable.  A sheet that is not applicable
    213   * should never be inserted into a style set.  A sheet may not be
    214   * applicable for a variety of reasons including being disabled and
    215   * being incomplete.
    216   */
    217  bool IsApplicable() const { return !Disabled() && IsComplete(); }
    218 
    219  already_AddRefed<StyleSheet> Clone(
    220      StyleSheet* aCloneParent,
    221      dom::DocumentOrShadowRoot* aCloneDocumentOrShadowRoot) const;
    222 
    223  /**
    224   * Creates a clone of the adopted style sheet as though it were constructed
    225   * by aConstructorDocument. This should only be used for printing.
    226   */
    227  already_AddRefed<StyleSheet> CloneAdoptedSheet(
    228      dom::Document& aConstructorDocument) const;
    229 
    230  bool HasForcedUniqueInner() const {
    231    return bool(mState & State::ForcedUniqueInner);
    232  }
    233 
    234  bool HasModifiedRules() const { return bool(mState & State::ModifiedRules); }
    235 
    236  bool HasModifiedRulesForDevtools() const {
    237    return bool(mState & State::ModifiedRulesForDevtools);
    238  }
    239 
    240  bool HasUniqueInner() const { return Inner().mSheets.Length() == 1; }
    241 
    242  void AssertHasUniqueInner() const { MOZ_ASSERT(HasUniqueInner()); }
    243 
    244  void EnsureUniqueInner();
    245 
    246  // Returns the DocumentOrShadowRoot* that owns us, if any.
    247  //
    248  // TODO(emilio): Maybe rename to GetOwner*() or such? Might be
    249  // confusing with nsINode::OwnerDoc and such.
    250  dom::DocumentOrShadowRoot* GetAssociatedDocumentOrShadowRoot() const;
    251 
    252  // Whether this stylesheet is kept alive by the associated or constructor
    253  // document somehow, and thus at least has the same lifetime as
    254  // GetAssociatedDocument().
    255  dom::Document* GetKeptAliveByDocument() const;
    256 
    257  // If this is a constructed style sheet, return mConstructorDocument.
    258  // Otherwise return the document we're associated to,
    259  // via mDocumentOrShadowRoot.
    260  //
    261  // Non-null iff GetAssociatedDocumentOrShadowRoot is non-null.
    262  dom::Document* GetAssociatedDocument() const;
    263 
    264  void SetAssociatedDocumentOrShadowRoot(dom::DocumentOrShadowRoot*);
    265  void ClearAssociatedDocumentOrShadowRoot() {
    266    SetAssociatedDocumentOrShadowRoot(nullptr);
    267  }
    268 
    269  nsINode* GetOwnerNode() const { return mOwningNode; }
    270 
    271  nsINode* GetOwnerNodeOfOutermostSheet() const {
    272    return OutermostSheet().GetOwnerNode();
    273  }
    274 
    275  StyleSheet* GetParentSheet() const { return mParentSheet; }
    276 
    277  void AddReferencingRule(dom::CSSImportRule& aRule) {
    278    MOZ_ASSERT(!mReferencingRules.Contains(&aRule));
    279    mReferencingRules.AppendElement(&aRule);
    280  }
    281 
    282  void RemoveReferencingRule(dom::CSSImportRule& aRule) {
    283    MOZ_ASSERT(mReferencingRules.Contains(&aRule));
    284    mReferencingRules.RemoveElement(&aRule);
    285  }
    286 
    287  // Note that when exposed to script, this should always have a <= 1 length.
    288  // CSSImportRule::GetStyleSheetForBindings takes care of that.
    289  dom::CSSImportRule* GetOwnerRule() const {
    290    return mReferencingRules.SafeElementAt(0);
    291  }
    292 
    293  void AppendStyleSheet(StyleSheet&);
    294 
    295  // Append a stylesheet to the child list without calling WillDirty.
    296  void AppendStyleSheetSilently(StyleSheet&);
    297 
    298  const nsTArray<RefPtr<StyleSheet>>& ChildSheets() const {
    299 #ifdef DEBUG
    300    for (StyleSheet* child : Inner().mChildren) {
    301      MOZ_ASSERT(child->GetParentSheet());
    302      MOZ_ASSERT(child->GetParentSheet()->mInner == mInner);
    303    }
    304 #endif
    305    return Inner().mChildren;
    306  }
    307 
    308  // Principal() never returns a null pointer.
    309  nsIPrincipal* Principal() const;
    310  void SetTitle(const nsAString& aTitle) { mTitle = aTitle; }
    311  void SetMedia(already_AddRefed<dom::MediaList> aMedia);
    312 
    313  // Get this style sheet's CORS mode
    314  CORSMode GetCORSMode() const { return Inner().mCORSMode; }
    315 
    316  // Get this style sheet's ReferrerInfo
    317  nsIReferrerInfo* GetReferrerInfo() const;
    318 
    319  // Get this style sheet's integrity metadata
    320  void GetIntegrity(dom::SRIMetadata& aResult) const {
    321    aResult = Inner().mIntegrity;
    322  }
    323 
    324  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
    325 #if defined(DEBUG) || defined(MOZ_LAYOUT_DEBUGGER)
    326  void List(FILE* aOut = stdout, int32_t aIndex = 0);
    327 #endif
    328 
    329  // WebIDL StyleSheet API
    330  void GetType(nsAString& aType);
    331  void GetHref(nsAString& aHref, ErrorResult& aRv);
    332  // GetOwnerNode is defined above.
    333  StyleSheet* GetParentStyleSheet() const { return GetParentSheet(); }
    334  void GetTitle(nsAString& aTitle);
    335  dom::MediaList* Media();
    336  bool Disabled() const { return bool(mState & State::Disabled); }
    337  void SetDisabled(bool aDisabled);
    338 
    339  void GetSourceMapURL(nsACString&);
    340  void SetSourceMapURL(nsCString&&);
    341  void GetSourceURL(nsACString& aSourceURL);
    342 
    343  // WebIDL CSSStyleSheet API
    344  // Can't be inline because we can't include ImportRule here.  And can't be
    345  // called GetOwnerRule because that would be ambiguous with the ImportRule
    346  // version.
    347  css::Rule* GetDOMOwnerRule() const;
    348  dom::CSSRuleList* GetCssRules(nsIPrincipal& aSubjectPrincipal, ErrorResult&);
    349  uint32_t InsertRule(const nsACString& aRule, uint32_t aIndex,
    350                      nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
    351  void DeleteRule(uint32_t aIndex, nsIPrincipal& aSubjectPrincipal,
    352                  ErrorResult& aRv);
    353  int32_t AddRule(const nsACString& aSelector, const nsACString& aBlock,
    354                  const dom::Optional<uint32_t>& aIndex,
    355                  nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
    356  already_AddRefed<dom::Promise> Replace(const nsACString& aText, ErrorResult&);
    357  void ReplaceSync(const nsACString& aText, ErrorResult&);
    358  bool ModificationDisallowed() const {
    359    return bool(mState & State::ModificationDisallowed);
    360  }
    361 
    362  // Called before and after the asynchronous Replace() function
    363  // to disable/re-enable modification while there is a pending promise.
    364  void SetModificationDisallowed(bool aDisallowed) {
    365    MOZ_ASSERT(IsConstructed());
    366    MOZ_ASSERT(!IsReadOnly());
    367    if (aDisallowed) {
    368      mState |= State::ModificationDisallowed;
    369      // Sheet will be re-set to complete when its rules are replaced
    370      mState &= ~State::Complete;
    371      if (!Disabled()) {
    372        ApplicableStateChanged(false);
    373      }
    374    } else {
    375      mState &= ~State::ModificationDisallowed;
    376    }
    377  }
    378 
    379  // True if the sheet was created through the Constructable StyleSheets API
    380  bool IsConstructed() const { return !!mConstructorDocument; }
    381 
    382  // Whether this sheet is directly associated to the given doc or shadow root.
    383  // That means that it's a non-imported regular, adopted, or additional style
    384  // sheet, and thus that it should be in the top level list of sheets for that
    385  // subtree. It can be cheaper than walking the whole list of stylesheets.
    386  bool IsDirectlyAssociatedTo(dom::DocumentOrShadowRoot&) const;
    387 
    388  // True if any of this sheet's ancestors were created through the
    389  // Constructable StyleSheets API
    390  bool SelfOrAncestorIsConstructed() const {
    391    return OutermostSheet().IsConstructed();
    392  }
    393 
    394  // Ture if the sheet's constructor document matches the given document
    395  bool ConstructorDocumentMatches(const dom::Document& aDocument) const {
    396    return mConstructorDocument == &aDocument;
    397  }
    398 
    399  // Add a document or shadow root to the list of adopters.
    400  // Adopters will be notified when styles are changed.
    401  void AddAdopter(dom::DocumentOrShadowRoot& aAdopter) {
    402    // MOZ_ASSERT(IsConstructed());
    403    MOZ_ASSERT(!mAdopters.Contains(&aAdopter));
    404    mAdopters.AppendElement(&aAdopter);
    405  }
    406 
    407  // Remove a document or shadow root from the list of adopters.
    408  void RemoveAdopter(dom::DocumentOrShadowRoot& aAdopter) {
    409    // Cannot assert IsConstructed() because this can run after unlink.
    410    mAdopters.RemoveElement(&aAdopter);
    411  }
    412 
    413  const nsTArray<dom::DocumentOrShadowRoot*>& SelfOrAncestorAdopters() const {
    414    return OutermostSheet().mAdopters;
    415  }
    416 
    417  // WebIDL miscellaneous bits
    418  inline dom::ParentObject GetParentObject() const;
    419  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
    420 
    421  // Changes to sheets should be after a WillDirty call.
    422  void WillDirty();
    423 
    424  // Called when a rule changes from CSSOM.
    425  //
    426  // FIXME(emilio): This shouldn't allow null, but MediaList doesn't know about
    427  // its owning media rule, plus it's used for the stylesheet media itself.
    428  void RuleChanged(css::Rule*, const StyleRuleChange&);
    429 
    430  void AddStyleSet(ServoStyleSet* aStyleSet);
    431  void DropStyleSet(ServoStyleSet* aStyleSet);
    432 
    433  nsresult DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex);
    434  nsresult InsertRuleIntoGroup(const nsACString& aRule, css::GroupRule* aGroup,
    435                               uint32_t aIndex);
    436 
    437  // Find the ID of the owner inner window.
    438  uint64_t FindOwningWindowInnerID() const;
    439 
    440  // Copy the contents of this style sheet into the shared memory buffer managed
    441  // by aBuilder.  Returns the pointer into the buffer that the sheet contents
    442  // were stored at.  (The returned pointer is to an Arc<Locked<Rules>> value,
    443  // or null, with a filled in aErrorMessage, on failure.)
    444  const StyleLockedCssRules* ToShared(StyleSharedMemoryBuilder* aBuilder,
    445                                      nsCString& aErrorMessage);
    446 
    447  // Sets the contents of this style sheet to the specified aSharedRules
    448  // pointer, which must be a pointer somewhere in the aSharedMemory buffer
    449  // as previously returned by a ToShared() call.
    450  void SetSharedContents(const StyleLockedCssRules* aSharedRules);
    451 
    452  // Whether this style sheet should not allow any modifications.
    453  //
    454  // This is true for any User Agent sheets once they are complete.
    455  bool IsReadOnly() const;
    456 
    457  // Removes a stylesheet from its parent sheet child list, if any.
    458  void RemoveFromParent();
    459 
    460  // Resolves mReplacePromise with this sheet.
    461  void MaybeResolveReplacePromise();
    462 
    463  // Rejects mReplacePromise with a NetworkError.
    464  void MaybeRejectReplacePromise();
    465 
    466  // Gets the relevant global if exists.
    467  nsISupports* GetRelevantGlobal() const;
    468 
    469  // Blocks/Unblocks resolution of parse promise
    470  void BlockParsePromise() {
    471 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
    472    uint32_t count =
    473 #endif
    474        ++mAsyncParseBlockers;
    475    MOZ_DIAGNOSTIC_ASSERT(count);
    476  }
    477 
    478  void UnblockParsePromise() {
    479    uint32_t count = --mAsyncParseBlockers;
    480    MOZ_DIAGNOSTIC_ASSERT(count != UINT32_MAX);
    481    if (!count && !mParsePromise.IsEmpty()) {
    482      mParsePromise.Resolve(true, __func__);
    483    }
    484  }
    485 
    486 private:
    487  void SetModifiedRules() {
    488    mState |= State::ModifiedRules | State::ModifiedRulesForDevtools;
    489  }
    490 
    491  const StyleSheet& OutermostSheet() const {
    492    const auto* current = this;
    493    while (current->mParentSheet) {
    494      MOZ_ASSERT(!current->mDocumentOrShadowRoot,
    495                 "Shouldn't be set on child sheets");
    496      MOZ_ASSERT(!current->mConstructorDocument,
    497                 "Shouldn't be set on child sheets");
    498      current = current->mParentSheet;
    499    }
    500    return *current;
    501  }
    502 
    503  StyleSheetInfo& Inner() {
    504    MOZ_ASSERT(mInner);
    505    return *mInner;
    506  }
    507 
    508  const StyleSheetInfo& Inner() const {
    509    MOZ_ASSERT(mInner);
    510    return *mInner;
    511  }
    512 
    513  // Check if the rules are available for read and write.
    514  // It does the security check as well as whether the rules have been
    515  // completely loaded. aRv will have an exception set if this function
    516  // returns false.
    517  bool AreRulesAvailable(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
    518 
    519 protected:
    520  // Internal methods which do not have security check and completeness check.
    521  uint32_t InsertRuleInternal(const nsACString& aRule, uint32_t aIndex,
    522                              ErrorResult&);
    523  void DeleteRuleInternal(uint32_t aIndex, ErrorResult&);
    524  nsresult InsertRuleIntoGroupInternal(const nsACString& aRule,
    525                                       css::GroupRule* aGroup, uint32_t aIndex);
    526 
    527  // Take the recently cloned sheets from the `@import` rules, and reparent them
    528  // correctly to `aPrimarySheet`.
    529  void FixUpAfterInnerClone();
    530 
    531  // aFromClone says whether this comes from a clone of the stylesheet (and thus
    532  // we should also fix up the wrappers for the individual rules in the rule
    533  // lists).
    534  void FixUpRuleListAfterContentsChangeIfNeeded(bool aFromClone = false);
    535 
    536  void DropRuleList();
    537 
    538  // Called when a rule is removed from the sheet from CSSOM.
    539  void RuleAdded(css::Rule&);
    540 
    541  // Called when a rule is added to the sheet from CSSOM.
    542  void RuleRemoved(css::Rule&);
    543 
    544  // Called when a stylesheet is cloned.
    545  void StyleSheetCloned(StyleSheet&);
    546 
    547  // Notifies that the applicable state changed.
    548  // aApplicable is the value that we expect to get from IsApplicable().
    549  // assertion will fail if the expectation does not match reality.
    550  void ApplicableStateChanged(bool aApplicable);
    551 
    552  void LastRelease();
    553 
    554  // Return success if the subject principal subsumes the principal of our
    555  // inner, error otherwise.  This will also succeed if access is allowed by
    556  // CORS.  In that case, it will set the principal of the inner to the
    557  // subject principal.
    558  void SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
    559                                     ErrorResult& aRv);
    560 
    561  // Drop our reference to mMedia
    562  void DropMedia();
    563  // Set our relevant global if needed.
    564  void UpdateRelevantGlobal();
    565  // Unlink our inner, if needed, for cycle collection.
    566  void UnlinkInner();
    567  // Traverse our inner, if needed, for cycle collection
    568  void TraverseInner(nsCycleCollectionTraversalCallback&);
    569 
    570  // Return whether the given @import rule has pending child sheet.
    571  static bool RuleHasPendingChildSheet(css::Rule* aRule);
    572 
    573  StyleSheet* mParentSheet;  // weak ref
    574 
    575  // A pointer to the sheet's relevant global object. This is populated when the
    576  // sheet gets an associated document and is complete.
    577  //
    578  // This is required for the sheet to be able to create a promise.
    579  // https://html.spec.whatwg.org/#concept-relevant-everything
    580  nsCOMPtr<nsIGlobalObject> mRelevantGlobal;
    581 
    582  RefPtr<dom::Document> mConstructorDocument;
    583 
    584  // Will be set in the Replace() function and resolved/rejected by the
    585  // sheet once its rules have been replaced and the sheet is complete again.
    586  RefPtr<dom::Promise> mReplacePromise;
    587 
    588  nsString mTitle;
    589 
    590  // weak ref; parents maintain this for their children
    591  dom::DocumentOrShadowRoot* mDocumentOrShadowRoot;
    592  nsINode* mOwningNode = nullptr;                   // weak ref
    593  nsTArray<dom::CSSImportRule*> mReferencingRules;  // weak ref
    594 
    595  RefPtr<dom::MediaList> mMedia;
    596 
    597  RefPtr<URLExtraData> mURLData;
    598  RefPtr<nsIURI> mOriginalSheetURI;
    599 
    600  // mParsingMode controls access to nonstandard style constructs that
    601  // are not safe for use on the public Web but necessary in UA sheets
    602  // and/or useful in user sheets.
    603  //
    604  // FIXME(emilio): Given we store the parsed contents in the Inner, this should
    605  // probably also move there.
    606  css::SheetParsingMode mParsingMode;
    607 
    608  State mState;
    609 
    610  Atomic<uint32_t, ReleaseAcquire> mAsyncParseBlockers{0};
    611 
    612  // Core information we get from parsed sheets, which are shared amongst
    613  // StyleSheet clones.
    614  //
    615  // Always nonnull until LastRelease().
    616  StyleSheetInfo* mInner;
    617 
    618  nsTArray<ServoStyleSet*> mStyleSets;
    619 
    620  RefPtr<ServoCSSRuleList> mRuleList;
    621 
    622  MozPromiseHolder<StyleSheetParsePromise> mParsePromise;
    623 
    624  nsTArray<dom::DocumentOrShadowRoot*> mAdopters;
    625 
    626  // Make StyleSheetInfo and subclasses into friends so they can use
    627  // ChildSheetListBuilder.
    628  friend struct StyleSheetInfo;
    629 };
    630 
    631 }  // namespace mozilla
    632 
    633 #endif  // mozilla_StyleSheet_h