diff options
author | Simon Wülker <simon.wuelker@arcor.de> | 2025-02-02 21:49:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-02 20:49:42 +0000 |
commit | 6a2e37183c1995aa7c4bc31dfd8e871f28dcbae7 (patch) | |
tree | 821cb8ea46526f14278a14941dcc289383b46d3b /components/layout_2020/dom_traversal.rs | |
parent | 938baf6bf36336d812277b0bc056d1a614c472cc (diff) | |
download | servo-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.rs | 54 |
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> {} |