mirror of
https://github.com/servo/servo.git
synced 2025-08-12 08:55:32 +01:00
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:
parent
39de0a068e
commit
7139a4185a
6 changed files with 100 additions and 27 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue