1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef ChildIterator_h
8 #define ChildIterator_h
11 * Iterates over the children on a node. If a child is an insertion point,
12 * iterates over the children inserted there instead, or the default content
13 * if no children are inserted there.
15 * The FlattenedChildIterator expands any anonymous content bound from an XBL
16 * binding's <xbl:content> element.
19 #include "nsIContent.h"
24 // This class iterates normal DOM child nodes of a given DOM node with
25 // <xbl:children> nodes replaced by the elements that have been filtered into that
26 // insertion point. Any bindings on the given element are ignored for purposes
27 // of determining which insertion point children are filtered into.
28 class ExplicitChildIterator
31 ExplicitChildIterator(nsIContent
* aParent
)
34 mDefaultChild(nullptr),
40 nsIContent
* GetNextChild();
42 // Looks for aChildToFind respecting insertion points until aChildToFind
43 // or aBound is found. If aBound is nullptr then the seek is unbounded. Returns
44 // whether aChildToFind was found as an explicit child prior to encountering
46 bool Seek(nsIContent
* aChildToFind
, nsIContent
* aBound
= nullptr)
48 // It would be nice to assert that we find aChildToFind, but bz thinks that
49 // we might not find aChildToFind when called from ContentInserted
50 // if first-letter frames are about.
54 child
= GetNextChild();
55 } while (child
&& child
!= aChildToFind
&& child
!= aBound
);
57 return child
== aChildToFind
;
61 // The parent of the children being iterated. For the FlattenedChildIterator,
62 // if there is a binding attached to the original parent, mParent points to
63 // the <xbl:content> element for the binding.
66 // The current child. When we encounter an <xbl:children> insertion point,
67 // mChild remains as the insertion point whose content we're iterating (and
68 // our state is controled by mDefaultChild or mIndexInInserted depending on
69 // whether the insertion point expands to its default content or not).
72 // If non-null, this points to the current default content for the current
73 // insertion point that we're iterating (i.e. mChild, which must be an
74 // nsXBLChildrenElement). Once this transitions back to null,
75 // we continue iterating at mChild's next sibling.
76 nsIContent
* mDefaultChild
;
78 // If not zero, we're iterating inserted children for an insertion point. This
79 // is an index into mChild's inserted children array (mChild must be an
80 // nsXBLChildrenElement). The index is one past the "current" child (as
81 // opposed to mChild which represents the "current" child).
82 uint32_t mIndexInInserted
;
84 // A flag to let us know that we haven't started iterating yet.
88 // Iterates over the flattened children of a node, which accounts for anonymous
89 // children and nodes moved by insertion points. If a node has anonymous
90 // children, those are iterated over.
91 class FlattenedChildIterator
: public ExplicitChildIterator
94 FlattenedChildIterator(nsIContent
* aParent
);
96 // Returns the current target of this iterator (which might be an explicit
97 // child of the node, default content for an <xbl:children> element or
98 // an inserted child for an <xbl:children> element.
101 // The inverse of GetNextChild. Properly steps in and out of <xbl:children>
103 nsIContent
* GetPreviousChild();
105 bool XBLInvolved() { return mXBLInvolved
; }
108 // For certain optimizations, nsCSSFrameConstructor needs to know if the
109 // child list of the element that we're iterating matches its .childNodes.
114 } // namespace mozilla