Commit Graph

438 Commits

Author SHA1 Message Date
Sam Atkins
5d86305596 Meta: Make embed_as_string_view.py produce Strings instead
This is only used for CSS style sheets. One case wants it as a String,
and the others don't care, but will in future also want to have the
source as a String.

(cherry picked from commit 8cbc2116162764479edeec78e4b2b7c41447b643;
amended to fix conflicts in two cmake files, due to serenity
still having more code_generators, and still buildling
OutOfProcessWebView.cpp. Also kept embed_as_string_view because
it's used by stringify_gml. Did this by giving embed_as_string.py
a --type= argument that defaults to string but can also be set
to string-view.)
2024-11-15 23:10:03 -05:00
Sam Atkins
23959eeb6f LibWeb: Rename Document::for_each_css_style_sheet for clarity
This only iterates style sheets that are in use, so make this clear by
renaming it to `for_each_active_css_style_sheet()`.

(cherry picked from commit c29f4f69ef9a16bd63a4bf133618120068e96bf3)
2024-11-15 23:10:03 -05:00
Carwyn Nelson
7a76f8b265 LibWeb: Skip transitions for pseudo elements
Transitions are currently not implemented for pseudo elements which
causes the transition to be applied to the "real"/"parent" element. When
a transition adjusts width/height on a pseudo element this causes the
real elements layout to break.

As a quick fix we just skip doing transitions when they are against
pseudo elements.

(cherry picked from commit 30f59cfe1aec0b385631a40da8b2447eed62ad79)
2024-11-11 17:22:42 -05:00
Andreas Kling
72227066c6 LibWeb: Avoid a weird reparse of style attributes for pseudo elements
For pseudo elements that represent a browser-generated shadow tree
element, such as ::placeholder, we were reparsing their style attribute
in StyleComputer for some reason.

Instead of doing this, just access the already-parsed version via
Element::inline_style().

(cherry picked from commit d21c5631aa5d3bebcf828e893f0d7da031481894)
2024-11-10 21:48:40 -05:00
Andreas Kling
bca2b88b45 LibWeb: Always blockify the root element
This is what the spec tells us to do:

    The root element’s display type is always blockified,
    and its principal box always establishes an independent
    formatting context.

    Additionally, a display of contents computes to block
    on the root element.

Spec link: https://drafts.csswg.org/css-display/#root

Fixes #1562

(cherry picked from commit f1be662f683155705f851bcf440fe30d0e606a87)
2024-11-10 10:46:01 -05:00
Sam Atkins
812c55784b 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. :^)

(cherry picked from commit dcf55dd4924e5369d75a3533af2b869033a0ebfd)
2024-11-10 10:46:01 -05:00
Sam Atkins
c369a2b48c 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.

(cherry picked from commit bea47a25545adfb96d83a16a3e4f4435bae05e39)
2024-11-10 10:46:01 -05:00
Andreas Kling
319dd59fc4 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.

(cherry picked from commit 8beb7c77002a3359ad2fe73969fc6bb2dbc75413)
2024-11-10 10:46:01 -05:00
Andreas Kling
4779c6ac60 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.

(cherry picked from commit 95bd0602ba079e0bd7608e39bcbc3b0403ed89d1)
2024-11-10 10:46:01 -05:00
Andreas Kling
1c8375f5df 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

(cherry picked from commit 9765a733d0bc297815fc1a7fce562e3d8f69cd84)
2024-11-05 10:48:01 -05:00
Sam Atkins
32406976d7 LibWeb: Ensure Elements don't need style update after computing style
Previously, we set the "needs style update" flag to false at the
beginning of recomputing the style. This meant that if any code within
the cascade set this flag to true, then we would end style computation
thinking the element still needed its style updating. This could occur
when starting a transition, and would make TreeBuilder crash.

By ensuring that we always set the flag to false at the very end of
style computation, this is avoided, along with any similar issues - I
noticed a comment in `Animation::cancel()` which sounds like a
workaround was needed for a similar problem previously.

(cherry picked from commit 8c79edac085ee164aca5ca7cf287e68e93e03217)
2024-11-04 19:29:49 -05:00
Andreas Kling
1030034130 LibWeb: Put CSS transitions debug spam behind CSS_TRANSITIONS_DEBUG
(cherry picked from commit 42a1a0bd73fecd22452e224859d27221588c3f5f;
amended to fix conflicts in Debug.h.in and all_the_debug_macros.cmake)
2024-11-04 13:15:58 -05:00
Aliaksandr Kalenik
0a348c394c LibWeb: Make sure style is up-to-date in getAnimations()
StyleComputer is responsible for assigning animation targets, so we
have to make sure there are no pending style updates before querying
animations of an element.

This change also introduces a version of getAnimations() that does not
check style updates and used by StyleComputer to avoid mutual recursion.

(cherry picked from commit 94b3b84dd808b6607e8fd0aead1796709f3a8721)
2024-11-04 13:15:58 -05:00
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
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
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
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
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
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
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
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
Andreas Kling
dff48c9cd2 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

(cherry picked from commit e399b472e9254294f48a057d8848814bdf25b2af)
2024-10-20 16:38:41 -04:00
Sam Atkins
d76b7744fd 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.

(cherry picked from commit fdcece2e88b91b9ec6cf63c3466525fb77540316;
amended to:
* resolve a conflict on height: in getComputedStyle-print-all.txt
* run prettier on CSSGeneratedFiles.md)
2024-10-20 10:29:44 -04:00
Andreas Kling
1b73445f55 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.

(cherry picked from commit ddbfac38b0074819470766846fca08fd78630eb0;
minorly amended for conflicts in AK/Debug.h.in and
Meta/CMake/all_the_debug_macros.cmake due to us having more debug
macros. Also, downstream got alphabetical order for
STYLE_INVALIDATION_DEBUG wrong.)
2024-10-20 01:32:53 -04:00
Aliaksandr Kalenik
57000ba58f LibWeb: Add slots for pseudo-elements animation cache in Animatable
Fixes the bug when animation does not run at all if an element has a
pseudo-element, because both of them use the same cache.

(cherry picked from commit 4049cce40cce31c45e528bbdf301b4e63b8912db)
2024-10-19 20:56:00 -04:00
Sam Atkins
b65ccb4dc6 LibWeb: Introduce color-function-specific style values
Instead of CSSColorValue holding a Gfx::Color, make it an abstract class
with subclasses for each different color function, to match the Typed-OM
spec. This means moving the color calculations from the parsing code to
the `to_color()` method on the style value.

This lets us have calc() inside a color function, instead of having to
fully resolve the color at parse time. The canvas fillStyle tests have
been updated to reflect this.

The other test change is Screenshot/css-color-functions.html: previously
we produced slightly different colors for an alpha of 0.5 and one of
50%, and this incorrect behavior was baked into the test. So now it's
more correct. :^)

(cherry picked from commit 3af6a69f1e13803c64466a9b24b7bd7d75d459df;
amended to:
* resolve a minor conflict in Parser.cpp due to upstream not having
  https://github.com/LadybirdBrowser/ladybird/pull/385#issuecomment-2227130015
* rebaseline canvas-fillstyle-rgb.png since the diff didn't apply due to
  us not having https://github.com/LadybirdBrowser/ladybird/pull/999
* remove css-color-functions-ref.png and instead update
  css-color-functions-ref.html since that file is still a reftest due to us
  not having https://github.com/LadybirdBrowser/ladybird/pull/736
  Makes it much easier to see what actually changed.
)
2024-10-11 10:12:33 -04:00
Sam Atkins
ff37cf75a2 LibWeb: Rename CSSColorValue::create() to create_from_color()
Soon, CSSColorValue will be an abstract class, and we'll instead create
a CSSRGB, CSSHSL, or other specific color type from the Typed-OM spec.
However, it's still useful to have an easy "just give me a style value
for this color" method. So change the name to distinguish this from the
usual StyleValue::create() methods.

(cherry picked from commit 37ea4e3b5f33464a58ee1260fe3ce5fc0699e29a)
2024-10-11 10:12:33 -04:00
Sam Atkins
816e8d99ca LibWeb: Store ShadowStyleValue's color as a StyleValue
Colors can be specified in a way that `Gfx::Color` can't represent, such
as named system colors, `currentColor`, or functions involving `calc()`.

(cherry picked from commit 4e48afd9a7e32cc97fcec5086afc2d2967ec4360)
2024-10-11 10:12:33 -04:00
Sam Atkins
250613d494 LibWeb: Rename ColorStyleValue -> CSSColorValue
This matches the name in the CSS Typed OM spec.
https://drafts.css-houdini.org/css-typed-om-1/#csscolorvalue

This is not (yet) the same as the CSSColorValue, but one step at a time.

(cherry picked from commit 581d00293c184e47015a5d7e9c4230410567db45)
2024-10-11 10:12:33 -04:00
Sam Atkins
4a26c03240 LibWeb: Use CSSKeywordValue for CSS-wide keywords
We previously had 4 single-instance StyleValues for these keywords.
CSS-Typed-OM expects them keywords to be exposed as CSSKeywordValue, so
it's simpler to treat them the same. The single-instance behaviour is
kept by having StyleValue::create() use a cached instance for each of
these.

(cherry picked from commit f518811f73539b5ca6631084001d8f517ea292be)
2024-10-10 10:08:59 -04:00
Sam Atkins
0a3b33e6f6 LibWeb: Rename "identifier" and "ValueID" to "Keyword" where correct
For a long time, we've used two terms, inconsistently:
- "Identifier" is a spec term, but refers to a sequence of alphanumeric
  characters, which may or may not be a keyword. (Keywords are a
  subset of all identifiers.)
- "ValueID" is entirely non-spec, and is directly called a "keyword" in
  the CSS specs.

So to avoid confusion as much as possible, let's align with the spec
terminology. I've attempted to change variable names as well, but
obviously we use Keywords in a lot of places in LibWeb and so I may
have missed some.

One exception is that I've not renamed "valid-identifiers" in
Properties.json... I'd like to combine that and the "valid-types" array
together eventually, so there's no benefit to doing an extra rename
now.

(cherry picked from commit 6a74b0164423d63904cf5a5b594772b595f57600;
very minorly amended to fix conflict in GenerateCSSKeyword.cpp caused
by #22870, and in libweb_generators.cmake due to us not having
https://github.com/LadybirdBrowser/ladybird/pull/741)
2024-10-10 10:08:59 -04:00
Sam Atkins
63e3442b15 LibWeb: Rename IdentifierStyleValue -> CSSKeywordValue
This matches the name in the CSS Typed OM spec.
https://drafts.css-houdini.org/css-typed-om-1/#csskeywordvalue

(cherry picked from commit 9559f0f123fcd1c2fddba625d4bdc4806bb8bd68)
2024-10-10 10:08:59 -04:00
Sam Atkins
a4981ae745 LibWeb: Rename StyleValue -> CSSStyleValue
This matches the name in the CSS Typed OM spec.
https://drafts.css-houdini.org/css-typed-om-1/#cssstylevalue

No behaviour changes.

(cherry picked from commit 0e3487b9ab455a7648185995363bb3b487551d40)
2024-10-10 10:08:59 -04:00
Andreas Kling
d4e86f10ac LibWeb: Don't crash on CSS all: revert
Not every value in a StyleProperties will be non-null by the time we
perform `revert`, so let's make a specialized function for reverting a
property instead of using the path that requires the value to be
non-null.

(cherry picked from commit a10610a1cad56294089fc9457e713eb7083312cd)
2024-09-27 22:18:42 -04:00
Andreas Kling
9348ea160a LibWeb: Use bitmaps for important/inherited bits in StyleProperties
This avoids padding the style value array, shrinking StyleProperties
from 4368 bytes to 2288 bytes per instance.

(cherry picked from commit b42b7c8dd02911504e6947fc2816b85220cdcf9f)
2024-08-13 15:42:19 -04:00
Andreas Kling
225dc0be5a LibWeb: Only remember source CSSStyleDeclaration for animation-name
We were saving to source declarations for *every* property, even though
we only ever looked it up for animation-name.

This patch gets rid of the per-property source pointer and we now keep
a single pointer to the animation-name source only.

This shrinks StyleProperties from 6512 bytes to 4368 bytes per instance.

(cherry picked from commit c288bfb40453d4abe95af694dfc7c2175cd04a14)
2024-08-13 15:42:19 -04:00
Andreas Kling
c2fce0f19c LibWeb: Implement :host and :host(<compound-selector>) selector matching
The :host family of pseudo class selectors select the shadow host
element when matching against a rule from within the element's shadow
tree.

This is a bit convoluted due to the fact that the document-level
StyleComputer keeps track of *all* style rules, and not just the
document-level ones.

In the future, we should refactor style storage so that shadow roots
have their own style scope, and we can simplify a lot of this.

(cherry picked from commit 4c326fc5f6f64797764e7f32a9789b74665f2fec)
2024-07-27 22:53:52 -04:00
Colin Reeder
a745a849cf LibWeb: Add more legacy -webkit- aliases
(cherry picked from commit 5c315b532e4edc561f30dfc492db9b2dcb59d5de)
2024-07-23 21:15:27 -04:00
Sam Atkins
6ab6138fe6 LibWeb/CSS: Make StringStyleValue hold a FlyString
We already have a FlyString of its value from parsing, and most users
also want a FlyString from it, so let's use that instead of converting
backwards and forwards.

The two users that did want a String are:
- Quotes, which make sense as FlyString instead, so I've converted that.
- Animation names, which should probably be FlyString too, but the code
  currently also allows for other kinds of StyleValue, and I don't want
  to dive into this right now to figure out if that's needed or not.

(cherry picked from commit 9fb44cb05777c6d7a8a1950258edadfcee6d4e09)
2024-07-21 14:07:33 -04:00
Colin Reeder
bf0a7667a0 LibWeb: Handle inline-start and inline-end as float values
Should resolve #449 for LTR languages at least

(cherry picked from commit d427344f39581cd7789280949eb6d102b39218a3)
2024-07-14 16:45:48 -04:00
Matthew Olsson
5e4e39d84a LibWeb: Remove TimingFunction in favor of EasingStyleValue::Function
Now that EasingStyleValue is a lot nicer to use, there isn't much reason
to keep TimingFunction around.

(cherry picked from commit 7950992fc21e2428a7f32954bbe893a2b2d58cf7,
manually amended with the output of `git clang-format master`)
2024-06-27 14:49:14 +02:00
Matthew Olsson
e301c1d038 LibWeb: Parse easing values manually
The values aren't that complex, so it doesn't make much sense to have a
dedicated generator for them. Parsing them manually also allows us to
have much more control over the produced values, so as a result of this
change, EasingStyleValue becomes much more ergonomic.

(cherry picked from commit 667e313731f06fabf2a3f75893c3e8f15a4172be,
manually amended with the output of `git clang-format master`)
2024-06-27 14:49:14 +02:00