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
162 .iter()
163 .all(|name| target.get_attr(name) == candidate.get_attr(name))
164}
165
166#[inline]
169pub fn revalidate_scope<E>(
170 target: &mut StyleSharingTarget<E>,
171 candidate: &mut StyleSharingCandidate<E>,
172 shared_context: &SharedStyleContext,
173 selector_caches: &mut SelectorCaches,
174) -> bool
175where
176 E: TElement,
177{
178 let stylist = &shared_context.stylist;
179 let for_element = target.scope_revalidation_results(stylist, selector_caches);
180 let for_candidate = candidate.scope_revalidation_results(stylist, selector_caches);
181
182 for_element == for_candidate
183}
184
185#[inline]
187pub fn may_match_different_id_rules<E>(
188 shared_context: &SharedStyleContext,
189 element: E,
190 candidate: E,
191) -> bool
192where
193 E: TElement,
194{
195 let element_id = element.id();
196 let candidate_id = candidate.id();
197
198 if element_id == candidate_id {
199 return false;
200 }
201
202 let stylist = &shared_context.stylist;
203
204 let may_have_rules_for_element = match element_id {
205 Some(id) => stylist.may_have_rules_for_id(id, element),
206 None => false,
207 };
208
209 if may_have_rules_for_element {
210 return true;
211 }
212
213 match candidate_id {
214 Some(id) => stylist.may_have_rules_for_id(id, candidate),
215 None => false,
216 }
217}