diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-04-16 17:32:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-16 15:32:48 +0000 |
commit | 7a8e75266ff2c138f212a301de9774eafb2b3143 (patch) | |
tree | 2d883a93dc1d62b835d20448b399b4b53d6556d4 | |
parent | af000d6c91f0958d6252b8e474cf596799001ae9 (diff) | |
download | servo-7a8e75266ff2c138f212a301de9774eafb2b3143.tar.gz servo-7a8e75266ff2c138f212a301de9774eafb2b3143.zip |
layout: Throw away nested marker elements instead of storing them in a `BoxSlot` (#36568)
`::before` and `::after` pseudo-elements can have their own `::marker`
pseudo-element. Since this case wasn't taken into account, they were
being stored in main element's `::marker` `BoxSlot`. This could cause
problems where two layout boxes would try to use the same `BoxSlot`. For
now, just don't store the nested version of the marker. Later, we'll
need to figure out how to store these layout objects without causing too
much memory usage.
Testing: This is covered by `/css/css-lists/nested-marker-styling.html`.
In
addition, we also made a test case that always causes this crash, but
since it
had to create 100000 `<div>`s it's probably not appropriate for a test
suite.
Fixes: #36551
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
-rw-r--r-- | components/layout_2020/flow/construct.rs | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index 07b2bbb5e0a..a6471756db8 100644 --- a/components/layout_2020/flow/construct.rs +++ b/components/layout_2020/flow/construct.rs @@ -169,10 +169,11 @@ impl BlockContainer { if let Some((marker_info, marker_contents)) = crate::lists::make_marker(context, info) { match marker_info.style.clone_list_style_position() { ListStylePosition::Inside => { - builder.handle_list_item_marker_inside(&marker_info, marker_contents) + builder.handle_list_item_marker_inside(&marker_info, info, marker_contents) }, ListStylePosition::Outside => builder.handle_list_item_marker_outside( &marker_info, + info, marker_contents, info.style.clone(), ), @@ -384,28 +385,50 @@ where { fn handle_list_item_marker_inside( &mut self, - info: &NodeAndStyleInfo<Node>, + marker_info: &NodeAndStyleInfo<Node>, + container_info: &NodeAndStyleInfo<Node>, contents: Vec<crate::dom_traversal::PseudoElementContentItem>, ) { + // TODO: We do not currently support saving box slots for ::marker pseudo-elements + // that are part nested in ::before and ::after pseudo elements. For now, just + // forget about them once they are built. + let box_slot = match container_info.pseudo_element_type { + Some(_) => BoxSlot::dummy(), + None => marker_info + .node + .pseudo_element_box_slot(PseudoElement::Marker), + }; + self.handle_inline_level_element( - info, + marker_info, DisplayInside::Flow { is_list_item: false, }, NonReplacedContents::OfPseudoElement(contents).into(), - info.node.pseudo_element_box_slot(PseudoElement::Marker), + box_slot, ); } fn handle_list_item_marker_outside( &mut self, - info: &NodeAndStyleInfo<Node>, + marker_info: &NodeAndStyleInfo<Node>, + container_info: &NodeAndStyleInfo<Node>, contents: Vec<crate::dom_traversal::PseudoElementContentItem>, list_item_style: Arc<ComputedValues>, ) { + // TODO: We do not currently support saving box slots for ::marker pseudo-elements + // that are part nested in ::before and ::after pseudo elements. For now, just + // forget about them once they are built. + let box_slot = match container_info.pseudo_element_type { + Some(_) => BoxSlot::dummy(), + None => marker_info + .node + .pseudo_element_box_slot(PseudoElement::Marker), + }; + self.block_level_boxes.push(BlockLevelJob { - info: info.clone(), - box_slot: info.node.pseudo_element_box_slot(PseudoElement::Marker), + info: marker_info.clone(), + box_slot, kind: BlockLevelCreator::OutsideMarker { contents, list_item_style, @@ -452,7 +475,7 @@ where // Ignore `list-style-position` here: // “If the list item is an inline box: this value is equivalent to `inside`.” // https://drafts.csswg.org/css-lists/#list-style-position-outside - self.handle_list_item_marker_inside(&marker_info, marker_contents) + self.handle_list_item_marker_inside(&marker_info, info, marker_contents) } } |