зеркало из https://github.com/mozilla/gecko-dev.git
615 строки
21 KiB
C++
615 строки
21 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_StyleSheet_h
|
|
#define mozilla_StyleSheet_h
|
|
|
|
#include "mozilla/css/SheetParsingMode.h"
|
|
#include "mozilla/dom/CSSStyleSheetBinding.h"
|
|
#include "mozilla/dom/SRIMetadata.h"
|
|
#include "mozilla/CORSMode.h"
|
|
#include "mozilla/MozPromise.h"
|
|
#include "mozilla/RefPtr.h"
|
|
#include "mozilla/ServoBindingTypes.h"
|
|
#include "mozilla/ServoTypes.h"
|
|
#include "mozilla/StyleSheetInfo.h"
|
|
#include "nsICSSLoaderObserver.h"
|
|
#include "nsIPrincipal.h"
|
|
#include "nsWrapperCache.h"
|
|
#include "nsStringFwd.h"
|
|
|
|
class nsIGlobalObject;
|
|
class nsINode;
|
|
class nsIPrincipal;
|
|
struct StyleLockedCssRules;
|
|
class nsIReferrerInfo;
|
|
|
|
namespace mozilla {
|
|
|
|
class ServoCSSRuleList;
|
|
class ServoStyleSet;
|
|
|
|
using StyleSheetParsePromise = MozPromise</* Dummy */ bool,
|
|
/* Dummy */ bool,
|
|
/* IsExclusive = */ true>;
|
|
|
|
enum class StyleRuleChangeKind : uint32_t;
|
|
|
|
namespace css {
|
|
class GroupRule;
|
|
class Loader;
|
|
class LoaderReusableStyleSheets;
|
|
class Rule;
|
|
class SheetLoadData;
|
|
} // namespace css
|
|
|
|
namespace dom {
|
|
class CSSImportRule;
|
|
class CSSRuleList;
|
|
class DocumentOrShadowRoot;
|
|
class MediaList;
|
|
class ShadowRoot;
|
|
struct CSSStyleSheetInit;
|
|
} // namespace dom
|
|
|
|
enum class StyleSheetState : uint8_t {
|
|
// Whether the sheet is disabled. Sheets can be made disabled via CSSOM, or
|
|
// via alternate links and such.
|
|
Disabled = 1 << 0,
|
|
// Whether the sheet is complete. The sheet is complete if it's finished
|
|
// loading. See StyleSheet::SetComplete.
|
|
Complete = 1 << 1,
|
|
// Whether we've forced a unique inner. StyleSheet objects share an 'inner'
|
|
// StyleSheetInfo object if they share URL, CORS mode, etc.
|
|
//
|
|
// See the Loader's `mCompleteSheets` and `mLoadingSheets`.
|
|
ForcedUniqueInner = 1 << 2,
|
|
// Whether this stylesheet has suffered any modification to the rules via
|
|
// CSSOM.
|
|
ModifiedRules = 1 << 3,
|
|
// Same flag, but devtools clears it in some specific situations.
|
|
//
|
|
// Used to control whether devtools shows the rule in its authored form or
|
|
// not.
|
|
ModifiedRulesForDevtools = 1 << 4,
|
|
// Whether modifications to the sheet are currently disallowed.
|
|
// This flag is set during the async Replace() function to ensure
|
|
// that the sheet is not modified until the promise is resolved.
|
|
ModificationDisallowed = 1 << 5,
|
|
};
|
|
|
|
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StyleSheetState)
|
|
|
|
class StyleSheet final : public nsICSSLoaderObserver, public nsWrapperCache {
|
|
StyleSheet(const StyleSheet& aCopy, StyleSheet* aParentSheetToUse,
|
|
dom::DocumentOrShadowRoot* aDocOrShadowRootToUse,
|
|
dom::Document* aConstructorDocToUse);
|
|
|
|
virtual ~StyleSheet();
|
|
|
|
using State = StyleSheetState;
|
|
|
|
public:
|
|
StyleSheet(css::SheetParsingMode aParsingMode, CORSMode aCORSMode,
|
|
const dom::SRIMetadata& aIntegrity);
|
|
|
|
static already_AddRefed<StyleSheet> Constructor(const dom::GlobalObject&,
|
|
const dom::CSSStyleSheetInit&,
|
|
ErrorResult&);
|
|
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(StyleSheet)
|
|
|
|
already_AddRefed<StyleSheet> CreateEmptyChildSheet(
|
|
already_AddRefed<dom::MediaList> aMediaList) const;
|
|
|
|
bool HasRules() const;
|
|
|
|
// Parses a stylesheet. The load data argument corresponds to the
|
|
// SheetLoadData for this stylesheet.
|
|
// NOTE: ParseSheet can run synchronously or asynchronously
|
|
// based on the result of `AllowParallelParse`
|
|
RefPtr<StyleSheetParsePromise> ParseSheet(css::Loader&,
|
|
const nsACString& aBytes,
|
|
css::SheetLoadData&);
|
|
|
|
// Common code that needs to be called after servo finishes parsing. This is
|
|
// shared between the parallel and sequential paths.
|
|
void FinishAsyncParse(already_AddRefed<StyleStylesheetContents>,
|
|
UniquePtr<StyleUseCounters>);
|
|
|
|
// Similar to `ParseSheet`, but guarantees that
|
|
// parsing will be performed synchronously.
|
|
// NOTE: ParseSheet can still run synchronously.
|
|
// This is not a strict alternative.
|
|
//
|
|
// The load data may be null sometimes.
|
|
void ParseSheetSync(
|
|
css::Loader* aLoader, const nsACString& aBytes,
|
|
css::SheetLoadData* aLoadData,
|
|
css::LoaderReusableStyleSheets* aReusableSheets = nullptr);
|
|
|
|
void ReparseSheet(const nsACString& aInput, ErrorResult& aRv);
|
|
|
|
const StyleStylesheetContents* RawContents() const {
|
|
return Inner().mContents;
|
|
}
|
|
|
|
const StyleUseCounters* GetStyleUseCounters() const {
|
|
return Inner().mUseCounters.get();
|
|
}
|
|
|
|
URLExtraData* URLData() const { return Inner().mURLData; }
|
|
|
|
// nsICSSLoaderObserver interface
|
|
NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasDeferred,
|
|
nsresult aStatus) final;
|
|
|
|
// Internal GetCssRules methods which do not have security check and
|
|
// completeness check.
|
|
ServoCSSRuleList* GetCssRulesInternal();
|
|
|
|
// Returns the stylesheet's Servo origin as a StyleOrigin value.
|
|
StyleOrigin GetOrigin() const;
|
|
|
|
void SetOwningNode(nsINode* aOwningNode) { mOwningNode = aOwningNode; }
|
|
|
|
css::SheetParsingMode ParsingMode() const { return mParsingMode; }
|
|
dom::CSSStyleSheetParsingMode ParsingModeDOM();
|
|
|
|
/**
|
|
* Whether the sheet is complete.
|
|
*/
|
|
bool IsComplete() const { return bool(mState & State::Complete); }
|
|
|
|
void SetComplete();
|
|
|
|
void SetEnabled(bool aEnabled) { SetDisabled(!aEnabled); }
|
|
|
|
// Whether the sheet is for an inline <style> element.
|
|
bool IsInline() const { return !GetOriginalURI(); }
|
|
|
|
nsIURI* GetSheetURI() const { return Inner().mSheetURI; }
|
|
|
|
/**
|
|
* Get the URI this sheet was originally loaded from, if any. Can return null.
|
|
*/
|
|
nsIURI* GetOriginalURI() const { return Inner().mOriginalSheetURI; }
|
|
|
|
nsIURI* GetBaseURI() const { return Inner().mBaseURI; }
|
|
|
|
/**
|
|
* SetURIs must be called on all sheets before parsing into them.
|
|
* SetURIs may only be called while the sheet is 1) incomplete and 2)
|
|
* has no rules in it.
|
|
*
|
|
* FIXME(emilio): Can we pass this down when constructing the sheet instead?
|
|
*/
|
|
inline void SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI,
|
|
nsIURI* aBaseURI);
|
|
|
|
/**
|
|
* Whether the sheet is applicable. A sheet that is not applicable
|
|
* should never be inserted into a style set. A sheet may not be
|
|
* applicable for a variety of reasons including being disabled and
|
|
* being incomplete.
|
|
*/
|
|
bool IsApplicable() const { return !Disabled() && IsComplete(); }
|
|
|
|
already_AddRefed<StyleSheet> Clone(
|
|
StyleSheet* aCloneParent,
|
|
dom::DocumentOrShadowRoot* aCloneDocumentOrShadowRoot) const;
|
|
|
|
/**
|
|
* Creates a clone of the adopted style sheet as though it were constructed
|
|
* by aConstructorDocument. This should only be used for printing.
|
|
*/
|
|
already_AddRefed<StyleSheet> CloneAdoptedSheet(
|
|
dom::Document& aConstructorDocument) const;
|
|
|
|
bool HasForcedUniqueInner() const {
|
|
return bool(mState & State::ForcedUniqueInner);
|
|
}
|
|
|
|
bool HasModifiedRules() const { return bool(mState & State::ModifiedRules); }
|
|
|
|
bool HasModifiedRulesForDevtools() const {
|
|
return bool(mState & State::ModifiedRulesForDevtools);
|
|
}
|
|
|
|
bool HasUniqueInner() const { return Inner().mSheets.Length() == 1; }
|
|
|
|
void AssertHasUniqueInner() const { MOZ_ASSERT(HasUniqueInner()); }
|
|
|
|
void EnsureUniqueInner();
|
|
|
|
// Returns the DocumentOrShadowRoot* that owns us, if any.
|
|
//
|
|
// TODO(emilio): Maybe rename to GetOwner*() or such? Might be
|
|
// confusing with nsINode::OwnerDoc and such.
|
|
dom::DocumentOrShadowRoot* GetAssociatedDocumentOrShadowRoot() const;
|
|
|
|
// Whether this stylesheet is kept alive by the associated or constructor
|
|
// document somehow, and thus at least has the same lifetime as
|
|
// GetAssociatedDocument().
|
|
dom::Document* GetKeptAliveByDocument() const;
|
|
|
|
// If this is a constructed style sheet, return mConstructorDocument.
|
|
// Otherwise return the document we're associated to,
|
|
// via mDocumentOrShadowRoot.
|
|
//
|
|
// Non-null iff GetAssociatedDocumentOrShadowRoot is non-null.
|
|
dom::Document* GetAssociatedDocument() const;
|
|
|
|
void SetAssociatedDocumentOrShadowRoot(dom::DocumentOrShadowRoot*);
|
|
void ClearAssociatedDocumentOrShadowRoot() {
|
|
SetAssociatedDocumentOrShadowRoot(nullptr);
|
|
}
|
|
|
|
nsINode* GetOwnerNode() const { return mOwningNode; }
|
|
|
|
nsINode* GetOwnerNodeOfOutermostSheet() const {
|
|
return OutermostSheet().GetOwnerNode();
|
|
}
|
|
|
|
StyleSheet* GetParentSheet() const { return mParentSheet; }
|
|
|
|
void AddReferencingRule(dom::CSSImportRule& aRule) {
|
|
MOZ_ASSERT(!mReferencingRules.Contains(&aRule));
|
|
mReferencingRules.AppendElement(&aRule);
|
|
}
|
|
|
|
void RemoveReferencingRule(dom::CSSImportRule& aRule) {
|
|
MOZ_ASSERT(mReferencingRules.Contains(&aRule));
|
|
mReferencingRules.RemoveElement(&aRule);
|
|
}
|
|
|
|
// Note that when exposed to script, this should always have a <= 1 length.
|
|
// CSSImportRule::GetStyleSheetForBindings takes care of that.
|
|
dom::CSSImportRule* GetOwnerRule() const {
|
|
return mReferencingRules.SafeElementAt(0);
|
|
}
|
|
|
|
void AppendStyleSheet(StyleSheet&);
|
|
|
|
// Append a stylesheet to the child list without calling WillDirty.
|
|
void AppendStyleSheetSilently(StyleSheet&);
|
|
|
|
const nsTArray<RefPtr<StyleSheet>>& ChildSheets() const {
|
|
#ifdef DEBUG
|
|
for (StyleSheet* child : Inner().mChildren) {
|
|
MOZ_ASSERT(child->GetParentSheet());
|
|
MOZ_ASSERT(child->GetParentSheet()->mInner == mInner);
|
|
}
|
|
#endif
|
|
return Inner().mChildren;
|
|
}
|
|
|
|
// Principal() never returns a null pointer.
|
|
nsIPrincipal* Principal() const { return Inner().mPrincipal; }
|
|
|
|
/**
|
|
* SetPrincipal should be called on all sheets before parsing into them.
|
|
* This can only be called once with a non-null principal.
|
|
*
|
|
* Calling this with a null pointer is allowed and is treated as a no-op.
|
|
*
|
|
* FIXME(emilio): Can we get this at construction time instead?
|
|
*/
|
|
void SetPrincipal(nsIPrincipal* aPrincipal) {
|
|
StyleSheetInfo& info = Inner();
|
|
MOZ_ASSERT(!info.mPrincipalSet, "Should only set principal once");
|
|
if (aPrincipal) {
|
|
info.mPrincipal = aPrincipal;
|
|
#ifdef DEBUG
|
|
info.mPrincipalSet = true;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void SetTitle(const nsAString& aTitle) { mTitle = aTitle; }
|
|
void SetMedia(already_AddRefed<dom::MediaList> aMedia);
|
|
|
|
// Get this style sheet's CORS mode
|
|
CORSMode GetCORSMode() const { return Inner().mCORSMode; }
|
|
|
|
// Get this style sheet's ReferrerInfo
|
|
nsIReferrerInfo* GetReferrerInfo() const { return Inner().mReferrerInfo; }
|
|
|
|
// Set this style sheet's ReferrerInfo
|
|
void SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
|
|
Inner().mReferrerInfo = aReferrerInfo;
|
|
}
|
|
|
|
// Get this style sheet's integrity metadata
|
|
void GetIntegrity(dom::SRIMetadata& aResult) const {
|
|
aResult = Inner().mIntegrity;
|
|
}
|
|
|
|
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
|
|
#if defined(DEBUG) || defined(MOZ_LAYOUT_DEBUGGER)
|
|
void List(FILE* aOut = stdout, int32_t aIndex = 0);
|
|
#endif
|
|
|
|
// WebIDL StyleSheet API
|
|
void GetType(nsAString& aType);
|
|
void GetHref(nsAString& aHref, ErrorResult& aRv);
|
|
// GetOwnerNode is defined above.
|
|
StyleSheet* GetParentStyleSheet() const { return GetParentSheet(); }
|
|
void GetTitle(nsAString& aTitle);
|
|
dom::MediaList* Media();
|
|
bool Disabled() const { return bool(mState & State::Disabled); }
|
|
void SetDisabled(bool aDisabled);
|
|
|
|
void GetSourceMapURL(nsACString&);
|
|
void SetSourceMapURL(nsCString&&);
|
|
void GetSourceURL(nsACString& aSourceURL);
|
|
|
|
// WebIDL CSSStyleSheet API
|
|
// Can't be inline because we can't include ImportRule here. And can't be
|
|
// called GetOwnerRule because that would be ambiguous with the ImportRule
|
|
// version.
|
|
css::Rule* GetDOMOwnerRule() const;
|
|
dom::CSSRuleList* GetCssRules(nsIPrincipal& aSubjectPrincipal, ErrorResult&);
|
|
uint32_t InsertRule(const nsACString& aRule, uint32_t aIndex,
|
|
nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
|
|
void DeleteRule(uint32_t aIndex, nsIPrincipal& aSubjectPrincipal,
|
|
ErrorResult& aRv);
|
|
int32_t AddRule(const nsACString& aSelector, const nsACString& aBlock,
|
|
const dom::Optional<uint32_t>& aIndex,
|
|
nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
|
|
already_AddRefed<dom::Promise> Replace(const nsACString& aText, ErrorResult&);
|
|
void ReplaceSync(const nsACString& aText, ErrorResult&);
|
|
bool ModificationDisallowed() const {
|
|
return bool(mState & State::ModificationDisallowed);
|
|
}
|
|
|
|
// Called before and after the asynchronous Replace() function
|
|
// to disable/re-enable modification while there is a pending promise.
|
|
void SetModificationDisallowed(bool aDisallowed) {
|
|
MOZ_ASSERT(IsConstructed());
|
|
MOZ_ASSERT(!IsReadOnly());
|
|
if (aDisallowed) {
|
|
mState |= State::ModificationDisallowed;
|
|
// Sheet will be re-set to complete when its rules are replaced
|
|
mState &= ~State::Complete;
|
|
if (!Disabled()) {
|
|
ApplicableStateChanged(false);
|
|
}
|
|
} else {
|
|
mState &= ~State::ModificationDisallowed;
|
|
}
|
|
}
|
|
|
|
// True if the sheet was created through the Constructable StyleSheets API
|
|
bool IsConstructed() const { return !!mConstructorDocument; }
|
|
|
|
// True if any of this sheet's ancestors were created through the
|
|
// Constructable StyleSheets API
|
|
bool SelfOrAncestorIsConstructed() const {
|
|
return OutermostSheet().IsConstructed();
|
|
}
|
|
|
|
// Ture if the sheet's constructor document matches the given document
|
|
bool ConstructorDocumentMatches(const dom::Document& aDocument) const {
|
|
return mConstructorDocument == &aDocument;
|
|
}
|
|
|
|
// Add a document or shadow root to the list of adopters.
|
|
// Adopters will be notified when styles are changed.
|
|
void AddAdopter(dom::DocumentOrShadowRoot& aAdopter) {
|
|
MOZ_ASSERT(IsConstructed());
|
|
MOZ_ASSERT(!mAdopters.Contains(&aAdopter));
|
|
mAdopters.AppendElement(&aAdopter);
|
|
}
|
|
|
|
// Remove a document or shadow root from the list of adopters.
|
|
void RemoveAdopter(dom::DocumentOrShadowRoot& aAdopter) {
|
|
// Cannot assert IsConstructed() because this can run after unlink.
|
|
mAdopters.RemoveElement(&aAdopter);
|
|
}
|
|
|
|
const nsTArray<dom::DocumentOrShadowRoot*>& SelfOrAncestorAdopters() const {
|
|
return OutermostSheet().mAdopters;
|
|
}
|
|
|
|
// WebIDL miscellaneous bits
|
|
inline dom::ParentObject GetParentObject() const;
|
|
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
|
|
|
|
// Changes to sheets should be after a WillDirty call.
|
|
void WillDirty();
|
|
|
|
// Called when a rule changes from CSSOM.
|
|
//
|
|
// FIXME(emilio): This shouldn't allow null, but MediaList doesn't know about
|
|
// its owning media rule, plus it's used for the stylesheet media itself.
|
|
void RuleChanged(css::Rule*, StyleRuleChangeKind);
|
|
|
|
void AddStyleSet(ServoStyleSet* aStyleSet);
|
|
void DropStyleSet(ServoStyleSet* aStyleSet);
|
|
|
|
nsresult DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex);
|
|
nsresult InsertRuleIntoGroup(const nsACString& aRule, css::GroupRule* aGroup,
|
|
uint32_t aIndex);
|
|
|
|
// Find the ID of the owner inner window.
|
|
uint64_t FindOwningWindowInnerID() const;
|
|
|
|
// Copy the contents of this style sheet into the shared memory buffer managed
|
|
// by aBuilder. Returns the pointer into the buffer that the sheet contents
|
|
// were stored at. (The returned pointer is to an Arc<Locked<Rules>> value,
|
|
// or null, with a filled in aErrorMessage, on failure.)
|
|
const StyleLockedCssRules* ToShared(StyleSharedMemoryBuilder* aBuilder,
|
|
nsCString& aErrorMessage);
|
|
|
|
// Sets the contents of this style sheet to the specified aSharedRules
|
|
// pointer, which must be a pointer somewhere in the aSharedMemory buffer
|
|
// as previously returned by a ToShared() call.
|
|
void SetSharedContents(const StyleLockedCssRules* aSharedRules);
|
|
|
|
// Whether this style sheet should not allow any modifications.
|
|
//
|
|
// This is true for any User Agent sheets once they are complete.
|
|
bool IsReadOnly() const;
|
|
|
|
// Removes a stylesheet from its parent sheet child list, if any.
|
|
void RemoveFromParent();
|
|
|
|
// Resolves mReplacePromise with this sheet.
|
|
void MaybeResolveReplacePromise();
|
|
|
|
// Rejects mReplacePromise with a NetworkError.
|
|
void MaybeRejectReplacePromise();
|
|
|
|
// Gets the relevant global if exists.
|
|
nsISupports* GetRelevantGlobal() const;
|
|
|
|
private:
|
|
void SetModifiedRules() {
|
|
mState |= State::ModifiedRules | State::ModifiedRulesForDevtools;
|
|
}
|
|
|
|
const StyleSheet& OutermostSheet() const {
|
|
const auto* current = this;
|
|
while (current->mParentSheet) {
|
|
MOZ_ASSERT(!current->mDocumentOrShadowRoot,
|
|
"Shouldn't be set on child sheets");
|
|
MOZ_ASSERT(!current->mConstructorDocument,
|
|
"Shouldn't be set on child sheets");
|
|
current = current->mParentSheet;
|
|
}
|
|
return *current;
|
|
}
|
|
|
|
StyleSheetInfo& Inner() {
|
|
MOZ_ASSERT(mInner);
|
|
return *mInner;
|
|
}
|
|
|
|
const StyleSheetInfo& Inner() const {
|
|
MOZ_ASSERT(mInner);
|
|
return *mInner;
|
|
}
|
|
|
|
// Check if the rules are available for read and write.
|
|
// It does the security check as well as whether the rules have been
|
|
// completely loaded. aRv will have an exception set if this function
|
|
// returns false.
|
|
bool AreRulesAvailable(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
|
|
|
|
void SetURLExtraData();
|
|
|
|
protected:
|
|
// Internal methods which do not have security check and completeness check.
|
|
uint32_t InsertRuleInternal(const nsACString& aRule, uint32_t aIndex,
|
|
ErrorResult&);
|
|
void DeleteRuleInternal(uint32_t aIndex, ErrorResult&);
|
|
nsresult InsertRuleIntoGroupInternal(const nsACString& aRule,
|
|
css::GroupRule* aGroup, uint32_t aIndex);
|
|
|
|
// Take the recently cloned sheets from the `@import` rules, and reparent them
|
|
// correctly to `aPrimarySheet`.
|
|
void FixUpAfterInnerClone();
|
|
|
|
// aFromClone says whether this comes from a clone of the stylesheet (and thus
|
|
// we should also fix up the wrappers for the individual rules in the rule
|
|
// lists).
|
|
void FixUpRuleListAfterContentsChangeIfNeeded(bool aFromClone = false);
|
|
|
|
void DropRuleList();
|
|
|
|
// Called when a rule is removed from the sheet from CSSOM.
|
|
void RuleAdded(css::Rule&);
|
|
|
|
// Called when a rule is added to the sheet from CSSOM.
|
|
void RuleRemoved(css::Rule&);
|
|
|
|
// Called when a stylesheet is cloned.
|
|
void StyleSheetCloned(StyleSheet&);
|
|
|
|
// Notifies that the applicable state changed.
|
|
// aApplicable is the value that we expect to get from IsApplicable().
|
|
// assertion will fail if the expectation does not match reality.
|
|
void ApplicableStateChanged(bool aApplicable);
|
|
|
|
void LastRelease();
|
|
|
|
// Return success if the subject principal subsumes the principal of our
|
|
// inner, error otherwise. This will also succeed if access is allowed by
|
|
// CORS. In that case, it will set the principal of the inner to the
|
|
// subject principal.
|
|
void SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
|
|
ErrorResult& aRv);
|
|
|
|
// Drop our reference to mMedia
|
|
void DropMedia();
|
|
|
|
// Unlink our inner, if needed, for cycle collection.
|
|
void UnlinkInner();
|
|
// Traverse our inner, if needed, for cycle collection
|
|
void TraverseInner(nsCycleCollectionTraversalCallback&);
|
|
|
|
// Return whether the given @import rule has pending child sheet.
|
|
static bool RuleHasPendingChildSheet(css::Rule* aRule);
|
|
|
|
StyleSheet* mParentSheet; // weak ref
|
|
|
|
// A pointer to the sheet's relevant global object. This is populated when the
|
|
// sheet gets an associated document and is complete.
|
|
//
|
|
// This is required for the sheet to be able to create a promise.
|
|
// https://html.spec.whatwg.org/#concept-relevant-everything
|
|
nsCOMPtr<nsIGlobalObject> mRelevantGlobal;
|
|
|
|
RefPtr<dom::Document> mConstructorDocument;
|
|
|
|
// Will be set in the Replace() function and resolved/rejected by the
|
|
// sheet once its rules have been replaced and the sheet is complete again.
|
|
RefPtr<dom::Promise> mReplacePromise;
|
|
|
|
nsString mTitle;
|
|
|
|
// weak ref; parents maintain this for their children
|
|
dom::DocumentOrShadowRoot* mDocumentOrShadowRoot;
|
|
nsINode* mOwningNode = nullptr; // weak ref
|
|
nsTArray<dom::CSSImportRule*> mReferencingRules; // weak ref
|
|
|
|
RefPtr<dom::MediaList> mMedia;
|
|
|
|
// mParsingMode controls access to nonstandard style constructs that
|
|
// are not safe for use on the public Web but necessary in UA sheets
|
|
// and/or useful in user sheets.
|
|
//
|
|
// FIXME(emilio): Given we store the parsed contents in the Inner, this should
|
|
// probably also move there.
|
|
css::SheetParsingMode mParsingMode;
|
|
|
|
State mState;
|
|
|
|
// Core information we get from parsed sheets, which are shared amongst
|
|
// StyleSheet clones.
|
|
//
|
|
// Always nonnull until LastRelease().
|
|
StyleSheetInfo* mInner;
|
|
|
|
nsTArray<ServoStyleSet*> mStyleSets;
|
|
|
|
RefPtr<ServoCSSRuleList> mRuleList;
|
|
|
|
MozPromiseHolder<StyleSheetParsePromise> mParsePromise;
|
|
|
|
nsTArray<dom::DocumentOrShadowRoot*> mAdopters;
|
|
|
|
// Make StyleSheetInfo and subclasses into friends so they can use
|
|
// ChildSheetListBuilder.
|
|
friend struct StyleSheetInfo;
|
|
};
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_StyleSheet_h
|