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
//! Traits that nodes must implement. Breaks the otherwise-cyclic dependency
6
//! between layout and style.
7
8
use crate::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
9
use crate::matching::{ElementSelectorFlags, MatchingContext};
10
use crate::parser::SelectorImpl;
11
use std::fmt::Debug;
12
use std::ptr::NonNull;
13
14
/// Opaque representation of an Element, for identity comparisons.
15
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
16
pub struct OpaqueElement(NonNull<()>);
17
18
unsafe impl Send for OpaqueElement {}
19
20
impl OpaqueElement {
21
/// Creates a new OpaqueElement from an arbitrarily-typed pointer.
22
pub fn new<T>(ptr: &T) -> Self {
23
unsafe {
24
OpaqueElement(NonNull::new_unchecked(
25
ptr as *const T as *const () as *mut (),
26
))
27
}
28
}
29
}
30
31
pub trait Element: Sized + Clone + Debug {
32
type Impl: SelectorImpl;
33
34
/// Converts self into an opaque representation.
35
fn opaque(&self) -> OpaqueElement;
36
37
fn parent_element(&self) -> Option<Self>;
38
39
/// Whether the parent node of this element is a shadow root.
40
fn parent_node_is_shadow_root(&self) -> bool;
41
42
/// The host of the containing shadow root, if any.
43
fn containing_shadow_host(&self) -> Option<Self>;
44
45
/// The parent of a given pseudo-element, after matching a pseudo-element
46
/// selector.
47
///
48
/// This is guaranteed to be called in a pseudo-element.
49
fn pseudo_element_originating_element(&self) -> Option<Self> {
50
debug_assert!(self.is_pseudo_element());
51
self.parent_element()
52
}
53
54
/// Whether we're matching on a pseudo-element.
55
fn is_pseudo_element(&self) -> bool;
56
57
/// Skips non-element nodes
58
fn prev_sibling_element(&self) -> Option<Self>;
59
60
/// Skips non-element nodes
61
fn next_sibling_element(&self) -> Option<Self>;
62
63
fn is_html_element_in_html_document(&self) -> bool;
64
65
fn has_local_name(&self, local_name: &<Self::Impl as SelectorImpl>::BorrowedLocalName) -> bool;
66
67
/// Empty string for no namespace
68
fn has_namespace(&self, ns: &<Self::Impl as SelectorImpl>::BorrowedNamespaceUrl) -> bool;
69
70
/// Whether this element and the `other` element have the same local name and namespace.
71
fn is_same_type(&self, other: &Self) -> bool;
72
73
fn attr_matches(
74
&self,
75
ns: &NamespaceConstraint<&<Self::Impl as SelectorImpl>::NamespaceUrl>,
76
local_name: &<Self::Impl as SelectorImpl>::LocalName,
77
operation: &AttrSelectorOperation<&<Self::Impl as SelectorImpl>::AttrValue>,
78
) -> bool;
79
80
fn match_non_ts_pseudo_class<F>(
81
&self,
82
pc: &<Self::Impl as SelectorImpl>::NonTSPseudoClass,
83
context: &mut MatchingContext<Self::Impl>,
84
flags_setter: &mut F,
85
) -> bool
86
where
87
F: FnMut(&Self, ElementSelectorFlags);
88
89
fn match_pseudo_element(
90
&self,
91
pe: &<Self::Impl as SelectorImpl>::PseudoElement,
92
context: &mut MatchingContext<Self::Impl>,
93
) -> bool;
94
95
/// Whether this element is a `link`.
96
fn is_link(&self) -> bool;
97
98
/// Returns whether the element is an HTML <slot> element.
99
fn is_html_slot_element(&self) -> bool;
100
101
/// Returns the assigned <slot> element this element is assigned to.
102
///
103
/// Necessary for the `::slotted` pseudo-class.
104
fn assigned_slot(&self) -> Option<Self> {
105
None
106
}
107
108
fn has_id(
109
&self,
110
id: &<Self::Impl as SelectorImpl>::Identifier,
111
case_sensitivity: CaseSensitivity,
112
) -> bool;
113
114
fn has_class(
115
&self,
116
name: &<Self::Impl as SelectorImpl>::ClassName,
117
case_sensitivity: CaseSensitivity,
118
) -> bool;
119
120
fn is_part(&self, name: &<Self::Impl as SelectorImpl>::PartName) -> bool;
121
122
/// Returns whether this element matches `:empty`.
123
///
124
/// That is, whether it does not contain any child element or any non-zero-length text node.
126
fn is_empty(&self) -> bool;
127
128
/// Returns whether this element matches `:root`,
129
/// i.e. whether it is the root element of a document.
130
///
131
/// Note: this can be false even if `.parent_element()` is `None`
132
/// if the parent node is a `DocumentFragment`.
133
fn is_root(&self) -> bool;
134
135
/// Returns whether this element should ignore matching nth child
136
/// selector.
137
fn ignores_nth_child_selectors(&self) -> bool {
138
false
139
}
140
}