Commit graph

2491 commits

Author SHA1 Message Date
Sam Atkins
fdcece2e88 LibWeb/CSS: Implement legacy name aliases for properties
When a property is a "legacy name alias", any time it is used in CSS or
via the CSSOM its aliased name is used instead.
(See https://drafts.csswg.org/css-cascade-5/#legacy-name-alias)

This means we only care about the alias when parsing a string as a
PropertyID - and we can just return the PropertyID it is an alias for.
No need for a distinct PropertyID for it, and no need for LibWeb to
care about it at all.

Previously, we had a bunch of these properties, which misused our code
for "logical aliases", some of which I've discovered were not even
fully implemented. But with this change, all that code can go away, and
making a legacy alias is just a case of putting it in the JSON. This
also shrinks `StyleProperties` as it doesn't need to contain data for
these aliases, and removes a whole load of `-webkit-*` spam from the
style inspector.
2024-09-27 17:16:23 +01:00
Sam Atkins
dcf55dd492 LibWeb/CSS: Clarify comment about cascading presentational hints
The spec allows us to either treat them as part of the UA origin, or as
its own origin before author styles. This second behaviour turns out to
be what we are currently doing, which is nice!

Funnily enough this was clarified in the spec barely a month after this
original comment was written. :^)
2024-09-26 08:08:38 +02:00
Sam Atkins
bea47a2554 LibWeb/CSS: Correct behavior of revert inside a @layer
`revert` is supposed to revert to the previous cascade origin, but we
previously had it reverting to the previous layer. To support both,
track them separately during the cascade.

As part of this, we make `set_property_expanding_shorthands()` fall back
to `initial` if it can't find a previous value to revert to. Previously
we would just shrug and do nothing if that happened, which only works
if the value you want to revert to is whatever is currently in `style`.
That's no longer the case, because `revert` should skip over any layer
styles that have been applied since the previous origin.
2024-09-26 08:08:38 +02:00
Andreas Kling
9765a733d0 LibWeb: Don't extrapolate transition properties for unknown properties
If we don't recognize a given transition-property value as a known CSS
property (one that we know about, not necessarily an invalid one),
we should not extrapolate the other transition-foo values for it.

Fixes #1480
2024-09-24 21:53:43 +02:00
Aliaksandr Kalenik
74588a0a16 LibWeb: Remove all font loaders linked to a StyleSheet when it's deleted
When a style sheet is removed, all font loaders created from that style
sheet should also be removed.
2024-09-22 20:10:30 +02:00
Andreas Kling
8beb7c7700 LibWeb: Cache whether there are any :has() selectors present
As useful as they may be to web developers, :has() selectors complicate
the style invalidation process quite a lot.

Let's have StyleComputer keep track of whether they are present at all
in the current set of active style sheets. This will allow us to
implement fast-path optimizations when there are no :has() selectors.
2024-09-22 18:42:40 +02:00
Andreas Kling
42a1a0bd73 LibWeb: Put CSS transitions debug spam behind CSS_TRANSITIONS_DEBUG 2024-09-22 10:46:54 +02:00
Andreas Kling
e40ad73ae7 LibWeb: Allow setting shorthand CSS properties via CSSStyleDeclaration
We now expand shorthands into their respective longhand values when
assigning to a shorthand named property on a CSSStyleDeclaration.

We also make sure that shorthands can be round-tripped by correctly
routing named property access through the getPropertyValue() AO,
and expanding it to handle shorthands as well.

A lot of WPT tests for CSS parsing rely on these mechanisms and should
now start working. :^)

Note that multi-level recursive shorthands like `border` don't work
100% correctly yet. We're going to need a bunch more logic to properly
serialize e.g `border-width` or `border` itself.
2024-09-22 09:45:59 +02:00
Sam Atkins
a1fca1a7f3 LibWeb: Start transitions when affected properties change
Co-authored-by: Matthew Olsson <matthewcolsson@gmail.com>
2024-09-22 06:41:55 +02:00
Sam Atkins
e544166977 LibWeb: Parse transition values and cache them on Animatable elements
Co-authored-by: Matthew Olsson <matthewcolsson@gmail.com>
2024-09-22 06:41:55 +02:00
Matthew Olsson
815a87100e LibWeb: Avoid copy when creating EasingStyleValue 2024-09-22 06:41:55 +02:00
Sam Atkins
70d99db992 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.
2024-09-22 06:41:55 +02:00
Sam Atkins
a0b96280e4 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.
2024-09-22 06:41:55 +02:00
Sam Atkins
3a10596136 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.
2024-09-22 06:41:55 +02:00
Andreas Kling
32299e74cb LibWeb: Make CSS font loader tolerate WPT web server shenanigans
The web server for WPT has a tendency to just disconnect after sending
us a resource. This makes curl think an error occurred, but it's
actually still recoverable and we have the data.

So instead of just bailing, do what we already do for other kinds of
resources and try to parse the data we got. If it works out, great!

It would be nice to solve this in the networking layer instead, but
I'll leave that as an exercise for our future selves.
2024-09-21 19:20:30 +02:00
Tim Ledbetter
087fcb84cb LibWeb: Don't crash when resolving grid properties of inline elements
Previously, attempting to get the computed value for a
grid-template-rows or grid-template-columns property would cause a
crash for inline elements.
2024-09-20 08:16:33 +02:00
Sam Atkins
76daba3069 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.
2024-09-18 20:38:41 +01:00
Sam Atkins
35cb6badc2 LibWeb/CSS: Remove unused checks for calculated dimension types
These are a remnant of when Length itself could hold a pointer to a
CalculatedStyleValue. That hasn't been the case for a long time now.
2024-09-18 20:38:41 +01:00
Tim Ledbetter
779de840af LibWeb: Don't crash when resolving style of grid template properties
Previously, attempting to get the computed value for a
grid-template-rows or grid-template-columns property would cause a crash
if the element had no associated paintable.
2024-09-18 17:38:20 +01:00
Aliaksandr Kalenik
41e37f0079 LibWeb: Use correct resolved type for round() CSS function
Function is defined as `round(<rounding-strategy>?, A, B?)`

With this change resolved type is `typeof(resolve(A))`, instead of
`typeof(A)`.

For example `round(up, 20%, 1px)` with 200px percentage basis is now
correctly resolved in 40px instead of 40%.

Progress on https://www.notion.so/ landing page.
2024-09-17 20:02:29 +02:00
Sam Atkins
8b3bcf9c0f LibWeb: Reduce unnecessary debug spam from parse_as_sizes_attribute()
Logging a parse error when the attribute is not present, is not useful,
but does fill the debug log with errors that hide any real parsing
errors. This patch introduces an early-out in this situation to prevent
this spam.
2024-09-12 07:39:11 +02:00
Sam Atkins
2a0f6fd23e LibWeb: Bring parse_as_sizes_attribute() up to date with the spec
The following spec algorithms had changed since we implemented them:
- "parse a sizes attribute"
- "update the source set"
- "create a source set"

This commit brings them up to date, as well as adding some additional
logging when parsing the sizes attribute fails in some way.
2024-09-12 07:39:11 +02:00
Sam Atkins
2671820ace LibWeb: Move our "default sizing algorithm" function into a public place
Specifically, this is used by the updated algorithm for parsing a sizes
attribute, so we need access to it there.

No behaviour changes.
2024-09-12 07:39:11 +02:00
Annya
bea7eec518 LibWeb/CSS: Implement revert-layer
With the introduction of the cascade layer, the 5th CSS-wide keyword,
`revert-layer`, has been added.
2024-09-11 22:30:20 +01:00
sideshowbarker
51528ec677 LibWeb: Normalize all WebIDL definition lines to four leading spaces
This change takes all existing WebIDL files in the repo that had
definition lines without four leading spaces, and fixes them so they
have four leading spaces.
2024-09-10 21:16:53 +01:00
Andreas Kling
87056ee0d2 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.
2024-09-10 16:54:40 +02:00
Andreas Kling
d22228ab93 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.
2024-09-10 15:19:55 +02:00
Andreas Kling
e399b472e9 LibWeb: Make CSS::StyleProperties copy-on-write internally
This makes the way we've implemented the CSS `revert` keyword a lot less
expensive.

Until now, we were making a deep copy of all property values at the
start of each cascade origin. (Those are the values that `revert` would
bring us back to if encountered.)

With this patch, the revert property set becomes a shallow copy, and we
only clone the property set if the cascade ends up writing something.

This knocks a 5% profile item down to 1.3% on https://tailwindcss.com
2024-09-10 13:51:28 +02:00
Gingeh
4a3a9e6ec4 LibWeb: Implement justify-*: left/right 2024-09-10 10:40:07 +01:00
Aliaksandr Kalenik
2aa07e0e65 LibWeb: Do not try to load a font if format detection has failed
Skia is more permissive when it comes to font loading, compared to our
own OpenType implementation, which it has superseded, parsing an invalid
TTF does not result in an error but rather produces a font that is
incorrectly displayed. This change updates the FontLoader to address
this behavior and to stop attempting to parse a font as a last resort
when format detection has failed.

Fixes regression on x.com when text is not displayed introduced in
a9d5a99568
2024-09-10 07:40:25 +02:00
Aliaksandr Kalenik
1d7c9cd1e1 LibWeb: Return computed grid-template-rows/columns if there's no used
If grid-template-rows or grid-template-columns queried for a box that is
not a grid container, the result should be computed value instead of
null.

Fixes crashing in inspector.
2024-09-09 20:12:20 +02:00
Andreas Kling
b2aff403fc 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%.
2024-09-09 20:12:07 +02:00
Andreas Kling
ef4f5ac8fb 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.
2024-09-09 20:12:07 +02:00
Andreas Kling
5bb0f43b90 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%.
2024-09-09 20:12:07 +02:00
Andreas Kling
49d2b11085 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.
2024-09-09 20:12:07 +02:00
Andreas Kling
c8f22f65d9 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.
2024-09-09 20:12:07 +02:00
Aliaksandr Kalenik
68fcc37531 LibWeb: Return used values for grid tracks in getComputedStyle()
That's awkward, but getComputedStyle needs to return used track values
for gridTemplateColumns and gridTemplateRows properties. This change
implements it by saving style values with used values into layout state,
so it could be assigned to paintables during LayoutState::commit() and
later accessed by style_value_for_property().

I haven't seen it used in the wild, but WPT grid tests extensively use
it. For example this change helps to go from 0/10 to 8/10 on this test:
https://wpt.live/css/css-grid/layout-algorithm/grid-fit-content-percentage.html
2024-09-09 12:48:06 +02:00
Andreas Kling
34fdd0d44f 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.
2024-09-09 12:46:55 +02:00
Andreas Kling
b365a5c42f 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%.
2024-09-09 12:46:55 +02:00
Andreas Kling
ad37c8cd26 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%.
2024-09-09 12:46:55 +02:00
Andreas Kling
ddbfac38b0 LibWeb: Note what's causing a style invalidation to happen
You can now build with STYLE_INVALIDATION_DEBUG and get a debug stream
of reasons why style invalidations are happening and where.

I've rewritten this code many times, so instead of throwing it away once
again, I figured we should at least have it behind a flag.
2024-09-08 09:45:31 +02:00
Andreas Kling
44e4ea3d7a 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%.
2024-09-07 13:23:55 +02:00
Andreas Kling
95bd0602ba LibWeb: Keep custom properties from all cascade layers
Before this change, we were cascading custom properties for each layer,
and then replacing any previously cascaded properties for the element
with only the set from this latest layer.

The patch fixes the issue by making each pass of the custom property
cascade add to the same set, and then finally assigning that set of
properties to the element.
2024-09-07 12:37:15 +02:00
Andrew Kaster
02a56f6480 LibWeb: Remove uses of obsolete PlatformObject::global_object()
This API is a relic from the time when it was important for objects to
have easy access to the Window, and to know it was the global object.

We now have more spec-related concepts like relevant_global_object and
current_global_object to pull the Window out of thin air.
2024-09-07 11:37:49 +02:00
Aliaksandr Kalenik
22b8380e37 LibWeb: Include system emoji font in a font cascade list
Adds emoji rendering support on macOS and linux (if it has "Noto Color
Emoji" font).
2024-09-06 08:30:30 -04:00
Aliaksandr Kalenik
67fe8d66b2 LibWeb: Skip font if it doesn't contain needed glyph in FontCascadeList
Before this change, we were only checking for actual glyph containment
in a font if unicode ranges were specified. However that is not
sufficient for emoji support, where we want to continue searching for
a font until one containing emojis is found.
2024-09-06 08:30:30 -04:00
Sam Atkins
a50da405e9 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
2024-09-06 07:49:55 +02:00
Sam Atkins
cbb4be3e5e 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.
2024-09-06 07:49:55 +02:00
Sam Atkins
4c98906e2c LibWeb/CSS: Parse @layer rules
This causes us to pass all of
http://wpt.live/css/css-cascade/parsing/layer.html :^)
2024-09-06 07:49:55 +02:00
Sam Atkins
1c6133aa52 LibWeb/CSS: Add CSSOM types for @layer rules
Depending on usage, `@layer` has two forms, with two different CSSOM
types. One simply lists layer names and the other defines a layer with
its contained rules.
2024-09-06 07:49:55 +02:00