1use js::context::NoGC;
6
7use super::FlatTreeParent;
8use crate::dom::Node;
9use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
10use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::ShadowRoot_Binding::ShadowRootMethods;
11use crate::dom::bindings::inheritance::Castable;
12use crate::dom::bindings::root::{DomRoot, UnrootedDom};
13use crate::dom::element::Element;
14use crate::dom::shadowroot::ShadowRoot;
15
16#[derive(Clone, Copy, PartialEq)]
18pub(crate) enum ShadowIncluding {
19 No,
20 Yes,
21}
22
23pub(crate) struct FollowingNodeIterator {
24 current: Option<DomRoot<Node>>,
25 root: DomRoot<Node>,
26 shadow_including: ShadowIncluding,
27}
28
29impl FollowingNodeIterator {
30 pub(crate) fn new(
31 current: Option<DomRoot<Node>>,
32 root: DomRoot<Node>,
33 shadow_including: ShadowIncluding,
34 ) -> Self {
35 FollowingNodeIterator {
36 current,
37 root,
38 shadow_including,
39 }
40 }
41}
42
43impl FollowingNodeIterator {
44 pub(crate) fn next_skipping_children(&mut self) -> Option<DomRoot<Node>> {
46 let current = self.current.take()?;
47 self.next_skipping_children_impl(current)
48 }
49
50 fn next_skipping_children_impl(&mut self, current: DomRoot<Node>) -> Option<DomRoot<Node>> {
51 if self.root == current {
52 self.current = None;
53 return None;
54 }
55
56 if let Some(next_sibling) = current.GetNextSibling() {
57 self.current = Some(next_sibling);
58 return current.GetNextSibling();
59 }
60
61 for ancestor in current.inclusive_ancestors(self.shadow_including) {
62 if self.root == ancestor {
63 break;
64 }
65 if let Some(next_sibling) = ancestor.GetNextSibling() {
66 self.current = Some(next_sibling);
67 return ancestor.GetNextSibling();
68 }
69 }
70 self.current = None;
71 None
72 }
73}
74
75impl Iterator for FollowingNodeIterator {
76 type Item = DomRoot<Node>;
77
78 fn next(&mut self) -> Option<DomRoot<Node>> {
80 let current = self.current.take()?;
81
82 if let Some(first_child) = current.GetFirstChild() {
83 self.current = Some(first_child);
84 return current.GetFirstChild();
85 }
86
87 self.next_skipping_children_impl(current)
88 }
89}
90
91pub(crate) struct UnrootedFollowingNodeIterator<'b> {
92 current: Option<UnrootedDom<'b, Node>>,
93 root: UnrootedDom<'b, Node>,
94 shadow_including: ShadowIncluding,
95 no_gc: &'b NoGC,
96}
97
98impl<'b> UnrootedFollowingNodeIterator<'b> {
99 pub(crate) fn new(
100 current: Option<UnrootedDom<'b, Node>>,
101 root: UnrootedDom<'b, Node>,
102 shadow_including: ShadowIncluding,
103 no_gc: &'b NoGC,
104 ) -> Self {
105 UnrootedFollowingNodeIterator {
106 current,
107 root,
108 shadow_including,
109 no_gc,
110 }
111 }
112}
113
114impl<'b> UnrootedFollowingNodeIterator<'b> {
115 fn next_skipping_children_impl(
116 &mut self,
117 current: UnrootedDom<'b, Node>,
118 ) -> Option<UnrootedDom<'b, Node>> {
119 if self.root == current {
120 self.current = None;
121 return None;
122 }
123
124 if let Some(next_sibling) = current.get_next_sibling_unrooted(self.no_gc) {
125 self.current = Some(next_sibling);
126 return current.get_next_sibling_unrooted(self.no_gc);
127 }
128
129 for ancestor in current.inclusive_ancestors_unrooted(self.no_gc, self.shadow_including) {
130 if self.root == ancestor {
131 break;
132 }
133 if let Some(next_sibling) = ancestor.get_next_sibling_unrooted(self.no_gc) {
134 self.current = Some(next_sibling);
135 return ancestor.get_next_sibling_unrooted(self.no_gc);
136 }
137 }
138 self.current = None;
139 None
140 }
141}
142
143impl<'b> Iterator for UnrootedFollowingNodeIterator<'b> {
144 type Item = UnrootedDom<'b, Node>;
145
146 fn next(&mut self) -> Option<UnrootedDom<'b, Node>> {
148 let current = self.current.take()?;
149
150 if let Some(first_child) = current.get_first_child_unrooted(self.no_gc) {
151 self.current = Some(first_child);
152 return current.get_first_child_unrooted(self.no_gc);
153 }
154
155 self.next_skipping_children_impl(current)
156 }
157}
158
159pub(crate) struct PrecedingNodeIterator {
160 current: Option<DomRoot<Node>>,
161 root: DomRoot<Node>,
162}
163
164impl PrecedingNodeIterator {
165 pub(crate) fn new(current: Option<DomRoot<Node>>, root: DomRoot<Node>) -> Self {
166 PrecedingNodeIterator { current, root }
167 }
168}
169
170impl Iterator for PrecedingNodeIterator {
171 type Item = DomRoot<Node>;
172
173 fn next(&mut self) -> Option<DomRoot<Node>> {
175 let current = self.current.take()?;
176
177 self.current = if self.root == current {
178 None
179 } else if let Some(previous_sibling) = current.GetPreviousSibling() {
180 if self.root == previous_sibling {
181 None
182 } else if let Some(last_child) = previous_sibling.descending_last_children().last() {
183 Some(last_child)
184 } else {
185 Some(previous_sibling)
186 }
187 } else {
188 current.GetParentNode()
189 };
190 self.current.clone()
191 }
192}
193
194pub(crate) struct UnrootedPrecedingNodeIterator<'b> {
195 current: Option<UnrootedDom<'b, Node>>,
196 no_gc: &'b NoGC,
197 root: UnrootedDom<'b, Node>,
198}
199
200impl<'b> UnrootedPrecedingNodeIterator<'b> {
201 pub(crate) fn new(
202 current: Option<UnrootedDom<'b, Node>>,
203 root: UnrootedDom<'b, Node>,
204 no_gc: &'b NoGC,
205 ) -> Self {
206 UnrootedPrecedingNodeIterator {
207 current,
208 no_gc,
209 root,
210 }
211 }
212}
213
214impl<'b> Iterator for UnrootedPrecedingNodeIterator<'b> {
215 type Item = UnrootedDom<'b, Node>;
216
217 fn next(&mut self) -> Option<UnrootedDom<'b, Node>> {
219 let current = self.current.take()?;
220
221 self.current = if self.root == current {
222 None
223 } else if let Some(previous_sibling) = current.get_previous_sibling_unrooted(self.no_gc) {
224 if self.root == previous_sibling {
225 None
226 } else if let Some(last_child) = previous_sibling
227 .descending_last_children_unrooted(self.no_gc)
228 .last()
229 {
230 Some(last_child)
231 } else {
232 Some(previous_sibling)
233 }
234 } else {
235 current.get_parent_node_unrooted(self.no_gc)
236 };
237
238 self.current.clone()
239 }
240}
241
242pub(crate) struct SimpleNodeIterator<I>
243where
244 I: Fn(&Node) -> Option<DomRoot<Node>>,
245{
246 current: Option<DomRoot<Node>>,
247 next_node: I,
248}
249
250impl<I> SimpleNodeIterator<I>
251where
252 I: Fn(&Node) -> Option<DomRoot<Node>>,
253{
254 pub(crate) fn new(current: Option<DomRoot<Node>>, next_node: I) -> Self {
255 SimpleNodeIterator { current, next_node }
256 }
257}
258
259impl<I> Iterator for SimpleNodeIterator<I>
260where
261 I: Fn(&Node) -> Option<DomRoot<Node>>,
262{
263 type Item = DomRoot<Node>;
264
265 fn next(&mut self) -> Option<Self::Item> {
266 let current = self.current.take();
267 self.current = current.as_ref().and_then(|c| (self.next_node)(c));
268 current
269 }
270}
271
272#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_interior)]
280pub(crate) struct UnrootedSimpleNodeIterator<'b, I>
281where
282 I: Fn(&Node, &'b NoGC) -> Option<UnrootedDom<'b, Node>>,
283{
284 current: Option<UnrootedDom<'b, Node>>,
285 next_node: I,
286 no_gc: &'b NoGC,
288}
289
290impl<'b, I> UnrootedSimpleNodeIterator<'b, I>
291where
292 I: Fn(&Node, &'b NoGC) -> Option<UnrootedDom<'b, Node>>,
293{
294 pub(crate) fn new(
295 current: Option<UnrootedDom<'b, Node>>,
296 next_node: I,
297 no_gc: &'b NoGC,
298 ) -> Self {
299 UnrootedSimpleNodeIterator {
300 current,
301 next_node,
302 no_gc,
303 }
304 }
305}
306
307impl<'b, I> Iterator for UnrootedSimpleNodeIterator<'b, I>
308where
309 I: Fn(&Node, &'b NoGC) -> Option<UnrootedDom<'b, Node>>,
310{
311 type Item = UnrootedDom<'b, Node>;
312
313 fn next(&mut self) -> Option<Self::Item> {
314 let current = self.current.take();
315 self.current = current
316 .as_ref()
317 .and_then(|c| (self.next_node)(c, self.no_gc));
318 current
319 }
320}
321
322pub(crate) type UnrootedAncestorIterator<'no_gc> = UnrootedSimpleNodeIterator<
323 'no_gc,
324 fn(&Node, &'no_gc NoGC) -> Option<UnrootedDom<'no_gc, Node>>,
325>;
326
327pub(crate) struct TreeIterator {
328 current: Option<DomRoot<Node>>,
329 depth: usize,
330 shadow_including: ShadowIncluding,
331}
332
333impl TreeIterator {
334 pub(crate) fn new(root: &Node, shadow_including: ShadowIncluding) -> TreeIterator {
335 TreeIterator {
336 current: Some(DomRoot::from_ref(root)),
337 depth: 0,
338 shadow_including,
339 }
340 }
341
342 pub(crate) fn next_skipping_children(&mut self) -> Option<DomRoot<Node>> {
343 let current = self.current.take()?;
344
345 self.next_skipping_children_impl(current)
346 }
347
348 fn next_skipping_children_impl(&mut self, current: DomRoot<Node>) -> Option<DomRoot<Node>> {
349 let iter = current.inclusive_ancestors(self.shadow_including);
350
351 for ancestor in iter {
352 if self.depth == 0 {
353 break;
354 }
355 if let Some(next_sibling) = ancestor.GetNextSibling() {
356 self.current = Some(next_sibling);
357 return Some(current);
358 }
359 if let Some(shadow_root) = ancestor.downcast::<ShadowRoot>() {
360 if let Some(child) = shadow_root.Host().upcast::<Node>().GetFirstChild() {
363 self.current = Some(child);
364 return Some(current);
365 }
366 }
367 self.depth -= 1;
368 }
369 debug_assert_eq!(self.depth, 0);
370 self.current = None;
371 Some(current)
372 }
373
374 pub(crate) fn peek(&self) -> Option<&DomRoot<Node>> {
375 self.current.as_ref()
376 }
377}
378
379impl Iterator for TreeIterator {
380 type Item = DomRoot<Node>;
381
382 fn next(&mut self) -> Option<DomRoot<Node>> {
385 let current = self.current.take()?;
386
387 if let Some(element) = current.downcast::<Element>() &&
389 let Some(shadow_root) = element.shadow_root() &&
390 self.shadow_including == ShadowIncluding::Yes
391 {
392 self.current = Some(DomRoot::from_ref(shadow_root.upcast::<Node>()));
393 self.depth += 1;
394 return Some(current);
395 }
396
397 if let Some(first_child) = current.GetFirstChild() {
398 self.current = Some(first_child);
399 self.depth += 1;
400 return Some(current);
401 };
402
403 self.next_skipping_children_impl(current)
404 }
405}
406
407#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_interior)]
415pub(crate) struct UnrootedTreeIterator<'b> {
416 current: Option<UnrootedDom<'b, Node>>,
417 depth: usize,
418 shadow_including: ShadowIncluding,
419 no_gc: &'b NoGC,
421}
422
423impl<'b> UnrootedTreeIterator<'b> {
424 pub(crate) fn new(root: &Node, shadow_including: ShadowIncluding, no_gc: &'b NoGC) -> Self {
425 Self {
426 current: Some(UnrootedDom::from_ref(root, no_gc)),
427 depth: 0,
428 shadow_including,
429 no_gc,
430 }
431 }
432
433 pub(crate) fn next_skipping_children(&mut self) -> Option<UnrootedDom<'b, Node>> {
434 let current = self.current.take()?;
435
436 let iter = current.inclusive_ancestors_unrooted(self.no_gc, self.shadow_including);
437
438 for ancestor in iter {
439 if self.depth == 0 {
440 break;
441 }
442
443 let next_sibling_option = ancestor.get_next_sibling_unrooted(self.no_gc);
444
445 if let Some(next_sibling) = next_sibling_option {
446 self.current = Some(next_sibling);
447 return Some(current);
448 }
449
450 if let Some(shadow_root) = ancestor.downcast::<ShadowRoot>() {
451 let child_option = shadow_root
454 .host_unrooted(self.no_gc)
455 .upcast::<Node>()
456 .get_first_child_unrooted(self.no_gc);
457
458 if let Some(child) = child_option {
459 self.current = Some(child);
460 return Some(current);
461 }
462 }
463 self.depth -= 1;
464 }
465 debug_assert_eq!(self.depth, 0);
466 self.current = None;
467 Some(current)
468 }
469}
470
471impl<'b> Iterator for UnrootedTreeIterator<'b> {
472 type Item = UnrootedDom<'b, Node>;
473
474 fn next(&mut self) -> Option<Self::Item> {
477 let current = self.current.take()?;
478
479 if let Some(element) = current.downcast::<Element>() &&
481 let Some(shadow_root) = element.shadow_root_unrooted(self.no_gc) &&
482 self.shadow_including == ShadowIncluding::Yes
483 {
484 self.current = Some(UnrootedDom::upcast(shadow_root));
485 self.depth += 1;
486 return Some(current);
487 }
488
489 let first_child_option = current.get_first_child_unrooted(self.no_gc);
490 if let Some(first_child) = first_child_option {
491 self.current = Some(first_child);
492 self.depth += 1;
493 return Some(current);
494 };
495
496 self.current = Some(current);
498 self.next_skipping_children()
499 }
500}
501
502#[derive(Clone)]
506pub(crate) enum PrePostIteration<T: Clone> {
507 Enter(T),
510 Leave(T),
513}
514
515#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_interior)]
522pub(crate) struct UnrootedFollowingFlatTreeNodesTraversal<'no_gc> {
523 start: UnrootedDom<'no_gc, Node>,
524 previously_returned_item: Option<PrePostIteration<UnrootedDom<'no_gc, Node>>>,
525 no_gc: &'no_gc NoGC,
526}
527
528impl<'no_gc> UnrootedFollowingFlatTreeNodesTraversal<'no_gc> {
529 pub(crate) fn new(root: &Node, no_gc: &'no_gc NoGC) -> Self {
530 Self {
531 start: UnrootedDom::from_ref(root, no_gc),
532 previously_returned_item: None,
533 no_gc,
534 }
535 }
536
537 pub(crate) fn next_skipping_subtree(
538 &mut self,
539 ) -> Option<PrePostIteration<UnrootedDom<'no_gc, Node>>> {
540 let next = self.find_next_skipping_subtree()?;
541 self.previously_returned_item = Some(next);
542 self.previously_returned_item.clone()
543 }
544
545 fn find_next_skipping_subtree(
546 &mut self,
547 ) -> Option<PrePostIteration<UnrootedDom<'no_gc, Node>>> {
548 match &self.previously_returned_item {
549 None => Some(PrePostIteration::Leave(self.start.clone())),
550 Some(PrePostIteration::Enter(previous)) => {
551 Some(PrePostIteration::Leave(previous.clone()))
552 },
553 Some(PrePostIteration::Leave(previous)) => {
554 Self::find_next_after_post(self.no_gc, previous)
555 },
556 }
557 }
558
559 fn find_next_after_post(
560 no_gc: &'no_gc NoGC,
561 previous: &UnrootedDom<'no_gc, Node>,
562 ) -> Option<PrePostIteration<UnrootedDom<'no_gc, Node>>> {
563 if let Some(next_sibling) = previous.next_flat_tree_sibling_unrooted(no_gc) {
564 return Some(PrePostIteration::Enter(next_sibling));
565 }
566 match previous.parent_in_flat_tree(no_gc) {
567 FlatTreeParent::Parent(parent_node) => Some(PrePostIteration::Leave(parent_node)),
568 FlatTreeParent::NotInFlatTree => None,
569 FlatTreeParent::RootNode => None,
570 }
571 }
572
573 fn find_next(&mut self) -> Option<PrePostIteration<UnrootedDom<'no_gc, Node>>> {
574 match &self.previously_returned_item {
575 None => Some(PrePostIteration::Enter(self.start.clone())),
576 Some(PrePostIteration::Enter(previous)) => {
577 if let Some(first_child) = previous.first_flat_tree_child_unrooted(self.no_gc) {
578 return Some(PrePostIteration::Enter(first_child));
579 }
580 Some(PrePostIteration::Leave(previous.clone()))
581 },
582 Some(PrePostIteration::Leave(previous)) => {
583 Self::find_next_after_post(self.no_gc, previous)
584 },
585 }
586 }
587}
588
589impl<'no_gc> Iterator for UnrootedFollowingFlatTreeNodesTraversal<'no_gc> {
590 type Item = PrePostIteration<UnrootedDom<'no_gc, Node>>;
591
592 fn next(&mut self) -> Option<Self::Item> {
593 let next = self.find_next()?;
594 self.previously_returned_item = Some(next);
595 self.previously_returned_item.clone()
596 }
597}