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
//! 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::{ComputedValues, PropertyFlags};
use crate::selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl};

View file

@ -48,17 +48,6 @@ PseudoElement::${pseudo.capitalized_pseudo()}${"({})".format(tree_arg) if pseudo
</%def>
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.
#[inline]
pub fn index(&self) -> usize {
@ -138,45 +127,36 @@ impl PseudoElement {
}
}
/// Construct a pseudo-element from a `CSSPseudoElementType`.
/// Construct a pseudo-element from a `PseudoStyleType`.
#[inline]
pub fn from_pseudo_type(type_: CSSPseudoElementType) -> Option<Self> {
pub fn from_pseudo_type(type_: PseudoStyleType) -> Option<Self> {
match type_ {
% for pseudo in PSEUDOS:
% if not pseudo.is_anon_box():
CSSPseudoElementType::${pseudo.pseudo_ident} => {
Some(${pseudo_element_variant(pseudo)})
},
% endif
% if not pseudo.is_tree_pseudo_element():
PseudoStyleType::${pseudo.pseudo_ident} => {
Some(${pseudo_element_variant(pseudo)})
},
% endif
% endfor
_ => None,
}
}
/// Construct a `CSSPseudoElementType` from a pseudo-element
/// Construct a `PseudoStyleType` from a pseudo-element
#[inline]
fn pseudo_type(&self) -> CSSPseudoElementType {
pub fn pseudo_type(&self) -> PseudoStyleType {
match *self {
% for pseudo in PSEUDOS:
% if not pseudo.is_anon_box():
PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::${pseudo.pseudo_ident},
% 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:
PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::NonInheritingAnonBox,
% endif
% if pseudo.is_tree_pseudo_element():
PseudoElement::${pseudo.capitalized_pseudo()}(..) => PseudoStyleType::XULTree,
% else:
PseudoElement::${pseudo.capitalized_pseudo()} => PseudoStyleType::${pseudo.pseudo_ident},
% endif
% endfor
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.
#[inline]
pub fn tree_pseudo_args(&self) -> Option<<&[Atom]> {
@ -188,45 +168,15 @@ 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.
#[inline]
pub fn from_tree_pseudo_atom(atom: &Atom, args: Box<[Atom]>) -> Option<Self> {
% for pseudo in PSEUDOS:
% if pseudo.is_tree_pseudo_element():
if atom == &atom!("${pseudo.value}") {
return Some(PseudoElement::${pseudo.capitalized_pseudo()}(args.into()));
}
% endif
% if pseudo.is_tree_pseudo_element():
if atom == &atom!("${pseudo.value}") {
return Some(PseudoElement::${pseudo.capitalized_pseudo()}(args.into()));
}
% endif
% endfor
None
}

View file

@ -41,8 +41,10 @@ class Atom:
# The type of atom: "Atom", "PseudoElement", "NonInheritingAnonBox",
# or "InheritingAnonBox".
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]
if self.is_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):
return self.pseudo_ident[0].upper() + self.pseudo_ident[1:]
def is_pseudo(self):
def is_pseudo_element(self):
return self.atom_type == "PseudoElementAtom"
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()
def is_non_inheriting_anon_box(self):
assert not self.is_tree_pseudo_element()
return self.atom_type == "NonInheritingAnonBoxAtom"
def is_inheriting_anon_box(self):
if self.is_tree_pseudo_element():
return False
return self.atom_type == "InheritingAnonBoxAtom"
def is_tree_pseudo_element(self):

View file

@ -236,7 +236,7 @@ where
parent_style.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());

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

View file

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