mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 1400936: Clear servo data after children data is cleared, and allow setting the root as the document if the tree is mid-unbind. r=bholley
This is the actual fix, and makes sure that the state is consistent even if we notify of state changes on a parent during unbind. We potentially do a bit more work than needed given we set the document as the root in that case instead of the parent which could potentially be the root itself, but that's not a huge deal I think, given these cases are rare. If this happens to be a perf problem, we may want to just drop the root during UnbindFromTree if aNullParent == true and the root is a descendant of `this`. MozReview-Commit-ID: A9d2igM0hMr Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
This commit is contained in:
parent
6761fabaa9
commit
9cbe3caa2c
@ -1898,19 +1898,6 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
DeleteProperty(nsGkAtoms::animationsProperty);
|
||||
}
|
||||
|
||||
// Computed style data isn't useful for detached nodes, and we'll need to
|
||||
// recompute it anyway if we ever insert the nodes back into a document.
|
||||
if (IsStyledByServo()) {
|
||||
if (document) {
|
||||
ClearServoData(document);
|
||||
} else {
|
||||
MOZ_ASSERT(!HasServoData());
|
||||
MOZ_ASSERT(!HasAnyOfFlags(kAllServoDescendantBits | NODE_NEEDS_FRAME));
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(!HasServoData());
|
||||
}
|
||||
|
||||
// Editable descendant count only counts descendants that
|
||||
// are in the uncomposed document.
|
||||
ResetEditableDescendantCount();
|
||||
@ -2004,6 +1991,19 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
|
||||
shadowRoot->SetIsComposedDocParticipant(false);
|
||||
}
|
||||
|
||||
// Computed style data isn't useful for detached nodes, and we'll need to
|
||||
// recompute it anyway if we ever insert the nodes back into a document.
|
||||
if (IsStyledByServo()) {
|
||||
if (document) {
|
||||
ClearServoData(document);
|
||||
} else {
|
||||
MOZ_ASSERT(!HasServoData());
|
||||
MOZ_ASSERT(!HasAnyOfFlags(kAllServoDescendantBits | NODE_NEEDS_FRAME));
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(!HasServoData());
|
||||
}
|
||||
}
|
||||
|
||||
nsICSSDeclaration*
|
||||
|
@ -66,8 +66,27 @@ nsIDocument::SetServoRestyleRoot(nsINode* aRoot, uint32_t aDirtyBits)
|
||||
MOZ_ASSERT((aDirtyBits & ~Element::kAllServoDescendantBits) == 0);
|
||||
MOZ_ASSERT((aDirtyBits & mServoRestyleRootDirtyBits) == mServoRestyleRootDirtyBits);
|
||||
|
||||
// NOTE(emilio): The !aRoot->IsElement() check allows us to handle cases where
|
||||
// we change the restyle root during unbinding of a subtree where the root is
|
||||
// not unbound yet (and thus hasn't cleared the restyle root yet).
|
||||
//
|
||||
// In that case the tree can be in a somewhat inconsistent state (with the
|
||||
// document no longer being the subtree root of the current root, but the root
|
||||
// not having being unbound first).
|
||||
//
|
||||
// In that case, given there's no common ancestor, aRoot should be the
|
||||
// document, and we allow that, provided that the previous root will
|
||||
// eventually be unbound and the dirty bits will be cleared.
|
||||
//
|
||||
// If we want to enforce calling into this method with the tree in a
|
||||
// consistent state, we'd need to move all the state changes that happen on
|
||||
// content unbinding for parents, like fieldset validity stuff and ancestor
|
||||
// direction changes off script runners or, alternatively, nulling out the
|
||||
// document and parent node _after_ nulling out the children's, and then
|
||||
// remove that line.
|
||||
MOZ_ASSERT(!mServoRestyleRoot ||
|
||||
mServoRestyleRoot == aRoot ||
|
||||
!aRoot->IsElement() ||
|
||||
nsContentUtils::ContentIsFlattenedTreeDescendantOfForStyle(mServoRestyleRoot, aRoot));
|
||||
MOZ_ASSERT(aRoot == aRoot->OwnerDocAsNode() ||
|
||||
(aRoot->IsElement() && aRoot->IsInComposedDoc()));
|
||||
|
Loading…
Reference in New Issue
Block a user