aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2025-04-07 19:49:05 +0200
committerGitHub <noreply@github.com>2025-04-07 17:49:05 +0000
commit2b63e60e8f2740f55a3a4fa0d918097e3b6fec97 (patch)
treee4cf9eff85b7520766e52ab83477fc87f930da25 /components/layout_2020
parenta5c547259f4a1eda8f266e6cc3f673d21d66723b (diff)
downloadservo-2b63e60e8f2740f55a3a4fa0d918097e3b6fec97.tar.gz
servo-2b63e60e8f2740f55a3a4fa0d918097e3b6fec97.zip
layout: Add initial support for the `::marker` pseudo-element (#36317)
This change adds support for the `::marker` pseudo-element and ensure that markers are cached into the box tree. This is only initial support, there are a few things missing such as animations, transitions, and support the `content` CSS property. Testing: There are WPT tests for this change. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/layout_2020')
-rw-r--r--components/layout_2020/dom.rs4
-rw-r--r--components/layout_2020/dom_traversal.rs4
-rw-r--r--components/layout_2020/flow/construct.rs4
-rw-r--r--components/layout_2020/lists.rs6
-rw-r--r--components/layout_2020/query.rs4
5 files changed, 13 insertions, 9 deletions
diff --git a/components/layout_2020/dom.rs b/components/layout_2020/dom.rs
index f8b3d6f9c29..2e8a823c11e 100644
--- a/components/layout_2020/dom.rs
+++ b/components/layout_2020/dom.rs
@@ -34,6 +34,7 @@ pub struct InnerDOMLayoutData {
pub(super) self_box: ArcRefCell<Option<LayoutBox>>,
pub(super) pseudo_before_box: ArcRefCell<Option<LayoutBox>>,
pub(super) pseudo_after_box: ArcRefCell<Option<LayoutBox>>,
+ pub(super) pseudo_marker_box: ArcRefCell<Option<LayoutBox>>,
}
/// A box that is stored in one of the `DOMLayoutData` slots.
@@ -222,6 +223,7 @@ where
let cell = match pseudo_element_type {
PseudoElement::Before => &data.pseudo_before_box,
PseudoElement::After => &data.pseudo_after_box,
+ PseudoElement::Marker => &data.pseudo_marker_box,
_ => unreachable!(
"Asked for box slot for unsupported pseudo-element: {:?}",
pseudo_element_type
@@ -235,6 +237,7 @@ where
let cell = match pseudo_element_type {
PseudoElement::Before => &data.pseudo_before_box,
PseudoElement::After => &data.pseudo_after_box,
+ PseudoElement::Marker => &data.pseudo_marker_box,
_ => unreachable!(
"Asked for box slot for unsupported pseudo-element: {:?}",
pseudo_element_type
@@ -248,6 +251,7 @@ where
*data.self_box.borrow_mut() = None;
*data.pseudo_before_box.borrow_mut() = None;
*data.pseudo_after_box.borrow_mut() = None;
+ *data.pseudo_marker_box.borrow_mut() = None;
// Stylo already takes care of removing all layout data
// for DOM descendants of elements with `display: none`.
}
diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs
index bcb6555fd13..5800637c50f 100644
--- a/components/layout_2020/dom_traversal.rs
+++ b/components/layout_2020/dom_traversal.rs
@@ -236,6 +236,10 @@ fn traverse_element<'dom, Node>(
) where
Node: NodeExt<'dom>,
{
+ // Clear any existing pseudo-element box slot, because markers are not handled like
+ // `::before`` and `::after`. They are processed during box tree creation.
+ element.unset_pseudo_element_box(PseudoElement::Marker);
+
let replaced = ReplacedContents::for_element(element, context);
let style = element.style(context);
match Display::from(style.get_box().display) {
diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs
index ef73ee3d007..c7667231260 100644
--- a/components/layout_2020/flow/construct.rs
+++ b/components/layout_2020/flow/construct.rs
@@ -393,7 +393,7 @@ where
is_list_item: false,
},
NonReplacedContents::OfPseudoElement(contents).into(),
- BoxSlot::dummy(),
+ info.node.pseudo_element_box_slot(PseudoElement::Marker),
);
}
@@ -405,7 +405,7 @@ where
) {
self.block_level_boxes.push(BlockLevelJob {
info: info.clone(),
- box_slot: BoxSlot::dummy(),
+ box_slot: info.node.pseudo_element_box_slot(PseudoElement::Marker),
kind: BlockLevelCreator::OutsideMarker {
contents,
list_item_style,
diff --git a/components/layout_2020/lists.rs b/components/layout_2020/lists.rs
index ee60a82ef01..d5a1f863865 100644
--- a/components/layout_2020/lists.rs
+++ b/components/layout_2020/lists.rs
@@ -19,11 +19,7 @@ pub(crate) fn make_marker<'dom, Node>(
where
Node: NodeExt<'dom>,
{
- // TODO: use `PseudoElement::Marker` when we add it.
- let marker_info = info.pseudo(
- context,
- style::selector_parser::PseudoElement::ServoLegacyText,
- )?;
+ let marker_info = info.pseudo(context, style::selector_parser::PseudoElement::Marker)?;
let style = &marker_info.style;
let list_style = style.get_list();
diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs
index 108a4e0540c..cf745376ecf 100644
--- a/components/layout_2020/query.rs
+++ b/components/layout_2020/query.rs
@@ -131,7 +131,7 @@ pub fn process_resolved_style_request<'dom>(
None => layout_element,
};
- let style = &*layout_element.resolved_style();
+ let style = &*layout_element.style(context);
let longhand_id = match *property {
PropertyId::NonCustom(id) => match id.longhand_or_shorthand() {
Ok(longhand_id) => longhand_id,
@@ -1122,7 +1122,7 @@ where
let element = node.as_element().unwrap();
let parent_style = if node.is_connected() {
if element.has_data() {
- node.to_threadsafe().as_element().unwrap().resolved_style()
+ node.to_threadsafe().as_element().unwrap().style(context)
} else {
let mut tlc = ThreadLocalStyleContext::new();
let mut context = StyleContext {