script: Eliminate PseudoElementType (#36146)

Servo has a `PseudoElementType` which more or less duplicate's Stylo's
`PseudoElement` with the addition of a non-pseudo element variant. This
type needs to be converted into `PseudoElement` anyway when asking for
the style of an element from Stylo, so eliminate Servo's version and
simply use `Option<PseudoElement>` with the `None` variant meaning the
non-pseudo.

This is preparation for adding support for the `::marker` pseudo
element.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-03-26 09:33:12 +01:00 committed by GitHub
parent 09041e77a0
commit a9b393a854
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 75 additions and 145 deletions

View file

@ -11,7 +11,7 @@ use constellation_traits::UntrustedNodeAddress;
use html5ever::{LocalName, Namespace, local_name, namespace_url, ns};
use js::jsapi::JSObject;
use script_layout_interface::wrapper_traits::{
LayoutNode, PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
};
use script_layout_interface::{LayoutNodeType, StyleData};
use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
@ -785,9 +785,9 @@ impl<'dom> ::selectors::Element for ServoLayoutElement<'dom> {
pub struct ServoThreadSafeLayoutElement<'dom> {
pub(super) element: ServoLayoutElement<'dom>,
/// The pseudo-element type, with (optionally)
/// a specified display value to override the stylesheet.
pub(super) pseudo: PseudoElementType,
/// The pseudo-element type for this element, or `None` if it is the non-pseudo
/// version of the element.
pub(super) pseudo: Option<PseudoElement>,
}
impl<'dom> ThreadSafeLayoutElement<'dom> for ServoThreadSafeLayoutElement<'dom> {
@ -801,14 +801,14 @@ impl<'dom> ThreadSafeLayoutElement<'dom> for ServoThreadSafeLayoutElement<'dom>
}
}
fn get_pseudo_element_type(&self) -> PseudoElementType {
fn pseudo_element(&self) -> Option<PseudoElement> {
self.pseudo
}
fn with_pseudo(&self, pseudo: PseudoElementType) -> Self {
fn with_pseudo(&self, pseudo: PseudoElement) -> Self {
ServoThreadSafeLayoutElement {
element: self.element,
pseudo,
pseudo: Some(pseudo),
}
}

View file

@ -13,9 +13,7 @@ use fonts_traits::ByteIndex;
use html5ever::{local_name, namespace_url, ns};
use pixels::{Image, ImageMetadata};
use range::Range;
use script_layout_interface::wrapper_traits::{
LayoutDataTrait, LayoutNode, PseudoElementType, ThreadSafeLayoutNode,
};
use script_layout_interface::wrapper_traits::{LayoutDataTrait, LayoutNode, ThreadSafeLayoutNode};
use script_layout_interface::{
GenericLayoutData, HTMLCanvasData, HTMLMediaData, LayoutNodeType, SVGSVGData, StyleData,
TrustedNodeAddress,
@ -25,6 +23,7 @@ use servo_url::ServoUrl;
use style;
use style::dom::{NodeInfo, TElement, TNode, TShadowRoot};
use style::properties::ComputedValues;
use style::selector_parser::PseudoElement;
use super::{
ServoLayoutDocument, ServoLayoutElement, ServoShadowRoot, ServoThreadSafeLayoutElement,
@ -230,18 +229,15 @@ pub struct ServoThreadSafeLayoutNode<'dom> {
/// The wrapped `ServoLayoutNode`.
pub(super) node: ServoLayoutNode<'dom>,
/// The pseudo-element type, with (optionally)
/// a specified display value to override the stylesheet.
pub(super) pseudo: PseudoElementType,
/// The pseudo-element type for this node, or `None` if it is the non-pseudo
/// version of the element.
pub(super) pseudo: Option<PseudoElement>,
}
impl<'dom> ServoThreadSafeLayoutNode<'dom> {
/// Creates a new `ServoThreadSafeLayoutNode` from the given `ServoLayoutNode`.
pub fn new(node: ServoLayoutNode<'dom>) -> Self {
ServoThreadSafeLayoutNode {
node,
pseudo: PseudoElementType::Normal,
}
ServoThreadSafeLayoutNode { node, pseudo: None }
}
/// Returns the interior of this node as a `LayoutDom`. This is highly unsafe for layout to
@ -289,8 +285,12 @@ impl<'dom> ThreadSafeLayoutNode<'dom> for ServoThreadSafeLayoutNode<'dom> {
unsafe { self.get_jsmanaged().opaque() }
}
fn pseudo_element(&self) -> Option<PseudoElement> {
self.pseudo
}
fn type_id(&self) -> Option<LayoutNodeType> {
if self.pseudo == PseudoElementType::Normal {
if self.pseudo.is_none() {
Some(self.node.type_id())
} else {
None
@ -434,12 +434,12 @@ pub struct ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
impl<'dom> ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
pub fn new(parent: ServoThreadSafeLayoutNode<'dom>) -> Self {
let first_child = match parent.get_pseudo_element_type() {
PseudoElementType::Normal => parent
.get_before_pseudo()
let first_child = match parent.pseudo_element() {
None => parent
.get_pseudo(PseudoElement::Before)
.or_else(|| parent.get_details_summary_pseudo())
.or_else(|| unsafe { parent.dangerous_first_child() }),
PseudoElementType::DetailsContent | PseudoElementType::DetailsSummary => unsafe {
Some(PseudoElement::DetailsContent) | Some(PseudoElement::DetailsSummary) => unsafe {
parent.dangerous_first_child()
},
_ => None,
@ -455,10 +455,10 @@ impl<'dom> Iterator for ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
type Item = ServoThreadSafeLayoutNode<'dom>;
fn next(&mut self) -> Option<ServoThreadSafeLayoutNode<'dom>> {
use selectors::Element;
match self.parent_node.get_pseudo_element_type() {
PseudoElementType::Before | PseudoElementType::After => None,
match self.parent_node.pseudo_element() {
Some(PseudoElement::Before) | Some(PseudoElement::After) => None,
PseudoElementType::DetailsSummary => {
Some(PseudoElement::DetailsSummary) => {
let mut current_node = self.current_node;
loop {
let next_node = if let Some(ref node) = current_node {
@ -479,7 +479,7 @@ impl<'dom> Iterator for ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
}
},
PseudoElementType::DetailsContent => {
Some(PseudoElement::DetailsContent) => {
let node = self.current_node;
let node = node.and_then(|node| {
if node.is_element() &&
@ -497,22 +497,24 @@ impl<'dom> Iterator for ServoThreadSafeLayoutNodeChildrenIterator<'dom> {
node
},
PseudoElementType::Normal => {
None | Some(_) => {
let node = self.current_node;
if let Some(ref node) = node {
self.current_node = match node.get_pseudo_element_type() {
PseudoElementType::Before => self
self.current_node = match node.pseudo_element() {
Some(PseudoElement::Before) => self
.parent_node
.get_details_summary_pseudo()
.or_else(|| unsafe { self.parent_node.dangerous_first_child() })
.or_else(|| self.parent_node.get_after_pseudo()),
PseudoElementType::Normal => unsafe { node.dangerous_next_sibling() }
.or_else(|| self.parent_node.get_after_pseudo()),
PseudoElementType::DetailsSummary => {
.or_else(|| self.parent_node.get_pseudo(PseudoElement::After)),
Some(PseudoElement::DetailsSummary) => {
self.parent_node.get_details_content_pseudo()
},
PseudoElementType::DetailsContent => self.parent_node.get_after_pseudo(),
PseudoElementType::After => None,
Some(PseudoElement::DetailsContent) => {
self.parent_node.get_pseudo(PseudoElement::After)
},
Some(PseudoElement::After) => None,
None | Some(_) => unsafe { node.dangerous_next_sibling() }
.or_else(|| self.parent_node.get_pseudo(PseudoElement::After)),
};
}
node