Bug 1419334: Fix GetFlattenedTreeParentNodeInternal test for unassigned XBL children nodes. r?smaug draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 21 Nov 2017 10:32:47 +0100
changeset 701422 8b3552539d02c16055e70cf020e8928775cab563
parent 701421 ad1eade5dae7e5677e22b9f7a89961b7b1c17ed9
child 741153 97760d9157a7ce7ef153f7cfe34fcbf15079183f
push id90147
push userbmo:emilio@crisal.io
push dateTue, 21 Nov 2017 16:21:39 +0000
reviewerssmaug
bugs1419334
milestone59.0a1
Bug 1419334: Fix GetFlattenedTreeParentNodeInternal test for unassigned XBL children nodes. r?smaug We check for them when the node doesn't have the MAY_BE_IN_BINDING_MNGR flag, but the flag is not precise, so in presence of dynamic changes that somehow make the node assigned, then unassigned, like changing the binding, it may not be correct. MozReview-Commit-ID: 9jyqCnR0yFn
dom/base/FragmentOrElement.cpp
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -246,24 +246,31 @@ nsIContent::GetFlattenedTreeParentNodeIn
     // but the child does not match any insertion points, thus
     // the flattened tree parent is nullptr.
     nsTArray<nsIContent*>* destInsertionPoints = GetExistingDestInsertionPoints();
     if (!destInsertionPoints || destInsertionPoints->IsEmpty()) {
       return nullptr;
     }
     parent = destInsertionPoints->LastElement()->GetParent();
     MOZ_ASSERT(parent);
-  } else if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
+  } else if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) ||
+             parent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
+    // We need to check `parent` to properly handle the unassigned child case
+    // below, since if we were never assigned we would never have the flag set.
+    //
+    // Note that unassigned child nodes _could_ have the flag set, if they were
+    // ever assigned, or if they have a binding themselves.
     if (nsIContent* insertionPoint = GetXBLInsertionPoint()) {
       parent = insertionPoint->GetParent();
       MOZ_ASSERT(parent);
+    } else if (parent->OwnerDoc()->BindingManager()->GetBindingWithContent(parent)) {
+      // This is an unassigned node child of the bound element, so it isn't part
+      // of the flat tree.
+      return nullptr;
     }
-  } else if (parent->OwnerDoc()->BindingManager()->GetBindingWithContent(parent)) {
-    // This is fallback content not assigned to any insertion point.
-    return nullptr;
   }
 
   // Shadow roots never shows up in the flattened tree. Return the host
   // instead.
   if (parent->IsInShadowTree()) {
     if (ShadowRoot* parentShadowRoot = ShadowRoot::FromNode(parent)) {
       return parentShadowRoot->GetHost();
     }