1use crate::bloom::StyleBloom;
10use crate::context::SharedStyleContext;
11use crate::dom::TElement;
12use crate::sharing::{StyleSharingCandidate, StyleSharingTarget};
13use selectors::matching::SelectorCaches;
14
15pub fn parents_allow_sharing<E>(
18 target: &mut StyleSharingTarget<E>,
19 candidate: &mut StyleSharingCandidate<E>,
20) -> bool
21where
22 E: TElement,
23{
24 if target.parent_style_identity() != candidate.parent_style_identity() {
27 return false;
28 }
29
30 let parent = target.inheritance_parent().unwrap();
32 let candidate_parent = candidate.element.inheritance_parent().unwrap();
33 if parent == candidate_parent {
34 return true;
35 }
36
37 let parent_data = parent.borrow_data().unwrap();
48 let candidate_parent_data = candidate_parent.borrow_data().unwrap();
49 if !parent_data.safe_for_cousin_sharing() || !candidate_parent_data.safe_for_cousin_sharing() {
50 return false;
51 }
52
53 true
54}
55
56pub fn have_same_style_attribute<E>(
60 target: &mut StyleSharingTarget<E>,
61 candidate: &mut StyleSharingCandidate<E>,
62 shared_context: &SharedStyleContext,
63) -> bool
64where
65 E: TElement,
66{
67 match (target.style_attribute(), candidate.style_attribute()) {
68 (None, None) => true,
69 (Some(_), None) | (None, Some(_)) => false,
70 (Some(a), Some(b)) => {
71 if std::ptr::eq(&*a, &*b) {
72 return true;
73 }
74 let guard = shared_context.guards.author;
75 *a.read_with(guard) == *b.read_with(guard)
76 },
77 }
78}
79
80pub fn have_same_presentational_hints<E>(
82 target: &mut StyleSharingTarget<E>,
83 candidate: &mut StyleSharingCandidate<E>,
84) -> bool
85where
86 E: TElement,
87{
88 target.pres_hints() == candidate.pres_hints()
89}
90
91pub fn have_same_class<E>(
95 target: &mut StyleSharingTarget<E>,
96 candidate: &mut StyleSharingCandidate<E>,
97) -> bool
98where
99 E: TElement,
100{
101 target.class_list() == candidate.class_list()
102}
103
104pub fn have_same_parts<E>(
108 target: &mut StyleSharingTarget<E>,
109 candidate: &mut StyleSharingCandidate<E>,
110) -> bool
111where
112 E: TElement,
113{
114 target.part_list() == candidate.part_list()
115}
116
117#[inline]
124pub fn revalidate<E>(
125 target: &mut StyleSharingTarget<E>,
126 candidate: &mut StyleSharingCandidate<E>,
127 shared_context: &SharedStyleContext,
128 bloom: &StyleBloom<E>,
129 selector_caches: &mut SelectorCaches,
130) -> bool
131where
132 E: TElement,
133{
134 let stylist = &shared_context.stylist;
135
136 let for_element = target.revalidation_match_results(stylist, bloom, selector_caches);
137
138 let for_candidate = candidate.revalidation_match_results(stylist, bloom, selector_caches);
139
140 for_element == for_candidate
141}
142
143#[inline]
146pub fn have_same_referenced_attrs<E>(
147 target: &StyleSharingTarget<E>,
148 candidate: &StyleSharingCandidate<E>,
149) -> bool
150where
151 E: TElement,
152{
153 let borrowed_data = candidate.element.borrow_data().unwrap();
155 let attrs_used = borrowed_data.styles.primary().attribute_references.as_ref();
156
157 let Some(attrs_used) = attrs_used else {
158 return true;
159 };
160
161 attrs_used.iter().all(|(name, namespaces)| {
162 namespaces.iter().all(|namespace| {
163 target.get_attr(name, namespace) == candidate.get_attr(name, namespace)
164 })
165 })
166}
167
168#[inline]
171pub fn revalidate_scope<E>(
172 target: &mut StyleSharingTarget<E>,
173 candidate: &mut StyleSharingCandidate<E>,
174 shared_context: &SharedStyleContext,
175 selector_caches: &mut SelectorCaches,
176) -> bool
177where
178 E: TElement,
179{
180 let stylist = &shared_context.stylist;
181 let for_element = target.scope_revalidation_results(stylist, selector_caches);
182 let for_candidate = candidate.scope_revalidation_results(stylist, selector_caches);
183
184 for_element == for_candidate
185}
186
187#[inline]
189pub fn may_match_different_id_rules<E>(
190 shared_context: &SharedStyleContext,
191 element: E,
192 candidate: E,
193) -> bool
194where
195 E: TElement,
196{
197 let element_id = element.id();
198 let candidate_id = candidate.id();
199
200 if element_id == candidate_id {
201 return false;
202 }
203
204 let stylist = &shared_context.stylist;
205
206 let may_have_rules_for_element = match element_id {
207 Some(id) => stylist.may_have_rules_for_id(id, element),
208 None => false,
209 };
210
211 if may_have_rules_for_element {
212 return true;
213 }
214
215 match candidate_id {
216 Some(id) => stylist.may_have_rules_for_id(id, candidate),
217 None => false,
218 }
219}