use crate::bloom::StyleBloom;
use crate::context::SharedStyleContext;
use crate::dom::TElement;
use crate::sharing::{StyleSharingCandidate, StyleSharingTarget};
use selectors::matching::SelectorCaches;
pub fn parents_allow_sharing<E>(
target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>,
) -> bool
where
E: TElement,
{
if target.parent_style_identity() != candidate.parent_style_identity() {
return false;
}
let parent = target.inheritance_parent().unwrap();
let candidate_parent = candidate.element.inheritance_parent().unwrap();
if parent == candidate_parent {
return true;
}
let parent_data = parent.borrow_data().unwrap();
let candidate_parent_data = candidate_parent.borrow_data().unwrap();
if !parent_data.safe_for_cousin_sharing() || !candidate_parent_data.safe_for_cousin_sharing() {
return false;
}
true
}
pub fn have_same_style_attribute<E>(
target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>,
shared_context: &SharedStyleContext,
) -> bool
where
E: TElement,
{
match (target.style_attribute(), candidate.style_attribute()) {
(None, None) => true,
(Some(_), None) | (None, Some(_)) => false,
(Some(a), Some(b)) => {
if std::ptr::eq(&*a, &*b) {
return true;
}
let guard = shared_context.guards.author;
*a.read_with(guard) == *b.read_with(guard)
},
}
}
pub fn have_same_presentational_hints<E>(
target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>,
) -> bool
where
E: TElement,
{
target.pres_hints() == candidate.pres_hints()
}
pub fn have_same_class<E>(
target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>,
) -> bool
where
E: TElement,
{
target.class_list() == candidate.class_list()
}
pub fn have_same_parts<E>(
target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>,
) -> bool
where
E: TElement,
{
target.part_list() == candidate.part_list()
}
#[inline]
pub fn revalidate<E>(
target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>,
shared_context: &SharedStyleContext,
bloom: &StyleBloom<E>,
selector_caches: &mut SelectorCaches,
) -> bool
where
E: TElement,
{
let stylist = &shared_context.stylist;
let for_element = target.revalidation_match_results(stylist, bloom, selector_caches);
let for_candidate = candidate.revalidation_match_results(stylist, bloom, selector_caches);
for_element == for_candidate
}
#[inline]
pub fn have_same_referenced_attrs<E>(
target: &StyleSharingTarget<E>,
candidate: &StyleSharingCandidate<E>,
) -> bool
where
E: TElement,
{
let borrowed_data = candidate.element.borrow_data().unwrap();
let attrs_used = borrowed_data.styles.primary().attribute_references.as_ref();
let Some(attrs_used) = attrs_used else {
return true;
};
attrs_used.iter().all(|(name, namespaces)| {
namespaces.iter().all(|namespace| {
target.get_attr(name, namespace) == candidate.get_attr(name, namespace)
})
})
}
#[inline]
pub fn revalidate_scope<E>(
target: &mut StyleSharingTarget<E>,
candidate: &mut StyleSharingCandidate<E>,
shared_context: &SharedStyleContext,
selector_caches: &mut SelectorCaches,
) -> bool
where
E: TElement,
{
let stylist = &shared_context.stylist;
let for_element = target.scope_revalidation_results(stylist, selector_caches);
let for_candidate = candidate.scope_revalidation_results(stylist, selector_caches);
for_element == for_candidate
}
#[inline]
pub fn may_match_different_id_rules<E>(
shared_context: &SharedStyleContext,
element: E,
candidate: E,
) -> bool
where
E: TElement,
{
let element_id = element.id();
let candidate_id = candidate.id();
if element_id == candidate_id {
return false;
}
let stylist = &shared_context.stylist;
let may_have_rules_for_element = match element_id {
Some(id) => stylist.may_have_rules_for_id(id, element),
None => false,
};
if may_have_rules_for_element {
return true;
}
match candidate_id {
Some(id) => stylist.may_have_rules_for_id(id, candidate),
None => false,
}
}