1use std::marker::PhantomData;
6
7use js::context::NoGC;
8
9use crate::dom::Node;
10use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
11use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::ShadowRoot_Binding::ShadowRootMethods;
12use crate::dom::bindings::inheritance::Castable;
13use crate::dom::bindings::root::{Dom, DomRoot, UnrootedDom};
14use crate::dom::element::Element;
15use crate::dom::shadowroot::ShadowRoot;
16
17#[derive(Clone, Copy, PartialEq)]
19pub(crate) enum ShadowIncluding {
20 No,
21 Yes,
22}
23
24pub(crate) struct FollowingNodeIterator {
25 current: Option<DomRoot<Node>>,
26 root: DomRoot<Node>,
27 shadow_including: ShadowIncluding,
28}
29
30impl FollowingNodeIterator {
31 pub(crate) fn new(
32 current: Option<DomRoot<Node>>,
33 root: DomRoot<Node>,
34 shadow_including: ShadowIncluding,
35 ) -> Self {
36 FollowingNodeIterator {
37 current,
38 root,
39 shadow_including,
40 }
41 }
42}
43
44impl FollowingNodeIterator {
45 pub(crate) fn next_skipping_children(&mut self) -> Option<DomRoot<Node>> {
47 let current = self.current.take()?;
48 self.next_skipping_children_impl(current)
49 }
50
51 fn next_skipping_children_impl(&mut self, current: DomRoot<Node>) -> Option<DomRoot<Node>> {
52 if self.root == current {
53 self.current = None;
54 return None;
55 }
56
57 if let Some(next_sibling) = current.GetNextSibling() {
58 self.current = Some(next_sibling);
59 return current.GetNextSibling();
60 }
61
62 for ancestor in current.inclusive_ancestors(self.shadow_including) {
63 if self.root == ancestor {
64 break;
65 }
66 if let Some(next_sibling) = ancestor.GetNextSibling() {
67 self.current = Some(next_sibling);
68 return ancestor.GetNextSibling();
69 }
70 }
71 self.current = None;
72 None
73 }
74}
75
76impl Iterator for FollowingNodeIterator {
77 type Item = DomRoot<Node>;
78
79 fn next(&mut self) -> Option<DomRoot<Node>> {
81 let current = self.current.take()?;
82
83 if let Some(first_child) = current.GetFirstChild() {
84 self.current = Some(first_child);
85 return current.GetFirstChild();
86 }
87
88 self.next_skipping_children_impl(current)
89 }
90}
91
92pub(crate) struct PrecedingNodeIterator {
93 current: Option<DomRoot<Node>>,
94 root: DomRoot<Node>,
95}
96
97impl PrecedingNodeIterator {
98 pub(crate) fn new(current: Option<DomRoot<Node>>, root: DomRoot<Node>) -> Self {
99 PrecedingNodeIterator { current, root }
100 }
101}
102
103impl Iterator for PrecedingNodeIterator {
104 type Item = DomRoot<Node>;
105
106 fn next(&mut self) -> Option<DomRoot<Node>> {
108 let current = self.current.take()?;
109
110 self.current = if self.root == current {
111 None
112 } else if let Some(previous_sibling) = current.GetPreviousSibling() {
113 if self.root == previous_sibling {
114 None
115 } else if let Some(last_child) = previous_sibling.descending_last_children().last() {
116 Some(last_child)
117 } else {
118 Some(previous_sibling)
119 }
120 } else {
121 current.GetParentNode()
122 };
123 self.current.clone()
124 }
125}
126
127pub(crate) struct SimpleNodeIterator<I>
128where
129 I: Fn(&Node) -> Option<DomRoot<Node>>,
130{
131 current: Option<DomRoot<Node>>,
132 next_node: I,
133}
134
135impl<I> SimpleNodeIterator<I>
136where
137 I: Fn(&Node) -> Option<DomRoot<Node>>,
138{
139 pub(crate) fn new(current: Option<DomRoot<Node>>, next_node: I) -> Self {
140 SimpleNodeIterator { current, next_node }
141 }
142}
143
144impl<I> Iterator for SimpleNodeIterator<I>
145where
146 I: Fn(&Node) -> Option<DomRoot<Node>>,
147{
148 type Item = DomRoot<Node>;
149
150 fn next(&mut self) -> Option<Self::Item> {
151 let current = self.current.take();
152 self.current = current.as_ref().and_then(|c| (self.next_node)(c));
153 current
154 }
155}
156
157#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_interior)]
165pub(crate) struct UnrootedSimpleNodeIterator<'a, 'b, I>
166where
167 I: Fn(&Node, &'b NoGC) -> Option<UnrootedDom<'b, Node>>,
168{
169 current: Option<UnrootedDom<'b, Node>>,
170 next_node: I,
171 no_gc: &'b NoGC,
173 phantom: PhantomData<&'a Node>,
174}
175
176impl<'a, 'b, I> UnrootedSimpleNodeIterator<'a, 'b, I>
177where
178 I: Fn(&Node, &'b NoGC) -> Option<UnrootedDom<'b, Node>>,
179{
180 pub(crate) fn new(
181 current: Option<UnrootedDom<'b, Node>>,
182 next_node: I,
183 no_gc: &'b NoGC,
184 ) -> Self {
185 UnrootedSimpleNodeIterator {
186 current,
187 next_node,
188 no_gc,
189 phantom: PhantomData,
190 }
191 }
192}
193
194impl<'a, 'b, I> Iterator for UnrootedSimpleNodeIterator<'a, 'b, I>
195where
196 'b: 'a,
197 I: Fn(&Node, &'b NoGC) -> Option<UnrootedDom<'b, Node>>,
198{
199 type Item = UnrootedDom<'b, Node>;
200
201 fn next(&mut self) -> Option<Self::Item> {
202 let current = self.current.take();
203 self.current = current
204 .as_ref()
205 .and_then(|c| (self.next_node)(c, self.no_gc));
206 current
207 }
208}
209
210pub(crate) struct TreeIterator {
211 current: Option<DomRoot<Node>>,
212 depth: usize,
213 shadow_including: ShadowIncluding,
214}
215
216impl TreeIterator {
217 pub(crate) fn new(root: &Node, shadow_including: ShadowIncluding) -> TreeIterator {
218 TreeIterator {
219 current: Some(DomRoot::from_ref(root)),
220 depth: 0,
221 shadow_including,
222 }
223 }
224
225 pub(crate) fn next_skipping_children(&mut self) -> Option<DomRoot<Node>> {
226 let current = self.current.take()?;
227
228 self.next_skipping_children_impl(current)
229 }
230
231 fn next_skipping_children_impl(&mut self, current: DomRoot<Node>) -> Option<DomRoot<Node>> {
232 let iter = current.inclusive_ancestors(self.shadow_including);
233
234 for ancestor in iter {
235 if self.depth == 0 {
236 break;
237 }
238 if let Some(next_sibling) = ancestor.GetNextSibling() {
239 self.current = Some(next_sibling);
240 return Some(current);
241 }
242 if let Some(shadow_root) = ancestor.downcast::<ShadowRoot>() {
243 if let Some(child) = shadow_root.Host().upcast::<Node>().GetFirstChild() {
246 self.current = Some(child);
247 return Some(current);
248 }
249 }
250 self.depth -= 1;
251 }
252 debug_assert_eq!(self.depth, 0);
253 self.current = None;
254 Some(current)
255 }
256
257 pub(crate) fn peek(&self) -> Option<&DomRoot<Node>> {
258 self.current.as_ref()
259 }
260}
261
262impl Iterator for TreeIterator {
263 type Item = DomRoot<Node>;
264
265 fn next(&mut self) -> Option<DomRoot<Node>> {
268 let current = self.current.take()?;
269
270 if let Some(element) = current.downcast::<Element>() &&
272 let Some(shadow_root) = element.shadow_root() &&
273 self.shadow_including == ShadowIncluding::Yes
274 {
275 self.current = Some(DomRoot::from_ref(shadow_root.upcast::<Node>()));
276 self.depth += 1;
277 return Some(current);
278 }
279
280 if let Some(first_child) = current.GetFirstChild() {
281 self.current = Some(first_child);
282 self.depth += 1;
283 return Some(current);
284 };
285
286 self.next_skipping_children_impl(current)
287 }
288}
289
290#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_interior)]
298pub(crate) struct UnrootedTreeIterator<'a, 'b> {
299 current: Option<UnrootedDom<'b, Node>>,
300 depth: usize,
301 shadow_including: ShadowIncluding,
302 no_gc: &'b NoGC,
304 phantom: PhantomData<&'a Node>,
305}
306
307impl<'a, 'b> UnrootedTreeIterator<'a, 'b>
308where
309 'b: 'a,
310{
311 pub(crate) fn new(
312 root: &'a Node,
313 shadow_including: ShadowIncluding,
314 no_gc: &'b NoGC,
315 ) -> UnrootedTreeIterator<'a, 'b> {
316 UnrootedTreeIterator {
317 current: Some(UnrootedDom::from_dom(Dom::from_ref(root), no_gc)),
318 depth: 0,
319 shadow_including,
320 no_gc,
321 phantom: PhantomData,
322 }
323 }
324
325 pub(crate) fn next_skipping_children(&mut self) -> Option<UnrootedDom<'b, Node>> {
326 let current = self.current.take()?;
327
328 let iter = current.inclusive_ancestors(self.shadow_including);
329
330 for ancestor in iter {
331 if self.depth == 0 {
332 break;
333 }
334
335 let next_sibling_option = ancestor.get_next_sibling_unrooted(self.no_gc);
336
337 if let Some(next_sibling) = next_sibling_option {
338 self.current = Some(next_sibling);
339 return Some(current);
340 }
341
342 if let Some(shadow_root) = ancestor.downcast::<ShadowRoot>() {
343 let child_option = shadow_root
346 .Host()
347 .upcast::<Node>()
348 .get_first_child_unrooted(self.no_gc);
349
350 if let Some(child) = child_option {
351 self.current = Some(child);
352 return Some(current);
353 }
354 }
355 self.depth -= 1;
356 }
357 debug_assert_eq!(self.depth, 0);
358 self.current = None;
359 Some(current)
360 }
361}
362
363impl<'a, 'b> Iterator for UnrootedTreeIterator<'a, 'b>
364where
365 'b: 'a,
366{
367 type Item = UnrootedDom<'b, Node>;
368
369 fn next(&mut self) -> Option<UnrootedDom<'b, Node>> {
372 let current = self.current.take()?;
373
374 if let Some(element) = current.downcast::<Element>() &&
376 let Some(shadow_root) = element.shadow_root() &&
377 self.shadow_including == ShadowIncluding::Yes
378 {
379 self.current = Some(UnrootedDom::from_dom(
380 Dom::from_ref(shadow_root.upcast::<Node>()),
381 self.no_gc,
382 ));
383 self.depth += 1;
384 return Some(current);
385 }
386
387 let first_child_option = current.get_first_child_unrooted(self.no_gc);
388 if let Some(first_child) = first_child_option {
389 self.current = Some(first_child);
390 self.depth += 1;
391 return Some(current);
392 };
393
394 let _ = self.current.insert(current);
396 self.next_skipping_children()
397 }
398}