Before this change, the `ComputedStyle` struct that is part of permanent style
data per element holds 2 `StrongRuleNode`s (unvisited and visited) and 2
`Arc<ComputedValues>` (unvisited and visited).
Both rule nodes and the visited values don't actually need to be here. This
patch moves these 3 to new temporary storage in `CascadeInputs` on
`CurrentElementInfo` during the match and cascade process. Rule nodes are
pushed down inside the `ComputedValues` for later access after the cascade.
(Visited values were already available there.)
The permanent style data per element now has just the `Arc<ComputedValues>` for
itself and eager pseudo-elements (plus the `RestyleHint`).
MozReview-Commit-ID: 3wq52ERMpdi
Before this patch, we were setting the dirty descendants bit in animation-only
restyles and it triggered unnecessary traversal for elements that does not need
the traversal (i.e no need selector matching).
If we check it and skip the child after ensure_element_data() call,
the child will have an empty element data, so we will succeed
element_data.is_some() check unexpectedly.
This commit also removes the old restyle_hints module and splits it into
multiple modules under components/style/invalidation/element/.
The basic approach is to walk down the tree using compound selectors as needed,
in order to do as little selector-matching as possible.
Bug: 1368240
MozReview-Commit-ID: 2YO8fKFygZI
This patch renames TNode::parent_element to traversal_parent, since it returns
the parent from the perspective of traversal (which in Gecko uses the
flattened tree). It also renames TNode::children to traversal_children
for the saem reason.
We keep parent_element and children functions on TNode to use for selector
matching, which must be done on the real DOM tree structure.
We only use whether the return value is IMPORTANT_RULES_CHANGED or not, so we
can just return true if an important rules was changed in the function.
Also, we can just return false in case of animation rules changes sine for
animation we can ensure there is no importan rules.
Because of these changes, replace_rule_node does not borrow |result| so that
we can drop a scope there.
If we add/remove important rules, we may need to update a list of all important
rules (in Gecko) which overrides animation properties. Therefore, we need to
set a flag if we update the primary rules which includes important ones.
If we have animations on this element, we update its effect properties, and
also send a task to update cascade results.
Calling get_properties_overriding_animations() might cases some impact
on performance because we need to walk the rule tree, so if possible, we could
just store this set into TNode to avoid finding the properties for both old
and new rules each time. This could be a future work if necessary.
I've chosen this approach mainly because there's no other good way to guarantee
the model is correct than holding the snapshots alive until a style refresh.
What I tried before this (storing them in a sort of "immutable element data") is
a pain, since we call into style from the frame constructor and other content
notifications, which makes keeping track of which snapshots should be cleared an
which shouldn't an insane task.
Ideally we'd have a single entry-point for style, but that's not the case right
now, and changing that requires pretty non-trivial changes to the frame
constructor.
MozReview-Commit-ID: FF1KWZv2iBM
Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
When an element has a display:none ancestor we don't traverse it during
restyle. However, at the end of restyling we expect the tree to be free
of dirty bits. We currently take special care to clear the regular
(non-animation) dirty bit on nodes in display:none subtrees in order to
preserve this invariant. This patch applies the same handling to the
animation-only dirty descendants bit.
While we're at it, we also eliminate the 'unknown' dom depth for the
bloom filter. Computing depth has negligible cost relative to the
amount of work we do setting up the bloom filter at a given depth.
Doing it once per traversal should be totally fine.
I originally separated the elimination of unknown dom depth from the
traversal changes, but I got bloom filter crashes on the intermediate
patch, presumably because I didn't properly fix the sequential traversal
for this case. Given that the final state is green, I just decided to
squash and move on.
The current mechanism requires threading a lot of this state through a bunch of
callsites that are several layers of abstraction above the code that actually
uses this vector (which is only compiled for servo). Putting it in
CurrentElementInfo gets it nicely out of the way.
MozReview-Commit-ID: 9PLBKcJreN0
This is necessary in order to make the computation of eager pseudos depend on
the primary ComputedValues, which we want to do for ::first-letter/::first-line.
This also fixes a bug where the behavior of EagerPseudoStyles::is_empty was reversed
in both the implementation and the callsite.
MozReview-Commit-ID: EXBxclyHWXu
This simplifies things by avoiding the computation of MatchResults when we
don't need them.
We continue to compute rule_nodes_changed, even though we don't use it
for the moment, since we will need it soon for various incremental restyle
optimizations.
MozReview-Commit-ID: 4qsUYaD5Bs2