style: Add code to make part rules affect the style of the elements.

I still haven't implemented each_part(), so this will do nothing yet.

The cascade order stuff is fishy, I know, and I'll fix in a followup if it's
fine with you. I moved the sorting of the rules to rule_collector, since it
seemed to me it was better that way that duplicating the code, and those
SelectorMap functions only have a single caller anyway.

Differential Revision: https://phabricator.services.mozilla.com/D32647
This commit is contained in:
Emilio Cobos Álvarez 2019-06-11 17:42:41 +00:00
parent 39de0a068e
commit 7139a4185a
No known key found for this signature in database
GPG key ID: E1152D0994E4BF8A
6 changed files with 100 additions and 27 deletions

View file

@ -54,6 +54,11 @@ pub fn containing_shadow_ignoring_svg_use<E: TElement>(
}
}
#[inline]
fn sort_rules_from(rules: &mut ApplicableDeclarationList, start: usize) {
rules[start..].sort_unstable_by_key(|block| (block.specificity, block.source_order()));
}
/// An object that we use with all the intermediate state needed for the
/// cascade.
///
@ -146,15 +151,7 @@ where
None => return,
};
map.get_all_matching_rules(
self.element,
self.rule_hash_target,
self.rules,
self.context,
self.flags_setter,
cascade_level,
0,
);
self.collect_rules_internal(None, map, cascade_level);
}
fn collect_user_agent_rules(&mut self) {
@ -200,11 +197,23 @@ where
cascade_level: CascadeLevel,
) {
debug_assert!(shadow_host.shadow_root().is_some());
self.collect_rules_internal(Some(shadow_host), map, cascade_level);
self.shadow_cascade_order += 1;
}
#[inline]
fn collect_rules_internal(
&mut self,
shadow_host: Option<E>,
map: &SelectorMap<Rule>,
cascade_level: CascadeLevel,
) {
let element = self.element;
let rule_hash_target = self.rule_hash_target;
let rules = &mut self.rules;
let flags_setter = &mut self.flags_setter;
let shadow_cascade_order = self.shadow_cascade_order;
let start = rules.len();
self.context.with_shadow_host(shadow_host, |context| {
map.get_all_matching_rules(
element,
@ -216,7 +225,7 @@ where
shadow_cascade_order,
);
});
self.shadow_cascade_order += 1;
sort_rules_from(rules, start);
}
/// Collects the rules for the ::slotted pseudo-element.
@ -310,6 +319,67 @@ where
self.collect_stylist_rules(Origin::Author);
}
fn collect_part_rules(&mut self) {
if !self.rule_hash_target.has_part_attr() {
return;
}
let shadow = match self.rule_hash_target.containing_shadow() {
Some(s) => s,
None => return,
};
let host = shadow.host();
let containing_shadow = host.containing_shadow();
let part_rules = match containing_shadow {
Some(shadow) => {
shadow
.style_data()
.and_then(|data| data.part_rules(self.pseudo_element))
},
None => {
self.stylist
.cascade_data()
.borrow_for_origin(Origin::Author)
.part_rules(self.pseudo_element)
}
};
// TODO(emilio): SameTreeAuthorNormal is a bit of a lie here, we may
// need an OuterTreeAuthorNormal cascade level or such, and change the
// cascade order, if we allow to forward parts to even outer trees.
//
// Though the current thing kinda works because we apply them after
// the outer tree, so as long as we don't allow forwarding we're
// good.
if let Some(part_rules) = part_rules {
let containing_host = containing_shadow.map(|s| s.host());
let element = self.element;
let rule_hash_target = self.rule_hash_target;
let rules = &mut self.rules;
let flags_setter = &mut self.flags_setter;
let shadow_cascade_order = self.shadow_cascade_order;
let cascade_level = CascadeLevel::SameTreeAuthorNormal;
let start = rules.len();
self.context.with_shadow_host(containing_host, |context| {
rule_hash_target.each_part(|p| {
if let Some(part_rules) = part_rules.get(p) {
SelectorMap::get_matching_rules(
element,
&part_rules,
rules,
context,
flags_setter,
cascade_level,
shadow_cascade_order,
);
}
});
});
sort_rules_from(rules, start);
}
}
fn collect_style_attribute_and_animation_rules(&mut self) {
if let Some(sa) = self.style_attribute {
self.rules
@ -368,6 +438,7 @@ where
self.collect_slotted_rules();
self.collect_normal_rules_from_containing_shadow_tree();
self.collect_document_author_rules();
self.collect_part_rules();
self.collect_style_attribute_and_animation_rules();
}
}