Bug 1075247 - Add support for starting the iteration from the end to FlattenedChildIterator and AllChildrenIterator. r=bzbarsky
authorMats Palmgren <mats@mozilla.com>
Thu, 02 Oct 2014 13:05:16 +0000
changeset 231604 f1fd436a75a1d3a2793d6332e9585c682107ec92
parent 231603 e2d1b98b34e6f367ed6a8f14db2aca191c480f7e
child 231605 a36f6475b2c3adbc7a32766b44824a35bf94621f
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1075247
milestone35.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 1075247 - Add support for starting the iteration from the end to FlattenedChildIterator and AllChildrenIterator. r=bzbarsky
content/base/src/ChildIterator.h
--- a/content/base/src/ChildIterator.h
+++ b/content/base/src/ChildIterator.h
@@ -117,22 +117,24 @@ protected:
   uint32_t mIndexInInserted;
 
   // A flag to let us know that we haven't started iterating yet.
   bool mIsFirst;
 };
 
 // Iterates over the flattened children of a node, which accounts for anonymous
 // children and nodes moved by insertion points. If a node has anonymous
-// children, those are iterated over.
+// children, those are iterated over.  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.
 class FlattenedChildIterator : public ExplicitChildIterator
 {
 public:
-  explicit FlattenedChildIterator(nsIContent* aParent)
-    : ExplicitChildIterator(aParent), mXBLInvolved(false)
+  explicit FlattenedChildIterator(nsIContent* aParent, bool aStartAtBeginning = true)
+    : ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false)
   {
     Init(false);
   }
 
   FlattenedChildIterator(FlattenedChildIterator&& aOther)
     : ExplicitChildIterator(Move(aOther)), mXBLInvolved(aOther.mXBLInvolved) {}
 
   FlattenedChildIterator(const FlattenedChildIterator& aOther)
@@ -140,40 +142,43 @@ public:
 
   bool XBLInvolved() { return mXBLInvolved; }
 
 protected:
   /**
    * This constructor is a hack to help AllChildrenIterator which sometimes
    * doesn't want to consider XBL.
    */
-  FlattenedChildIterator(nsIContent* aParent, bool aIgnoreXBL)
-    : ExplicitChildIterator(aParent), mXBLInvolved(false)
+  FlattenedChildIterator(nsIContent* aParent, uint32_t aFlags, bool aStartAtBeginning = true)
+    : ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false)
   {
-    Init(aIgnoreXBL);
+    bool ignoreXBL = aFlags & nsIContent::eAllButXBL;
+    Init(ignoreXBL);
   }
 
   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.
+ * 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.
  */
 class AllChildrenIterator : private FlattenedChildIterator
 {
 public:
-  AllChildrenIterator(nsIContent* aNode, uint32_t aFlags) :
-    FlattenedChildIterator(aNode, (aFlags & nsIContent::eAllButXBL)),
+  AllChildrenIterator(nsIContent* aNode, uint32_t aFlags, bool aStartAtBeginning = true) :
+    FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
     mOriginalContent(aNode), mFlags(aFlags),
     mPhase(eNeedBeforeKid) {}
 
   AllChildrenIterator(AllChildrenIterator&& aOther)
     : FlattenedChildIterator(Move(aOther)),
       mOriginalContent(aOther.mOriginalContent),
       mAnonKids(Move(aOther.mAnonKids)), mFlags(aOther.mFlags),
       mPhase(aOther.mPhase)