Bug 1630835 - Don't propagate associated document or shadow root to child sheets. r=nordzilla

This should have no behavior change, but makes the setup simpler and
more similar to the constructable sheets.

Differential Revision: https://phabricator.services.mozilla.com/D71262
This commit is contained in:
Emilio Cobos Álvarez 2020-04-17 22:54:35 +00:00
Родитель c64e7f13d2
Коммит 63dce710f2
2 изменённых файлов: 27 добавлений и 68 удалений

Просмотреть файл

@ -163,11 +163,10 @@ Document* StyleSheet::GetAssociatedDocument() const {
dom::DocumentOrShadowRoot* StyleSheet::GetAssociatedDocumentOrShadowRoot() dom::DocumentOrShadowRoot* StyleSheet::GetAssociatedDocumentOrShadowRoot()
const { const {
if (mDocumentOrShadowRoot) {
return mDocumentOrShadowRoot;
}
for (const auto* sheet = this; sheet; sheet = sheet->mParentSheet) { for (const auto* sheet = this; sheet; sheet = sheet->mParentSheet) {
MOZ_ASSERT(!sheet->mDocumentOrShadowRoot); if (sheet->mDocumentOrShadowRoot) {
return sheet->mDocumentOrShadowRoot;
}
if (sheet->IsConstructed()) { if (sheet->IsConstructed()) {
return sheet->mConstructorDocument; return sheet->mConstructorDocument;
} }
@ -176,14 +175,11 @@ dom::DocumentOrShadowRoot* StyleSheet::GetAssociatedDocumentOrShadowRoot()
} }
Document* StyleSheet::GetKeptAliveByDocument() const { Document* StyleSheet::GetKeptAliveByDocument() const {
// TODO(emilio): Now that we're doing parent walks for both this and
// GetAssociatedDocument(), seems we could simplify the association code not
// to be propagated to children.
if (mAssociationMode == OwnedByDocumentOrShadowRoot) {
MOZ_ASSERT(mDocumentOrShadowRoot);
return mDocumentOrShadowRoot->AsNode().GetComposedDoc();
}
for (const auto* sheet = this; sheet; sheet = sheet->mParentSheet) { for (const auto* sheet = this; sheet; sheet = sheet->mParentSheet) {
if (sheet->mAssociationMode == OwnedByDocumentOrShadowRoot) {
MOZ_ASSERT(sheet->mDocumentOrShadowRoot);
return sheet->mDocumentOrShadowRoot->AsNode().GetComposedDoc();
}
if (sheet->IsConstructed()) { if (sheet->IsConstructed()) {
for (DocumentOrShadowRoot* adopter : sheet->mAdopters) { for (DocumentOrShadowRoot* adopter : sheet->mAdopters) {
MOZ_ASSERT(adopter->AsNode().OwnerDoc() == sheet->mConstructorDocument); MOZ_ASSERT(adopter->AsNode().OwnerDoc() == sheet->mConstructorDocument);
@ -221,12 +217,6 @@ void StyleSheet::UnlinkInner() {
for (StyleSheet* child : ChildSheets()) { for (StyleSheet* child : ChildSheets()) {
MOZ_ASSERT(child->mParentSheet == this, "We have a unique inner!"); MOZ_ASSERT(child->mParentSheet == this, "We have a unique inner!");
child->mParentSheet = nullptr; child->mParentSheet = 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 doesn'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->ClearAssociatedDocumentOrShadowRoot();
} }
Inner().mChildren.Clear(); Inner().mChildren.Clear();
} }
@ -321,13 +311,15 @@ void StyleSheet::ApplicableStateChanged(bool aApplicable) {
} }
}; };
if (mDocumentOrShadowRoot) { for (const auto* sheet = this; sheet; sheet = sheet->mParentSheet) {
Notify(*mDocumentOrShadowRoot); if (sheet->mDocumentOrShadowRoot) {
} Notify(*sheet->mDocumentOrShadowRoot);
}
for (DocumentOrShadowRoot* adopter : mAdopters) { for (DocumentOrShadowRoot* adopter : sheet->mAdopters) {
MOZ_ASSERT(adopter, "adopters should never be null"); MOZ_ASSERT(adopter, "adopters should never be null");
Notify(*adopter); Notify(*adopter);
}
} }
} }
@ -431,8 +423,6 @@ void StyleSheetInfo::RemoveSheet(StyleSheet* aSheet) {
StyleSheet* newParent = mSheets[1]; StyleSheet* newParent = mSheets[1];
for (StyleSheet* child : mChildren) { for (StyleSheet* child : mChildren) {
child->mParentSheet = newParent; child->mParentSheet = newParent;
child->SetAssociatedDocumentOrShadowRoot(newParent->mDocumentOrShadowRoot,
newParent->mAssociationMode);
} }
} }
@ -500,21 +490,18 @@ void StyleSheet::DropStyleSet(ServoStyleSet* aStyleSet) {
// too, so no need to do it for each ancestor. // too, so no need to do it for each ancestor.
#define NOTIFY(function_, args_) \ #define NOTIFY(function_, args_) \
do { \ do { \
if (auto* shadow = GetContainingShadow()) { \
shadow->function_ args_; \
} \
/* FIXME(emilio, bug 1630835): This should probably do something \
* for constructed sheets, at least for some notifications. */ \
if (mDocumentOrShadowRoot) { \
if (auto* doc = mDocumentOrShadowRoot->AsNode().GetComposedDoc()) { \
doc->function_ args_; \
} \
} \
StyleSheet* current = this; \ StyleSheet* current = this; \
do { \ do { \
for (ServoStyleSet * set : current->mStyleSets) { \ for (ServoStyleSet * set : current->mStyleSets) { \
set->function_ args_; \ set->function_ args_; \
} \ } \
if (auto* docOrShadow = current->mDocumentOrShadowRoot) { \
if (auto* shadow = ShadowRoot::FromNode(docOrShadow->AsNode())) { \
shadow->function_ args_; \
} else { \
docOrShadow->AsNode().AsDocument()->function_ args_; \
} \
} \
for (auto* adopter : mAdopters) { \ for (auto* adopter : mAdopters) { \
if (auto* shadow = ShadowRoot::FromNode(adopter->AsNode())) { \ if (auto* shadow = ShadowRoot::FromNode(adopter->AsNode())) { \
shadow->function_ args_; \ shadow->function_ args_; \
@ -800,14 +787,6 @@ nsresult StyleSheet::DeleteRuleFromGroup(css::GroupRule* aGroup,
return NS_OK; return NS_OK;
} }
ShadowRoot* StyleSheet::GetContainingShadow() const {
auto* docOrShadow = GetAssociatedDocumentOrShadowRoot();
if (!docOrShadow) {
return nullptr;
}
return ShadowRoot::FromNode(docOrShadow->AsNode());
}
void StyleSheet::RuleAdded(css::Rule& aRule) { void StyleSheet::RuleAdded(css::Rule& aRule) {
SetModifiedRules(); SetModifiedRules();
NOTIFY(RuleAdded, (*this, aRule)); NOTIFY(RuleAdded, (*this, aRule));
@ -902,19 +881,17 @@ void StyleSheet::RemoveFromParent() {
MOZ_ASSERT(mParentSheet->ChildSheets().Contains(this)); MOZ_ASSERT(mParentSheet->ChildSheets().Contains(this));
mParentSheet->Inner().mChildren.RemoveElement(this); mParentSheet->Inner().mChildren.RemoveElement(this);
mParentSheet = nullptr; mParentSheet = nullptr;
ClearAssociatedDocumentOrShadowRoot();
} }
void StyleSheet::UnparentChildren() { void StyleSheet::UnparentChildren() {
MOZ_ASSERT(mAssociationMode == NotOwnedByDocumentOrShadowRoot,
"How did we get to the destructor, exactly, if we're owned "
"by a document?");
// XXXbz this is a little bogus; see the comment where we // XXXbz this is a little bogus; see the comment where we
// declare mChildren in StyleSheetInfo. // declare mChildren in StyleSheetInfo.
for (StyleSheet* child : ChildSheets()) { for (StyleSheet* child : ChildSheets()) {
if (child->mParentSheet == this) { if (child->mParentSheet == this) {
child->mParentSheet = nullptr; child->mParentSheet = nullptr;
MOZ_ASSERT(child->mAssociationMode == NotOwnedByDocumentOrShadowRoot,
"How did we get to the destructor, exactly, if we're owned "
"by a document?");
child->mDocumentOrShadowRoot = nullptr;
} }
} }
} }
@ -978,20 +955,12 @@ void StyleSheet::SetAssociatedDocumentOrShadowRoot(
MOZ_ASSERT(!IsConstructed()); MOZ_ASSERT(!IsConstructed());
MOZ_ASSERT(aDocOrShadowRoot || MOZ_ASSERT(aDocOrShadowRoot ||
aAssociationMode == NotOwnedByDocumentOrShadowRoot); aAssociationMode == NotOwnedByDocumentOrShadowRoot);
MOZ_ASSERT(!mParentSheet || !aDocOrShadowRoot,
"Shouldn't be set on child sheets");
// not ref counted // not ref counted
mDocumentOrShadowRoot = aDocOrShadowRoot; mDocumentOrShadowRoot = aDocOrShadowRoot;
mAssociationMode = aAssociationMode; mAssociationMode = aAssociationMode;
// Now set the same document on all our child sheets....
// XXXbz this is a little bogus; see the comment where we
// declare mChildren in StyleSheetInfo.
for (StyleSheet* child : ChildSheets()) {
if (child->mParentSheet == this) {
child->SetAssociatedDocumentOrShadowRoot(aDocOrShadowRoot,
aAssociationMode);
}
}
} }
void StyleSheet::AppendStyleSheet(StyleSheet& aSheet) { void StyleSheet::AppendStyleSheet(StyleSheet& aSheet) {
@ -1007,8 +976,6 @@ void StyleSheet::AppendStyleSheetSilently(StyleSheet& aSheet) {
// This is not reference counted. Our parent tells us when // This is not reference counted. Our parent tells us when
// it's going away. // it's going away.
aSheet.mParentSheet = this; aSheet.mParentSheet = this;
aSheet.SetAssociatedDocumentOrShadowRoot(mDocumentOrShadowRoot,
mAssociationMode);
} }
size_t StyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { size_t StyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
@ -1278,7 +1245,6 @@ void StyleSheet::ReparseSheet(const nsACString& aInput, ErrorResult& aRv) {
// Clean up child sheets list. // Clean up child sheets list.
for (StyleSheet* child : ChildSheets()) { for (StyleSheet* child : ChildSheets()) {
child->mParentSheet = nullptr; child->mParentSheet = nullptr;
child->ClearAssociatedDocumentOrShadowRoot();
} }
Inner().mChildren.Clear(); Inner().mChildren.Clear();

Просмотреть файл

@ -479,13 +479,6 @@ class StyleSheet final : public nsICSSLoaderObserver, public nsWrapperCache {
mState |= State::ModifiedRules | State::ModifiedRulesForDevtools; mState |= State::ModifiedRules | State::ModifiedRulesForDevtools;
} }
// Returns the ShadowRoot that contains this stylesheet or our ancestor
// stylesheet, if any.
//
// TODO(emilio): This may need to have multiple shadow roots with
// constructable stylesheets.
dom::ShadowRoot* GetContainingShadow() const;
StyleSheetInfo& Inner() { StyleSheetInfo& Inner() {
MOZ_ASSERT(mInner); MOZ_ASSERT(mInner);
return *mInner; return *mInner;