style: Improve style::selector_matching documentation

This commit is contained in:
Emilio Cobos Álvarez 2016-03-31 12:40:04 +02:00 committed by Emilio Cobos Álvarez
parent 5e73e1015b
commit 41708d753e

View file

@ -83,27 +83,47 @@ lazy_static! {
}; };
} }
/// This structure holds all the selectors and device characteristics
/// for a given document. The selectors are converted into `Rule`s
/// (defined in rust-selectors), and introduced in a `SelectorMap`
/// depending on the pseudo-element (see `PerPseudoElementSelectorMap`),
/// stylesheet origin (see `PerOriginSelectorMap`), and priority
/// (see the `normal` and `important` fields in `PerOriginSelectorMap`).
///
/// This structure is effectively created once per pipeline, in the
/// LayoutThread corresponding to that pipeline.
///
/// The stylist is parameterized on `SelectorImplExt`, a trait that extends
/// `selectors::parser::SelectorImpl`, and that allows to customise what
/// pseudo-classes and pseudo-elements are parsed. This is actually either
/// `ServoSelectorImpl`, the implementation used by Servo's layout system in
/// regular builds, or `GeckoSelectorImpl`, the implementation used in the
/// geckolib port.
#[derive(HeapSizeOf)] #[derive(HeapSizeOf)]
pub struct Stylist<Impl: SelectorImplExt> { pub struct Stylist<Impl: SelectorImplExt> {
// Device that the stylist is currently evaluating against. /// Device that the stylist is currently evaluating against.
pub device: Device, pub device: Device,
// Viewport constraints based on the current device. /// Viewport constraints based on the current device.
viewport_constraints: Option<ViewportConstraints>, viewport_constraints: Option<ViewportConstraints>,
// If true, the quirks-mode stylesheet is applied. /// If true, the quirks-mode stylesheet is applied.
quirks_mode: bool, quirks_mode: bool,
// If true, the device has changed, and the stylist needs to be updated. /// If true, the device has changed, and the stylist needs to be updated.
is_device_dirty: bool, is_device_dirty: bool,
// The current selector maps, after evaluating media /// The current selector maps, after evaluating media
// rules against the current device. /// rules against the current device.
element_map: PerPseudoElementSelectorMap<Impl>, element_map: PerPseudoElementSelectorMap<Impl>,
pseudos_map: HashMap<Impl::PseudoElement, PerPseudoElementSelectorMap<Impl>, BuildHasherDefault<::fnv::FnvHasher>>, /// The selector maps corresponding to a given pseudo-element
/// (depending on the implementation)
pseudos_map: HashMap<Impl::PseudoElement,
PerPseudoElementSelectorMap<Impl>,
BuildHasherDefault<::fnv::FnvHasher>>,
rules_source_order: usize, rules_source_order: usize,
// Selector dependencies used to compute restyle hints. /// Selector dependencies used to compute restyle hints.
state_deps: DependencySet<Impl>, state_deps: DependencySet<Impl>,
} }
@ -137,6 +157,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
if !(self.is_device_dirty || stylesheets_changed) { if !(self.is_device_dirty || stylesheets_changed) {
return false; return false;
} }
self.element_map = PerPseudoElementSelectorMap::new(); self.element_map = PerPseudoElementSelectorMap::new();
self.pseudos_map = HashMap::with_hasher(Default::default()); self.pseudos_map = HashMap::with_hasher(Default::default());
self.rules_source_order = 0; self.rules_source_order = 0;
@ -171,7 +192,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
// them into the SelectorMap of that priority. // them into the SelectorMap of that priority.
macro_rules! append( macro_rules! append(
($style_rule: ident, $priority: ident) => { ($style_rule: ident, $priority: ident) => {
if $style_rule.declarations.$priority.len() > 0 { if !$style_rule.declarations.$priority.is_empty() {
for selector in &$style_rule.selectors { for selector in &$style_rule.selectors {
let map = if let Some(ref pseudo) = selector.pseudo_element { let map = if let Some(ref pseudo) = selector.pseudo_element {
self.pseudos_map.entry(pseudo.clone()) self.pseudos_map.entry(pseudo.clone())
@ -243,12 +264,13 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
self.quirks_mode = enabled; self.quirks_mode = enabled;
} }
/// Returns the applicable CSS declarations for the given element. This corresponds to /// Returns the applicable CSS declarations for the given element.
/// `ElementRuleCollector` in WebKit. /// This corresponds to `ElementRuleCollector` in WebKit.
/// ///
/// The returned boolean indicates whether the style is *shareable*; that is, whether the /// The returned boolean indicates whether the style is *shareable*;
/// matched selectors are simple enough to allow the matching logic to be reduced to the logic /// that is, whether the matched selectors are simple enough to allow the
/// in `css::matching::PrivateMatchMethods::candidate_element_allows_for_style_sharing`. /// matching logic to be reduced to the logic in
/// `css::matching::PrivateMatchMethods::candidate_element_allows_for_style_sharing`.
pub fn push_applicable_declarations<E, V>( pub fn push_applicable_declarations<E, V>(
&self, &self,
element: &E, element: &E,
@ -333,14 +355,20 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
shareable shareable
} }
#[inline]
pub fn is_device_dirty(&self) -> bool { pub fn is_device_dirty(&self) -> bool {
self.is_device_dirty self.is_device_dirty
} }
} }
/// Map that contains the CSS rules for a given origin.
#[derive(HeapSizeOf)] #[derive(HeapSizeOf)]
struct PerOriginSelectorMap<Impl: SelectorImpl> { struct PerOriginSelectorMap<Impl: SelectorImpl> {
/// Rules that contains at least one property declararion with
/// normal importance.
normal: SelectorMap<Vec<PropertyDeclaration>, Impl>, normal: SelectorMap<Vec<PropertyDeclaration>, Impl>,
/// Rules that contains at least one property declararion with
/// !important.
important: SelectorMap<Vec<PropertyDeclaration>, Impl>, important: SelectorMap<Vec<PropertyDeclaration>, Impl>,
} }
@ -354,10 +382,15 @@ impl<Impl: SelectorImpl> PerOriginSelectorMap<Impl> {
} }
} }
/// Map that contains the CSS rules for a specific PseudoElement
/// (or lack of PseudoElement).
#[derive(HeapSizeOf)] #[derive(HeapSizeOf)]
struct PerPseudoElementSelectorMap<Impl: SelectorImpl> { struct PerPseudoElementSelectorMap<Impl: SelectorImpl> {
/// Rules from user agent stylesheets
user_agent: PerOriginSelectorMap<Impl>, user_agent: PerOriginSelectorMap<Impl>,
/// Rules from author stylesheets
author: PerOriginSelectorMap<Impl>, author: PerOriginSelectorMap<Impl>,
/// Rules from user stylesheets
user: PerOriginSelectorMap<Impl>, user: PerOriginSelectorMap<Impl>,
} }