mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Improve some ergonomics around pseudo-elements.
I think a lot of the current indirection predates the crate merge. MozReview-Commit-ID: FM28dgZa5go
This commit is contained in:
parent
e8ed3e0b7f
commit
1ff008caa3
5 changed files with 53 additions and 46 deletions
|
@ -55,6 +55,31 @@ impl PseudoElement {
|
||||||
self.1
|
self.1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether this pseudo-element is ::before or ::after.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_before_or_after(&self) -> bool {
|
||||||
|
*self.as_atom() == atom!(":before") ||
|
||||||
|
*self.as_atom() == atom!(":after")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether this pseudo-element is eagerly-cascaded.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_eager(&self) -> bool {
|
||||||
|
self.is_before_or_after()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether this pseudo-element is lazily-cascaded.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_lazy(&self) -> bool {
|
||||||
|
!self.is_eager() && !self.is_precomputed()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether this pseudo-element is precomputed.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_precomputed(&self) -> bool {
|
||||||
|
self.is_anon_box()
|
||||||
|
}
|
||||||
|
|
||||||
/// Construct a pseudo-element from an `Atom`, receiving whether it is also
|
/// Construct a pseudo-element from an `Atom`, receiving whether it is also
|
||||||
/// an anonymous box, and don't check it on release builds.
|
/// an anonymous box, and don't check it on release builds.
|
||||||
///
|
///
|
||||||
|
@ -398,7 +423,8 @@ impl SelectorImpl {
|
||||||
///
|
///
|
||||||
/// We resolve the others lazily, see `Servo_ResolvePseudoStyle`.
|
/// We resolve the others lazily, see `Servo_ResolvePseudoStyle`.
|
||||||
pub fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
|
pub fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
|
||||||
if Self::pseudo_is_before_or_after(pseudo) {
|
if pseudo.is_eager() {
|
||||||
|
debug_assert!(!pseudo.is_anon_box());
|
||||||
return PseudoElementCascadeType::Eager
|
return PseudoElementCascadeType::Eager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,13 +449,6 @@ impl SelectorImpl {
|
||||||
include!("generated/gecko_pseudo_element_helper.rs")
|
include!("generated/gecko_pseudo_element_helper.rs")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Returns whether the given pseudo-element is `::before` or `::after`.
|
|
||||||
pub fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool {
|
|
||||||
*pseudo.as_atom() == atom!(":before") ||
|
|
||||||
*pseudo.as_atom() == atom!(":after")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Returns the relevant state flag for a given non-tree-structural
|
/// Returns the relevant state flag for a given non-tree-structural
|
||||||
/// pseudo-class.
|
/// pseudo-class.
|
||||||
|
|
|
@ -20,7 +20,6 @@ use properties::longhands::display::computed_value as display;
|
||||||
use restyle_hints::{RESTYLE_STYLE_ATTRIBUTE, RESTYLE_CSS_ANIMATIONS, RestyleHint};
|
use restyle_hints::{RESTYLE_STYLE_ATTRIBUTE, RESTYLE_CSS_ANIMATIONS, RestyleHint};
|
||||||
use rule_tree::{CascadeLevel, RuleTree, StrongRuleNode};
|
use rule_tree::{CascadeLevel, RuleTree, StrongRuleNode};
|
||||||
use selector_parser::{PseudoElement, RestyleDamage, SelectorImpl};
|
use selector_parser::{PseudoElement, RestyleDamage, SelectorImpl};
|
||||||
use selectors::MatchAttr;
|
|
||||||
use selectors::bloom::BloomFilter;
|
use selectors::bloom::BloomFilter;
|
||||||
use selectors::matching::{ElementSelectorFlags, StyleRelations};
|
use selectors::matching::{ElementSelectorFlags, StyleRelations};
|
||||||
use selectors::matching::AFFECTED_BY_PSEUDO_ELEMENTS;
|
use selectors::matching::AFFECTED_BY_PSEUDO_ELEMENTS;
|
||||||
|
@ -905,7 +904,7 @@ pub trait MatchMethods : TElement {
|
||||||
SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
||||||
let mut per_pseudo = &mut data.styles_mut().pseudos;
|
let mut per_pseudo = &mut data.styles_mut().pseudos;
|
||||||
debug_assert!(applicable_declarations.is_empty());
|
debug_assert!(applicable_declarations.is_empty());
|
||||||
let pseudo_animation_rules = if <Self as MatchAttr>::Impl::pseudo_is_before_or_after(&pseudo) {
|
let pseudo_animation_rules = if pseudo.is_before_or_after() {
|
||||||
self.get_animation_rules(Some(&pseudo))
|
self.get_animation_rules(Some(&pseudo))
|
||||||
} else {
|
} else {
|
||||||
AnimationRules(None, None)
|
AnimationRules(None, None)
|
||||||
|
@ -995,8 +994,7 @@ pub trait MatchMethods : TElement {
|
||||||
animation_rule.as_ref(),
|
animation_rule.as_ref(),
|
||||||
primary_rules);
|
primary_rules);
|
||||||
|
|
||||||
let iter = element_styles.pseudos.iter_mut().filter(|&(p, _)|
|
let iter = element_styles.pseudos.iter_mut().filter(|&(p, _)| p.is_before_or_after());
|
||||||
<Self as MatchAttr>::Impl::pseudo_is_before_or_after(p));
|
|
||||||
for (pseudo, ref mut computed) in iter {
|
for (pseudo, ref mut computed) in iter {
|
||||||
let animation_rule = self.get_animation_rule(Some(pseudo));
|
let animation_rule = self.get_animation_rule(Some(pseudo));
|
||||||
let pseudo_rules = &mut computed.rules;
|
let pseudo_rules = &mut computed.rules;
|
||||||
|
@ -1212,7 +1210,7 @@ pub trait MatchMethods : TElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only ::before and ::after are animatable.
|
// Only ::before and ::after are animatable.
|
||||||
let animate = <Self as MatchAttr>::Impl::pseudo_is_before_or_after(&pseudo);
|
let animate = pseudo.is_before_or_after();
|
||||||
self.cascade_primary_or_pseudo(context, data, Some(&pseudo),
|
self.cascade_primary_or_pseudo(context, data, Some(&pseudo),
|
||||||
&mut possibly_expired_animations,
|
&mut possibly_expired_animations,
|
||||||
CascadeBooleans {
|
CascadeBooleans {
|
||||||
|
|
|
@ -102,26 +102,6 @@ pub enum PseudoElementCascadeType {
|
||||||
Precomputed,
|
Precomputed,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PseudoElementCascadeType {
|
|
||||||
/// Simple accessor to check whether the cascade type is eager.
|
|
||||||
#[inline]
|
|
||||||
pub fn is_eager(&self) -> bool {
|
|
||||||
*self == PseudoElementCascadeType::Eager
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Simple accessor to check whether the cascade type is lazy.
|
|
||||||
#[inline]
|
|
||||||
pub fn is_lazy(&self) -> bool {
|
|
||||||
*self == PseudoElementCascadeType::Lazy
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Simple accessor to check whether the cascade type is precomputed.
|
|
||||||
#[inline]
|
|
||||||
pub fn is_precomputed(&self) -> bool {
|
|
||||||
*self == PseudoElementCascadeType::Precomputed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An extension to rust-selector's `Element` trait.
|
/// An extension to rust-selector's `Element` trait.
|
||||||
pub trait ElementExt: Element<Impl=SelectorImpl> + Debug {
|
pub trait ElementExt: Element<Impl=SelectorImpl> + Debug {
|
||||||
/// Whether this element is a `link`.
|
/// Whether this element is a `link`.
|
||||||
|
@ -144,7 +124,7 @@ impl SelectorImpl {
|
||||||
where F: FnMut(PseudoElement),
|
where F: FnMut(PseudoElement),
|
||||||
{
|
{
|
||||||
Self::each_pseudo_element(|pseudo| {
|
Self::each_pseudo_element(|pseudo| {
|
||||||
if Self::pseudo_element_cascade_type(&pseudo).is_eager() {
|
if pseudo.is_eager() {
|
||||||
fun(pseudo)
|
fun(pseudo)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -160,7 +140,7 @@ impl SelectorImpl {
|
||||||
where F: FnMut(PseudoElement),
|
where F: FnMut(PseudoElement),
|
||||||
{
|
{
|
||||||
Self::each_pseudo_element(|pseudo| {
|
Self::each_pseudo_element(|pseudo| {
|
||||||
if Self::pseudo_element_cascade_type(&pseudo).is_precomputed() {
|
if pseudo.is_precomputed() {
|
||||||
fun(pseudo)
|
fun(pseudo)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -78,6 +78,24 @@ impl PseudoElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether this pseudo-element is eagerly-cascaded.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_eager(&self) -> bool {
|
||||||
|
self.cascade_type() == PseudoElementCascadeType::Eager
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether this pseudo-element is lazily-cascaded.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_lazy(&self) -> bool {
|
||||||
|
self.cascade_type() == PseudoElementCascadeType::Lazy
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether this pseudo-element is precomputed.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_precomputed(&self) -> bool {
|
||||||
|
self.cascade_type() == PseudoElementCascadeType::Precomputed
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns which kind of cascade type has this pseudo.
|
/// Returns which kind of cascade type has this pseudo.
|
||||||
///
|
///
|
||||||
/// For more info on cascade types, see docs/components/style.md
|
/// For more info on cascade types, see docs/components/style.md
|
||||||
|
@ -396,12 +414,6 @@ impl SelectorImpl {
|
||||||
pub fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState {
|
pub fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState {
|
||||||
pc.state_flag()
|
pc.state_flag()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether this pseudo is either :before or :after.
|
|
||||||
#[inline]
|
|
||||||
pub fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool {
|
|
||||||
pseudo.is_before_or_after()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Servo's version of an element snapshot.
|
/// Servo's version of an element snapshot.
|
||||||
|
|
|
@ -345,7 +345,7 @@ impl Stylist {
|
||||||
parent: Option<&Arc<ComputedValues>>,
|
parent: Option<&Arc<ComputedValues>>,
|
||||||
cascade_flags: CascadeFlags)
|
cascade_flags: CascadeFlags)
|
||||||
-> ComputedStyle {
|
-> ComputedStyle {
|
||||||
debug_assert!(SelectorImpl::pseudo_element_cascade_type(pseudo).is_precomputed());
|
debug_assert!(pseudo.is_precomputed());
|
||||||
|
|
||||||
let rule_node = match self.precomputed_pseudo_element_decls.get(pseudo) {
|
let rule_node = match self.precomputed_pseudo_element_decls.get(pseudo) {
|
||||||
Some(declarations) => {
|
Some(declarations) => {
|
||||||
|
@ -435,7 +435,7 @@ impl Stylist {
|
||||||
fmt::Debug +
|
fmt::Debug +
|
||||||
PresentationalHintsSynthetizer
|
PresentationalHintsSynthetizer
|
||||||
{
|
{
|
||||||
debug_assert!(SelectorImpl::pseudo_element_cascade_type(pseudo).is_lazy());
|
debug_assert!(pseudo.is_lazy());
|
||||||
if self.pseudos_map.get(pseudo).is_none() {
|
if self.pseudos_map.get(pseudo).is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -603,9 +603,7 @@ impl Stylist {
|
||||||
debug_assert!(!self.is_device_dirty);
|
debug_assert!(!self.is_device_dirty);
|
||||||
debug_assert!(style_attribute.is_none() || pseudo_element.is_none(),
|
debug_assert!(style_attribute.is_none() || pseudo_element.is_none(),
|
||||||
"Style attributes do not apply to pseudo-elements");
|
"Style attributes do not apply to pseudo-elements");
|
||||||
debug_assert!(pseudo_element.is_none() ||
|
debug_assert!(pseudo_element.as_ref().map_or(true, |p| !p.is_precomputed()));
|
||||||
!SelectorImpl::pseudo_element_cascade_type(pseudo_element.as_ref().unwrap())
|
|
||||||
.is_precomputed());
|
|
||||||
|
|
||||||
let map = match pseudo_element {
|
let map = match pseudo_element {
|
||||||
Some(ref pseudo) => self.pseudos_map.get(pseudo).unwrap(),
|
Some(ref pseudo) => self.pseudos_map.get(pseudo).unwrap(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue