Apart from shrinking StyleComputer a little, we need the ability to get
the current value of a transition from outside of it.
(cherry picked from commit 70d99db9924b068d2a20dd64fec2bd71f7d7b346)
There's no need to have a virtual method here when we can just store the
owning element pointer on the Animation instead.
(cherry picked from commit a0b96280e498d53576ec855d0deea56f508c9e7c)
The algorithm for starting a transition requires us to examine the
before-change and after-change values of the property, without taking
any current animations into account.
(cherry picked from commit 3a105961360740a2aef793b7320ba4c832389f09)
With the introduction of the cascade layer, the 5th CSS-wide keyword,
`revert-layer`, has been added.
(cherry picked from commit bea7eec5183a816a100d190e409a622f429d7405)
Instead of throwing all pseudo-element rules in one bucket, let's have
one bucket per pseudo-element.
This means we only run ::before rules for ::before pseudo-elements,
only ::after rules for ::after, etc.
Average style update time on https://tailwindcss.com/ 250ms -> 215ms.
(cherry picked from commit 87056ee0d2505c26149a36fc5b69446504b172bb)
Once we know the final value of the `content` property for a
pseudo-element, we can bail early if the value is `none` or `normal`
(note that `normal` only applies to ::before and ::after).
In those cases, no pseudo-element will be generated, so everything
that follows in StyleComputer would be wasted work.
This noticeably improves performance on many pages, such as
https://tailwindcss.com/ where style updates go from 360ms -> 250ms.
(cherry picked from commit d22228ab93b387e043b5bce29f79ef5ffa7c0f9d)
And also make it inline. We were spending 8% of selector matching on
creating and destroying FlyString copies here. With this change, it's
now ~1%.
(cherry picked from commit b2aff403fc596bfab64c0ab43a45f3d39f836afb)
Some websites (like vercel.com...) have a *lot* of :hover selectors that
we can simply skip for any element that isn't currently hovered.
(cherry picked from commit ef4f5ac8fb761f43839e9fbd753716a57544c795)
Instead of only bucketing these by class name, let's also bucket by
tag name and ID.
Reduces the number of selectors evaluated on https://tailwindcss.com/
from 2.9% to 1.9%.
(cherry picked from commit 5bb0f43b90a56275a0bfb92116826b2349c69dd3)
This can be a local variable while building a rule cache, no need to
take up space in MatchingRule.
(cherry picked from commit 49d2b11085c8a59db2f1c54ad8e8f5938e6776c9)
By filtering first, we end up allocating much less vector space
most of the time.
This is mostly helpful in pathological cases where there's a huge number
of rules present, but most of them get rejected early.
(cherry picked from commit c8f22f65d9631c9da12390eeec05033e6efa76f2)
This makes cascade layer filtering take <2% of CPU time when loading
https://vercel.com instead of 30%.
(cherry picked from commit 44e4ea3d7aaf9aed6ad09cc9f049b2842e3e0d28)
Before this change, the ancestor filter would only reject rules that
required a certain set of descendant strings (class, ID or tag name)
to be present in the current element's ancestor chain.
An immediate child is also a descendant, so we can include this
relationship in the ancestor filter as well.
This substantially improves the efficiency of the ancestor filter on
websites using Tailwind CSS.
For example, https://tailwindcss.com/ itself goes from full style
updates taking ~1400ms to ~350ms. Still *way* too long, but a huge
improvement nonetheless.
(cherry picked from commit 34fdd0d44fcf916540ea66ba9c895ba005a54b9a)
By bucketing these seletors by class or ID, we can avoid running them
in more cases.
Before, we were only avoiding them if the context element wasn't a div.
Now we avoid them for any element that doesn't have that specific class
or ID.
This reduces the number of selectors ran on https://vercel.com by a bit
more, from 1.90% to 1.65%.
(cherry picked from commit b365a5c42f4e978496fb03924b129406d4a6c5b0)
These are just roundabout ways of writing .foo, so we can still put them
in the rules-by-class bucket and skip running them when the element
doesn't have that class.
Note that :is(.foo .bar) is also bucketed as a class rule, since the
context element must have the `bar` class for the selector to match.
This is a massive speedup on https://vercel.com/ as it cuts the number
of selectors we actually evaluate from 7.0% to 1.9%.
(cherry picked from commit ad37c8cd26208157be405fb3a329d0955f402fc9)
Similar to LadybirdBrowser/ladybird#1714.
We don't implement the linejoin values `miter-clip` and `arcs`, because
according to the SVG 2 spec:
> The values miter-clip and arcs of the stroke-linejoin property are at
> risk. There are no known browser implementations. See issue Github
> issue w3c/svgwg#592.
Nothing uses this yet. The next step is to change
SVGPathPaintable::paint() to read `graphics_element.stroke_linejoin()`
and `graphics_element.stroke_miterlimit()` when painting.
(cherry picked from commit 421cf8d9bf276cff61acdc32dc55d978d37fb671;
amended to resolve conflict on `height:` in
getComputedStyle-print-all.txt)
Previously we would serialize these as the empty string. eg, this:
```
<div style="grid-auto-columns: auto"></div>
```
would have a computed `grid-auto-columns` value of ``.
(cherry picked from commit 7c2680b7efd2588cf2c5e595f7a60813dabf3b92)
In order to know whether `calc(2.5)` is a number or an integer, we have
to see what the property will accept. So, add that knowledge to
`Parser::expand_unresolved_values()`.
This makes `counter-increment: foo calc(2 * var(--n));` work correctly,
in a test I'm working on.
(cherry picked from commit 69d064697ad8bbf602eb2dc73fc532b0e1b16716)
This allows us to run the WPT tests under quirks/unitless-length/
without crashing, giving us over 4600 new passing subtests. :^)
(cherry picked from commit 5df6c6eecff678bf2a1fe8960149302d42015439)
This allows us to progress further on this WPT test:
https://wpt.live/quirks/unitless-length/quirks.html
...although it still crashes before finishing.
(cherry picked from commit 5e240f997caa8b62275d3c5d18a1cf1885349971)
Example of the difference:
50 * 2.55 --> 127.4999 --> round towards +∞ --> 127
50 * 255 / 100 --> 127.5000 --> round towards +∞ --> 128
Now, 9 failing WPT tests in /css/css-color/ pass.
(cherry picked from commit 6c3ecf6a342cbc0a83c1deac89e1a7edf6d959c4;
amended because css-color-functions.html is a reftest for us, not
a screenshot test)
These are legacy name aliases for the properties without the 'grid-'
prefix. See https://drafts.csswg.org/css-align-3/#gap-legacy
(cherry picked from commit c79f261bec40a61373d45508c1935f839454c95d)
Adapt the existing `font-face-src-local-serialization.html` test into a
more general test for these.
(cherry picked from commit c497e5f850a5c7f43d6f216d9fd74a58ddefd9a0)
(cherry picked from commit 55812aaed20ce8f7aeea233a47bcab73b60edd5e;
amended to include AK/QuickSort.h in Parser.cpp to fix a compile
error, and to update height: in getComputedStyle-print-all.txt)
Multiple font properties are either the `normal` keyword or some
non-keyword value, so this lets us avoid some boilerplate for those, at
the cost of the existing `none` users having marginally more verbose
code.
(cherry picked from commit 1a127c9d37e47b8793057ab68305bf399ad3106f)
This is a special form of `<string>` so doesn't need its own style value
type. It's used in a couple of font-related properties. For completeness
it's included in ValueType.
(cherry picked from commit cd13b30fb871ab521777ce164bff7696aa0fbfca)
Two font properties, font-feature-settings and font-variation-settings,
contain a list of values that are an `<opentype-tag>` followed by a
single value. This class is intended to fill both roles.
(cherry picked from commit c22a2d8f2b720b7cd69a1c3b84d1cf7d443498ee)
CSS Fonts level 4 renames font-stretch to font-width, with font-stretch
being left as a legacy alias. Unfortunately the other specs have not yet
been updated, so both terms are used in different places.
(cherry picked from commit 4a67b28600437901e6d8a366c56a5ddd8665deb1)
This matches the name in the CSS Typed OM spec. There's quite a lot
still to do to make it match the spec behavior, but this is the first
step.
(cherry picked from commit 76daba3069de4c184c6b2317d0c89b50f81a8c00)
I didn't want to add another set of boilerplatey tree-walking methods,
so here's a general-purpose one. :^)
`for_each_effective_rule()` walks the tree of effective style rules, and
runs the callback on each one, in either pre- or postorder. The
previous `for_each_effective_style/keyframes_rule()` methods of
`CSSStyleSheet` are then reimplemented in terms of
`for_each_effective_rule()`, and we can get rid of their equivalents
elsewhere.
(cherry picked from commit cbb4be3e5e266da09d145435fe8279a83099f363)