Commit Graph

2366 Commits

Author SHA1 Message Date
Sam Atkins
87e74c6c0c LibWeb: Start transitions when affected properties change
Co-authored-by: Matthew Olsson <matthewcolsson@gmail.com>
(cherry picked from commit a1fca1a7f3f70e4acf15052014d5b180197df9fd)
2024-11-04 13:15:58 -05:00
Sam Atkins
0ff996ef4e LibWeb: Parse transition values and cache them on Animatable elements
Co-authored-by: Matthew Olsson <matthewcolsson@gmail.com>
(cherry picked from commit e5441669776b228435dbec87f31b0f25ebebc320)
2024-11-04 13:15:58 -05:00
Matthew Olsson
3539a491a2 LibWeb: Avoid copy when creating EasingStyleValue
(cherry picked from commit 815a87100ec472436929720f7d40e4741e5c4100)
2024-11-04 13:15:58 -05:00
Sam Atkins
147fcb39e7 LibWeb/CSS: Extract interpolation code into its own files
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)
2024-11-04 13:15:58 -05:00
Sam Atkins
d5b302d18e LibWeb: Move "owning element" of Animation classes into Animation
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)
2024-11-04 13:15:58 -05:00
Sam Atkins
ef0ba958a3 LibWeb/CSS: Allow getting a property's computed value without animations
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)
2024-11-04 13:15:58 -05:00
Annya
265c942698 LibWeb/CSS: Implement revert-layer
With the introduction of the cascade layer, the 5th CSS-wide keyword,
`revert-layer`, has been added.

(cherry picked from commit bea7eec5183a816a100d190e409a622f429d7405)
2024-10-31 21:51:50 -04:00
Andreas Kling
e2a9a7f838 LibWeb: Bucket CSS rules by pseudo-element
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)
2024-10-31 21:33:21 -04:00
Andreas Kling
aeca8c4902 LibWeb: Bail early from doomed pseudo-element style computation
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)
2024-10-31 21:33:11 -04:00
Tim Ledbetter
6b2891da01 LibWeb: Match class selectors case insensitively in quirks mode
This align our implementation with the CSSWG Selectors Level 4
specification.

(cherry picked from commit 82ed2534776406872337b34ddf2dfaa0b3332c32)
2024-10-31 19:59:29 -04:00
Andreas Kling
7d24bd06f2 LibWeb: Make CSSStyleRule::qualified_layer_name() return a const-ref
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)
2024-10-31 09:47:47 -04:00
Andreas Kling
417d2005a9 LibWeb: Filter :hover selectors early for elements that aren't hovered
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)
2024-10-31 09:47:47 -04:00
Andreas Kling
318d53e9b4 LibWeb: Bucket :is/where() selectors by tag name and ID as well
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)
2024-10-31 09:47:47 -04:00
Andreas Kling
cddee1633d LibWeb: Remove MatchingRule::contains_root_pseudo_class member
This can be a local variable while building a rule cache, no need to
take up space in MatchingRule.

(cherry picked from commit 49d2b11085c8a59db2f1c54ad8e8f5938e6776c9)
2024-10-31 09:47:47 -04:00
Andreas Kling
255b3980c0 LibWeb: Filter rules to run before allocating vector of matches
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)
2024-10-31 09:47:47 -04:00
Andreas Kling
1e59f8aafc LibWeb: Cache the qualified layer name in CSSRule
This makes cascade layer filtering take <2% of CPU time when loading
https://vercel.com instead of 30%.

(cherry picked from commit 44e4ea3d7aaf9aed6ad09cc9f049b2842e3e0d28)
2024-10-31 08:56:58 -04:00
Andreas Kling
7bf0f0e908 LibWeb: Include immediate child (>) combinator in ancestor filter
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)
2024-10-30 22:17:22 -04:00
Andreas Kling
e2b3d7775e LibWeb: Bucket div.foo and div#foo as class/ID rather than tag(div)
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)
2024-10-30 22:17:22 -04:00
Andreas Kling
49bcdd7a2a LibWeb: Treat :is(.foo) & :where(.foo) as class selectors when bucketing
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)
2024-10-30 22:17:22 -04:00
Nico Weber
6f09a68baf LibWeb: Parse stroke-{linejoin,miterlimit} attributes
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)
2024-10-29 21:42:09 -04:00
Kostya Farber
0b90c18afb LibWeb: Parse the word-break css property
(cherry picked from commit 44b1c4f2b59563cf29f6af81bb86645f2fa89155)
2024-10-27 20:06:44 -04:00
Kostya Farber
797697e0f2 LibWeb: Add letter-spacing css property to Node
(cherry picked from commit 537cbf55c36c14247d027f0495d595eb357dd84d)
2024-10-27 18:30:52 -04:00
Kostya Farber
22af58eb7a LibWeb: Apply the word-spacing css property to Node
This will let us start to begin applying this during
text shaping.

(cherry picked from commit da42c19cb66656e3b2531c29542b4bb27b21ec94)
2024-10-27 18:06:39 -04:00
Sam Atkins
bcbb7b19cd LibWeb/CSS: Serialize empty grid-template-* values correctly
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)
2024-10-27 16:58:12 -04:00
Sam Atkins
cbd9e88ffd LibWeb/CSS: Handle calculated integers when expanding unresolved values
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)
2024-10-27 16:58:12 -04:00
Andreas Kling
4a4da86792 LibWeb: Don't crash when encountering calc() inside a CSS rect() value
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)
2024-10-26 23:26:45 -04:00
Andreas Kling
0ed1c4fcab LibWeb: Don't crash when encountering border-spacing: calc(...)
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)
2024-10-26 23:26:45 -04:00
ronak69
a3f56f9abb LibWeb/CSS: Tweak in CSSRGB::to_color() to avoid floating point errors
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)
2024-10-26 11:39:39 -04:00
Sam Atkins
07bc7de068 LibWeb/CSS: Mark grid-[gap, column-gap, row-gap] properties as aliases
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)
2024-10-26 10:46:49 -04:00
Sam Atkins
d29d44951d LibWeb: Serialize more @font-face descriptors
Adapt the existing `font-face-src-local-serialization.html` test into a
more general test for these.

(cherry picked from commit c497e5f850a5c7f43d6f216d9fd74a58ddefd9a0)
2024-10-26 09:29:16 -04:00
Sam Atkins
9b9b5fef6d LibWeb/CSS: Parse font-[feature,variation]-settings descriptors
(cherry picked from commit e43f3e4808b0775dfcd8ef9d7218d87e6f617d21)
2024-10-26 09:29:16 -04:00
Sam Atkins
f8a66c346e LibWeb/CSS: Parse and propagate font-feature-settings property
(cherry picked from commit 95c17dfab51fefdd5ca364652e8571827d9693b1)
2024-10-26 09:29:16 -04:00
Sam Atkins
7b35ed0c66 LibWeb/CSS: Parse and propagate font-variation-settings property
(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)
2024-10-26 09:29:16 -04:00
Sam Atkins
f23d61c8ae LibWeb/CSS: Expand single-none-parsing helper to parse any keyword
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)
2024-10-26 09:29:16 -04:00
Sam Atkins
1df9984d5c LibWeb/CSS: Add parsing for <opentype-tag>
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)
2024-10-26 09:29:16 -04:00
Sam Atkins
552f4540d7 LibWeb/CSS: Return StringStyleValue's FlyString by reference
Most of the time this copy is completely unnecessary, so let's avoid it!

(cherry picked from commit f7f8d2fe0d29fb33dd3321a99e3628d8eb5803a0)
2024-10-26 09:29:16 -04:00
Sam Atkins
60a1bcd250 LibWeb/CSS: Return StringStyleValue from parse_string_value()
Callers already relied on this being true, so let's make it contractual.

(cherry picked from commit 2516297c865f44c51d09a07001169b08ba430631)
2024-10-26 09:29:16 -04:00
Sam Atkins
d077fc463e LibWeb/CSS: Introduce OpenTypeTaggedStyleValue
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)
2024-10-26 09:29:16 -04:00
Kostya Farber
8718238254 LibWeb/CSS: Parse the tab-size property
(cherry picked from commit 68a28ff33abe29376cea009e24c406d3a23d4890;
amended to update `height:` line in getComputedStyle-print-all.txt)
2024-10-25 21:11:16 -04:00
Sam Atkins
a6b7c0eefb LibWeb/CSS: Parse the font-language-override descriptor
(cherry picked from commit 20af2eb2b0d196b464db536222d8b9f0df75a79d)
2024-10-21 09:36:47 -04:00
Sam Atkins
ee3710f681 LibWeb/CSS: Parse and propagate the font-language-override property
(cherry picked from commit 1d8867d9ae9de1312fe6624bf9040dde12bfa9df;
amended to fix `height:` line in getComputedStyle-print-all.txt)
2024-10-21 09:36:47 -04:00
Sam Atkins
6936b2c3e6 LibWeb/CSS: Parse font-width descriptor and its font-stretch alias
(cherry picked from commit b1870e70298b9d5933fd4cee4fc6d947b8198d98)
2024-10-21 09:36:47 -04:00
Sam Atkins
a627165df9 LibWeb/CSS: Make font-stretch a legacy alias for new font-width
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)
2024-10-21 09:36:47 -04:00
Sam Atkins
5606a54a22 LibWeb/CSS: Parse font-named-instance descriptor
(cherry picked from commit 7c50a31402c0240ccd19658284dec48ff876fc17)
2024-10-21 09:36:47 -04:00
Sam Atkins
85b5d7b93e LibWeb/CSS: Parse font-display descriptor
(cherry picked from commit 3eb6d510fd0c7d4b6b21b64ac36a06571ea1fd9f)
2024-10-21 09:36:47 -04:00
Sam Atkins
8b35708f83 LibWeb/CSS: Sort Keywords.json
(cherry picked from commit 19cb3d4c819ace6313ffc3b6bf93902a1886de12)
2024-10-21 09:36:47 -04:00
Sam Atkins
272c1c64cb LibWeb: Parse ascent-, descent-, and line-gap-override descriptors
(cherry picked from commit 2f7d18865dc509a0d7c9e1c751266ede92f58ca6)
2024-10-21 09:36:47 -04:00
Sam Atkins
e47c20c994 LibWeb/CSS: Rename CalculatedStyleValue -> CSSMathValue
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)
2024-10-20 22:24:57 -04:00
Sam Atkins
536fb5a0bc LibWeb/CSS: Implement cascade layers (aka @layer)
This is done quite simply for now, there are certainly optimizations
that can and should be made later.

With this we now pass:
- http://wpt.live/css/css-cascade/layer-basic.html
- http://wpt.live/css/css-cascade/layer-important.html
- http://wpt.live/css/css-cascade/layer-statement-copy-crash.html
- http://wpt.live/css/css-cascade/layer-stylesheet-sharing-important.html
- http://wpt.live/css/css-cascade/layer-stylesheet-sharing.html
- http://wpt.live/css/css-cascade/layer-vs-inline-style.html

(cherry picked from commit a50da405e9c350266edfc89e5d27f7acddbee422)
2024-10-20 21:09:21 -04:00
Sam Atkins
17c7fa12c3 LibWeb/CSS: Replace style-rule iteration methods with a generic one
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)
2024-10-20 21:09:21 -04:00