Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upstyle: Avoid selector-matching when only the style attribute is changed. #15317
Conversation
highfive
commented
Jan 31, 2017
|
Heads up! This PR modifies the following files:
|
highfive
commented
Jan 31, 2017
|
@bors-servo try |
style: Avoid selector-matching when only the style attribute is changed. r? @bholley <!-- 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/15317) <!-- Reviewable:end -->
|
|
|
So there are two tests failing there, and I believe none of them is my fault. The first seems like a timing-related incremental table layout bug ( The second I can't reproduce it at all, but seems similarly a reflow issue, not a styling issue: |
|
@bors-servo retry |
style: Avoid selector-matching when only the style attribute is changed. r? @bholley <!-- 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/15317) <!-- Reviewable:end -->
|
lgtm with those changes. Thanks for doing this! |
| /// The rule nodes for each of the pseudo-elements of an element. | ||
| /// | ||
| /// TODO(emilio): Probably shouldn't be a `HashMap` by default, but a smaller | ||
| /// array. |
This comment has been minimized.
This comment has been minimized.
| /// | ||
| /// FIXME(emilio): We could in theory avoid creating these when we have | ||
| /// support for just re-cascading an element. Then the input to | ||
| /// `cascade_node` could be `MatchResults` or just `UseExistingStyle`. |
This comment has been minimized.
This comment has been minimized.
| } | ||
|
|
||
| /// Whether the element holding the hint needs to be restyled on some way. | ||
| pub fn needs_restyle_self(&self) -> bool { |
This comment has been minimized.
This comment has been minimized.
| /// | ||
| /// This hint is stripped down, and only contains hints that are a subset of | ||
| /// RestyleHint::for_single_element(). | ||
| pub for_self: RestyleHint, |
This comment has been minimized.
This comment has been minimized.
bholley
Jan 31, 2017
Contributor
Nit: for_self is a bit of a naming clash with |descendants|. It would be nice to call these |self|, but I think that's a reserved keyword in Rust. So maybe just |self_|?
|
|
||
| // TODO(emilio): Here we'll need to support animation-only hints | ||
| // and similar. | ||
| match_results = if data.needs_only_style_attribute_update() { |
This comment has been minimized.
This comment has been minimized.
bholley
Jan 31, 2017
Contributor
Given that it seems like we'll eventually want to do this the other way around, I think we want the opposite predicate here:
if data.restyle_self() {
// do full selector matching
} else {
if data.style_attribute_changed() {
// Handle style attributes
}
if data.tick_animation() {
// Handle animations
}
// etc
}
So let's get rid of needs_only_style_attribute_update() (since it doesn't scale), and replace it with restyle_self() and style_attribute_changed().
| impl RestyleHint { | ||
| /// The subset hints that affect the styling of a single element during the | ||
| /// traversal. | ||
| pub fn for_single_element() -> Self { |
This comment has been minimized.
This comment has been minimized.
| @@ -635,6 +627,40 @@ pub trait MatchMethods : TElement { | |||
| } | |||
| } | |||
|
|
|||
| /// Updates the style attribute rule nodes without re-running selector | |||
| /// matching, using just the rule tree. | |||
| fn update_style_attribute(&self, | |||
This comment has been minimized.
This comment has been minimized.
bholley
Jan 31, 2017
Contributor
Given that we're going to be stacking this up with similar calls (for animations and transitions, etc), it seems like this should just accept the old rule node as an argument and return a rule node, rather than operating on ElementData and returning MatchResults. We can handle grabbing the old pseudo rule nodes at the callsite, once all the rule tree fixups have been performed.
| -> MatchResults { | ||
| let style_attribute = self.style_attribute(); | ||
|
|
||
| let mut new_rule_node = data.styles().primary.rules.clone(); |
This comment has been minimized.
This comment has been minimized.
bholley
Jan 31, 2017
Contributor
Nit: I'd just call this |rule_node|, because it's not new at this point, and it's confusing when we pass the old rule node to replace_rule_level_if_applicable as |new_rule_node|.
| // transitions, but could not be so for SMIL animations, which we'd need | ||
| // to special-case (isn't hard, it's just about removing the `if` and | ||
| // special cases, and replacing them for a `while` loop, avoiding the | ||
| // optimizations). |
This comment has been minimized.
This comment has been minimized.
bholley
Jan 31, 2017
Contributor
Can you file this as a dependency to https://bugzilla.mozilla.org/show_bug.cgi?id=1302948 ?
| /// Returns the resulting node that represents the new path. | ||
| /// | ||
| /// TODO(emilio): Maybe this should be in `StrongRuleNode`? | ||
| pub fn replace_rule_at_level_if_applicable(&self, |
This comment has been minimized.
This comment has been minimized.
bholley
Jan 31, 2017
Contributor
So, the if_applicable part of the name here deals with the fact that we might be either inserting or removing, instead of strictly replacing?
How about fn update_rule_at_level(...)?
|
@bors-servo delegate+ |
|
|
|
|
|
@bors-servo try |
style: Avoid selector-matching when only the style attribute is changed. r? @bholley <!-- 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/15317) <!-- Reviewable:end -->
|
Bobby, I added another large-ish commit refactoring stuff and adding support for the cascade-only thing, I'd appreciate if you can take another look at it. |
|
|
|
@bors-servo retry |
style: Avoid selector-matching when only the style attribute is changed. r? @bholley <!-- 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/15317) <!-- Reviewable:end -->
|
|
| /// Whether this element should be restyled during the traversal, and how. | ||
| /// | ||
| /// This hint is stripped down, and only contains hints that are a subset of | ||
| /// RestyleHint::for_single_element(). |
This comment has been minimized.
This comment has been minimized.
| shared_context, &mut data) } | ||
| }; | ||
| // TODO(emilio): Make cascade_input less expensive to compute in the cases | ||
| // we don't need to run selector matching. |
This comment has been minimized.
This comment has been minimized.
bholley
Feb 2, 2017
Contributor
Yeah. I'm not super wild about the structure here, but I'm ok with fixing it up later.
|
@bors-servo delegate+ |
|
|
|
@bors-servo r=bholley I backed out the first |
|
|
style: Avoid selector-matching when only the style attribute is changed. r? @bholley <!-- 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/15317) <!-- Reviewable:end -->
|
|


emilio commentedJan 31, 2017
•
edited by larsbergstrom
r? @bholley
This change is