diff options
Diffstat (limited to 'dom/base/ChildIterator.h')
-rw-r--r-- | dom/base/ChildIterator.h | 77 |
1 files changed, 41 insertions, 36 deletions
diff --git a/dom/base/ChildIterator.h b/dom/base/ChildIterator.h index ffff8dce5..78acdc146 100644 --- a/dom/base/ChildIterator.h +++ b/dom/base/ChildIterator.h @@ -36,27 +36,20 @@ class ExplicitChildIterator { public: explicit ExplicitChildIterator(const nsIContent* aParent, - bool aStartAtBeginning = true) - : mParent(aParent), - mChild(nullptr), - mDefaultChild(nullptr), - mIndexInInserted(0), - mIsFirst(aStartAtBeginning) - { - } + bool aStartAtBeginning = true); ExplicitChildIterator(const ExplicitChildIterator& aOther) - : mParent(aOther.mParent), mChild(aOther.mChild), + : mParent(aOther.mParent), + mParentAsSlot(aOther.mParentAsSlot), + mChild(aOther.mChild), mDefaultChild(aOther.mDefaultChild), - mShadowIterator(aOther.mShadowIterator ? - new ExplicitChildIterator(*aOther.mShadowIterator) : - nullptr), mIndexInInserted(aOther.mIndexInInserted), mIsFirst(aOther.mIsFirst) {} ExplicitChildIterator(ExplicitChildIterator&& aOther) - : mParent(aOther.mParent), mChild(aOther.mChild), + : mParent(aOther.mParent), + mParentAsSlot(aOther.mParentAsSlot), + mChild(aOther.mChild), mDefaultChild(aOther.mDefaultChild), - mShadowIterator(Move(aOther.mShadowIterator)), mIndexInInserted(aOther.mIndexInInserted), mIsFirst(aOther.mIsFirst) {} nsIContent* GetNextChild(); @@ -65,13 +58,13 @@ public: // found. This version can take shortcuts that the two-argument version // can't, so can be faster (and in fact can be O(1) instead of O(N) in many // cases). - bool Seek(nsIContent* aChildToFind); + bool Seek(const nsIContent* aChildToFind); // Looks for aChildToFind respecting insertion points until aChildToFind is found. // or aBound is found. If aBound is nullptr then the seek is unbounded. Returns // whether aChildToFind was found as an explicit child prior to encountering // aBound. - bool Seek(nsIContent* aChildToFind, nsIContent* aBound) + bool Seek(const nsIContent* aChildToFind, nsIContent* aBound) { // It would be nice to assert that we find aChildToFind, but bz thinks that // we might not find aChildToFind when called from ContentInserted @@ -102,6 +95,10 @@ protected: // the <xbl:content> element for the binding. const nsIContent* mParent; + // If parent is a slot element, this points to the parent as HTMLSlotElement, + // otherwise, it's null. + const HTMLSlotElement* mParentAsSlot; + // The current child. When we encounter an insertion point, // mChild remains as the insertion point whose content we're iterating (and // our state is controled by mDefaultChild or mIndexInInserted depending on @@ -114,11 +111,6 @@ protected: // to null, we continue iterating at mChild's next sibling. nsIContent* mDefaultChild; - // If non-null, this points to an iterator of the explicit children of - // the ShadowRoot projected by the current shadow element that we're - // iterating. - nsAutoPtr<ExplicitChildIterator> mShadowIterator; - // If not zero, we're iterating inserted children for an insertion point. This // is an index into mChild's inserted children array (mChild must be an // nsXBLChildrenElement). The index is one past the "current" child (as @@ -139,19 +131,29 @@ class FlattenedChildIterator : public ExplicitChildIterator public: explicit FlattenedChildIterator(const nsIContent* aParent, bool aStartAtBeginning = true) - : ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false) + : ExplicitChildIterator(aParent, aStartAtBeginning) + , mXBLInvolved(false) + , mOriginalContent(aParent) { Init(false); } FlattenedChildIterator(FlattenedChildIterator&& aOther) - : ExplicitChildIterator(Move(aOther)), mXBLInvolved(aOther.mXBLInvolved) {} + : ExplicitChildIterator(Move(aOther)) + , mXBLInvolved(aOther.mXBLInvolved) + , mOriginalContent(aOther.mOriginalContent) + {} FlattenedChildIterator(const FlattenedChildIterator& aOther) - : ExplicitChildIterator(aOther), mXBLInvolved(aOther.mXBLInvolved) {} + : ExplicitChildIterator(aOther) + , mXBLInvolved(aOther.mXBLInvolved) + , mOriginalContent(aOther.mOriginalContent) + {} bool XBLInvolved() { return mXBLInvolved; } + const nsIContent* Parent() const { return mOriginalContent; } + protected: /** * This constructor is a hack to help AllChildrenIterator which sometimes @@ -159,7 +161,9 @@ protected: */ FlattenedChildIterator(const nsIContent* aParent, uint32_t aFlags, bool aStartAtBeginning = true) - : ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false) + : ExplicitChildIterator(aParent, aStartAtBeginning) + , mXBLInvolved(false) + , mOriginalContent(aParent) { bool ignoreXBL = aFlags & nsIContent::eAllButXBL; Init(ignoreXBL); @@ -170,6 +174,8 @@ protected: // For certain optimizations, nsCSSFrameConstructor needs to know if the // child list of the element that we're iterating matches its .childNodes. bool mXBLInvolved; + + const nsIContent* mOriginalContent; }; /** @@ -187,12 +193,11 @@ public: AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags, bool aStartAtBeginning = true) : FlattenedChildIterator(aNode, aFlags, aStartAtBeginning), - mOriginalContent(aNode), mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0), + mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0), mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { } AllChildrenIterator(AllChildrenIterator&& aOther) : FlattenedChildIterator(Move(aOther)), - mOriginalContent(aOther.mOriginalContent), mAnonKids(Move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx), mFlags(aOther.mFlags), mPhase(aOther.mPhase) #ifdef DEBUG @@ -211,11 +216,10 @@ public: // 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); + bool Seek(const nsIContent* aChildToFind); nsIContent* GetNextChild(); nsIContent* GetPreviousChild(); - const nsIContent* Parent() const { return mOriginalContent; } enum IteratorPhase { @@ -233,8 +237,6 @@ private: void AppendNativeAnonymousChildren(); void AppendNativeAnonymousChildrenFromFrame(nsIFrame* aFrame); - const nsIContent* mOriginalContent; - // mAnonKids is an array of native anonymous children, mAnonKidsIdx is index // in the array. If mAnonKidsIdx < mAnonKids.Length() and mPhase is // eAtAnonKids then the iterator points at a child at mAnonKidsIdx index. If @@ -256,10 +258,11 @@ private: /** * StyleChildrenIterator traverses the children of the element from the * perspective of the style system, particularly the children we need to traverse - * during restyle. This is identical to AllChildrenIterator with eAllChildren, - * _except_ that we detect and skip any native anonymous children that are used - * to implement pseudo-elements (since the style system needs to cascade those - * using different algorithms). + * during restyle. This is identical to AllChildrenIterator with + * (eAllChildren | eSkipDocumentLevelNativeAnonymousContent), _except_ that we + * detect and skip any native anonymous children that are used to implement + * pseudo-elements (since the style system needs to cascade those using + * different algorithms). * * 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. @@ -267,7 +270,9 @@ private: class StyleChildrenIterator : private AllChildrenIterator { public: explicit StyleChildrenIterator(const nsIContent* aContent) - : AllChildrenIterator(aContent, nsIContent::eAllChildren) + : AllChildrenIterator(aContent, + nsIContent::eAllChildren | + nsIContent::eSkipDocumentLevelNativeAnonymousContent) { MOZ_COUNT_CTOR(StyleChildrenIterator); } |