style: Include anon boxes in CSSPseudoElementType, to remove ComputedStyle::mPseudoTag.

This is more consistent with what the Rust bits of the style system do, and
removes a pointer from ComputedStyle which is always nice.

This also aligns the Rust bits with the C++ bits re. not treating xul pseudos as
anonymous boxes. See the comment in nsTreeStyleCache.cpp regarding those.

Can't wait for XUL trees to die.

Differential Revision: https://phabricator.services.mozilla.com/D19002
This commit is contained in:
Emilio Cobos Álvarez 2019-02-19 13:44:33 +00:00
parent 22e12a0f52
commit 3231714758
6 changed files with 41 additions and 94 deletions

View file

@ -8,7 +8,7 @@
//! `pseudo_element_definition.mako.rs`. If you touch that file, you probably //! `pseudo_element_definition.mako.rs`. If you touch that file, you probably
//! need to update the checked-in files for Servo. //! need to update the checked-in files for Servo.
use crate::gecko_bindings::structs::{self, CSSPseudoElementType}; use crate::gecko_bindings::structs::{self, PseudoStyleType};
use crate::properties::longhands::display::computed_value::T as Display; use crate::properties::longhands::display::computed_value::T as Display;
use crate::properties::{ComputedValues, PropertyFlags}; use crate::properties::{ComputedValues, PropertyFlags};
use crate::selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl}; use crate::selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl};

View file

@ -48,17 +48,6 @@ PseudoElement::${pseudo.capitalized_pseudo()}${"({})".format(tree_arg) if pseudo
</%def> </%def>
impl PseudoElement { impl PseudoElement {
/// Get the pseudo-element as an atom.
#[inline]
fn atom(&self) -> Atom {
match *self {
% for pseudo in PSEUDOS:
${pseudo_element_variant(pseudo)} => atom!("${pseudo.value}"),
% endfor
PseudoElement::UnknownWebkit(..) => unreachable!(),
}
}
/// Returns an index of the pseudo-element. /// Returns an index of the pseudo-element.
#[inline] #[inline]
pub fn index(&self) -> usize { pub fn index(&self) -> usize {
@ -138,13 +127,13 @@ impl PseudoElement {
} }
} }
/// Construct a pseudo-element from a `CSSPseudoElementType`. /// Construct a pseudo-element from a `PseudoStyleType`.
#[inline] #[inline]
pub fn from_pseudo_type(type_: CSSPseudoElementType) -> Option<Self> { pub fn from_pseudo_type(type_: PseudoStyleType) -> Option<Self> {
match type_ { match type_ {
% for pseudo in PSEUDOS: % for pseudo in PSEUDOS:
% if not pseudo.is_anon_box(): % if not pseudo.is_tree_pseudo_element():
CSSPseudoElementType::${pseudo.pseudo_ident} => { PseudoStyleType::${pseudo.pseudo_ident} => {
Some(${pseudo_element_variant(pseudo)}) Some(${pseudo_element_variant(pseudo)})
}, },
% endif % endif
@ -153,30 +142,21 @@ impl PseudoElement {
} }
} }
/// Construct a `CSSPseudoElementType` from a pseudo-element /// Construct a `PseudoStyleType` from a pseudo-element
#[inline] #[inline]
fn pseudo_type(&self) -> CSSPseudoElementType { pub fn pseudo_type(&self) -> PseudoStyleType {
match *self { match *self {
% for pseudo in PSEUDOS: % for pseudo in PSEUDOS:
% if not pseudo.is_anon_box(): % if pseudo.is_tree_pseudo_element():
PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::${pseudo.pseudo_ident}, PseudoElement::${pseudo.capitalized_pseudo()}(..) => PseudoStyleType::XULTree,
% elif pseudo.is_tree_pseudo_element():
PseudoElement::${pseudo.capitalized_pseudo()}(..) => CSSPseudoElementType::XULTree,
% elif pseudo.is_inheriting_anon_box():
PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::InheritingAnonBox,
% else: % else:
PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::NonInheritingAnonBox, PseudoElement::${pseudo.capitalized_pseudo()} => PseudoStyleType::${pseudo.pseudo_ident},
% endif % endif
% endfor % endfor
PseudoElement::UnknownWebkit(..) => unreachable!(), PseudoElement::UnknownWebkit(..) => unreachable!(),
} }
} }
/// Get a PseudoInfo for a pseudo
pub fn pseudo_info(&self) -> (*mut structs::nsAtom, CSSPseudoElementType) {
(self.atom().as_ptr(), self.pseudo_type())
}
/// Get the argument list of a tree pseudo-element. /// Get the argument list of a tree pseudo-element.
#[inline] #[inline]
pub fn tree_pseudo_args(&self) -> Option<<&[Atom]> { pub fn tree_pseudo_args(&self) -> Option<<&[Atom]> {
@ -188,36 +168,6 @@ impl PseudoElement {
} }
} }
/// Construct a pseudo-element from an `Atom`.
#[inline]
pub fn from_atom(atom: &Atom) -> Option<Self> {
% for pseudo in PSEUDOS:
% if pseudo.is_tree_pseudo_element():
// We cannot generate ${pseudo_element_variant(pseudo)} from just an atom.
% else:
if atom == &atom!("${pseudo.value}") {
return Some(${pseudo_element_variant(pseudo)});
}
% endif
% endfor
None
}
/// Construct a pseudo-element from an anonymous box `Atom`.
#[inline]
pub fn from_anon_box_atom(atom: &Atom) -> Option<Self> {
% for pseudo in PSEUDOS:
% if pseudo.is_tree_pseudo_element():
// We cannot generate ${pseudo_element_variant(pseudo)} from just an atom.
% elif pseudo.is_anon_box():
if atom == &atom!("${pseudo.value}") {
return Some(${pseudo_element_variant(pseudo)});
}
% endif
% endfor
None
}
/// Construct a tree pseudo-element from atom and args. /// Construct a tree pseudo-element from atom and args.
#[inline] #[inline]
pub fn from_tree_pseudo_atom(atom: &Atom, args: Box<[Atom]>) -> Option<Self> { pub fn from_tree_pseudo_atom(atom: &Atom, args: Box<[Atom]>) -> Option<Self> {

View file

@ -41,8 +41,10 @@ class Atom:
# The type of atom: "Atom", "PseudoElement", "NonInheritingAnonBox", # The type of atom: "Atom", "PseudoElement", "NonInheritingAnonBox",
# or "InheritingAnonBox". # or "InheritingAnonBox".
self.atom_type = atom_type self.atom_type = atom_type
if self.is_pseudo() or self.is_anon_box():
if self.is_pseudo_element() or self.is_anon_box() or self.is_tree_pseudo_element():
self.pseudo_ident = (ident.split("_", 1))[1] self.pseudo_ident = (ident.split("_", 1))[1]
if self.is_anon_box(): if self.is_anon_box():
assert self.is_inheriting_anon_box() or self.is_non_inheriting_anon_box() assert self.is_inheriting_anon_box() or self.is_non_inheriting_anon_box()
@ -52,16 +54,21 @@ class Atom:
def capitalized_pseudo(self): def capitalized_pseudo(self):
return self.pseudo_ident[0].upper() + self.pseudo_ident[1:] return self.pseudo_ident[0].upper() + self.pseudo_ident[1:]
def is_pseudo(self): def is_pseudo_element(self):
return self.atom_type == "PseudoElementAtom" return self.atom_type == "PseudoElementAtom"
def is_anon_box(self): def is_anon_box(self):
if self.is_tree_pseudo_element():
return False
return self.is_non_inheriting_anon_box() or self.is_inheriting_anon_box() return self.is_non_inheriting_anon_box() or self.is_inheriting_anon_box()
def is_non_inheriting_anon_box(self): def is_non_inheriting_anon_box(self):
assert not self.is_tree_pseudo_element()
return self.atom_type == "NonInheritingAnonBoxAtom" return self.atom_type == "NonInheritingAnonBoxAtom"
def is_inheriting_anon_box(self): def is_inheriting_anon_box(self):
if self.is_tree_pseudo_element():
return False
return self.atom_type == "InheritingAnonBoxAtom" return self.atom_type == "InheritingAnonBoxAtom"
def is_tree_pseudo_element(self): def is_tree_pseudo_element(self):

View file

@ -236,7 +236,7 @@ where
parent_style.unwrap(), parent_style.unwrap(),
parent_style_ignoring_first_line.unwrap() parent_style_ignoring_first_line.unwrap()
) || ) ||
parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine) parent_style.unwrap().is_first_line_style()
); );
let inherited_style = parent_style.unwrap_or(device.default_computed_values()); let inherited_style = parent_style.unwrap_or(device.default_computed_values());

View file

@ -38,7 +38,7 @@ use crate::gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom}
use crate::gecko_bindings::bindings::RawGeckoPresContextBorrowed; use crate::gecko_bindings::bindings::RawGeckoPresContextBorrowed;
use crate::gecko_bindings::structs; use crate::gecko_bindings::structs;
use crate::gecko_bindings::structs::nsCSSPropertyID; use crate::gecko_bindings::structs::nsCSSPropertyID;
use crate::gecko_bindings::structs::mozilla::CSSPseudoElementType; use crate::gecko_bindings::structs::mozilla::PseudoStyleType;
use crate::gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut}; use crate::gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
use crate::gecko_bindings::sugar::refptr::RefPtr; use crate::gecko_bindings::sugar::refptr::RefPtr;
use crate::gecko::values::convert_nscolor_to_rgba; use crate::gecko::values::convert_nscolor_to_rgba;
@ -115,26 +115,17 @@ impl ComputedValues {
).to_outer(None) ).to_outer(None)
} }
#[inline]
pub fn pseudo(&self) -> Option<PseudoElement> { pub fn pseudo(&self) -> Option<PseudoElement> {
let atom = (self.0).mPseudoTag.mRawPtr; if self.0.mPseudoType == PseudoStyleType::NotPseudo {
if atom.is_null() {
return None; return None;
} }
PseudoElement::from_pseudo_type(self.0.mPseudoType)
let atom = unsafe { Atom::from_raw(atom) };
PseudoElement::from_atom(&atom)
} }
#[inline] #[inline]
fn get_pseudo_type(&self) -> CSSPseudoElementType { pub fn is_first_line_style(&self) -> bool {
self.0.mPseudoType self.pseudo() == Some(PseudoElement::FirstLine)
}
#[inline]
pub fn is_anon_box(&self) -> bool {
let our_type = self.get_pseudo_type();
return our_type == CSSPseudoElementType::InheritingAnonBox ||
our_type == CSSPseudoElementType::NonInheritingAnonBox;
} }
/// Returns true if the display property is changed from 'none' to others. /// Returns true if the display property is changed from 'none' to others.
@ -213,9 +204,9 @@ impl ComputedValuesInner {
self, self,
pseudo: Option<<&PseudoElement>, pseudo: Option<<&PseudoElement>,
) -> Arc<ComputedValues> { ) -> Arc<ComputedValues> {
let (pseudo_tag, pseudo_ty) = match pseudo { let pseudo_ty = match pseudo {
Some(p) => p.pseudo_info(), Some(p) => p.pseudo_type(),
None => (ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo), None => structs::PseudoStyleType::NotPseudo,
}; };
let arc = unsafe { let arc = unsafe {
let arc: Arc<ComputedValues> = Arc::new(uninitialized()); let arc: Arc<ComputedValues> = Arc::new(uninitialized());
@ -223,7 +214,6 @@ impl ComputedValuesInner {
&arc.0 as *const _ as *mut _, &arc.0 as *const _ as *mut _,
&self, &self,
pseudo_ty, pseudo_ty,
pseudo_tag
); );
// We're simulating a move by having C++ do a memcpy and then forgetting // We're simulating a move by having C++ do a memcpy and then forgetting
// it on this end. // it on this end.

View file

@ -3358,7 +3358,7 @@ impl<'a> StyleBuilder<'a> {
debug_assert!(parent_style.is_none() || debug_assert!(parent_style.is_none() ||
std::ptr::eq(parent_style.unwrap(), std::ptr::eq(parent_style.unwrap(),
parent_style_ignoring_first_line.unwrap()) || parent_style_ignoring_first_line.unwrap()) ||
parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine)); parent_style.unwrap().is_first_line_style());
let reset_style = device.default_computed_values(); let reset_style = device.default_computed_values();
let inherited_style = parent_style.unwrap_or(reset_style); let inherited_style = parent_style.unwrap_or(reset_style);
let inherited_style_ignoring_first_line = parent_style_ignoring_first_line.unwrap_or(reset_style); let inherited_style_ignoring_first_line = parent_style_ignoring_first_line.unwrap_or(reset_style);
@ -3402,7 +3402,7 @@ impl<'a> StyleBuilder<'a> {
let inherited_style = parent_style.unwrap_or(reset_style); let inherited_style = parent_style.unwrap_or(reset_style);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
debug_assert!(parent_style.is_none() || debug_assert!(parent_style.is_none() ||
parent_style.unwrap().pseudo() != Some(PseudoElement::FirstLine)); !parent_style.unwrap().is_first_line_style());
StyleBuilder { StyleBuilder {
device, device,
inherited_style, inherited_style,