Bug 1398119: Move the common case of NoteDirtyElement during innerHTML up.
MozReview-Commit-ID: 4KznPYcBr05
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -4349,16 +4349,31 @@ PropagateBits(Element* aElement, uint32_
// element under the current root is dirtied, that's why we don't trivially use
// `nsContentUtils::GetCommonFlattenedTreeAncestorForStyle`.
static void
NoteDirtyElement(Element* aElement, uint32_t aBits)
{
MOZ_ASSERT(aElement->IsInComposedDoc());
MOZ_ASSERT(aElement->IsStyledByServo());
+ nsIDocument* doc = aElement->GetComposedDoc();
+
+ nsINode* existingRoot = doc->GetServoRestyleRoot();
+ uint32_t existingBits = existingRoot ? doc->GetServoRestyleRootDirtyBits() : 0;
+
+ // The bit checks below rely on this to arrive to useful conclusions about the
+ // shape of the tree.
+ AssertNoBitsPropagatedFrom(existingRoot);
+
+ // If the root is already aElement, just note the root+bits and return.
+ if (existingRoot == aElement) {
+ doc->SetServoRestyleRoot(aElement, existingBits | aBits);
+ return;
+ }
+
Element* parent = aElement->GetFlattenedTreeParentElementForStyle();
if (MOZ_LIKELY(parent)) {
// If our parent is unstyled, we can inductively assume that it will be
// traversed when the time is right, and that the traversal will reach us
// when it happens. Nothing left to do.
if (!parent->HasServoData()) {
return;
}
@@ -4380,32 +4395,23 @@ NoteDirtyElement(Element* aElement, uint
// The check above doesn't work for <area> element because <area> always
// have display:none, but before we fix bug 135040, it may have primary
// frame from <img>.
if (parent->IsHTMLElement(nsGkAtoms::area)) {
return;
}
}
- nsIDocument* doc = aElement->GetComposedDoc();
- if (nsIPresShell* shell = doc->GetShell()) {
- shell->EnsureStyleFlush();
- }
-
- nsINode* existingRoot = doc->GetServoRestyleRoot();
- uint32_t existingBits = existingRoot ? doc->GetServoRestyleRootDirtyBits() : 0;
-
- // The bit checks below rely on this to arrive to useful conclusions about the
- // shape of the tree.
- AssertNoBitsPropagatedFrom(existingRoot);
-
- // If there's no existing restyle root, or if the root is already aElement,
- // just note the root+bits and return.
- if (!existingRoot || existingRoot == aElement) {
- doc->SetServoRestyleRoot(aElement, existingBits | aBits);
+ // If there's no existing restyle root, just record it and ensure a style
+ // flush happens.
+ if (!existingRoot) {
+ if (nsIPresShell* shell = doc->GetShell()) {
+ shell->EnsureStyleFlush();
+ }
+ doc->SetServoRestyleRoot(aElement, aBits);
return;
}
// There is an existing restyle root - walk up the tree from our element,
// propagating bits as we go.
const bool reachedDocRoot = !parent || !PropagateBits(parent, aBits, existingRoot);
if (!reachedDocRoot || existingRoot == doc) {