Bug 1253834 - add AllChildrenIterator::Get(), r=bz
authorAlexander Surkov <surkov.alexander@gmail.com>
Tue, 08 Mar 2016 15:54:46 -0500
changeset 287371 96018aec0a70
parent 287370 5e3325cc1758
child 287372 d3bc99831ce6
push id30068
push usercbook@mozilla.com
push date2016-03-09 10:46 +0000
treeherdermozilla-central@af7c0cb0798f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1253834
milestone47.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 1253834 - add AllChildrenIterator::Get(), r=bz
dom/base/ChildIterator.cpp
dom/base/ChildIterator.h
--- a/dom/base/ChildIterator.cpp
+++ b/dom/base/ChildIterator.cpp
@@ -210,17 +210,17 @@ ExplicitChildIterator::Seek(nsIContent* 
   // 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);
 }
 
 nsIContent*
-ExplicitChildIterator::Get()
+ExplicitChildIterator::Get() const
 {
   MOZ_ASSERT(!mIsFirst);
 
   if (mIndexInInserted) {
     MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
     return assignedChildren[mIndexInInserted - 1];
   } else if (mShadowIterator)  {
     return mShadowIterator->Get();
@@ -306,16 +306,48 @@ ExplicitChildIterator::GetPreviousChild(
 
   if (!mChild) {
     mIsFirst = true;
   }
 
   return mChild;
 }
 
+nsIContent*
+AllChildrenIterator::Get() const
+{
+  switch (mPhase) {
+    case eAtBeforeKid: {
+      nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
+      MOZ_ASSERT(frame, "No frame at eAtBeforeKid phase");
+      nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
+      MOZ_ASSERT(beforeFrame, "No content before frame at eAtBeforeKid phase");
+      return beforeFrame->GetContent();
+    }
+
+    case eAtExplicitKids:
+      return ExplicitChildIterator::Get();
+
+    case eAtAnonKids:
+      return mAnonKids[mAnonKidsIdx];
+
+    case eAtAfterKid: {
+      nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
+      MOZ_ASSERT(frame, "No frame at eAtAfterKid phase");
+      nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
+      MOZ_ASSERT(afterFrame, "No content before frame at eAtBeforeKid phase");
+      return afterFrame->GetContent();
+    }
+
+    default:
+      return nullptr;
+  }
+}
+
+
 bool
 AllChildrenIterator::Seek(nsIContent* aChildToFind)
 {
   if (mPhase == eAtBegin || mPhase == eAtBeforeKid) {
     mPhase = eAtExplicitKids;
     nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
     if (frame) {
       nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
--- a/dom/base/ChildIterator.h
+++ b/dom/base/ChildIterator.h
@@ -84,17 +84,17 @@ public:
     } while (child && child != aChildToFind && child != aBound);
 
     return child == aChildToFind;
   }
 
   // Returns the current target of this iterator (which might be an explicit
   // child of the node, fallback content of an insertion point or
   // a node distributed to an insertion point.
-  nsIContent* Get();
+  nsIContent* Get() const;
 
   // The inverse of GetNextChild. Properly steps in and out of insertion
   // points.
   nsIContent* GetPreviousChild();
 
 protected:
   // The parent of the children being iterated. For the FlattenedChildIterator,
   // if there is a binding attached to the original parent, mParent points to
@@ -165,22 +165,23 @@ protected:
   void Init(bool aIgnoreXBL);
 
   // For certain optimizations, nsCSSFrameConstructor needs to know if the
   // child list of the element that we're iterating matches its .childNodes.
   bool mXBLInvolved;
 };
 
 /**
- * AllChildrenIterator returns the children of a element including before /
- * after content and optionally XBL children.  It assumes that no mutation of
- * the DOM or frame tree takes place during iteration, and will break horribly
- * if that is not true.  The iterator can be initialized to start at the end by
- * providing false for aStartAtBeginning in order to start iterating in reverse
- * from the last child.
+ * AllChildrenIterator traverses the children of an element including before /
+ * after content and optionally XBL children.  The iterator can be initialized
+ * to start at the end by providing false for aStartAtBeginning in order to
+ * start iterating in reverse from the last child.
+ *
+ * Note: it assumes that no mutation of the DOM or frame tree takes place during
+ * iteration, and will break horribly if that is not true.
  */
 class AllChildrenIterator : private FlattenedChildIterator
 {
 public:
   AllChildrenIterator(nsIContent* aNode, uint32_t aFlags, bool aStartAtBeginning = true) :
     FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
     mOriginalContent(aNode), mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
     mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
@@ -194,16 +195,23 @@ public:
       , mMutationGuard(aOther.mMutationGuard)
 #endif
       {}
 
 #ifdef DEBUG
   ~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
 #endif
 
+  // Returns the current target the iterator is at, or null if the iterator
+  // doesn't point to any child node (either eAtBegin or eAtEnd phase).
+  nsIContent* Get() const;
+
+  // Seeks the given node in children of a parent element, starting from
+  // the current iterator's position, and sets the iterator at the given child
+  // node if it was found.
   bool Seek(nsIContent* aChildToFind);
 
   nsIContent* GetNextChild();
   nsIContent* GetPreviousChild();
   nsIContent* Parent() const { return mOriginalContent; }
 
   enum IteratorPhase
   {