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 revalidate_scope<E>(
147 target: &mut StyleSharingTarget<E>,
148 candidate: &mut StyleSharingCandidate<E>,
149 shared_context: &SharedStyleContext,
150 selector_caches: &mut SelectorCaches,
151) -> bool
152where
153 E: TElement,
154{
155 let stylist = &shared_context.stylist;
156 let for_element = target.scope_revalidation_results(stylist, selector_caches);
157 let for_candidate = candidate.scope_revalidation_results(stylist, selector_caches);
158
159 for_element == for_candidate
160}
161
162#[inline]
164pub fn may_match_different_id_rules<E>(
165 shared_context: &SharedStyleContext,
166 element: E,
167 candidate: E,
168) -> bool
169where
170 E: TElement,
171{
172 let element_id = element.id();
173 let candidate_id = candidate.id();
174
175 if element_id == candidate_id {
176 return false;
177 }
178
179 let stylist = &shared_context.stylist;
180
181 let may_have_rules_for_element = match element_id {
182 Some(id) => stylist.may_have_rules_for_id(id, element),
183 None => false,
184 };
185
186 if may_have_rules_for_element {
187 return true;
188 }
189
190 match candidate_id {
191 Some(id) => stylist.may_have_rules_for_id(id, candidate),
192 None => false,
193 }
194}