aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/dom_traversal.rs
diff options
context:
space:
mode:
authorSimon Wülker <simon.wuelker@arcor.de>2025-02-02 21:49:42 +0100
committerGitHub <noreply@github.com>2025-02-02 20:49:42 +0000
commit6a2e37183c1995aa7c4bc31dfd8e871f28dcbae7 (patch)
tree821cb8ea46526f14278a14941dcc289383b46d3b /components/layout_2020/dom_traversal.rs
parent938baf6bf36336d812277b0bc056d1a614c472cc (diff)
downloadservo-6a2e37183c1995aa7c4bc31dfd8e871f28dcbae7.tar.gz
servo-6a2e37183c1995aa7c4bc31dfd8e871f28dcbae7.zip
Lay out the contents of slot elements (#35220)
* Make Slottable match layout/alignment of NonNull<Node> Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Implement ServoLayoutElement::slotted_nodes Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Bump mozjs Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Layout the contents of slot elements Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Implement ServoLayoutElement::assigned_slot Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * implement ServoLayoutElement::traversal_parent Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Simplify slottable name update Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Don't iterate over children of shadow hosts Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Recompute slot style when contents change Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Change match_slottable to a function instead of a macro Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Fix crown errors Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Update WPT expectations Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Reset a slottable's assigned slot when it's removed from the slot Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Diffstat (limited to 'components/layout_2020/dom_traversal.rs')
-rw-r--r--components/layout_2020/dom_traversal.rs54
1 files changed, 43 insertions, 11 deletions
diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs
index 7c7697be740..3a66a34e30c 100644
--- a/components/layout_2020/dom_traversal.rs
+++ b/components/layout_2020/dom_traversal.rs
@@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::borrow::Cow;
+use std::iter::FusedIterator;
use html5ever::{local_name, LocalName};
use log::warn;
@@ -464,18 +465,49 @@ where
}
}
-pub(crate) fn iter_child_nodes<'dom, Node>(parent: Node) -> impl Iterator<Item = Node>
+pub enum ChildNodeIterator<Node> {
+ /// Iterating over the children of a node
+ Node(Option<Node>),
+ /// Iterating over the assigned nodes of a `HTMLSlotElement`
+ Slottables(<Vec<Node> as IntoIterator>::IntoIter),
+}
+
+#[allow(clippy::unnecessary_to_owned)] // Clippy is wrong.
+pub(crate) fn iter_child_nodes<'dom, Node>(parent: Node) -> ChildNodeIterator<Node>
where
Node: NodeExt<'dom>,
{
- if let Some(shadow) = parent.as_element().and_then(|e| e.shadow_root()) {
- return iter_child_nodes(shadow.as_node());
- };
-
- let mut next = parent.first_child();
- std::iter::from_fn(move || {
- next.inspect(|child| {
- next = child.next_sibling();
- })
- })
+ if let Some(element) = parent.as_element() {
+ if let Some(shadow) = element.shadow_root() {
+ return iter_child_nodes(shadow.as_node());
+ };
+
+ let slotted_nodes = element.slotted_nodes();
+ if !slotted_nodes.is_empty() {
+ return ChildNodeIterator::Slottables(slotted_nodes.to_owned().into_iter());
+ }
+ }
+
+ let first = parent.first_child();
+ ChildNodeIterator::Node(first)
+}
+
+impl<'dom, Node> Iterator for ChildNodeIterator<Node>
+where
+ Node: NodeExt<'dom>,
+{
+ type Item = Node;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self {
+ Self::Node(node) => {
+ let old = *node;
+ *node = old?.next_sibling();
+ old
+ },
+ Self::Slottables(slots) => slots.next(),
+ }
+ }
}
+
+impl<'dom, Node> FusedIterator for ChildNodeIterator<Node> where Node: NodeExt<'dom> {}