When setting the textContent of an element with no children to null or
the empty string, nothing happens. Even so, we were still invalidating
style, layout and collections, causing pointless churn.
Skipping invalidation in this case also revealed that we were missing
invalidation when changing the selected state of HTMLOptionElement.
This was all caught by existing tests already in-tree. :^)
It is possible to skip inherited style recalculation for children if
parent's recalculation does not cause any changes.
Improves performance on Github where we could avoid dozens of inherited
style calculations that do not produce any visible changes.
Previously, we optimized hover style invalidation to mark for style
updates only those elements that were matched by :hover selectors in the
last style calculation.
This change takes it a step further by invalidating only the elements
where the set of selectors that use :hover changes after hovered element
is modified. The implementation is as follows:
1. Collect all elements whose styles might be affected by a change in
the hovered element.
2. Retrieve a list of all selectors that use :hover.
3. Test each selector against each element and record which selectors
match.
4. Update m_hovered_node to the newly hovered element.
5. Repeat step 3.
6. For each element, compare the previous and current sets of matched
selectors. If they differ, mark the element for style recalculation.
Instead of recalculating styles for all nodes in the common ancestor of
the new and old hovered nodes' subtrees, this change introduces the
following approach:
- While calculating ComputedProperties, a flag is saved if any rule
applied to an element is affected by the hover state during the
execution of SelectorEngine::matches().
- When the hovered element changes, styles are marked for recalculation
only if the flag saved in ComputedProperties indicates that the
element could be affected by the hover state.
Previously, `percentage_of` would be called on the previous value,
potentially changing its numeric type, yet this potential change
was never reflected as the old numeric type was always used. Now,
the numeric type will be re-calculated every time after the
percentage is resolved. As well, VERIFY checks have been placed to
uphold the requirements for the numeric types to match what the
actual values are.
The "strictly split" infra algorithm feels like an inefficient way of
doing basically what our existing split() does, except working with
code points instead of bytes. It didn't seem worth it to implement now.
Unfortunately, there is no explicit and step-by-step spec to perform
the serialization of `color()` declared values, so while being
spec-informed, this is quite ad-hoc.
Fixes 81 subtests in:
- css/css-color/parsing/color-valid-color-function.html
Some websites (Reddit, for example) create lots of temporary documents
for fragment parsing. Before this change, we had to build a rule cache
for these documents just to determine whether there are :has, :defined,
or attribute selectors, while it should be safe to simply return `false`
right away.
Which will have proper handling of the exection context when performing
a microtask checkpoint. This fixes an assertion to be added in the next
commit where perform_a_microtask_check is invoked on a non-empty
execution context stack.
Instead of storing all storage objects in static memory, we now
follow the the spec by lazily creating a unique Storage object
on each document object.
Each Storage object now holds a 'proxy' to the underlying backing
storage. For now, this proxy is simply a reference to the backing
object. In the future, it will need to be some type of interface
object that stores on a SQLite database or similar.
Session storage is now correctly stored / tracked as part of the
TraversableNavigable object.
Local storage is still stored in a static map, but eventually this
should be factored into something that is stored at the user agent
level.
This is consistent with other functions such as
HTMLElement::offset_width and fixes a crash for the included test.
Returning an offset of zero is not correct for this case, but this is
still an improvement to not crash.
This fixes a bug where, if a non-existent font family is specified in
CSS, whitespaces would be rendered using the emoji font, while letters
would use the default font. This issue occurred because the font was
resolved separately for each code point. Since the emoji font was listed
before the default font, it was chosen for whitespace characters due to
its inclusion of whitespace glyphs (at least in the Apple Color Emoji
font on macOS). This change resolves the issue by placing the default
font before the emoji font in the list.
In particular:
- Don't compute DOM node editability if we don't need it. This was 22%
of CPU time when scrolling on Wikipedia.
- Defer inversion of transformed coordinates until we actually need
them, after we've performed early returns.
This event is fired while both the previous and the current phase are
active.
This prevents this test from timing out:
- css/css-animations/animationevent-types.txt