--- a/dom/base/DocumentOrShadowRoot.cpp
+++ b/dom/base/DocumentOrShadowRoot.cpp
@@ -29,16 +29,45 @@ StyleSheetList&
DocumentOrShadowRoot::EnsureDOMStyleSheets()
{
if (!mDOMStyleSheets) {
mDOMStyleSheets = new StyleSheetList(*this);
}
return *mDOMStyleSheets;
}
+void
+DocumentOrShadowRoot::AppendSheet(StyleSheet& aSheet)
+{
+ aSheet.SetAssociatedDocumentOrShadowRoot(
+ this, StyleSheet::OwnedByDocumentOrShadowRoot);
+ mStyleSheets.AppendElement(&aSheet);
+}
+
+void
+DocumentOrShadowRoot::InsertSheetAt(size_t aIndex, StyleSheet& aSheet)
+{
+ aSheet.SetAssociatedDocumentOrShadowRoot(
+ this, StyleSheet::OwnedByDocumentOrShadowRoot);
+ mStyleSheets.InsertElementAt(aIndex, &aSheet);
+}
+
+RefPtr<StyleSheet>
+DocumentOrShadowRoot::RemoveSheet(StyleSheet& aSheet)
+{
+ auto index = mStyleSheets.IndexOf(&aSheet);
+ if (index == nsTArray<RefPtr<StyleSheet>>::NoIndex) {
+ return nullptr;
+ }
+ RefPtr<StyleSheet> sheet = Move(mStyleSheets[index]);
+ mStyleSheets.RemoveElementAt(index);
+ sheet->ClearAssociatedDocumentOrShadowRoot();
+ return sheet;
+}
+
Element*
DocumentOrShadowRoot::GetElementById(const nsAString& aElementId)
{
if (MOZ_UNLIKELY(aElementId.IsEmpty())) {
nsContentUtils::ReportEmptyGetElementByIdArg(AsNode().OwnerDoc());
return nullptr;
}
--- a/dom/base/DocumentOrShadowRoot.h
+++ b/dom/base/DocumentOrShadowRoot.h
@@ -2,16 +2,18 @@
/* 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_dom_DocumentOrShadowRoot_h__
#define mozilla_dom_DocumentOrShadowRoot_h__
+#include "mozilla/dom/NameSpaceConstants.h"
+#include "nsContentListDeclarations.h"
#include "nsTArray.h"
#include "nsIdentifierMapEntry.h"
class nsContentList;
class nsINode;
namespace mozilla {
class StyleSheet;
@@ -60,31 +62,16 @@ public:
return mStyleSheets.Length();
}
int32_t IndexOfSheet(const StyleSheet& aSheet) const
{
return mStyleSheets.IndexOf(&aSheet);
}
- void InsertSheetAt(size_t aIndex, StyleSheet& aSheet)
- {
- mStyleSheets.InsertElementAt(aIndex, &aSheet);
- }
-
- void RemoveSheet(StyleSheet& aSheet)
- {
- mStyleSheets.RemoveElement(&aSheet);
- }
-
- void AppendStyleSheet(StyleSheet& aSheet)
- {
- mStyleSheets.AppendElement(&aSheet);
- }
-
StyleSheetList& EnsureDOMStyleSheets();
Element* GetElementById(const nsAString& aElementId);
/**
* This method returns _all_ the elements in this scope which have id
* aElementId, if there are any. Otherwise it returns null.
*
@@ -135,16 +122,21 @@ public:
FLUSH_LAYOUT = 2,
IS_ELEMENT_FROM_POINT = 4
};
void ElementsFromPointHelper(float aX, float aY, uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
protected:
+ // Returns the reference to the sheet, if found in mStyleSheets.
+ RefPtr<StyleSheet> RemoveSheet(StyleSheet& aSheet);
+ void AppendSheet(StyleSheet& aSheet);
+ void InsertSheetAt(size_t aIndex, StyleSheet& aSheet);
+
nsIContent* Retarget(nsIContent* aContent) const;
/**
* If focused element's subtree root is this document or shadow root, return
* focused element, otherwise, get the shadow host recursively until the
* shadow host's subtree root is this document or shadow root.
*/
Element* GetRetargetedFocusedElement();
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -127,17 +127,17 @@ ShadowRoot::WrapObject(JSContext* aCx, J
void
ShadowRoot::CloneInternalDataFrom(ShadowRoot* aOther)
{
size_t sheetCount = aOther->SheetCount();
for (size_t i = 0; i < sheetCount; ++i) {
StyleSheet* sheet = aOther->SheetAt(i);
if (sheet->IsApplicable()) {
RefPtr<StyleSheet> clonedSheet =
- sheet->Clone(nullptr, nullptr, nullptr, nullptr);
+ sheet->Clone(nullptr, nullptr, this, nullptr);
if (clonedSheet) {
AppendStyleSheet(*clonedSheet.get());
}
}
}
}
void
@@ -321,17 +321,17 @@ ShadowRoot::InsertSheetAt(size_t aIndex,
if (aSheet.IsApplicable()) {
InsertSheetIntoAuthorData(aIndex, aSheet);
}
}
void
ShadowRoot::AppendStyleSheet(StyleSheet& aSheet)
{
- DocumentOrShadowRoot::AppendStyleSheet(aSheet);
+ DocumentOrShadowRoot::AppendSheet(aSheet);
if (aSheet.IsApplicable()) {
Servo_AuthorStyles_AppendStyleSheet(mServoStyles.get(), &aSheet);
if (mStyleRuleMap) {
mStyleRuleMap->SheetAdded(aSheet);
}
ApplicableRulesChanged();
}
}
@@ -386,16 +386,18 @@ ShadowRoot::InsertSheetIntoAuthorData(si
ApplicableRulesChanged();
return;
}
Servo_AuthorStyles_AppendStyleSheet(mServoStyles.get(), &aSheet);
ApplicableRulesChanged();
}
+// FIXME(emilio): This needs to notify document observers and such,
+// presumably.
void
ShadowRoot::StyleSheetApplicableStateChanged(StyleSheet& aSheet, bool aApplicable)
{
MOZ_ASSERT(mStyleSheets.Contains(&aSheet));
if (aApplicable) {
int32_t index = IndexOfSheet(aSheet);
MOZ_RELEASE_ASSERT(index >= 0);
InsertSheetIntoAuthorData(size_t(index), aSheet);
@@ -406,22 +408,24 @@ ShadowRoot::StyleSheetApplicableStateCha
Servo_AuthorStyles_RemoveStyleSheet(mServoStyles.get(), &aSheet);
ApplicableRulesChanged();
}
}
void
ShadowRoot::RemoveSheet(StyleSheet* aSheet)
{
- DocumentOrShadowRoot::RemoveSheet(*aSheet);
- if (aSheet->IsApplicable()) {
+ MOZ_ASSERT(aSheet);
+ RefPtr<StyleSheet> sheet = DocumentOrShadowRoot::RemoveSheet(*aSheet);
+ MOZ_ASSERT(sheet);
+ if (sheet->IsApplicable()) {
if (mStyleRuleMap) {
- mStyleRuleMap->SheetRemoved(*aSheet);
+ mStyleRuleMap->SheetRemoved(*sheet);
}
- Servo_AuthorStyles_RemoveStyleSheet(mServoStyles.get(), aSheet);
+ Servo_AuthorStyles_RemoveStyleSheet(mServoStyles.get(), sheet);
ApplicableRulesChanged();
}
}
void
ShadowRoot::AddToIdTable(Element* aElement, nsAtom* aId)
{
nsIdentifierMapEntry* entry = mIdentifierMap.PutEntry(aId);
--- a/dom/base/ShadowRoot.h
+++ b/dom/base/ShadowRoot.h
@@ -4,16 +4,17 @@
* 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_dom_shadowroot_h__
#define mozilla_dom_shadowroot_h__
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/DocumentOrShadowRoot.h"
+#include "mozilla/dom/NameSpaceConstants.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIdentifierMapEntry.h"
#include "nsTHashtable.h"
class nsAtom;
class nsIContent;
class nsXBLPrototypeBinding;
@@ -31,35 +32,17 @@ namespace dom {
class Element;
class ShadowRoot final : public DocumentFragment,
public DocumentOrShadowRoot,
public nsStubMutationObserver
{
public:
- static ShadowRoot* FromNode(nsINode* aNode)
- {
- return aNode->IsShadowRoot() ? static_cast<ShadowRoot*>(aNode) : nullptr;
- }
-
- static const ShadowRoot* FromNode(const nsINode* aNode)
- {
- return aNode->IsShadowRoot() ? static_cast<const ShadowRoot*>(aNode) : nullptr;
- }
-
- static ShadowRoot* FromNodeOrNull(nsINode* aNode)
- {
- return aNode ? FromNode(aNode) : nullptr;
- }
-
- static const ShadowRoot* FromNodeOrNull(const nsINode* aNode)
- {
- return aNode ? FromNode(aNode) : nullptr;
- }
+ NS_IMPL_FROMNODE_HELPER(ShadowRoot, IsShadowRoot());
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot,
DocumentFragment)
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3464,17 +3464,17 @@ nsDOMWindowUtils::AddSheet(nsIPreloadedS
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
StyleSheet* sheet = nullptr;
auto preloadedSheet = static_cast<PreloadedStyleSheet*>(aSheet);
nsresult rv = preloadedSheet->GetSheet(&sheet);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
- if (sheet->GetAssociatedDocument()) {
+ if (sheet->GetAssociatedDocumentOrShadowRoot()) {
return NS_ERROR_INVALID_ARG;
}
nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
return doc->AddAdditionalStyleSheet(type, sheet);
}
NS_IMETHODIMP
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1685,21 +1685,21 @@ nsDocument::~nsDocument()
mChildren.ChildAt(indx)->UnbindFromTree();
mChildren.RemoveChildAt(indx);
}
mFirstChild = nullptr;
mCachedRootElement = nullptr;
// Let the stylesheets know we're going away
for (StyleSheet* sheet : mStyleSheets) {
- sheet->ClearAssociatedDocument();
+ sheet->ClearAssociatedDocumentOrShadowRoot();
}
for (auto& sheets : mAdditionalSheets) {
for (StyleSheet* sheet : sheets) {
- sheet->ClearAssociatedDocument();
+ sheet->ClearAssociatedDocumentOrShadowRoot();
}
}
if (mAttrStyleSheet) {
mAttrStyleSheet->SetOwningDocument(nullptr);
}
// We don't own the mOnDemandBuiltInUASheets, so we don't need to reset them.
if (mListenerManager) {
@@ -2426,17 +2426,17 @@ nsIDocument::MaybeDowngradePrincipal(nsI
return principal.forget();
}
void
nsIDocument::RemoveDocStyleSheetsFromStyleSets()
{
// The stylesheets should forget us
for (StyleSheet* sheet : Reversed(mStyleSheets)) {
- sheet->ClearAssociatedDocument();
+ sheet->ClearAssociatedDocumentOrShadowRoot();
if (sheet->IsApplicable()) {
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
shell->StyleSet()->RemoveDocStyleSheet(sheet);
}
}
// XXX Tell observers?
@@ -2445,17 +2445,17 @@ nsIDocument::RemoveDocStyleSheetsFromSty
void
nsIDocument::RemoveStyleSheetsFromStyleSets(
const nsTArray<RefPtr<StyleSheet>>& aSheets,
SheetType aType)
{
// The stylesheets should forget us
for (StyleSheet* sheet : Reversed(aSheets)) {
- sheet->ClearAssociatedDocument();
+ sheet->ClearAssociatedDocumentOrShadowRoot();
if (sheet->IsApplicable()) {
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
shell->StyleSet()->RemoveStyleSheet(aType, sheet);
}
}
// XXX Tell observers?
@@ -4332,55 +4332,53 @@ nsIDocument::NotifyStyleSheetRemoved(Sty
aDocumentSheet);
}
}
void
nsIDocument::AddStyleSheet(StyleSheet* aSheet)
{
MOZ_ASSERT(aSheet);
- mStyleSheets.AppendElement(aSheet);
- aSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
+ DocumentOrShadowRoot::AppendSheet(*aSheet);
if (aSheet->IsApplicable()) {
AddStyleSheetToStyleSets(aSheet);
}
NotifyStyleSheetAdded(aSheet, true);
}
void
nsIDocument::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet)
{
- nsCOMPtr<nsIPresShell> shell = GetShell();
- if (shell) {
+ if (nsIPresShell* shell = GetShell()) {
shell->StyleSet()->RemoveDocStyleSheet(aSheet);
}
}
void
nsIDocument::RemoveStyleSheet(StyleSheet* aSheet)
{
- MOZ_ASSERT(aSheet, "null arg");
- RefPtr<StyleSheet> sheet = aSheet; // hold ref so it won't die too soon
-
- if (!mStyleSheets.RemoveElement(aSheet)) {
+ MOZ_ASSERT(aSheet);
+ RefPtr<StyleSheet> sheet = DocumentOrShadowRoot::RemoveSheet(*aSheet);
+
+ if (!sheet) {
NS_ASSERTION(mInUnlinkOrDeletion, "stylesheet not found");
return;
}
if (!mIsGoingAway) {
- if (aSheet->IsApplicable()) {
- RemoveStyleSheetFromStyleSets(aSheet);
- }
-
- NotifyStyleSheetRemoved(aSheet, true);
- }
-
- aSheet->ClearAssociatedDocument();
+ if (sheet->IsApplicable()) {
+ RemoveStyleSheetFromStyleSets(sheet);
+ }
+
+ NotifyStyleSheetRemoved(sheet, true);
+ }
+
+ sheet->ClearAssociatedDocumentOrShadowRoot();
}
void
nsIDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets,
nsTArray<RefPtr<StyleSheet>>& aNewSheets)
{
BeginUpdate(UPDATE_STYLE);
@@ -4397,39 +4395,34 @@ nsIDocument::UpdateStyleSheets(nsTArray<
// First remove the old sheet.
NS_ASSERTION(oldSheet, "None of the old sheets should be null");
int32_t oldIndex = mStyleSheets.IndexOf(oldSheet);
RemoveStyleSheet(oldSheet); // This does the right notifications
// Now put the new one in its place. If it's null, just ignore it.
StyleSheet* newSheet = aNewSheets[i];
if (newSheet) {
- mStyleSheets.InsertElementAt(oldIndex, newSheet);
- newSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
+ DocumentOrShadowRoot::InsertSheetAt(oldIndex, *newSheet);
if (newSheet->IsApplicable()) {
AddStyleSheetToStyleSets(newSheet);
}
NotifyStyleSheetAdded(newSheet, true);
}
}
EndUpdate(UPDATE_STYLE);
}
void
nsIDocument::InsertStyleSheetAt(StyleSheet* aSheet, size_t aIndex)
{
MOZ_ASSERT(aSheet);
- // FIXME(emilio): Stop touching DocumentOrShadowRoot's members directly, and use an
- // accessor.
- mStyleSheets.InsertElementAt(aIndex, aSheet);
-
- aSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
+ DocumentOrShadowRoot::InsertSheetAt(aIndex, *aSheet);
if (aSheet->IsApplicable()) {
AddStyleSheetToStyleSets(aSheet);
}
NotifyStyleSheetAdded(aSheet, true);
}
@@ -4547,17 +4540,18 @@ nsIDocument::LoadAdditionalStyleSheet(ad
default:
MOZ_CRASH("impossible value for aType");
}
RefPtr<StyleSheet> sheet;
nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true, &sheet);
NS_ENSURE_SUCCESS(rv, rv);
- sheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
+ sheet->SetAssociatedDocumentOrShadowRoot(
+ this, StyleSheet::OwnedByDocumentOrShadowRoot);
MOZ_ASSERT(sheet->IsApplicable());
return AddAdditionalStyleSheet(aType, sheet);
}
nsresult
nsIDocument::AddAdditionalStyleSheet(additionalSheetType aType, StyleSheet* aSheet)
{
@@ -4605,17 +4599,17 @@ nsIDocument::RemoveAdditionalStyleSheet(
}
}
// Passing false, so documet.styleSheets.length will not be affected by
// these additional sheets.
NotifyStyleSheetRemoved(sheetRef, false);
EndUpdate(UPDATE_STYLE);
- sheetRef->ClearAssociatedDocument();
+ sheetRef->ClearAssociatedDocumentOrShadowRoot();
}
}
nsIGlobalObject*
nsIDocument::GetScopeObject() const
{
nsCOMPtr<nsIGlobalObject> scope(do_QueryReferent(mScopeObject));
return scope;
@@ -11759,17 +11753,17 @@ nsIDocument::DocAddSizeOfIncludingThis(n
static size_t
SizeOfOwnedSheetArrayExcludingThis(const nsTArray<RefPtr<StyleSheet>>& aSheets,
MallocSizeOf aMallocSizeOf)
{
size_t n = 0;
n += aSheets.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (StyleSheet* sheet : aSheets) {
- if (!sheet->GetAssociatedDocument()) {
+ if (!sheet->GetAssociatedDocumentOrShadowRoot()) {
// Avoid over-reporting shared sheets.
continue;
}
n += sheet->SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -3044,17 +3044,18 @@ NS_IMETHODIMP
HTMLEditor::EnableStyleSheet(const nsAString& aURL,
bool aEnable)
{
RefPtr<StyleSheet> sheet = GetStyleSheetForURL(aURL);
NS_ENSURE_TRUE(sheet, NS_OK); // Don't fail if sheet not found
// Ensure the style sheet is owned by our document.
nsCOMPtr<nsIDocument> document = GetDocument();
- sheet->SetAssociatedDocument(document, StyleSheet::NotOwnedByDocument);
+ sheet->SetAssociatedDocumentOrShadowRoot(
+ document, StyleSheet::NotOwnedByDocumentOrShadowRoot);
sheet->SetDisabled(!aEnable);
return NS_OK;
}
bool
HTMLEditor::EnableExistingStyleSheet(const nsAString& aURL)
{
@@ -3062,17 +3063,18 @@ HTMLEditor::EnableExistingStyleSheet(con
// Enable sheet if already loaded.
if (!sheet) {
return false;
}
// Ensure the style sheet is owned by our document.
nsCOMPtr<nsIDocument> document = GetDocument();
- sheet->SetAssociatedDocument(document, StyleSheet::NotOwnedByDocument);
+ sheet->SetAssociatedDocumentOrShadowRoot(
+ document, StyleSheet::NotOwnedByDocumentOrShadowRoot);
// FIXME: This used to do sheet->SetDisabled(false), figure out if we can
// just remove all this code in bug 1449522, since it seems unused.
return true;
}
nsresult
HTMLEditor::AddNewStyleSheetToList(const nsAString& aURL,
--- a/layout/style/ErrorReporter.cpp
+++ b/layout/style/ErrorReporter.cpp
@@ -172,16 +172,27 @@ ErrorReporter::ShouldReportErrors(const
return false;
}
bool report = false;
shell->GetCssErrorReportingEnabled(&report);
return report;
}
+static nsINode*
+SheetOwner(const StyleSheet& aSheet)
+{
+ if (nsINode* owner = aSheet.GetOwnerNode()) {
+ return owner;
+ }
+
+ auto* associated = aSheet.GetAssociatedDocumentOrShadowRoot();
+ return associated ? &associated->AsNode() : nullptr;
+}
+
bool
ErrorReporter::ShouldReportErrors()
{
MOZ_ASSERT(NS_IsMainThread());
EnsureGlobalsInitialized();
if (!sReportErrors) {
return false;
@@ -189,20 +200,17 @@ ErrorReporter::ShouldReportErrors()
if (mInnerWindowID) {
// We already reported an error, and that has cleared mSheet and mLoader, so
// we'd get the bogus value otherwise.
return true;
}
if (mSheet) {
- nsINode* owner = mSheet->GetOwnerNode()
- ? mSheet->GetOwnerNode()
- : mSheet->GetAssociatedDocument();
-
+ nsINode* owner = SheetOwner(*mSheet);
if (owner && ShouldReportErrors(*owner->OwnerDoc())) {
return true;
}
}
if (mLoader && mLoader->GetDocument() &&
ShouldReportErrors(*mLoader->GetDocument())) {
return true;
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -1238,18 +1238,17 @@ Loader::InsertSheetInDoc(StyleSheet* aSh
* practice, we get the call to load the child sheet before the CSSOM
* has finished inserting the @import rule, so we have no idea where
* to put it anyway. So just append for now. (In the future if we
* want to insert the sheet at the correct position, we'll need to
* restore CSSStyleSheet::InsertStyleSheetAt, which was removed in
* bug 1220506.)
*/
nsresult
-Loader::InsertChildSheet(StyleSheet* aSheet,
- StyleSheet* aParentSheet)
+Loader::InsertChildSheet(StyleSheet* aSheet, StyleSheet* aParentSheet)
{
LOG(("css::Loader::InsertChildSheet"));
MOZ_ASSERT(aSheet, "Nothing to insert");
MOZ_ASSERT(aParentSheet, "Need a parent to insert into");
// child sheets should always start out enabled, even if they got
// cloned off of top-level sheets which were disabled
aSheet->SetEnabled(true);
@@ -2158,19 +2157,17 @@ Loader::LoadChildSheet(StyleSheet* aPare
}
LOG_URI(" Child uri: '%s'", aURL);
nsCOMPtr<nsINode> owningNode;
// Check for an associated document: if none, don't bother walking up the
// parent sheets.
- //
- // FIXME(emilio): This looks wrong for Shadow DOM.
- if (aParentSheet->GetAssociatedDocument()) {
+ if (aParentSheet->GetAssociatedDocumentOrShadowRoot()) {
StyleSheet* topSheet = aParentSheet;
while (StyleSheet* parent = topSheet->GetParentSheet()) {
topSheet = parent;
}
owningNode = topSheet->GetOwnerNode();
}
nsINode* context = nullptr;
--- a/layout/style/MediaList.cpp
+++ b/layout/style/MediaList.cpp
@@ -40,20 +40,18 @@ MediaList::SetStyleSheet(StyleSheet* aSh
"Multiple style sheets competing for one media list");
mStyleSheet = aSheet;
}
template<typename Func>
nsresult
MediaList::DoMediaChange(Func aCallback)
{
- nsCOMPtr<nsIDocument> doc;
- if (mStyleSheet) {
- doc = mStyleSheet->GetAssociatedDocument();
- }
+ nsIDocument* doc =
+ mStyleSheet ? mStyleSheet->GetComposedDoc() : nullptr;
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
if (mStyleSheet) {
mStyleSheet->WillDirty();
}
nsresult rv = aCallback();
if (NS_FAILED(rv)) {
return rv;
--- a/layout/style/Rule.cpp
+++ b/layout/style/Rule.cpp
@@ -4,16 +4,17 @@
* 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/. */
/* base class for all rule types in a CSS style sheet */
#include "Rule.h"
#include "mozilla/css/GroupRule.h"
+#include "mozilla/dom/DocumentOrShadowRoot.h"
#include "nsCCUncollectableMarker.h"
#include "nsIDocument.h"
#include "nsWrapperCacheInlines.h"
using namespace mozilla;
using namespace mozilla::dom;
namespace mozilla {
@@ -42,22 +43,22 @@ Rule::IsKnownLive() const
return true;
}
StyleSheet* sheet = GetStyleSheet();
if (!sheet) {
return false;
}
- if (!sheet->IsOwnedByDocument()) {
+ if (!sheet->IsKeptAliveByDocument()) {
return false;
}
return nsCCUncollectableMarker::InGeneration(
- sheet->GetAssociatedDocument()->GetMarkedCCGeneration());
+ GetComposedDoc()->GetMarkedCCGeneration());
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(Rule)
return tmp->IsCCLeaf() || tmp->IsKnownLive();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(Rule)
// Please see documentation for nsCycleCollectionParticipant::CanSkip* for why
--- a/layout/style/Rule.h
+++ b/layout/style/Rule.h
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* base class for all rule types in a CSS style sheet */
#ifndef mozilla_css_Rule_h___
#define mozilla_css_Rule_h___
#include "mozilla/dom/CSSRuleBinding.h"
+#include "mozilla/dom/DocumentOrShadowRoot.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/MemoryReporting.h"
#include "nsISupports.h"
#include "nsWrapperCache.h"
class nsIDocument;
struct nsRuleData;
template<class T> struct already_AddRefed;
@@ -39,37 +40,44 @@ protected:
Rule(const Rule& aCopy)
: mSheet(aCopy.mSheet),
mParentRule(aCopy.mParentRule),
mLineNumber(aCopy.mLineNumber),
mColumnNumber(aCopy.mColumnNumber)
{
}
- virtual ~Rule() {}
+ virtual ~Rule() = default;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(Rule)
// Return true if this rule is known to be a cycle collection leaf, in the
// sense that it doesn't have any outgoing owning edges.
virtual bool IsCCLeaf() const MOZ_MUST_OVERRIDE;
#ifdef DEBUG
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const = 0;
#endif
StyleSheet* GetStyleSheet() const { return mSheet; }
- // Return the document the rule lives in, if any
- nsIDocument* GetDocument() const
+ // Return the document the rule applies to, if any.
+ //
+ // Suitable for style updates, and that's about it.
+ nsIDocument* GetComposedDoc() const
{
- StyleSheet* sheet = GetStyleSheet();
- return sheet ? sheet->GetAssociatedDocument() : nullptr;
+ return mSheet ? mSheet->GetComposedDoc() : nullptr;
+ }
+
+ // Return the document that owns this rule, if any.
+ nsIDocument* GetOwnerDoc() const
+ {
+ return mSheet ? mSheet->GetOwnerDoc() : nullptr;
}
virtual void SetStyleSheet(StyleSheet* aSheet);
// We don't reference count this up reference. The rule will tell us
// when it's going away or when we're detached from it.
void SetParentRule(Rule* aRule) {
#ifdef DEBUG
@@ -94,17 +102,24 @@ public:
const MOZ_MUST_OVERRIDE = 0;
// WebIDL interface
virtual uint16_t Type() const = 0;
virtual void GetCssText(nsAString& aCssText) const = 0;
void SetCssText(const nsAString& aCssText);
Rule* GetParentRule() const;
StyleSheet* GetParentStyleSheet() const { return GetStyleSheet(); }
- nsIDocument* GetParentObject() const { return GetDocument(); }
+ nsINode* GetParentObject() const
+ {
+ if (!mSheet) {
+ return nullptr;
+ }
+ auto* associated = mSheet->GetAssociatedDocumentOrShadowRoot();
+ return associated ? &associated->AsNode() : nullptr;
+ }
protected:
// True if we're known-live for cycle collection purposes.
bool IsKnownLive() const;
// This is sometimes null (e.g., for style attributes).
StyleSheet* mSheet;
// When the parent GroupRule is destroyed, it will call SetParentRule(nullptr)
--- a/layout/style/ServoCSSRuleList.cpp
+++ b/layout/style/ServoCSSRuleList.cpp
@@ -171,17 +171,17 @@ ServoCSSRuleList::DropReference()
nsresult
ServoCSSRuleList::InsertRule(const nsAString& aRule, uint32_t aIndex)
{
MOZ_ASSERT(mStyleSheet, "Caller must ensure that "
"the list is not unlinked from stylesheet");
NS_ConvertUTF16toUTF8 rule(aRule);
bool nested = !!mParentRule;
css::Loader* loader = nullptr;
- if (nsIDocument* doc = mStyleSheet->GetAssociatedDocument()) {
+ if (nsIDocument* doc = mStyleSheet->GetOwnerDoc()) {
loader = doc->CSSLoader();
}
uint16_t type;
nsresult rv = Servo_CssRules_InsertRule(mRawRules, mStyleSheet->RawContents(),
&rule, aIndex, nested,
loader, mStyleSheet, &type);
if (NS_FAILED(rv)) {
return rv;
--- a/layout/style/ServoCounterStyleRule.cpp
+++ b/layout/style/ServoCounterStyleRule.cpp
@@ -51,20 +51,19 @@ ServoCounterStyleRule::GetName(nsAString
nsAtom* name = Servo_CounterStyleRule_GetName(mRawRule);
nsDependentAtomString nameStr(name);
nsStyleUtil::AppendEscapedCSSIdent(nameStr, aName);
}
void
ServoCounterStyleRule::SetName(const nsAString& aName)
{
- nsIDocument* doc = GetDocument();
NS_ConvertUTF16toUTF8 name(aName);
if (Servo_CounterStyleRule_SetName(mRawRule, &name)) {
- MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
+ MOZ_AUTO_DOC_UPDATE(GetComposedDoc(), UPDATE_STYLE, true);
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
}
}
}
#define CSS_COUNTER_DESC(name_, method_) \
void \
@@ -75,18 +74,17 @@ ServoCounterStyleRule::SetName(const nsA
mRawRule, eCSSCounterDesc_##method_, &aValue); \
} \
void \
ServoCounterStyleRule::Set##method_(const nsAString& aValue) \
{ \
NS_ConvertUTF16toUTF8 value(aValue); \
if (Servo_CounterStyleRule_SetDescriptor( \
mRawRule, eCSSCounterDesc_##method_, &value)) { \
- nsIDocument* doc = GetDocument(); \
- MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); \
+ MOZ_AUTO_DOC_UPDATE(GetComposedDoc(), UPDATE_STYLE, true);\
if (StyleSheet* sheet = GetStyleSheet()) { \
sheet->RuleChanged(this); \
} \
} \
}
#include "nsCSSCounterDescList.h"
#undef CSS_COUNTER_DESC
--- a/layout/style/ServoFontFaceRule.cpp
+++ b/layout/style/ServoFontFaceRule.cpp
@@ -135,17 +135,17 @@ css::Rule*
ServoFontFaceRuleDecl::GetParentRule()
{
return ContainingRule();
}
nsINode*
ServoFontFaceRuleDecl::GetParentObject()
{
- return ContainingRule()->GetDocument();
+ return ContainingRule()->GetParentObject();
}
JSObject*
ServoFontFaceRuleDecl::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
{
return CSSStyleDeclarationBinding::Wrap(cx, this, aGivenProto);
}
--- a/layout/style/ServoKeyframeRule.cpp
+++ b/layout/style/ServoKeyframeRule.cpp
@@ -61,17 +61,17 @@ public:
nsIPrincipal* aSubjectPrincipal) const final
{
return GetServoCSSParsingEnvironmentForRule(mRule);
}
nsIDocument* DocToUpdate() final { return nullptr; }
nsINode* GetParentObject() final
{
- return mRule ? mRule->GetDocument() : nullptr;
+ return mRule ? mRule->GetParentObject() : nullptr;
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
// TODO we may want to add size of mDecls as well
return n;
}
@@ -144,18 +144,17 @@ ServoKeyframeRule::List(FILE* out, int32
fprintf_stderr(out, "%s\n", str.get());
}
#endif
template<typename Func>
void
ServoKeyframeRule::UpdateRule(Func aCallback)
{
- nsIDocument* doc = GetDocument();
- MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
+ MOZ_AUTO_DOC_UPDATE(GetComposedDoc(), UPDATE_STYLE, true);
aCallback();
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
}
}
--- a/layout/style/ServoKeyframesRule.cpp
+++ b/layout/style/ServoKeyframesRule.cpp
@@ -227,18 +227,17 @@ ServoKeyframesRule::FindRuleIndexForKey(
NS_ConvertUTF16toUTF8 key(aKey);
return Servo_KeyframesRule_FindRule(mRawRule, &key);
}
template<typename Func>
void
ServoKeyframesRule::UpdateRule(Func aCallback)
{
- nsIDocument* doc = GetDocument();
- MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
+ MOZ_AUTO_DOC_UPDATE(GetComposedDoc(), UPDATE_STYLE, true);
aCallback();
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
}
}
--- a/layout/style/ServoPageRule.cpp
+++ b/layout/style/ServoPageRule.cpp
@@ -50,17 +50,17 @@ css::Rule*
ServoPageRuleDeclaration::GetParentRule()
{
return Rule();
}
nsINode*
ServoPageRuleDeclaration::GetParentObject()
{
- return Rule()->GetDocument();
+ return Rule()->GetParentObject();
}
DeclarationBlock*
ServoPageRuleDeclaration::GetCSSDeclaration(Operation aOperation)
{
return mDecls;
}
--- a/layout/style/ServoStyleRule.cpp
+++ b/layout/style/ServoStyleRule.cpp
@@ -53,32 +53,31 @@ css::Rule*
ServoStyleRuleDeclaration::GetParentRule()
{
return Rule();
}
nsINode*
ServoStyleRuleDeclaration::GetParentObject()
{
- return Rule()->GetDocument();
+ return Rule()->GetParentObject();
}
DeclarationBlock*
ServoStyleRuleDeclaration::GetCSSDeclaration(Operation aOperation)
{
return mDecls;
}
nsresult
ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
{
ServoStyleRule* rule = Rule();
if (RefPtr<StyleSheet> sheet = rule->GetStyleSheet()) {
- nsCOMPtr<nsIDocument> doc = sheet->GetAssociatedDocument();
- mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
+ mozAutoDocUpdate updateBatch(sheet->GetComposedDoc(), UPDATE_STYLE, true);
if (aDecl != mDecls) {
mDecls->SetOwningRule(nullptr);
RefPtr<ServoDeclarationBlock> decls = aDecl->AsServo();
Servo_StyleRule_SetStyle(rule->Raw(), decls->Raw());
mDecls = decls.forget();
mDecls->SetOwningRule(rule);
}
sheet->RuleChanged(rule);
@@ -192,19 +191,17 @@ ServoStyleRule::GetSelectorText(nsAStrin
{
Servo_StyleRule_GetSelectorText(mRawRule, &aSelectorText);
}
void
ServoStyleRule::SetSelectorText(const nsAString& aSelectorText)
{
if (RefPtr<StyleSheet> sheet = GetStyleSheet()) {
- nsIDocument* doc = sheet->GetAssociatedDocument();
-
- mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
+ mozAutoDocUpdate updateBatch(sheet->GetComposedDoc(), UPDATE_STYLE, true);
// StyleRule lives inside of the Inner, it is unsafe to call WillDirty
// if sheet does not already have a unique Inner.
sheet->AssertHasUniqueInner();
sheet->WillDirty();
const RawServoStyleSheetContents* contents = sheet->RawContents();
if (Servo_StyleRule_SetSelectorText(contents, mRawRule, &aSelectorText)) {
@@ -213,17 +210,16 @@ ServoStyleRule::SetSelectorText(const ns
}
}
uint32_t
ServoStyleRule::GetSelectorCount()
{
uint32_t aCount;
Servo_StyleRule_GetSelectorCount(mRawRule, &aCount);
-
return aCount;
}
nsresult
ServoStyleRule::GetSelectorText(uint32_t aSelectorIndex, nsAString& aText)
{
Servo_StyleRule_GetSelectorTextAtIndex(mRawRule, aSelectorIndex, &aText);
return NS_OK;
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -25,44 +25,44 @@
namespace mozilla {
StyleSheet::StyleSheet(css::SheetParsingMode aParsingMode,
CORSMode aCORSMode,
net::ReferrerPolicy aReferrerPolicy,
const dom::SRIMetadata& aIntegrity)
: mParent(nullptr)
- , mDocument(nullptr)
+ , mDocumentOrShadowRoot(nullptr)
, mOwningNode(nullptr)
, mOwnerRule(nullptr)
, mParsingMode(aParsingMode)
, mDisabled(false)
, mDirtyFlags(0)
- , mDocumentAssociationMode(NotOwnedByDocument)
+ , mAssociationMode(NotOwnedByDocumentOrShadowRoot)
, mInner(new StyleSheetInfo(aCORSMode, aReferrerPolicy, aIntegrity, aParsingMode))
{
mInner->AddSheet(this);
}
StyleSheet::StyleSheet(const StyleSheet& aCopy,
StyleSheet* aParentToUse,
dom::CSSImportRule* aOwnerRuleToUse,
- nsIDocument* aDocumentToUse,
+ dom::DocumentOrShadowRoot* aDocumentOrShadowRoot,
nsINode* aOwningNodeToUse)
: mParent(aParentToUse)
, mTitle(aCopy.mTitle)
- , mDocument(aDocumentToUse)
+ , mDocumentOrShadowRoot(aDocumentOrShadowRoot)
, mOwningNode(aOwningNodeToUse)
, mOwnerRule(aOwnerRuleToUse)
, mParsingMode(aCopy.mParsingMode)
, mDisabled(aCopy.mDisabled)
, mDirtyFlags(aCopy.mDirtyFlags)
// We only use this constructor during cloning. It's the cloner's
// responsibility to notify us if we end up being owned by a document.
- , mDocumentAssociationMode(NotOwnedByDocument)
+ , mAssociationMode(NotOwnedByDocumentOrShadowRoot)
, mInner(aCopy.mInner) // Shallow copy, but concrete subclasses will fix up.
{
MOZ_ASSERT(mInner, "Should only copy StyleSheets with an mInner.");
mInner->AddSheet(this);
if (HasForcedUniqueInner()) { // CSSOM's been there, force full copy now
NS_ASSERTION(mInner->mComplete,
"Why have rules been accessed on an incomplete sheet?");
@@ -83,16 +83,42 @@ StyleSheet::~StyleSheet()
}
bool
StyleSheet::HasRules() const
{
return Servo_StyleSheet_HasRules(Inner().mContents);
}
+nsIDocument*
+StyleSheet::GetOwnerDoc() const
+{
+ return mDocumentOrShadowRoot
+ ? mDocumentOrShadowRoot->AsNode().OwnerDoc()
+ : nullptr;
+}
+
+nsIDocument*
+StyleSheet::GetComposedDoc() const
+{
+ return mDocumentOrShadowRoot
+ ? mDocumentOrShadowRoot->AsNode().GetComposedDoc()
+ : nullptr;
+}
+
+bool
+StyleSheet::IsKeptAliveByDocument() const
+{
+ if (mAssociationMode != OwnedByDocumentOrShadowRoot) {
+ return false;
+ }
+
+ return !!GetComposedDoc();
+}
+
void
StyleSheet::LastRelease()
{
MOZ_ASSERT(mInner, "Should have an mInner at time of destruction.");
MOZ_ASSERT(mInner->mSheets.Contains(this), "Our mInner should include us.");
UnparentChildren();
@@ -123,17 +149,17 @@ StyleSheet::UnlinkInner()
while (child) {
MOZ_ASSERT(child->mParent == this, "We have a unique inner!");
child->mParent = nullptr;
// We (and child) might still think we're owned by a document, because
// unlink order is non-deterministic, so the document's unlink, which would
// tell us it does't own us anymore, may not have happened yet. But if
// we're being unlinked, clearly we're not owned by a document anymore
// conceptually!
- child->SetAssociatedDocument(nullptr, NotOwnedByDocument);
+ child->ClearAssociatedDocumentOrShadowRoot();
RefPtr<StyleSheet> next;
// Null out child->mNext, but don't let it die yet
next.swap(child->mNext);
// Switch to looking at the old value of child->mNext next iteration
child.swap(next);
// "next" is now our previous value of child; it'll get released
// as we loop around.
@@ -221,24 +247,28 @@ StyleSheet::SetComplete()
if (!mDisabled) {
ApplicableStateChanged(true);
}
}
void
StyleSheet::ApplicableStateChanged(bool aApplicable)
{
- if (mDocument) {
- mDocument->BeginUpdate(UPDATE_STYLE);
- mDocument->SetStyleSheetApplicableState(this, aApplicable);
- mDocument->EndUpdate(UPDATE_STYLE);
+ if (!mDocumentOrShadowRoot) {
+ return;
}
- if (dom::ShadowRoot* shadow = GetContainingShadow()) {
+ nsINode& node = mDocumentOrShadowRoot->AsNode();
+ if (auto* shadow = ShadowRoot::FromNode(node)) {
shadow->StyleSheetApplicableStateChanged(*this, aApplicable);
+ } else {
+ nsIDocument* doc = node.AsDocument();
+ doc->BeginUpdate(UPDATE_STYLE);
+ doc->SetStyleSheetApplicableState(this, aApplicable);
+ doc->EndUpdate(UPDATE_STYLE);
}
}
void
StyleSheet::SetEnabled(bool aEnabled)
{
// Internal method, so callers must handle BeginUpdate/EndUpdate
bool oldDisabled = mDisabled;
@@ -342,42 +372,42 @@ StyleSheetInfo::RemoveSheet(StyleSheet*
mSheets.RemoveElement(aSheet);
}
void
StyleSheet::ChildSheetListBuilder::SetParentLinks(StyleSheet* aSheet)
{
aSheet->mParent = parent;
- aSheet->SetAssociatedDocument(parent->mDocument,
- parent->mDocumentAssociationMode);
+ aSheet->SetAssociatedDocumentOrShadowRoot(parent->mDocumentOrShadowRoot,
+ parent->mAssociationMode);
}
void
StyleSheet::ChildSheetListBuilder::ReparentChildList(StyleSheet* aPrimarySheet,
StyleSheet* aFirstChild)
{
for (StyleSheet *child = aFirstChild; child; child = child->mNext) {
child->mParent = aPrimarySheet;
- child->SetAssociatedDocument(aPrimarySheet->mDocument,
- aPrimarySheet->mDocumentAssociationMode);
+ child->SetAssociatedDocumentOrShadowRoot(aPrimarySheet->mDocumentOrShadowRoot,
+ aPrimarySheet->mAssociationMode);
}
}
void
StyleSheet::GetType(nsAString& aType)
{
aType.AssignLiteral("text/css");
}
void
StyleSheet::SetDisabled(bool aDisabled)
{
// DOM method, so handle BeginUpdate/EndUpdate
- MOZ_AUTO_DOC_UPDATE(mDocument, UPDATE_STYLE, true);
+ MOZ_AUTO_DOC_UPDATE(GetComposedDoc(), UPDATE_STYLE, true);
SetEnabled(!aDisabled);
}
void
StyleSheet::GetHref(nsAString& aHref, ErrorResult& aRv)
{
if (nsIURI* sheetURI = Inner().mOriginalSheetURI) {
nsAutoCString str;
@@ -550,17 +580,17 @@ StyleSheet::DeleteRuleFromGroup(css::Gro
RefPtr<css::Rule> rule = aGroup->GetStyleRuleAt(aIndex);
NS_ENSURE_TRUE(rule, NS_ERROR_ILLEGAL_VALUE);
// check that the rule actually belongs to this sheet!
if (this != rule->GetStyleSheet()) {
return NS_ERROR_INVALID_ARG;
}
- mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
+ mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_STYLE, true);
WillDirty();
nsresult result = aGroup->DeleteStyleRuleAt(aIndex);
NS_ENSURE_SUCCESS(result, result);
rule->SetStyleSheet(nullptr);
RuleRemoved(*rule);
@@ -591,40 +621,40 @@ StyleSheet::GetContainingShadow() const
} while (0)
void
StyleSheet::RuleAdded(css::Rule& aRule)
{
mDirtyFlags |= MODIFIED_RULES;
NOTIFY(RuleAdded, (*this, aRule));
- if (mDocument) {
- mDocument->StyleRuleAdded(this, &aRule);
+ if (nsIDocument* doc = GetComposedDoc()) {
+ doc->StyleRuleAdded(this, &aRule);
}
}
void
StyleSheet::RuleRemoved(css::Rule& aRule)
{
mDirtyFlags |= MODIFIED_RULES;
NOTIFY(RuleRemoved, (*this, aRule));
- if (mDocument) {
- mDocument->StyleRuleRemoved(this, &aRule);
+ if (nsIDocument* doc = GetComposedDoc()) {
+ doc->StyleRuleRemoved(this, &aRule);
}
}
void
StyleSheet::RuleChanged(css::Rule* aRule)
{
mDirtyFlags |= MODIFIED_RULES;
NOTIFY(RuleChanged, (*this, aRule));
- if (mDocument) {
- mDocument->StyleRuleChanged(this, aRule);
+ if (nsIDocument* doc = GetComposedDoc()) {
+ doc->StyleRuleChanged(this, aRule);
}
}
#undef NOTIFY
nsresult
StyleSheet::InsertRuleIntoGroup(const nsAString& aRule,
css::GroupRule* aGroup,
@@ -632,33 +662,33 @@ StyleSheet::InsertRuleIntoGroup(const ns
{
NS_ASSERTION(IsComplete(), "No inserting into an incomplete sheet!");
// check that the group actually belongs to this sheet!
if (this != aGroup->GetStyleSheet()) {
return NS_ERROR_INVALID_ARG;
}
// parse and grab the rule
- mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
+ mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_STYLE, true);
WillDirty();
nsresult result = InsertRuleIntoGroupInternal(aRule, aGroup, aIndex);
NS_ENSURE_SUCCESS(result, result);
RuleAdded(*aGroup->GetStyleRuleAt(aIndex));
return NS_OK;
}
uint64_t
StyleSheet::FindOwningWindowInnerID() const
{
uint64_t windowID = 0;
- if (mDocument) {
- windowID = mDocument->InnerWindowID();
+ if (nsIDocument* doc = GetOwnerDoc()) {
+ windowID = doc->InnerWindowID();
}
if (windowID == 0 && mOwningNode) {
windowID = mOwningNode->OwnerDoc()->InnerWindowID();
}
RefPtr<css::Rule> ownerRule;
if (windowID == 0 && (ownerRule = GetDOMOwnerRule())) {
@@ -680,20 +710,20 @@ StyleSheet::UnparentChildren()
{
// XXXbz this is a little bogus; see the XXX comment where we
// declare mFirstChild in StyleSheetInfo.
for (StyleSheet* child = GetFirstChild();
child;
child = child->mNext) {
if (child->mParent == this) {
child->mParent = nullptr;
- MOZ_ASSERT(child->mDocumentAssociationMode == NotOwnedByDocument,
+ MOZ_ASSERT(child->mAssociationMode == NotOwnedByDocumentOrShadowRoot,
"How did we get to the destructor, exactly, if we're owned "
"by a document?");
- child->mDocument = nullptr;
+ child->mDocumentOrShadowRoot = nullptr;
}
}
}
void
StyleSheet::SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
ErrorResult& aRv)
{
@@ -752,43 +782,38 @@ StyleSheet::AreRulesAvailable(nsIPrincip
StyleSheet*
StyleSheet::GetFirstChild() const
{
return Inner().mFirstChild;
}
void
-StyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
- DocumentAssociationMode aAssociationMode)
+StyleSheet::SetAssociatedDocumentOrShadowRoot(DocumentOrShadowRoot* aDocOrShadowRoot,
+ AssociationMode aAssociationMode)
{
- MOZ_ASSERT(aDocument || aAssociationMode == NotOwnedByDocument);
+ MOZ_ASSERT(aDocOrShadowRoot ||
+ aAssociationMode == NotOwnedByDocumentOrShadowRoot);
// not ref counted
- mDocument = aDocument;
- mDocumentAssociationMode = aAssociationMode;
+ mDocumentOrShadowRoot = aDocOrShadowRoot;
+ mAssociationMode = aAssociationMode;
// Now set the same document on all our child sheets....
// XXXbz this is a little bogus; see the XXX comment where we
// declare mFirstChild.
for (StyleSheet* child = GetFirstChild();
child; child = child->mNext) {
if (child->mParent == this) {
- child->SetAssociatedDocument(aDocument, aAssociationMode);
+ child->SetAssociatedDocumentOrShadowRoot(aDocOrShadowRoot, aAssociationMode);
}
}
}
void
-StyleSheet::ClearAssociatedDocument()
-{
- SetAssociatedDocument(nullptr, NotOwnedByDocument);
-}
-
-void
StyleSheet::PrependStyleSheet(StyleSheet* aSheet)
{
WillDirty();
PrependStyleSheetSilently(aSheet);
}
void
StyleSheet::PrependStyleSheetSilently(StyleSheet* aSheet)
@@ -796,17 +821,17 @@ StyleSheet::PrependStyleSheetSilently(St
MOZ_ASSERT(aSheet);
aSheet->mNext = Inner().mFirstChild;
Inner().mFirstChild = aSheet;
// This is not reference counted. Our parent tells us when
// it's going away.
aSheet->mParent = this;
- aSheet->SetAssociatedDocument(mDocument, mDocumentAssociationMode);
+ aSheet->SetAssociatedDocumentOrShadowRoot(mDocumentOrShadowRoot, mAssociationMode);
}
size_t
StyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = 0;
const StyleSheet* s = this;
while (s) {
@@ -1088,40 +1113,40 @@ StyleSheet::ReparseSheet(const nsAString
{
if (!mInner->mComplete) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
// Hold strong ref to the CSSLoader in case the document update
// kills the document
RefPtr<css::Loader> loader;
- if (mDocument) {
- loader = mDocument->CSSLoader();
+ if (nsIDocument* doc = GetOwnerDoc()) {
+ loader = doc->CSSLoader();
NS_ASSERTION(loader, "Document with no CSS loader!");
} else {
loader = new css::Loader;
}
- mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
+ mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_STYLE, true);
WillDirty();
// cache child sheets to reuse
css::LoaderReusableStyleSheets reusableSheets;
for (StyleSheet* child = GetFirstChild(); child; child = child->mNext) {
if (child->GetOriginalURI()) {
reusableSheets.AddReusableSheet(child);
}
}
// clean up child sheets list
for (StyleSheet* child = GetFirstChild(); child; ) {
StyleSheet* next = child->mNext;
child->mParent = nullptr;
- child->SetAssociatedDocument(nullptr, NotOwnedByDocument);
+ child->ClearAssociatedDocumentOrShadowRoot();
child->mNext = nullptr;
child = next;
}
Inner().mFirstChild = nullptr;
uint32_t lineNumber = 1;
if (mOwningNode) {
nsCOMPtr<nsIStyleSheetLinkingElement> link = do_QueryInterface(mOwningNode);
@@ -1188,17 +1213,17 @@ StyleSheet::StyleSheetLoaded(StyleSheet*
{
if (!aSheet->GetParentSheet()) {
return NS_OK; // ignore if sheet has been detached already
}
NS_ASSERTION(this == aSheet->GetParentSheet(),
"We are being notified of a sheet load for a sheet that is not our child!");
if (NS_SUCCEEDED(aStatus)) {
- mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
+ mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_STYLE, true);
RuleAdded(*aSheet->GetOwnerRule());
}
return NS_OK;
}
void
StyleSheet::DropRuleList()
@@ -1207,24 +1232,24 @@ StyleSheet::DropRuleList()
mRuleList->DropReference();
mRuleList = nullptr;
}
}
already_AddRefed<StyleSheet>
StyleSheet::Clone(StyleSheet* aCloneParent,
dom::CSSImportRule* aCloneOwnerRule,
- nsIDocument* aCloneDocument,
+ dom::DocumentOrShadowRoot* aCloneDocumentOrShadowRoot,
nsINode* aCloneOwningNode) const
{
RefPtr<StyleSheet> clone =
new StyleSheet(*this,
aCloneParent,
aCloneOwnerRule,
- aCloneDocument,
+ aCloneDocumentOrShadowRoot,
aCloneOwningNode);
return clone.forget();
}
ServoCSSRuleList*
StyleSheet::GetCssRulesInternal()
{
if (!mRuleList) {
@@ -1241,17 +1266,17 @@ StyleSheet::GetCssRulesInternal()
uint32_t
StyleSheet::InsertRuleInternal(const nsAString& aRule,
uint32_t aIndex,
ErrorResult& aRv)
{
// Ensure mRuleList is constructed.
GetCssRulesInternal();
- mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
+ mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_STYLE, true);
aRv = mRuleList->InsertRule(aRule, aIndex);
if (aRv.Failed()) {
return 0;
}
// XXX We may not want to get the rule when stylesheet change event
// is not enabled.
css::Rule* rule = mRuleList->GetRule(aIndex);
@@ -1268,17 +1293,17 @@ StyleSheet::DeleteRuleInternal(uint32_t
{
// Ensure mRuleList is constructed.
GetCssRulesInternal();
if (aIndex >= mRuleList->Length()) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
- mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
+ mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_STYLE, true);
// Hold a strong ref to the rule so it doesn't die when we remove it
// from the list. XXX We may not want to hold it if stylesheet change
// event is not enabled.
RefPtr<css::Rule> rule = mRuleList->GetRule(aIndex);
aRv = mRuleList->DeleteRule(aIndex);
MOZ_ASSERT(!aRv.ErrorCodeIs(NS_ERROR_DOM_INDEX_SIZE_ERR),
"IndexSizeError should have been handled earlier");
if (!aRv.Failed()) {
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -42,28 +42,29 @@ class Loader;
class LoaderReusableStyleSheets;
class Rule;
class SheetLoadData;
}
namespace dom {
class CSSImportRule;
class CSSRuleList;
+class DocumentOrShadowRoot;
class MediaList;
class ShadowRoot;
class SRIMetadata;
} // namespace dom
class StyleSheet final : public nsICSSLoaderObserver
, public nsWrapperCache
{
StyleSheet(const StyleSheet& aCopy,
StyleSheet* aParentToUse,
dom::CSSImportRule* aOwnerRuleToUse,
- nsIDocument* aDocumentToUse,
+ dom::DocumentOrShadowRoot* aDocOrShadowRootToUse,
nsINode* aOwningNodeToUse);
virtual ~StyleSheet();
public:
StyleSheet(css::SheetParsingMode aParsingMode,
CORSMode aCORSMode,
net::ReferrerPolicy aReferrerPolicy,
@@ -205,17 +206,17 @@ public:
*/
bool IsApplicable() const
{
return !mDisabled && Inner().mComplete;
}
already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
dom::CSSImportRule* aCloneOwnerRule,
- nsIDocument* aCloneDocument,
+ dom::DocumentOrShadowRoot* aCloneDocumentOrShadowRoot,
nsINode* aCloneOwningNode) const;
bool HasForcedUniqueInner() const
{
return mDirtyFlags & FORCED_UNIQUE_INNER;
}
bool HasModifiedRules() const
@@ -239,31 +240,42 @@ public:
}
void EnsureUniqueInner();
// Append all of this sheet's child sheets to aArray.
void AppendAllChildSheets(nsTArray<StyleSheet*>& aArray);
// style sheet owner info
- enum DocumentAssociationMode : uint8_t {
- // OwnedByDocument means mDocument owns us (possibly via a chain of other
- // stylesheets).
- OwnedByDocument,
+ enum AssociationMode : uint8_t {
+ // OwnedByDocumentOrShadowRoot means mDocumentOrShadowRoot owns us (possibly
+ // via a chain of other stylesheets).
+ OwnedByDocumentOrShadowRoot,
// NotOwnedByDocument means we're owned by something that might have a
// different lifetime than mDocument.
- NotOwnedByDocument
+ NotOwnedByDocumentOrShadowRoot
};
- nsIDocument* GetAssociatedDocument() const { return mDocument; }
- bool IsOwnedByDocument() const {
- return mDocumentAssociationMode == OwnedByDocument;
+ dom::DocumentOrShadowRoot* GetAssociatedDocumentOrShadowRoot() const
+ {
+ return mDocumentOrShadowRoot;
}
- // aDocument must not be null.
- void SetAssociatedDocument(nsIDocument* aDocument, DocumentAssociationMode);
- void ClearAssociatedDocument();
+ bool IsKeptAliveByDocument() const;
+
+ // Returns the document whose styles this sheet is affecting.
+ nsIDocument* GetComposedDoc() const;
+
+ // Returns the document we belong to, if any.
+ nsIDocument* GetOwnerDoc() const;
+
+ void SetAssociatedDocumentOrShadowRoot(dom::DocumentOrShadowRoot*,
+ AssociationMode);
+ void ClearAssociatedDocumentOrShadowRoot()
+ {
+ SetAssociatedDocumentOrShadowRoot(nullptr, NotOwnedByDocumentOrShadowRoot);
+ }
nsINode* GetOwnerNode() const
{
return mOwningNode;
}
StyleSheet* GetParentSheet() const
{
@@ -477,17 +489,17 @@ protected:
void TraverseInner(nsCycleCollectionTraversalCallback &);
// Return whether the given @import rule has pending child sheet.
static bool RuleHasPendingChildSheet(css::Rule* aRule);
StyleSheet* mParent; // weak ref
nsString mTitle;
- nsIDocument* mDocument; // weak ref; parents maintain this for their children
+ dom::DocumentOrShadowRoot* mDocumentOrShadowRoot; // weak ref; parents maintain this for their children
nsINode* mOwningNode; // weak ref
dom::CSSImportRule* mOwnerRule; // weak ref
RefPtr<dom::MediaList> mMedia;
RefPtr<StyleSheet> mNext;
// mParsingMode controls access to nonstandard style constructs that
@@ -498,20 +510,21 @@ protected:
bool mDisabled;
enum dirtyFlagAttributes {
FORCED_UNIQUE_INNER = 0x1,
MODIFIED_RULES = 0x2,
};
uint8_t mDirtyFlags; // has been modified
- // mDocumentAssociationMode determines whether mDocument directly owns us (in
- // the sense that if it's known-live then we're known-live). Always
- // NotOwnedByDocument when mDocument is null.
- DocumentAssociationMode mDocumentAssociationMode;
+ // mAssociationMode determines whether mDocumentOrShadowRoot directly owns us
+ // (in the sense that if it's known-live then we're known-live).
+ //
+ // Always NotOwnedByDocumentOrShadowRoot when mDocumentOrShadowRoot is null.
+ AssociationMode mAssociationMode;
// Core information we get from parsed sheets, which are shared amongst
// StyleSheet clones.
//
// FIXME(emilio): Should be NonNull.
StyleSheetInfo* mInner;
nsTArray<ServoStyleSet*> mStyleSets;
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -231,17 +231,17 @@ nsDOMCSSDeclaration::RemoveProperty(cons
/* static */ nsDOMCSSDeclaration::ServoCSSParsingEnvironment
nsDOMCSSDeclaration::GetServoCSSParsingEnvironmentForRule(const css::Rule* aRule)
{
StyleSheet* sheet = aRule ? aRule->GetStyleSheet() : nullptr;
if (!sheet) {
return { nullptr, eCompatibility_FullStandards, nullptr };
}
- if (nsIDocument* document = aRule->GetDocument()) {
+ if (nsIDocument* document = aRule->GetOwnerDoc()) {
return {
sheet->URLData(),
document->GetCompatibilityMode(),
document->CSSLoader(),
};
}
return {