Backed out changeset 58dbd2146e24 (bug 944961) for bustage.
[gecko.git] / content / base / src / ChildIterator.h
blob7761810558c4fb0c745b30dbabb4a65b79809587
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
10 /**
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"
21 namespace mozilla {
22 namespace dom {
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
30 public:
31 ExplicitChildIterator(nsIContent* aParent)
32 : mParent(aParent),
33 mChild(nullptr),
34 mDefaultChild(nullptr),
35 mIndexInInserted(0),
36 mIsFirst(true)
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
45 // aBound.
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.
52 nsIContent* child;
53 do {
54 child = GetNextChild();
55 } while (child && child != aChildToFind && child != aBound);
57 return child == aChildToFind;
60 protected:
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.
64 nsIContent* mParent;
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).
70 nsIContent* mChild;
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.
85 bool mIsFirst;
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
93 public:
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.
99 nsIContent* Get();
101 // The inverse of GetNextChild. Properly steps in and out of <xbl:children>
102 // elements.
103 nsIContent* GetPreviousChild();
105 bool XBLInvolved() { return mXBLInvolved; }
107 private:
108 // For certain optimizations, nsCSSFrameConstructor needs to know if the
109 // child list of the element that we're iterating matches its .childNodes.
110 bool mXBLInvolved;
113 } // namespace dom
114 } // namespace mozilla
116 #endif