Bug 1406275 - Don't assert the status of dirty bits in an unbinding subtree when choosing a new restyle root. r=emilio
authorCameron McCormack <cam@mcc.id.au>
Fri, 06 Oct 2017 17:26:07 +0800
changeset 427550 2c2fbf414099ca5e1369e7619107ce9ca8ba6680
parent 427549 2a31dd6fe18fcadd477bdf9dda2867f2656b9be9
child 427551 6f0a242f6396659626119a40976ffcec08b651a3
push id97
push userfmarier@mozilla.com
push dateSat, 14 Oct 2017 01:12:59 +0000
reviewersemilio
bugs1406275
milestone58.0a1
Bug 1406275 - Don't assert the status of dirty bits in an unbinding subtree when choosing a new restyle root. r=emilio MozReview-Commit-ID: 7EVGjjCoF6p
dom/base/Element.cpp
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -4347,22 +4347,41 @@ BitsArePropagated(const Element* aElemen
                   parentNode == aElement->OwnerDoc() ||
                   parentNode == parentNode->OwnerDoc()->GetRootElement());
   }
   return true;
 }
 #endif
 
 static inline void
-AssertNoBitsPropagatedFrom(nsINode* aRoot) {
+AssertNoBitsPropagatedFrom(nsINode* aRoot)
+{
 #ifdef DEBUG
   if (!aRoot || !aRoot->IsElement()) {
     return;
   }
 
+  // If we are in the middle of unbinding a subtree, then the bits on elements
+  // in that subtree (and which we haven't yet unbound) could be dirty.
+  // Just skip asserting the absence of bits on those element that are in
+  // the unbinding subtree.  (The incorrect bits will only cause us to
+  // incorrectly choose a new restyle root if the newly dirty element is
+  // also within the unbinding subtree, so it is OK to leave them there.)
+  for (nsINode* n = aRoot; n; n = n->GetFlattenedTreeParentElementForStyle()) {
+    if (!n->IsInComposedDoc()) {
+      // Find the top-most element that is marked as no longer in the document,
+      // so we can start checking bits from its parent.
+      do {
+        aRoot = n;
+        n = n->GetFlattenedTreeParentElementForStyle();
+      } while (n && !n->IsInComposedDoc());
+      break;
+    }
+  }
+
   auto* element = aRoot->GetFlattenedTreeParentElementForStyle();
   while (element) {
     MOZ_ASSERT(!element->HasAnyOfFlags(Element::kAllServoDescendantBits));
     element = element->GetFlattenedTreeParentElementForStyle();
   }
 #endif
 }