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>(
58 target: &mut StyleSharingTarget<E>,
59 candidate: &mut StyleSharingCandidate<E>,
60) -> bool
61where
62 E: TElement,
63{
64 match (target.style_attribute(), candidate.style_attribute()) {
65 (None, None) => true,
66 (Some(_), None) | (None, Some(_)) => false,
67 (Some(a), Some(b)) => &*a as *const _ == &*b as *const _,
68 }
69}
70
71pub fn have_same_presentational_hints<E>(
73 target: &mut StyleSharingTarget<E>,
74 candidate: &mut StyleSharingCandidate<E>,
75) -> bool
76where
77 E: TElement,
78{
79 target.pres_hints() == candidate.pres_hints()
80}
81
82pub fn have_same_class<E>(
86 target: &mut StyleSharingTarget<E>,
87 candidate: &mut StyleSharingCandidate<E>,
88) -> bool
89where
90 E: TElement,
91{
92 target.class_list() == candidate.class_list()
93}
94
95pub fn have_same_parts<E>(
99 target: &mut StyleSharingTarget<E>,
100 candidate: &mut StyleSharingCandidate<E>,
101) -> bool
102where
103 E: TElement,
104{
105 target.part_list() == candidate.part_list()
106}
107
108#[inline]
115pub fn revalidate<E>(
116 target: &mut StyleSharingTarget<E>,
117 candidate: &mut StyleSharingCandidate<E>,
118 shared_context: &SharedStyleContext,
119 bloom: &StyleBloom<E>,
120 selector_caches: &mut SelectorCaches,
121) -> bool
122where
123 E: TElement,
124{
125 let stylist = &shared_context.stylist;
126
127 let for_element = target.revalidation_match_results(stylist, bloom, selector_caches);
128
129 let for_candidate = candidate.revalidation_match_results(stylist, bloom, selector_caches);
130
131 for_element == for_candidate
132}
133
134#[inline]
137pub fn revalidate_scope<E>(
138 target: &mut StyleSharingTarget<E>,
139 candidate: &mut StyleSharingCandidate<E>,
140 shared_context: &SharedStyleContext,
141 selector_caches: &mut SelectorCaches,
142) -> bool
143where
144 E: TElement,
145{
146 let stylist = &shared_context.stylist;
147 let for_element = target.scope_revalidation_results(stylist, selector_caches);
148 let for_candidate = candidate.scope_revalidation_results(stylist, selector_caches);
149
150 for_element == for_candidate
151}
152
153#[inline]
155pub fn may_match_different_id_rules<E>(
156 shared_context: &SharedStyleContext,
157 element: E,
158 candidate: E,
159) -> bool
160where
161 E: TElement,
162{
163 let element_id = element.id();
164 let candidate_id = candidate.id();
165
166 if element_id == candidate_id {
167 return false;
168 }
169
170 let stylist = &shared_context.stylist;
171
172 let may_have_rules_for_element = match element_id {
173 Some(id) => stylist.may_have_rules_for_id(id, element),
174 None => false,
175 };
176
177 if may_have_rules_for_element {
178 return true;
179 }
180
181 match candidate_id {
182 Some(id) => stylist.may_have_rules_for_id(id, candidate),
183 None => false,
184 }
185}