Bug 1455891: Improve StyleChildrenIterator. r?smaug draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 03 Jul 2018 08:33:09 +0200
changeset 813916 38f319f756a311a2545fc1162e2157bb6d739bbc
parent 813480 f11d6645684c86f7070714f235668873d553d4e8
child 813917 00d0cb65f72503452bcf83d3ea41240330c2dfb8
push id115046
push userbmo:emilio@crisal.io
push dateWed, 04 Jul 2018 05:02:13 +0000
reviewerssmaug
bugs1455891
milestone63.0a1
Bug 1455891: Improve StyleChildrenIterator. r?smaug Support move assignment, and export more AllChildrenIterator stuff. Also add a static GetParent function that we'll use shortly. MozReview-Commit-ID: 2KCxq29dyP
dom/base/ChildIterator.cpp
dom/base/ChildIterator.h
--- a/dom/base/ChildIterator.cpp
+++ b/dom/base/ChildIterator.cpp
@@ -467,16 +467,10 @@ AllChildrenIterator::GetPreviousChild()
       return beforeContent;
     }
   }
 
   mPhase = eAtBegin;
   return nullptr;
 }
 
-nsIContent*
-StyleChildrenIterator::GetNextChild()
-{
-  return AllChildrenIterator::GetNextChild();
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/ChildIterator.h
+++ b/dom/base/ChildIterator.h
@@ -3,28 +3,28 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ChildIterator_h
 #define ChildIterator_h
 
 #include "nsIContent.h"
+#include "nsIContentInlines.h"
+#include <stdint.h>
 
 /**
  * Iterates over the children on a node. If a child is an insertion point,
  * iterates over the children inserted there instead, or the default content
  * if no children are inserted there.
  *
  * The FlattenedChildIterator expands any anonymous content bound from an XBL
  * binding's <xbl:content> element.
  */
 
-#include <stdint.h>
-#include "nsAutoPtr.h"
 
 class nsIContent;
 
 namespace mozilla {
 namespace dom {
 
 // This class iterates normal DOM child nodes of a given DOM node with
 // <xbl:children> nodes replaced by the elements that have been filtered into that
@@ -196,30 +196,44 @@ private:
  * 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(const nsIContent* aNode, uint32_t aFlags,
-                      bool aStartAtBeginning = true) :
-    FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
-    mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
-    mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
+  AllChildrenIterator(const nsIContent* aNode,
+                      uint32_t aFlags,
+                      bool aStartAtBeginning = true)
+    : FlattenedChildIterator(aNode, aFlags, aStartAtBeginning)
+    , mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0)
+    , mFlags(aFlags)
+    , mPhase(aStartAtBeginning ? eAtBegin : eAtEnd)
+  {
+  }
 
   AllChildrenIterator(AllChildrenIterator&& aOther)
-    : FlattenedChildIterator(std::move(aOther)),
-      mAnonKids(std::move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
-      mFlags(aOther.mFlags), mPhase(aOther.mPhase)
+    : FlattenedChildIterator(std::move(aOther))
+    , mAnonKids(std::move(aOther.mAnonKids))
+    , mAnonKidsIdx(aOther.mAnonKidsIdx)
+    , mFlags(aOther.mFlags)
+    , mPhase(aOther.mPhase)
 #ifdef DEBUG
-      , mMutationGuard(aOther.mMutationGuard)
+    , mMutationGuard(aOther.mMutationGuard)
 #endif
-      {}
+  {
+  }
+
+  AllChildrenIterator& operator=(AllChildrenIterator&& aOther)
+  {
+    this->~AllChildrenIterator();
+    new (this) AllChildrenIterator(std::move(aOther));
+    return *this;
+  }
 
 #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;
@@ -280,24 +294,47 @@ private:
  * iteration, and will break horribly if that is not true.
  *
  * We require this to be memmovable since Rust code can create and move
  * StyleChildrenIterators.
  */
 class MOZ_NEEDS_MEMMOVABLE_MEMBERS StyleChildrenIterator : private AllChildrenIterator
 {
 public:
-  explicit StyleChildrenIterator(const nsIContent* aContent)
+  static nsIContent* GetParent(const nsIContent& aContent)
+  {
+    nsINode* node = aContent.GetFlattenedTreeParentNodeForStyle();
+    return node && node->IsContent() ? node->AsContent() : nullptr;
+  }
+
+  StyleChildrenIterator(const nsIContent* aContent, bool aStartAtBeginning = true)
     : AllChildrenIterator(aContent,
                           nsIContent::eAllChildren |
-                          nsIContent::eSkipDocumentLevelNativeAnonymousContent)
+                          nsIContent::eSkipDocumentLevelNativeAnonymousContent,
+                          aStartAtBeginning)
   {
     MOZ_COUNT_CTOR(StyleChildrenIterator);
   }
+
+  StyleChildrenIterator(StyleChildrenIterator&& aOther)
+    : AllChildrenIterator(std::move(aOther))
+  {
+    MOZ_COUNT_CTOR(StyleChildrenIterator);
+  }
+
+  StyleChildrenIterator& operator=(StyleChildrenIterator&& aOther)
+  {
+    AllChildrenIterator::operator=(std::move(aOther));
+    return *this;
+  }
+
+
   ~StyleChildrenIterator() { MOZ_COUNT_DTOR(StyleChildrenIterator); }
 
-  nsIContent* GetNextChild();
+  using AllChildrenIterator::GetNextChild;
+  using AllChildrenIterator::GetPreviousChild;
+  using AllChildrenIterator::Seek;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif