1use crate::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
9use crate::bloom::BloomFilter;
10use crate::matching::{ElementSelectorFlags, MatchingContext};
11use crate::parser::SelectorImpl;
12use std::fmt::Debug;
13use std::ptr::NonNull;
14
15#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
17pub struct OpaqueElement(NonNull<()>);
18
19unsafe impl Send for OpaqueElement {}
20unsafe impl Sync for OpaqueElement {}
23
24impl OpaqueElement {
25 pub fn new<T>(ptr: &T) -> Self {
27 unsafe {
30 OpaqueElement(NonNull::new_unchecked(
31 ptr as *const T as *const () as *mut (),
32 ))
33 }
34 }
35
36 pub fn from_ptr(ptr: NonNull<()>) -> Self {
38 Self(ptr)
39 }
40
41 #[inline]
43 pub fn to_ptr(&self) -> NonNull<()> {
44 self.0
45 }
46}
47
48pub trait Element: Sized + Copy + Clone + Debug {
49 type Impl: SelectorImpl;
50
51 fn opaque(&self) -> OpaqueElement;
53
54 fn parent_element(&self) -> Option<Self>;
55
56 fn parent_node_is_shadow_root(&self) -> bool;
58
59 fn containing_shadow_host(&self) -> Option<Self>;
61
62 fn pseudo_element_originating_element(&self) -> Option<Self> {
67 debug_assert!(self.is_pseudo_element());
68 self.parent_element()
69 }
70
71 fn is_pseudo_element(&self) -> bool;
73
74 fn prev_sibling_element(&self) -> Option<Self>;
76
77 fn next_sibling_element(&self) -> Option<Self>;
79
80 fn first_element_child(&self) -> Option<Self>;
82
83 fn is_html_element_in_html_document(&self) -> bool;
84
85 fn has_local_name(&self, local_name: &<Self::Impl as SelectorImpl>::BorrowedLocalName) -> bool;
86
87 fn has_namespace(&self, ns: &<Self::Impl as SelectorImpl>::BorrowedNamespaceUrl) -> bool;
89
90 fn is_same_type(&self, other: &Self) -> bool;
92
93 fn attr_matches(
94 &self,
95 ns: &NamespaceConstraint<&<Self::Impl as SelectorImpl>::NamespaceUrl>,
96 local_name: &<Self::Impl as SelectorImpl>::LocalName,
97 operation: &AttrSelectorOperation<&<Self::Impl as SelectorImpl>::AttrValue>,
98 ) -> bool;
99
100 fn has_attr_in_no_namespace(
101 &self,
102 local_name: &<Self::Impl as SelectorImpl>::LocalName,
103 ) -> bool {
104 self.attr_matches(
105 &NamespaceConstraint::Specific(&crate::parser::namespace_empty_string::<Self::Impl>()),
106 local_name,
107 &AttrSelectorOperation::Exists,
108 )
109 }
110
111 fn match_non_ts_pseudo_class(
112 &self,
113 pc: &<Self::Impl as SelectorImpl>::NonTSPseudoClass,
114 context: &mut MatchingContext<Self::Impl>,
115 ) -> bool;
116
117 fn match_pseudo_element(
118 &self,
119 pe: &<Self::Impl as SelectorImpl>::PseudoElement,
120 context: &mut MatchingContext<Self::Impl>,
121 ) -> bool;
122
123 fn apply_selector_flags(&self, flags: ElementSelectorFlags);
127
128 fn is_link(&self) -> bool;
130
131 fn is_html_slot_element(&self) -> bool;
133
134 fn assigned_slot(&self) -> Option<Self> {
138 None
139 }
140
141 fn has_id(
142 &self,
143 id: &<Self::Impl as SelectorImpl>::Identifier,
144 case_sensitivity: CaseSensitivity,
145 ) -> bool;
146
147 fn has_class(
148 &self,
149 name: &<Self::Impl as SelectorImpl>::Identifier,
150 case_sensitivity: CaseSensitivity,
151 ) -> bool;
152
153 fn has_custom_state(&self, name: &<Self::Impl as SelectorImpl>::Identifier) -> bool;
154
155 fn imported_part(
158 &self,
159 name: &<Self::Impl as SelectorImpl>::Identifier,
160 ) -> Option<<Self::Impl as SelectorImpl>::Identifier>;
161
162 fn is_part(&self, name: &<Self::Impl as SelectorImpl>::Identifier) -> bool;
163
164 fn is_empty(&self) -> bool;
169
170 fn is_root(&self) -> bool;
176
177 fn ignores_nth_child_selectors(&self) -> bool {
180 false
181 }
182
183 fn add_element_unique_hashes(&self, filter: &mut BloomFilter) -> bool;
186
187 fn subtree_filter(&self) -> u64 {
192 u64::MAX
193 }
194
195 #[inline]
197 fn subtree_may_have_hashes(&self, hashes: u64) -> bool {
198 (self.subtree_filter() & hashes) == hashes
199 }
200}