style: Make MatchingContext generic over SelectorImpl.

This will help Xidorn implement tree pseudos, and in general makes sense,
allowing to put specific matching data in a selectors implementation.
This commit is contained in:
Emilio Cobos Álvarez 2017-10-18 09:13:00 +02:00
parent 4cf2ce66fc
commit b0e54968ec
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
9 changed files with 121 additions and 85 deletions

View file

@ -686,21 +686,23 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
self.element.namespace() self.element.namespace()
} }
fn match_pseudo_element(&self, fn match_pseudo_element(
&self,
_pseudo: &PseudoElement, _pseudo: &PseudoElement,
_context: &mut MatchingContext) _context: &mut MatchingContext<Self::Impl>,
-> bool ) -> bool {
{
false false
} }
fn match_non_ts_pseudo_class<F>(&self, fn match_non_ts_pseudo_class<F>(
&self,
pseudo_class: &NonTSPseudoClass, pseudo_class: &NonTSPseudoClass,
_: &mut MatchingContext, _: &mut MatchingContext<Self::Impl>,
_: &RelevantLinkStatus, _: &RelevantLinkStatus,
_: &mut F) _: &mut F,
-> bool ) -> bool
where F: FnMut(&Self, ElementSelectorFlags), where
F: FnMut(&Self, ElementSelectorFlags),
{ {
match *pseudo_class { match *pseudo_class {
// https://github.com/servo/servo/issues/8718 // https://github.com/servo/servo/issues/8718
@ -1176,11 +1178,11 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
self.element.get_namespace() self.element.get_namespace()
} }
fn match_pseudo_element(&self, fn match_pseudo_element(
&self,
_pseudo: &PseudoElement, _pseudo: &PseudoElement,
_context: &mut MatchingContext) _context: &mut MatchingContext<Self::Impl>
-> bool ) -> bool {
{
false false
} }
@ -1203,13 +1205,15 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
} }
} }
fn match_non_ts_pseudo_class<F>(&self, fn match_non_ts_pseudo_class<F>(
&self,
_: &NonTSPseudoClass, _: &NonTSPseudoClass,
_: &mut MatchingContext, _: &mut MatchingContext<Self::Impl>,
_: &RelevantLinkStatus, _: &RelevantLinkStatus,
_: &mut F) _: &mut F,
-> bool ) -> bool
where F: FnMut(&Self, ElementSelectorFlags), where
F: FnMut(&Self, ElementSelectorFlags),
{ {
// NB: This could maybe be implemented // NB: This could maybe be implemented
warn!("ServoThreadSafeLayoutElement::match_non_ts_pseudo_class called"); warn!("ServoThreadSafeLayoutElement::match_non_ts_pseudo_class called");

View file

@ -2528,11 +2528,11 @@ impl<'a> SelectorsElement for DomRoot<Element> {
self.upcast::<Node>().GetParentElement() self.upcast::<Node>().GetParentElement()
} }
fn match_pseudo_element(&self, fn match_pseudo_element(
&self,
_pseudo: &PseudoElement, _pseudo: &PseudoElement,
_context: &mut MatchingContext) _context: &mut MatchingContext<Self::Impl>,
-> bool ) -> bool {
{
false false
} }
@ -2594,13 +2594,15 @@ impl<'a> SelectorsElement for DomRoot<Element> {
self.namespace() self.namespace()
} }
fn match_non_ts_pseudo_class<F>(&self, fn match_non_ts_pseudo_class<F>(
&self,
pseudo_class: &NonTSPseudoClass, pseudo_class: &NonTSPseudoClass,
_: &mut MatchingContext, _: &mut MatchingContext<Self::Impl>,
_: &RelevantLinkStatus, _: &RelevantLinkStatus,
_: &mut F) _: &mut F,
-> bool ) -> bool
where F: FnMut(&Self, ElementSelectorFlags), where
F: FnMut(&Self, ElementSelectorFlags),
{ {
match *pseudo_class { match *pseudo_class {
// https://github.com/servo/servo/issues/8718 // https://github.com/servo/servo/issues/8718

View file

@ -5,6 +5,7 @@
use attr::CaseSensitivity; use attr::CaseSensitivity;
use bloom::BloomFilter; use bloom::BloomFilter;
use nth_index_cache::NthIndexCache; use nth_index_cache::NthIndexCache;
use parser::SelectorImpl;
use tree::OpaqueElement; use tree::OpaqueElement;
/// What kind of selector matching mode we should use. /// What kind of selector matching mode we should use.
@ -74,7 +75,10 @@ impl QuirksMode {
/// Data associated with the matching process for a element. This context is /// 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 /// used across many selectors for an element, so it's not appropriate for
/// transient data that applies to only a single selector. /// transient data that applies to only a single selector.
pub struct MatchingContext<'a> { pub struct MatchingContext<'a, Impl>
where
Impl: SelectorImpl,
{
/// Input with the matching mode we should use when matching selectors. /// Input with the matching mode we should use when matching selectors.
pub matching_mode: MatchingMode, pub matching_mode: MatchingMode,
/// Input with the bloom filter used to fast-reject selectors. /// Input with the bloom filter used to fast-reject selectors.
@ -107,9 +111,13 @@ pub struct MatchingContext<'a> {
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
classes_and_ids_case_sensitivity: CaseSensitivity, classes_and_ids_case_sensitivity: CaseSensitivity,
_impl: ::std::marker::PhantomData<Impl>,
} }
impl<'a> MatchingContext<'a> { impl<'a, Impl> MatchingContext<'a, Impl>
where
Impl: SelectorImpl,
{
/// Constructs a new `MatchingContext`. /// Constructs a new `MatchingContext`.
pub fn new( pub fn new(
matching_mode: MatchingMode, matching_mode: MatchingMode,
@ -144,6 +152,7 @@ impl<'a> MatchingContext<'a> {
classes_and_ids_case_sensitivity: quirks_mode.classes_and_ids_case_sensitivity(), classes_and_ids_case_sensitivity: quirks_mode.classes_and_ids_case_sensitivity(),
scope_element: None, scope_element: None,
nesting_level: 0, nesting_level: 0,
_impl: ::std::marker::PhantomData,
} }
} }

View file

@ -55,15 +55,15 @@ impl ElementSelectorFlags {
} }
/// Holds per-compound-selector data. /// Holds per-compound-selector data.
struct LocalMatchingContext<'a, 'b: 'a> { struct LocalMatchingContext<'a, 'b: 'a, Impl: SelectorImpl> {
shared: &'a mut MatchingContext<'b>, shared: &'a mut MatchingContext<'b, Impl>,
matches_hover_and_active_quirk: bool, matches_hover_and_active_quirk: bool,
} }
pub fn matches_selector_list<E>( pub fn matches_selector_list<E>(
selector_list: &SelectorList<E::Impl>, selector_list: &SelectorList<E::Impl>,
element: &E, element: &E,
context: &mut MatchingContext, context: &mut MatchingContext<E::Impl>,
) -> bool ) -> bool
where where
E: Element E: Element
@ -141,9 +141,13 @@ impl RelevantLinkStatus {
/// If we found the relevant link for this element, record that in the /// If we found the relevant link for this element, record that in the
/// overall matching context for the element as a whole and stop looking for /// overall matching context for the element as a whole and stop looking for
/// addtional links. /// addtional links.
fn examine_potential_link<E>(&self, element: &E, context: &mut MatchingContext) fn examine_potential_link<E>(
-> RelevantLinkStatus &self,
where E: Element, element: &E,
context: &mut MatchingContext<E::Impl>,
) -> RelevantLinkStatus
where
E: Element,
{ {
// If a relevant link was previously found, we no longer want to look // If a relevant link was previously found, we no longer want to look
// for links. Only the nearest ancestor link is considered relevant. // for links. Only the nearest ancestor link is considered relevant.
@ -168,8 +172,13 @@ impl RelevantLinkStatus {
/// matching. This is true only if the element is a link, an relevant link /// matching. This is true only if the element is a link, an relevant link
/// exists for the element, and the visited handling mode is set to accept /// exists for the element, and the visited handling mode is set to accept
/// relevant links as visited. /// relevant links as visited.
pub fn is_visited<E>(&self, element: &E, context: &MatchingContext) -> bool pub fn is_visited<E>(
where E: Element, &self,
element: &E,
context: &MatchingContext<E::Impl>,
) -> bool
where
E: Element,
{ {
if !element.is_link() { if !element.is_link() {
return false return false
@ -193,8 +202,13 @@ impl RelevantLinkStatus {
/// as visited. If this is a relevant link, then is it unvisited if the /// as visited. If this is a relevant link, then is it unvisited if the
/// visited handling mode is set to treat all links as unvisted (including /// visited handling mode is set to treat all links as unvisted (including
/// relevant links). /// relevant links).
pub fn is_unvisited<E>(&self, element: &E, context: &MatchingContext) -> bool pub fn is_unvisited<E>(
where E: Element, &self,
element: &E,
context: &MatchingContext<E::Impl>
) -> bool
where
E: Element,
{ {
if !element.is_link() { if !element.is_link() {
return false return false
@ -277,7 +291,7 @@ pub fn matches_selector<E, F>(
offset: usize, offset: usize,
hashes: Option<&AncestorHashes>, hashes: Option<&AncestorHashes>,
element: &E, element: &E,
context: &mut MatchingContext, context: &mut MatchingContext<E::Impl>,
flags_setter: &mut F, flags_setter: &mut F,
) -> bool ) -> bool
where where
@ -318,7 +332,7 @@ pub enum CompoundSelectorMatchingResult {
pub fn matches_compound_selector<E>( pub fn matches_compound_selector<E>(
selector: &Selector<E::Impl>, selector: &Selector<E::Impl>,
mut from_offset: usize, mut from_offset: usize,
context: &mut MatchingContext, context: &mut MatchingContext<E::Impl>,
element: &E, element: &E,
) -> CompoundSelectorMatchingResult ) -> CompoundSelectorMatchingResult
where where
@ -361,7 +375,7 @@ where
pub fn matches_complex_selector<E, F>( pub fn matches_complex_selector<E, F>(
mut iter: SelectorIter<E::Impl>, mut iter: SelectorIter<E::Impl>,
element: &E, element: &E,
context: &mut MatchingContext, context: &mut MatchingContext<E::Impl>,
flags_setter: &mut F, flags_setter: &mut F,
) -> bool ) -> bool
where where
@ -410,7 +424,7 @@ where
#[inline] #[inline]
fn matches_hover_and_active_quirk<Impl: SelectorImpl>( fn matches_hover_and_active_quirk<Impl: SelectorImpl>(
selector_iter: &SelectorIter<Impl>, selector_iter: &SelectorIter<Impl>,
context: &MatchingContext, context: &MatchingContext<Impl>,
rightmost: Rightmost, rightmost: Rightmost,
) -> bool { ) -> bool {
if context.quirks_mode() != QuirksMode::Quirks { if context.quirks_mode() != QuirksMode::Quirks {
@ -465,7 +479,7 @@ enum Rightmost {
fn matches_complex_selector_internal<E, F>( fn matches_complex_selector_internal<E, F>(
mut selector_iter: SelectorIter<E::Impl>, mut selector_iter: SelectorIter<E::Impl>,
element: &E, element: &E,
context: &mut MatchingContext, context: &mut MatchingContext<E::Impl>,
relevant_link: &mut RelevantLinkStatus, relevant_link: &mut RelevantLinkStatus,
flags_setter: &mut F, flags_setter: &mut F,
rightmost: Rightmost, rightmost: Rightmost,
@ -589,7 +603,7 @@ where
fn matches_simple_selector<E, F>( fn matches_simple_selector<E, F>(
selector: &Component<E::Impl>, selector: &Component<E::Impl>,
element: &E, element: &E,
context: &mut LocalMatchingContext, context: &mut LocalMatchingContext<E::Impl>,
relevant_link: &RelevantLinkStatus, relevant_link: &RelevantLinkStatus,
flags_setter: &mut F, flags_setter: &mut F,
) -> bool ) -> bool
@ -761,7 +775,7 @@ fn select_name<'a, T>(is_html: bool, local_name: &'a T, local_name_lower: &'a T)
#[inline] #[inline]
fn matches_generic_nth_child<E, F>( fn matches_generic_nth_child<E, F>(
element: &E, element: &E,
context: &mut LocalMatchingContext, context: &mut LocalMatchingContext<E::Impl>,
a: i32, a: i32,
b: i32, b: i32,
is_of_type: bool, is_of_type: bool,

View file

@ -67,17 +67,18 @@ pub trait Element: Sized + Clone + Debug {
fn match_non_ts_pseudo_class<F>( fn match_non_ts_pseudo_class<F>(
&self, &self,
pc: &<Self::Impl as SelectorImpl>::NonTSPseudoClass, pc: &<Self::Impl as SelectorImpl>::NonTSPseudoClass,
context: &mut MatchingContext, context: &mut MatchingContext<Self::Impl>,
relevant_link: &RelevantLinkStatus, relevant_link: &RelevantLinkStatus,
flags_setter: &mut F, flags_setter: &mut F,
) -> bool ) -> bool
where where
F: FnMut(&Self, ElementSelectorFlags); F: FnMut(&Self, ElementSelectorFlags);
fn match_pseudo_element(&self, fn match_pseudo_element(
&self,
pe: &<Self::Impl as SelectorImpl>::PseudoElement, pe: &<Self::Impl as SelectorImpl>::PseudoElement,
context: &mut MatchingContext) context: &mut MatchingContext<Self::Impl>,
-> bool; ) -> bool;
/// Whether this element is a `link`. /// Whether this element is a `link`.
fn is_link(&self) -> bool; fn is_link(&self) -> bool;

View file

@ -1834,7 +1834,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
fn match_non_ts_pseudo_class<F>( fn match_non_ts_pseudo_class<F>(
&self, &self,
pseudo_class: &NonTSPseudoClass, pseudo_class: &NonTSPseudoClass,
context: &mut MatchingContext, context: &mut MatchingContext<Self::Impl>,
relevant_link: &RelevantLinkStatus, relevant_link: &RelevantLinkStatus,
flags_setter: &mut F, flags_setter: &mut F,
) -> bool ) -> bool
@ -1975,7 +1975,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
fn match_pseudo_element( fn match_pseudo_element(
&self, &self,
pseudo_element: &PseudoElement, pseudo_element: &PseudoElement,
_context: &mut MatchingContext _context: &mut MatchingContext<Self::Impl>,
) -> bool { ) -> bool {
// TODO(emilio): I believe we could assert we are a pseudo-element and // TODO(emilio): I believe we could assert we are a pseudo-element and
// match the proper pseudo-element, given how we rulehash the stuff // match the proper pseudo-element, given how we rulehash the stuff

View file

@ -152,7 +152,7 @@ impl<'a, E> Element for ElementWrapper<'a, E>
fn match_non_ts_pseudo_class<F>( fn match_non_ts_pseudo_class<F>(
&self, &self,
pseudo_class: &NonTSPseudoClass, pseudo_class: &NonTSPseudoClass,
context: &mut MatchingContext, context: &mut MatchingContext<Self::Impl>,
relevant_link: &RelevantLinkStatus, relevant_link: &RelevantLinkStatus,
_setter: &mut F, _setter: &mut F,
) -> bool ) -> bool
@ -258,7 +258,7 @@ impl<'a, E> Element for ElementWrapper<'a, E>
fn match_pseudo_element( fn match_pseudo_element(
&self, &self,
pseudo_element: &PseudoElement, pseudo_element: &PseudoElement,
context: &mut MatchingContext, context: &mut MatchingContext<Self::Impl>,
) -> bool { ) -> bool {
self.element.match_pseudo_element(pseudo_element, context) self.element.match_pseudo_element(pseudo_element, context)
} }

View file

@ -162,15 +162,18 @@ impl SelectorMap<Rule> {
/// ///
/// Extract matching rules as per element's ID, classes, tag name, etc.. /// Extract matching rules as per element's ID, classes, tag name, etc..
/// Sort the Rules at the end to maintain cascading order. /// Sort the Rules at the end to maintain cascading order.
pub fn get_all_matching_rules<E, V, F>(&self, pub fn get_all_matching_rules<E, V, F>(
&self,
element: &E, element: &E,
rule_hash_target: &E, rule_hash_target: &E,
matching_rules_list: &mut V, matching_rules_list: &mut V,
context: &mut MatchingContext, context: &mut MatchingContext<E::Impl>,
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
flags_setter: &mut F, flags_setter: &mut F,
cascade_level: CascadeLevel) cascade_level: CascadeLevel,
where E: TElement, )
where
E: TElement,
V: VecLike<ApplicableDeclarationBlock>, V: VecLike<ApplicableDeclarationBlock>,
F: FnMut(&E, ElementSelectorFlags), F: FnMut(&E, ElementSelectorFlags),
{ {
@ -223,13 +226,16 @@ impl SelectorMap<Rule> {
} }
/// Adds rules in `rules` that match `element` to the `matching_rules` list. /// Adds rules in `rules` that match `element` to the `matching_rules` list.
fn get_matching_rules<E, V, F>(element: &E, fn get_matching_rules<E, V, F>(
element: &E,
rules: &[Rule], rules: &[Rule],
matching_rules: &mut V, matching_rules: &mut V,
context: &mut MatchingContext, context: &mut MatchingContext<E::Impl>,
flags_setter: &mut F, flags_setter: &mut F,
cascade_level: CascadeLevel) cascade_level: CascadeLevel,
where E: TElement, )
where
E: TElement,
V: VecLike<ApplicableDeclarationBlock>, V: VecLike<ApplicableDeclarationBlock>,
F: FnMut(&E, ElementSelectorFlags), F: FnMut(&E, ElementSelectorFlags),
{ {

View file

@ -1198,7 +1198,7 @@ impl Stylist {
animation_rules: AnimationRules, animation_rules: AnimationRules,
rule_inclusion: RuleInclusion, rule_inclusion: RuleInclusion,
applicable_declarations: &mut V, applicable_declarations: &mut V,
context: &mut MatchingContext, context: &mut MatchingContext<E::Impl>,
flags_setter: &mut F, flags_setter: &mut F,
) )
where where