summaryrefslogtreecommitdiffstats
path: root/dom/base/ChildIterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/ChildIterator.h')
-rw-r--r--dom/base/ChildIterator.h77
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);
}