mirror of
https://github.com/servo/servo.git
synced 2025-08-11 16:35:33 +01:00
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:
parent
22e12a0f52
commit
3231714758
6 changed files with 41 additions and 94 deletions
|
@ -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};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue