mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #18337 - kuoe0:make-the-order-of-rules-in-DevTools-be-the-specificity-order, r=emilio
Make the order of rules in DevTools be the specificity order. We insert rules with any important declaration into rule tree twice, one for the normal level and another for the important level. And when we fetch them from rule tree, we skip the important one to make the order be the specificity order. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix [Bug 1391198](https://bugzilla.mozilla.org/show_bug.cgi?id=1391198) <!-- Either: --> - [ ] There are tests for these changes OR - [X] These changes do not require tests because test cases already in gecko <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18337) <!-- Reviewable:end -->
This commit is contained in:
commit
af52f5394a
2 changed files with 27 additions and 24 deletions
|
@ -199,10 +199,11 @@ impl RuleTree {
|
|||
for (source, level) in iter {
|
||||
debug_assert!(last_level <= level, "Not really ordered");
|
||||
debug_assert!(!level.is_important(), "Important levels handled internally");
|
||||
let (any_normal, any_important) = {
|
||||
let any_important = {
|
||||
let pdb = source.read(level.guard(guards));
|
||||
(pdb.any_normal(), pdb.any_important())
|
||||
pdb.any_important()
|
||||
};
|
||||
|
||||
if any_important {
|
||||
found_important = true;
|
||||
match level {
|
||||
|
@ -216,19 +217,25 @@ impl RuleTree {
|
|||
_ => {},
|
||||
};
|
||||
}
|
||||
// We really want to ensure empty rule nodes appear in the rule tree for
|
||||
// devtools, this condition ensures that if we find an empty rule node, we
|
||||
// insert it at the normal level.
|
||||
if any_normal || !any_important {
|
||||
if matches!(level, Transitions) && found_important {
|
||||
// There can be at most one transition, and it will come at
|
||||
// the end of the iterator. Stash it and apply it after
|
||||
// !important rules.
|
||||
debug_assert!(transition.is_none());
|
||||
transition = Some(source);
|
||||
} else {
|
||||
current = current.ensure_child(self.root.downgrade(), source, level);
|
||||
}
|
||||
|
||||
// We don't optimize out empty rules, even though we could.
|
||||
//
|
||||
// Inspector relies on every rule being inserted in the normal level
|
||||
// at least once, in order to return the rules with the correct
|
||||
// specificity order.
|
||||
//
|
||||
// TODO(emilio): If we want to apply these optimizations without
|
||||
// breaking inspector's expectations, we'd need to run
|
||||
// selector-matching again at the inspector's request. That may or
|
||||
// may not be a better trade-off.
|
||||
if matches!(level, Transitions) && found_important {
|
||||
// There can be at most one transition, and it will come at
|
||||
// the end of the iterator. Stash it and apply it after
|
||||
// !important rules.
|
||||
debug_assert!(transition.is_none());
|
||||
transition = Some(source);
|
||||
} else {
|
||||
current = current.ensure_child(self.root.downgrade(), source, level);
|
||||
}
|
||||
last_level = level;
|
||||
}
|
||||
|
|
|
@ -1921,9 +1921,6 @@ pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(values: ServoStyleContex
|
|||
None => return,
|
||||
};
|
||||
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
|
||||
// TODO(emilio): Will benefit from SmallVec.
|
||||
let mut result = vec![];
|
||||
for node in rule_node.self_and_ancestors() {
|
||||
|
@ -1932,13 +1929,12 @@ pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(values: ServoStyleContex
|
|||
_ => continue,
|
||||
};
|
||||
|
||||
// For the rules with any important declaration, we insert them into
|
||||
// rule tree twice, one for normal level and another for important
|
||||
// level. So, we skip the important one to keep the specificity order of
|
||||
// rules.
|
||||
if node.importance().important() {
|
||||
let block = style_rule.read_with(&guard).block.read_with(&guard);
|
||||
if block.any_normal() {
|
||||
// We'll append it when we find the normal rules in our
|
||||
// parent chain.
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push(style_rule);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue