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