aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2025-04-16 17:32:48 +0200
committerGitHub <noreply@github.com>2025-04-16 15:32:48 +0000
commit7a8e75266ff2c138f212a301de9774eafb2b3143 (patch)
tree2d883a93dc1d62b835d20448b399b4b53d6556d4
parentaf000d6c91f0958d6252b8e474cf596799001ae9 (diff)
downloadservo-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.rs39
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)
}
}