Source code

Revision control

Other Tools

1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5
//! Visitor traits for selectors.
6
7
#![deny(missing_docs)]
8
9
use crate::attr::NamespaceConstraint;
10
use crate::parser::{Combinator, Component, SelectorImpl};
11
12
/// A trait to visit selector properties.
13
///
14
/// All the `visit_foo` methods return a boolean indicating whether the
15
/// traversal should continue or not.
16
pub trait SelectorVisitor {
17
/// The selector implementation this visitor wants to visit.
18
type Impl: SelectorImpl;
19
20
/// Visit an attribute selector that may match (there are other selectors
21
/// that may never match, like those containing whitespace or the empty
22
/// string).
23
fn visit_attribute_selector(
24
&mut self,
25
_namespace: &NamespaceConstraint<&<Self::Impl as SelectorImpl>::NamespaceUrl>,
26
_local_name: &<Self::Impl as SelectorImpl>::LocalName,
27
_local_name_lower: &<Self::Impl as SelectorImpl>::LocalName,
28
) -> bool {
29
true
30
}
31
32
/// Visit a simple selector.
33
fn visit_simple_selector(&mut self, _: &Component<Self::Impl>) -> bool {
34
true
35
}
36
37
/// Visits a complex selector.
38
///
39
/// Gets the combinator to the right of the selector, or `None` if the
40
/// selector is the rightmost one.
41
fn visit_complex_selector(&mut self, _combinator_to_right: Option<Combinator>) -> bool {
42
true
43
}
44
}
45
46
/// Enables traversing selector components stored in various types
47
pub trait Visit {
48
/// The type parameter of selector component types.
49
type Impl: SelectorImpl;
50
51
/// Traverse selector components inside `self`.
52
///
53
/// Implementations of this method should call `SelectorVisitor` methods
54
/// or other impls of `Visit` as appropriate based on the fields of `Self`.
55
///
56
/// A return value of `false` indicates terminating the traversal.
57
/// It should be propagated with an early return.
58
/// On the contrary, `true` indicates that all fields of `self` have been traversed:
59
///
60
/// ```rust,ignore
61
/// if !visitor.visit_simple_selector(&self.some_simple_selector) {
62
/// return false;
63
/// }
64
/// if !self.some_component.visit(visitor) {
65
/// return false;
66
/// }
67
/// true
68
/// ```
69
fn visit<V>(&self, visitor: &mut V) -> bool
70
where
71
V: SelectorVisitor<Impl = Self::Impl>;
72
}