mirror of
https://github.com/servo/servo.git
synced 2025-08-12 00:45: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
|
//! `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};
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue