Bug 1426536: Remove nsContentUtils::IsContentInsertionPoint. r?smaug draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 20 Dec 2017 22:45:19 +0100
changeset 713749 afee677f89f376b57b79213336957343d11d250f
parent 713748 deddef361ef06a0d70ec8a7a32e5c87d730222bf
child 744419 a294bd07d628b9cda13400aeadba13012b2d47f3
push id93738
push userbmo:emilio@crisal.io
push dateWed, 20 Dec 2017 23:04:59 +0000
reviewerssmaug
bugs1426536
milestone59.0a1
Bug 1426536: Remove nsContentUtils::IsContentInsertionPoint. r?smaug We're not going to need it in Shadow DOM v1. MozReview-Commit-ID: HOokTPlm2Wt
dom/base/ChildIterator.cpp
dom/base/ShadowRoot.cpp
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
layout/base/GeckoRestyleManager.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsFrameManager.cpp
--- a/dom/base/ChildIterator.cpp
+++ b/dom/base/ChildIterator.cpp
@@ -12,58 +12,16 @@
 #include "nsIAnonymousContentCreator.h"
 #include "nsIFrame.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsDocument.h"
 
 namespace mozilla {
 namespace dom {
 
-class MatchedNodes {
-public:
-  explicit MatchedNodes()
-    : mIsContentElement(false), mChildrenElement(nullptr) {}
-  explicit MatchedNodes(XBLChildrenElement* aInsertionPoint)
-    : mIsContentElement(false), mChildrenElement(aInsertionPoint) {}
-
-  uint32_t Length() const
-  {
-    return mChildrenElement ? mChildrenElement->InsertedChildrenLength() : 0;
-  }
-
-  nsIContent* operator[](int32_t aIndex) const
-  {
-    return mChildrenElement ? mChildrenElement->InsertedChild(aIndex) : nullptr;
-  }
-
-  bool IsEmpty() const
-  {
-    return mChildrenElement && !mChildrenElement->HasInsertedChildren();
-  }
-protected:
-  // Leftover from Shadow DOM v0.
-  bool mIsContentElement;
-  union {
-    XBLChildrenElement* mChildrenElement;
-  };
-};
-
-static inline MatchedNodes
-GetMatchedNodesForPoint(nsIContent* aContent)
-{
-  if (aContent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
-    // XBL case
-    return MatchedNodes(static_cast<XBLChildrenElement*>(aContent));
-  }
-
-  return MatchedNodes();
-  // Web components case
-  // XXX handle <slot> element?
-}
-
 ExplicitChildIterator::ExplicitChildIterator(const nsIContent* aParent,
                                              bool aStartAtBeginning)
   : mParent(aParent),
     mChild(nullptr),
     mDefaultChild(nullptr),
     mIsFirst(aStartAtBeginning),
     mIndexInInserted(0)
 {
@@ -83,26 +41,28 @@ ExplicitChildIterator::GetNextChild()
       const nsTArray<RefPtr<nsINode>>& assignedNodes =
         mParentAsSlot->AssignedNodes();
 
       mChild = (mIndexInInserted < assignedNodes.Length()) ?
         assignedNodes[mIndexInInserted++]->AsContent() : nullptr;
       return mChild;
     }
 
-    MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
-    if (mIndexInInserted < assignedChildren.Length()) {
-      return assignedChildren[mIndexInInserted++];
+    MOZ_ASSERT(mChild->IsActiveChildrenElement());
+    auto* childrenElement =
+      static_cast<XBLChildrenElement*>(mChild);
+    if (mIndexInInserted < childrenElement->InsertedChildrenLength()) {
+      return childrenElement->InsertedChild(mIndexInInserted++);
     }
     mIndexInInserted = 0;
     mChild = mChild->GetNextSibling();
   } else if (mDefaultChild) {
     // If we're already in default content, check if there are more nodes there
     MOZ_ASSERT(mChild);
-    MOZ_ASSERT(nsContentUtils::IsContentInsertionPoint(mChild));
+    MOZ_ASSERT(mChild->IsActiveChildrenElement());
 
     mDefaultChild = mDefaultChild->GetNextSibling();
     if (mDefaultChild) {
       return mDefaultChild;
     }
 
     mChild = mChild->GetNextSibling();
   } else if (mIsFirst) {  // at the beginning of the child list
@@ -123,25 +83,26 @@ ExplicitChildIterator::GetNextChild()
     mIsFirst = false;
   } else if (mChild) { // in the middle of the child list
     mChild = mChild->GetNextSibling();
   }
 
   // Iterate until we find a non-insertion point, or an insertion point with
   // content.
   while (mChild) {
-    if (nsContentUtils::IsContentInsertionPoint(mChild)) {
+    if (mChild->IsActiveChildrenElement()) {
       // If the current child being iterated is a content insertion point
       // then the iterator needs to return the nodes distributed into
       // the content insertion point.
-      MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
-      if (!assignedChildren.IsEmpty()) {
+      auto* childrenElement =
+        static_cast<XBLChildrenElement*>(mChild);
+      if (childrenElement->HasInsertedChildren()) {
         // Iterate through elements projected on insertion point.
         mIndexInInserted = 1;
-        return assignedChildren[0];
+        return childrenElement->InsertedChild(0);
       }
 
       // Insertion points inside fallback/default content
       // are considered inactive and do not get assigned nodes.
       mDefaultChild = mChild->GetFirstChild();
       if (mDefaultChild) {
         return mDefaultChild;
       }
@@ -197,17 +158,17 @@ ExplicitChildIterator::Seek(const nsICon
   if (aChildToFind->GetParent() == mParent &&
       !aChildToFind->IsRootOfAnonymousSubtree()) {
     // Fast path: just point ourselves to aChildToFind, which is a
     // normal DOM child of ours.
     mChild = const_cast<nsIContent*>(aChildToFind);
     mIndexInInserted = 0;
     mDefaultChild = nullptr;
     mIsFirst = false;
-    MOZ_ASSERT(!nsContentUtils::IsContentInsertionPoint(mChild));
+    MOZ_ASSERT(!mChild->IsActiveChildrenElement());
     return true;
   }
 
   // Can we add more fast paths here based on whether the parent of aChildToFind
   // is a shadow insertion point or content insertion point?
 
   // Slow path: just walk all our kids.
   return Seek(aChildToFind, nullptr);
@@ -220,18 +181,19 @@ ExplicitChildIterator::Get() const
 
   // When mParentAsSlot is set, mChild is always set to the current child. It
   // does not matter whether mChild is an assigned node or a fallback content.
   if (mParentAsSlot) {
     return mChild;
   }
 
   if (mIndexInInserted) {
-    MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
-    return assignedChildren[mIndexInInserted - 1];
+    MOZ_ASSERT(mChild->IsActiveChildrenElement());
+    auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
+    return childrenElement->InsertedChild(mIndexInInserted - 1);
   }
 
   return mDefaultChild ? mDefaultChild : mChild;
 }
 
 nsIContent*
 ExplicitChildIterator::GetPreviousChild()
 {
@@ -248,19 +210,20 @@ ExplicitChildIterator::GetPreviousChild(
       if (!mChild) {
         mIsFirst = true;
       }
       return mChild;
     }
 
     // NB: mIndexInInserted points one past the last returned child so we need
     // to look *two* indices back in order to return the previous child.
-    MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
+    MOZ_ASSERT(mChild->IsActiveChildrenElement());
+    auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
     if (--mIndexInInserted) {
-      return assignedChildren[mIndexInInserted - 1];
+      return childrenElement->InsertedChild(mIndexInInserted - 1);
     }
     mChild = mChild->GetPreviousSibling();
   } else if (mDefaultChild) {
     // If we're already in default content, check if there are more nodes there
     mDefaultChild = mDefaultChild->GetPreviousSibling();
     if (mDefaultChild) {
       return mDefaultChild;
     }
@@ -284,24 +247,24 @@ ExplicitChildIterator::GetPreviousChild(
     }
 
     mChild = mParent->GetLastChild();
   }
 
   // Iterate until we find a non-insertion point, or an insertion point with
   // content.
   while (mChild) {
-    if (nsContentUtils::IsContentInsertionPoint(mChild)) {
+    if (mChild->IsActiveChildrenElement()) {
       // If the current child being iterated is a content insertion point
       // then the iterator needs to return the nodes distributed into
       // the content insertion point.
-      MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
-      if (!assignedChildren.IsEmpty()) {
-        mIndexInInserted = assignedChildren.Length();
-        return assignedChildren[mIndexInInserted - 1];
+      auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
+      if (childrenElement->HasInsertedChildren()) {
+        mIndexInInserted = childrenElement->InsertedChildrenLength();
+        return childrenElement->InsertedChild(mIndexInInserted - 1);
       }
 
       mDefaultChild = mChild->GetLastChild();
       if (mDefaultChild) {
         return mDefaultChild;
       }
 
       mChild = mChild->GetPreviousSibling();
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -469,43 +469,16 @@ ShadowRoot::SetApplyAuthorStyles(bool aA
   nsIPresShell* shell = OwnerDoc()->GetShell();
   if (shell) {
     OwnerDoc()->BeginUpdate(UPDATE_STYLE);
     shell->RecordShadowStyleChange(this);
     OwnerDoc()->EndUpdate(UPDATE_STYLE);
   }
 }
 
-/**
- * Returns whether the web components pool population algorithm
- * on the host would contain |aContent|. This function ignores
- * insertion points in the pool, thus should only be used to
- * test nodes that have not yet been distributed.
- */
-bool
-ShadowRoot::IsPooledNode(nsIContent* aContent) const
-{
-  if (nsContentUtils::IsContentInsertionPoint(aContent)) {
-    // Insertion points never end up in the pool.
-    return false;
-  }
-
-  auto* host = GetHost();
-  auto* container = aContent->GetParent();
-  if (container == host && !aContent->IsRootOfAnonymousSubtree()) {
-    // Children of the host will end up in the pool. We check to ensure
-    // that the content is in the same anonymous tree as the container
-    // because anonymous content may report its container as the host
-    // but it may not be in the host's child list.
-    return true;
-  }
-
-  return false;
-}
-
 void
 ShadowRoot::AttributeChanged(nsIDocument* aDocument,
                              Element* aElement,
                              int32_t aNameSpaceID,
                              nsAtom* aAttribute,
                              int32_t aModType,
                              const nsAttrValue* aOldValue)
 {
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -7515,29 +7515,16 @@ nsContentUtils::GetHTMLEditor(nsPresCont
   bool isEditable;
   if (!docShell ||
       NS_FAILED(docShell->GetEditable(&isEditable)) || !isEditable)
     return nullptr;
 
   return docShell->GetHTMLEditor();
 }
 
-bool
-nsContentUtils::IsContentInsertionPoint(nsIContent* aContent)
-{
-  // Check if the content is a XBL insertion point.
-  if (aContent->IsActiveChildrenElement()) {
-    return true;
-  }
-
-  // Check if the content is a web components content insertion point.
-  // XXX handle <slot>?
-  return false;
-}
-
 // static
 bool
 nsContentUtils::HasDistributedChildren(nsIContent* aContent)
 {
   if (!aContent || !nsDocument::IsWebComponentsEnabled(aContent)) {
     return false;
   }
 
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2705,28 +2705,16 @@ public:
   /**
    * Returns a LogModule that dump calls from content script are logged to.
    * This can be enabled with the 'Dump' module, and is useful for synchronizing
    * content JS to other logging modules.
    */
   static mozilla::LogModule* DOMDumpLog();
 
   /**
-   * Returns whether a content is an insertion point for XBL
-   * bindings or web components ShadowRoot. In web components,
-   * this corresponds to a <content> element that participates
-   * in node distribution. In XBL this corresponds to an
-   * <xbl:children> element in anonymous content.
-   *
-   * @param aContent The content to test for being an insertion point.
-   */
-  static bool IsContentInsertionPoint(nsIContent* aContent);
-
-
-  /**
    * Returns whether the children of the provided content are
    * nodes that are distributed to Shadow DOM insertion points.
    */
   static bool HasDistributedChildren(nsIContent* aContent);
 
   /**
    * Returns whether a given header is forbidden for an XHR or fetch
    * request.
--- a/layout/base/GeckoRestyleManager.cpp
+++ b/layout/base/GeckoRestyleManager.cpp
@@ -3260,17 +3260,17 @@ ElementRestyler::RestyleUndisplayedNodes
     LOG_RESTYLE("RestyleUndisplayedChildren: undisplayed->mContent = %p",
                 undisplayed->mContent.get());
 
     // Get the parent of the undisplayed content and check if it is a XBL
     // children element. Push the children element as an ancestor here because it does
     // not have a frame and would not otherwise be pushed as an ancestor.
     nsIContent* parent = undisplayed->mContent->GetParent();
     TreeMatchContext::AutoAncestorPusher insertionPointPusher(&mTreeMatchContext);
-    if (parent && nsContentUtils::IsContentInsertionPoint(parent)) {
+    if (parent && parent->IsActiveChildrenElement()) {
       insertionPointPusher.PushAncestorAndStyleScope(parent);
     }
 
     nsRestyleHint thisChildHint = aChildRestyleHint;
     nsAutoPtr<RestyleTracker::RestyleData> undisplayedRestyleData;
     Element* element = undisplayed->mContent->AsElement();
     if (mRestyleTracker.GetRestyleData(element,
                                        undisplayedRestyleData)) {
@@ -3486,17 +3486,17 @@ ElementRestyler::RestyleContentChildren(
         // is a XBL children element. Push the children element as an
         // ancestor here because it does not have a frame and would not
         // otherwise be pushed as an ancestor.
 
         // Check if the frame has a content because |child| may be a
         // nsPageFrame that does not have a content.
         nsIContent* parent = child->GetContent() ? child->GetContent()->GetParent() : nullptr;
         TreeMatchContext::AutoAncestorPusher insertionPointPusher(&mTreeMatchContext);
-        if (parent && nsContentUtils::IsContentInsertionPoint(parent)) {
+        if (parent && parent->IsActiveChildrenElement()) {
           insertionPointPusher.PushAncestorAndStyleScope(parent);
         }
 
         // only do frames that are in flow
         if (child->IsPlaceholderFrame()) { // placeholder
           // get out of flow frame and recur there
           nsIFrame* outOfFlowFrame =
             nsPlaceholderFrame::GetRealFrameForPlaceholder(child);
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3961,17 +3961,17 @@ nsCSSFrameConstructor::ConstructFrameFro
   // Push the children element as an ancestor here because it does
   // not have a frame and would not otherwise be pushed as an ancestor. It is
   // necessary to do so in order to correctly handle style resolution on
   // descendants.  (If !adcp.IsEmpty() then it was already pushed by
   // AutoDisplayContentsAncestorPusher above.)
   TreeMatchContext::AutoAncestorPusher
     insertionPointPusher(aState.mTreeMatchContext);
   if (adcp.isSome() && adcp->IsEmpty() && parent &&
-      nsContentUtils::IsContentInsertionPoint(parent)) {
+      parent->IsActiveChildrenElement()) {
     if (aState.mTreeMatchContext->mAncestorFilter.HasFilter()) {
       insertionPointPusher.PushAncestorAndStyleScope(parent);
     } else {
       insertionPointPusher.PushStyleScope(parent);
     }
   }
 
   // Push the content as a style ancestor now, so we don't have to do
--- a/layout/base/nsFrameManager.cpp
+++ b/layout/base/nsFrameManager.cpp
@@ -725,17 +725,17 @@ nsIContent*
 nsFrameManagerBase::UndisplayedMap::GetApplicableParent(nsIContent* aParent)
 {
   // In the case of XBL default content, <xbl:children> elements do not get a
   // frame causing a mismatch between the content tree and the frame tree.
   // |GetEntryFor| is sometimes called with the content tree parent (which may
   // be a <xbl:children> element) but the parent in the frame tree would be the
   // insertion parent (parent of the <xbl:children> element). Here the children
   // elements are normalized to the insertion parent to correct for the mismatch.
-  if (aParent && nsContentUtils::IsContentInsertionPoint(aParent)) {
+  if (aParent && aParent->IsActiveChildrenElement()) {
     return aParent->GetParent();
   }
 
   return aParent;
 }
 
 LinkedList<UndisplayedNode>*
 nsFrameManagerBase::UndisplayedMap::GetListFor(nsIContent* aParent)