Bug 1426536: Remove nsContentUtils::IsContentInsertionPoint. r=smaug
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 20 Dec 2017 22:45:19 +0100
changeset 397051 2e3ea8471db5b87005dc382343aef0ad2d099780
parent 397050 ca8505867b1aff500a589371083d990d5cc01877
child 397052 07c4aa18a0b6ce4df6626c9a4fb9d4a37fe4c5d4
push id33123
push userncsoregi@mozilla.com
push dateThu, 21 Dec 2017 10:00:47 +0000
treeherdermozilla-central@06a19fbe2581 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1426536
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
@@ -505,43 +505,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
@@ -7485,29 +7485,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
@@ -2698,28 +2698,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)