mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
style: Make style sharing look at XBL / Shadow DOM rules.
Bug: 1412251 Reviewed-by: bz MozReview-Commit-ID: II6lk6OmSZU
This commit is contained in:
parent
76a71996f4
commit
0df912be93
5 changed files with 148 additions and 47 deletions
|
@ -6,7 +6,6 @@
|
|||
//! quickly whether it's worth to share style, and whether two different
|
||||
//! elements can indeed share the same style.
|
||||
|
||||
use Atom;
|
||||
use bloom::StyleBloom;
|
||||
use context::{SelectorFlagsMap, SharedStyleContext};
|
||||
use dom::TElement;
|
||||
|
@ -96,14 +95,16 @@ pub fn have_same_class<E>(target: &mut StyleSharingTarget<E>,
|
|||
/// :first-child, etc, or on attributes that we don't check off-hand (pretty
|
||||
/// much every attribute selector except `id` and `class`.
|
||||
#[inline]
|
||||
pub fn revalidate<E>(target: &mut StyleSharingTarget<E>,
|
||||
candidate: &mut StyleSharingCandidate<E>,
|
||||
shared_context: &SharedStyleContext,
|
||||
bloom: &StyleBloom<E>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
selector_flags_map: &mut SelectorFlagsMap<E>)
|
||||
-> bool
|
||||
where E: TElement,
|
||||
pub fn revalidate<E>(
|
||||
target: &mut StyleSharingTarget<E>,
|
||||
candidate: &mut StyleSharingCandidate<E>,
|
||||
shared_context: &SharedStyleContext,
|
||||
bloom: &StyleBloom<E>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
selector_flags_map: &mut SelectorFlagsMap<E>,
|
||||
) -> bool
|
||||
where
|
||||
E: TElement,
|
||||
{
|
||||
let stylist = &shared_context.stylist;
|
||||
|
||||
|
@ -130,16 +131,25 @@ pub fn revalidate<E>(target: &mut StyleSharingTarget<E>,
|
|||
|
||||
/// Checks whether we might have rules for either of the two ids.
|
||||
#[inline]
|
||||
pub fn may_have_rules_for_ids(shared_context: &SharedStyleContext,
|
||||
element_id: Option<&Atom>,
|
||||
candidate_id: Option<&Atom>) -> bool
|
||||
pub fn may_match_different_id_rules<E>(
|
||||
shared_context: &SharedStyleContext,
|
||||
element: E,
|
||||
candidate: E,
|
||||
) -> bool
|
||||
where
|
||||
E: TElement,
|
||||
{
|
||||
// We shouldn't be called unless the ids are different.
|
||||
debug_assert!(element_id.is_some() || candidate_id.is_some());
|
||||
let element_id = element.get_id();
|
||||
let candidate_id = candidate.get_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),
|
||||
Some(ref id) => stylist.may_have_rules_for_id(id, element),
|
||||
None => false
|
||||
};
|
||||
|
||||
|
@ -148,7 +158,7 @@ pub fn may_have_rules_for_ids(shared_context: &SharedStyleContext,
|
|||
}
|
||||
|
||||
match candidate_id {
|
||||
Some(id) => stylist.may_have_rules_for_id(id),
|
||||
Some(ref id) => stylist.may_have_rules_for_id(id, candidate),
|
||||
None => false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,10 +206,11 @@ impl ValidationData {
|
|||
bloom: &StyleBloom<E>,
|
||||
nth_index_cache: &mut NthIndexCache,
|
||||
bloom_known_valid: bool,
|
||||
flags_setter: &mut F
|
||||
flags_setter: &mut F,
|
||||
) -> &SmallBitVec
|
||||
where E: TElement,
|
||||
F: FnMut(&E, ElementSelectorFlags),
|
||||
where
|
||||
E: TElement,
|
||||
F: FnMut(&E, ElementSelectorFlags),
|
||||
{
|
||||
if self.revalidation_match_results.is_none() {
|
||||
// The bloom filter may already be set up for our element.
|
||||
|
@ -230,10 +231,12 @@ impl ValidationData {
|
|||
}
|
||||
};
|
||||
self.revalidation_match_results =
|
||||
Some(stylist.match_revalidation_selectors(&element,
|
||||
bloom_to_use,
|
||||
nth_index_cache,
|
||||
flags_setter));
|
||||
Some(stylist.match_revalidation_selectors(
|
||||
element,
|
||||
bloom_to_use,
|
||||
nth_index_cache,
|
||||
flags_setter,
|
||||
));
|
||||
}
|
||||
|
||||
self.revalidation_match_results.as_ref().unwrap()
|
||||
|
@ -661,6 +664,15 @@ impl<E: TElement> StyleSharingCache<E> {
|
|||
return None;
|
||||
}
|
||||
|
||||
// Note that in the XBL case, we should be able to assert that the
|
||||
// scopes are different, since two elements with different XBL bindings
|
||||
// need to necessarily have different style (and thus children of them
|
||||
// would never pass the parent check).
|
||||
if target.element.style_scope() != candidate.element.style_scope() {
|
||||
trace!("Miss: Different style scopes");
|
||||
return None;
|
||||
}
|
||||
|
||||
if *target.get_local_name() != *candidate.element.get_local_name() {
|
||||
trace!("Miss: Local Name");
|
||||
return None;
|
||||
|
@ -690,15 +702,17 @@ impl<E: TElement> StyleSharingCache<E> {
|
|||
return None;
|
||||
}
|
||||
|
||||
let element_id = target.element.get_id();
|
||||
let candidate_id = candidate.element.get_id();
|
||||
if element_id != candidate_id {
|
||||
// It's possible that there are no styles for either id.
|
||||
if checks::may_have_rules_for_ids(shared, element_id.as_ref(),
|
||||
candidate_id.as_ref()) {
|
||||
trace!("Miss: ID Attr");
|
||||
return None;
|
||||
}
|
||||
// It's possible that there are no styles for either id.
|
||||
let may_match_different_id_rules =
|
||||
checks::may_match_different_id_rules(
|
||||
shared,
|
||||
target.element,
|
||||
candidate.element,
|
||||
);
|
||||
|
||||
if may_match_different_id_rules {
|
||||
trace!("Miss: ID Attr");
|
||||
return None;
|
||||
}
|
||||
|
||||
if !checks::have_same_style_attribute(target, candidate) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue