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::{Dom, 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) struct TreeIterator {
323 current: Option<DomRoot<Node>>,
324 depth: usize,
325 shadow_including: ShadowIncluding,
326}
327
328impl TreeIterator {
329 pub(crate) fn new(root: &Node, shadow_including: ShadowIncluding) -> TreeIterator {
330 TreeIterator {
331 current: Some(DomRoot::from_ref(root)),
332 depth: 0,
333 shadow_including,
334 }
335 }
336
337 pub(crate) fn next_skipping_children(&mut self) -> Option<DomRoot<Node>> {
338 let current = self.current.take()?;
339
340 self.next_skipping_children_impl(current)
341 }
342
343 fn next_skipping_children_impl(&mut self, current: DomRoot<Node>) -> Option<DomRoot<Node>> {
344 let iter = current.inclusive_ancestors(self.shadow_including);
345
346 for ancestor in iter {
347 if self.depth == 0 {
348 break;
349 }
350 if let Some(next_sibling) = ancestor.GetNextSibling() {
351 self.current = Some(next_sibling);
352 return Some(current);
353 }
354 if let Some(shadow_root) = ancestor.downcast::<ShadowRoot>() {
355 if let Some(child) = shadow_root.Host().upcast::<Node>().GetFirstChild() {
358 self.current = Some(child);
359 return Some(current);
360 }
361 }
362 self.depth -= 1;
363 }
364 debug_assert_eq!(self.depth, 0);
365 self.current = None;
366 Some(current)
367 }
368
369 pub(crate) fn peek(&self) -> Option<&DomRoot<Node>> {
370 self.current.as_ref()
371 }
372}
373
374impl Iterator for TreeIterator {
375 type Item = DomRoot<Node>;
376
377 fn next(&mut self) -> Option<DomRoot<Node>> {
380 let current = self.current.take()?;
381
382 if let Some(element) = current.downcast::<Element>() &&
384 let Some(shadow_root) = element.shadow_root() &&
385 self.shadow_including == ShadowIncluding::Yes
386 {
387 self.current = Some(DomRoot::from_ref(shadow_root.upcast::<Node>()));
388 self.depth += 1;
389 return Some(current);
390 }
391
392 if let Some(first_child) = current.GetFirstChild() {
393 self.current = Some(first_child);
394 self.depth += 1;
395 return Some(current);
396 };
397
398 self.next_skipping_children_impl(current)
399 }
400}
401
402#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_interior)]
410pub(crate) struct UnrootedTreeIterator<'b> {
411 current: Option<UnrootedDom<'b, Node>>,
412 depth: usize,
413 shadow_including: ShadowIncluding,
414 no_gc: &'b NoGC,
416}
417
418impl<'b> UnrootedTreeIterator<'b> {
419 pub(crate) fn new(root: &Node, shadow_including: ShadowIncluding, no_gc: &'b NoGC) -> Self {
420 Self {
421 current: Some(UnrootedDom::from_dom(Dom::from_ref(root), no_gc)),
422 depth: 0,
423 shadow_including,
424 no_gc,
425 }
426 }
427
428 pub(crate) fn next_skipping_children(&mut self) -> Option<UnrootedDom<'b, Node>> {
429 let current = self.current.take()?;
430
431 let iter = current.inclusive_ancestors_unrooted(self.no_gc, self.shadow_including);
432
433 for ancestor in iter {
434 if self.depth == 0 {
435 break;
436 }
437
438 let next_sibling_option = ancestor.get_next_sibling_unrooted(self.no_gc);
439
440 if let Some(next_sibling) = next_sibling_option {
441 self.current = Some(next_sibling);
442 return Some(current);
443 }
444
445 if let Some(shadow_root) = ancestor.downcast::<ShadowRoot>() {
446 let child_option = shadow_root
449 .host_unrooted(self.no_gc)
450 .upcast::<Node>()
451 .get_first_child_unrooted(self.no_gc);
452
453 if let Some(child) = child_option {
454 self.current = Some(child);
455 return Some(current);
456 }
457 }
458 self.depth -= 1;
459 }
460 debug_assert_eq!(self.depth, 0);
461 self.current = None;
462 Some(current)
463 }
464}
465
466impl<'b> Iterator for UnrootedTreeIterator<'b> {
467 type Item = UnrootedDom<'b, Node>;
468
469 fn next(&mut self) -> Option<Self::Item> {
472 let current = self.current.take()?;
473
474 if let Some(element) = current.downcast::<Element>() &&
476 let Some(shadow_root) = element.shadow_root_unrooted(self.no_gc) &&
477 self.shadow_including == ShadowIncluding::Yes
478 {
479 self.current = Some(UnrootedDom::upcast(shadow_root));
480 self.depth += 1;
481 return Some(current);
482 }
483
484 let first_child_option = current.get_first_child_unrooted(self.no_gc);
485 if let Some(first_child) = first_child_option {
486 self.current = Some(first_child);
487 self.depth += 1;
488 return Some(current);
489 };
490
491 self.current = Some(current);
493 self.next_skipping_children()
494 }
495}
496
497#[derive(Clone)]
501pub(crate) enum PrePostIteration<T: Clone> {
502 Enter(T),
505 Leave(T),
508}
509
510#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_interior)]
517pub(crate) struct UnrootedFollowingFlatTreeNodesTraversal<'no_gc> {
518 start: UnrootedDom<'no_gc, Node>,
519 previously_returned_item: Option<PrePostIteration<UnrootedDom<'no_gc, Node>>>,
520 no_gc: &'no_gc NoGC,
521}
522
523impl<'no_gc> UnrootedFollowingFlatTreeNodesTraversal<'no_gc> {
524 pub(crate) fn new(root: &Node, no_gc: &'no_gc NoGC) -> Self {
525 Self {
526 start: UnrootedDom::from_dom(Dom::from_ref(root), no_gc),
527 previously_returned_item: None,
528 no_gc,
529 }
530 }
531
532 pub(crate) fn next_skipping_subtree(
533 &mut self,
534 ) -> Option<PrePostIteration<UnrootedDom<'no_gc, Node>>> {
535 let next = self.find_next_skipping_subtree()?;
536 self.previously_returned_item = Some(next);
537 self.previously_returned_item.clone()
538 }
539
540 fn find_next_skipping_subtree(
541 &mut self,
542 ) -> Option<PrePostIteration<UnrootedDom<'no_gc, Node>>> {
543 match &self.previously_returned_item {
544 None => Some(PrePostIteration::Leave(self.start.clone())),
545 Some(PrePostIteration::Enter(previous)) => {
546 Some(PrePostIteration::Leave(previous.clone()))
547 },
548 Some(PrePostIteration::Leave(previous)) => {
549 Self::find_next_after_post(self.no_gc, previous)
550 },
551 }
552 }
553
554 fn find_next_after_post(
555 no_gc: &'no_gc NoGC,
556 previous: &UnrootedDom<'no_gc, Node>,
557 ) -> Option<PrePostIteration<UnrootedDom<'no_gc, Node>>> {
558 if let Some(next_sibling) = previous.next_flat_tree_sibling_unrooted(no_gc) {
559 return Some(PrePostIteration::Enter(next_sibling));
560 }
561 match previous.parent_in_flat_tree(no_gc) {
562 FlatTreeParent::Parent(parent_node) => Some(PrePostIteration::Leave(parent_node)),
563 FlatTreeParent::NotInFlatTree => None,
564 FlatTreeParent::RootNode => None,
565 }
566 }
567
568 fn find_next(&mut self) -> Option<PrePostIteration<UnrootedDom<'no_gc, Node>>> {
569 match &self.previously_returned_item {
570 None => Some(PrePostIteration::Enter(self.start.clone())),
571 Some(PrePostIteration::Enter(previous)) => {
572 if let Some(first_child) = previous.first_flat_tree_child_unrooted(self.no_gc) {
573 return Some(PrePostIteration::Enter(first_child));
574 }
575 Some(PrePostIteration::Leave(previous.clone()))
576 },
577 Some(PrePostIteration::Leave(previous)) => {
578 Self::find_next_after_post(self.no_gc, previous)
579 },
580 }
581 }
582}
583
584impl<'no_gc> Iterator for UnrootedFollowingFlatTreeNodesTraversal<'no_gc> {
585 type Item = PrePostIteration<UnrootedDom<'no_gc, Node>>;
586
587 fn next(&mut self) -> Option<Self::Item> {
588 let next = self.find_next()?;
589 self.previously_returned_item = Some(next);
590 self.previously_returned_item.clone()
591 }
592}