diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2017-06-13 00:31:29 +0200 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2017-06-13 00:31:29 +0200 |
commit | 700aaf2bd6dad1e86508813883e1c41491cd02bc (patch) | |
tree | 829f198e8681f0f5b551cc413c8353932e2382b3 | |
parent | c5c1c1b350a016acb02a389ac3e5737d039796e7 (diff) | |
download | servo-700aaf2bd6dad1e86508813883e1c41491cd02bc.tar.gz servo-700aaf2bd6dad1e86508813883e1c41491cd02bc.zip |
Move MatchingContext to a new module
-rw-r--r-- | components/selectors/context.rs | 137 | ||||
-rw-r--r-- | components/selectors/lib.rs | 1 | ||||
-rw-r--r-- | components/selectors/matching.rs | 135 |
3 files changed, 141 insertions, 132 deletions
diff --git a/components/selectors/context.rs b/components/selectors/context.rs new file mode 100644 index 00000000000..766eac800fc --- /dev/null +++ b/components/selectors/context.rs @@ -0,0 +1,137 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use attr::CaseSensitivity; +use bloom::BloomFilter; + +bitflags! { + /// Set of flags that determine the different kind of elements affected by + /// the selector matching process. + /// + /// This is used to implement efficient sharing. + #[derive(Default)] + pub flags StyleRelations: usize { + /// Whether this element is affected by presentational hints. This is + /// computed externally (that is, in Servo). + const AFFECTED_BY_PRESENTATIONAL_HINTS = 1 << 0, + /// Whether this element has pseudo-element styles. Computed externally. + const AFFECTED_BY_PSEUDO_ELEMENTS = 1 << 1, + } +} + +/// What kind of selector matching mode we should use. +/// +/// There are two modes of selector matching. The difference is only noticeable +/// in presence of pseudo-elements. +#[derive(Debug, PartialEq, Copy, Clone)] +pub enum MatchingMode { + /// Don't ignore any pseudo-element selectors. + Normal, + + /// Ignores any stateless pseudo-element selectors in the rightmost sequence + /// of simple selectors. + /// + /// This is useful, for example, to match against ::before when you aren't a + /// pseudo-element yourself. + /// + /// For example, in presence of `::before:hover`, it would never match, but + /// `::before` would be ignored as in "matching". + /// + /// It's required for all the selectors you match using this mode to have a + /// pseudo-element. + ForStatelessPseudoElement, +} + +/// The mode to use when matching unvisited and visited links. +#[derive(PartialEq, Eq, Copy, Clone, Debug)] +pub enum VisitedHandlingMode { + /// All links are matched as if they are unvisted. + AllLinksUnvisited, + /// A element's "relevant link" is the element being matched if it is a link + /// or the nearest ancestor link. The relevant link is matched as though it + /// is visited, and all other links are matched as if they are unvisited. + RelevantLinkVisited, +} + +/// Which quirks mode is this document in. +/// +/// See: https://quirks.spec.whatwg.org/ +#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)] +pub enum QuirksMode { + /// Quirks mode. + Quirks, + /// Limited quirks mode. + LimitedQuirks, + /// No quirks mode. + NoQuirks, +} + +impl QuirksMode { + #[inline] + pub fn classes_and_ids_case_sensitivity(self) -> CaseSensitivity { + match self { + QuirksMode::NoQuirks | + QuirksMode::LimitedQuirks => CaseSensitivity::CaseSensitive, + QuirksMode::Quirks => CaseSensitivity::AsciiCaseInsensitive, + } + } +} + +/// Data associated with the matching process for a element. This context is +/// used across many selectors for an element, so it's not appropriate for +/// transient data that applies to only a single selector. +#[derive(Clone)] +pub struct MatchingContext<'a> { + /// Output that records certains relations between elements noticed during + /// matching (and also extended after matching). + pub relations: StyleRelations, + /// Input with the matching mode we should use when matching selectors. + pub matching_mode: MatchingMode, + /// Input with the bloom filter used to fast-reject selectors. + pub bloom_filter: Option<&'a BloomFilter>, + /// Input that controls how matching for links is handled. + pub visited_handling: VisitedHandlingMode, + /// Output that records whether we encountered a "relevant link" while + /// matching _any_ selector for this element. (This differs from + /// `RelevantLinkStatus` which tracks the status for the _current_ selector + /// only.) + pub relevant_link_found: bool, + /// The quirks mode of the document. + pub quirks_mode: QuirksMode, +} + +impl<'a> MatchingContext<'a> { + /// Constructs a new `MatchingContext`. + pub fn new(matching_mode: MatchingMode, + bloom_filter: Option<&'a BloomFilter>, + quirks_mode: QuirksMode) + -> Self + { + Self { + relations: StyleRelations::empty(), + matching_mode: matching_mode, + bloom_filter: bloom_filter, + visited_handling: VisitedHandlingMode::AllLinksUnvisited, + relevant_link_found: false, + quirks_mode: quirks_mode, + } + } + + /// Constructs a new `MatchingContext` for use in visited matching. + pub fn new_for_visited(matching_mode: MatchingMode, + bloom_filter: Option<&'a BloomFilter>, + visited_handling: VisitedHandlingMode, + quirks_mode: QuirksMode) + -> Self + { + Self { + relations: StyleRelations::empty(), + matching_mode: matching_mode, + bloom_filter: bloom_filter, + visited_handling: visited_handling, + relevant_link_found: false, + quirks_mode: quirks_mode, + } + } +} diff --git a/components/selectors/lib.rs b/components/selectors/lib.rs index 130475271fc..16a7949cfa9 100644 --- a/components/selectors/lib.rs +++ b/components/selectors/lib.rs @@ -15,6 +15,7 @@ extern crate smallvec; pub mod attr; pub mod bloom; +pub mod context; pub mod matching; pub mod parser; #[cfg(test)] mod size_of_tests; diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index 6e8702433fc..d221a1613c7 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -2,34 +2,21 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use attr::{ParsedAttrSelectorOperation, AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; +use attr::{ParsedAttrSelectorOperation, AttrSelectorOperation, NamespaceConstraint}; use bloom::{BLOOM_HASH_MASK, BloomFilter}; use parser::{AncestorHashes, Combinator, Component, LocalName}; use parser::{Selector, SelectorImpl, SelectorIter, SelectorList}; use std::borrow::Borrow; use tree::Element; +pub use context::*; + // The bloom filter for descendant CSS selectors will have a <1% false // positive rate until it has this many selectors in it, then it will // rapidly increase. pub static RECOMMENDED_SELECTOR_BLOOM_FILTER_SIZE: usize = 4096; bitflags! { - /// Set of flags that determine the different kind of elements affected by - /// the selector matching process. - /// - /// This is used to implement efficient sharing. - #[derive(Default)] - pub flags StyleRelations: usize { - /// Whether this element is affected by presentational hints. This is - /// computed externally (that is, in Servo). - const AFFECTED_BY_PRESENTATIONAL_HINTS = 1 << 0, - /// Whether this element has pseudo-element styles. Computed externally. - const AFFECTED_BY_PSEUDO_ELEMENTS = 1 << 1, - } -} - -bitflags! { /// Set of flags that are set on either the element or its parent (depending /// on the flag) if the element could potentially match a selector. pub flags ElementSelectorFlags: usize { @@ -66,122 +53,6 @@ impl ElementSelectorFlags { } } -/// What kind of selector matching mode we should use. -/// -/// There are two modes of selector matching. The difference is only noticeable -/// in presence of pseudo-elements. -#[derive(Debug, PartialEq, Copy, Clone)] -pub enum MatchingMode { - /// Don't ignore any pseudo-element selectors. - Normal, - - /// Ignores any stateless pseudo-element selectors in the rightmost sequence - /// of simple selectors. - /// - /// This is useful, for example, to match against ::before when you aren't a - /// pseudo-element yourself. - /// - /// For example, in presence of `::before:hover`, it would never match, but - /// `::before` would be ignored as in "matching". - /// - /// It's required for all the selectors you match using this mode to have a - /// pseudo-element. - ForStatelessPseudoElement, -} - -/// The mode to use when matching unvisited and visited links. -#[derive(PartialEq, Eq, Copy, Clone, Debug)] -pub enum VisitedHandlingMode { - /// All links are matched as if they are unvisted. - AllLinksUnvisited, - /// A element's "relevant link" is the element being matched if it is a link - /// or the nearest ancestor link. The relevant link is matched as though it - /// is visited, and all other links are matched as if they are unvisited. - RelevantLinkVisited, -} - -/// Which quirks mode is this document in. -/// -/// See: https://quirks.spec.whatwg.org/ -#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)] -pub enum QuirksMode { - /// Quirks mode. - Quirks, - /// Limited quirks mode. - LimitedQuirks, - /// No quirks mode. - NoQuirks, -} - -impl QuirksMode { - #[inline] - pub fn classes_and_ids_case_sensitivity(self) -> CaseSensitivity { - match self { - QuirksMode::NoQuirks | - QuirksMode::LimitedQuirks => CaseSensitivity::CaseSensitive, - QuirksMode::Quirks => CaseSensitivity::AsciiCaseInsensitive, - } - } -} - -/// Data associated with the matching process for a element. This context is -/// used across many selectors for an element, so it's not appropriate for -/// transient data that applies to only a single selector. -#[derive(Clone)] -pub struct MatchingContext<'a> { - /// Output that records certains relations between elements noticed during - /// matching (and also extended after matching). - pub relations: StyleRelations, - /// Input with the matching mode we should use when matching selectors. - pub matching_mode: MatchingMode, - /// Input with the bloom filter used to fast-reject selectors. - pub bloom_filter: Option<&'a BloomFilter>, - /// Input that controls how matching for links is handled. - pub visited_handling: VisitedHandlingMode, - /// Output that records whether we encountered a "relevant link" while - /// matching _any_ selector for this element. (This differs from - /// `RelevantLinkStatus` which tracks the status for the _current_ selector - /// only.) - pub relevant_link_found: bool, - /// The quirks mode of the document. - pub quirks_mode: QuirksMode, -} - -impl<'a> MatchingContext<'a> { - /// Constructs a new `MatchingContext`. - pub fn new(matching_mode: MatchingMode, - bloom_filter: Option<&'a BloomFilter>, - quirks_mode: QuirksMode) - -> Self - { - Self { - relations: StyleRelations::empty(), - matching_mode: matching_mode, - bloom_filter: bloom_filter, - visited_handling: VisitedHandlingMode::AllLinksUnvisited, - relevant_link_found: false, - quirks_mode: quirks_mode, - } - } - - /// Constructs a new `MatchingContext` for use in visited matching. - pub fn new_for_visited(matching_mode: MatchingMode, - bloom_filter: Option<&'a BloomFilter>, - visited_handling: VisitedHandlingMode, - quirks_mode: QuirksMode) - -> Self - { - Self { - relations: StyleRelations::empty(), - matching_mode: matching_mode, - bloom_filter: bloom_filter, - visited_handling: visited_handling, - relevant_link_found: false, - quirks_mode: quirks_mode, - } - } -} - /// Holds per-element data alongside a pointer to MatchingContext. pub struct LocalMatchingContext<'a, 'b: 'a, Impl: SelectorImpl> { /// Shared `MatchingContext`. |