Commit graph

420 commits

Author SHA1 Message Date
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
Aliaksandr Kalenik
a9d5a99568 LibGfx+LibWeb: Replace remaining OpenType implementation with Skia
This change should move us forward toward emoji support, as we are no
longer limited by our own OpenType implementation, which was failing
to parse the TrueType Collection format used to store emoji fonts
(at least on macOS).
2024-09-05 19:21:52 +02:00
Aliaksandr Kalenik
db74244fb2 LibWeb: Read header to check if a blob without mime type is WOFF/WOFF2
Currently we rely on parser returning an error if encoded data cannot be
parsed into a valid WOFF or WOFF2 font, which is not going to be true
after switching to Skia that sometimes does not fail even if a data does
not represent a valid font.
2024-09-05 19:21:52 +02:00
Sam Atkins
49b2eb5f51 LibWeb: Add Document::get_style_sheet_source()
This returns the source text of the specified style sheet. StyleComputer
now exposes user agent style sheets so that these can also be requested.
2024-09-03 10:12:07 +01:00
Sam Atkins
8cbc211616 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.
2024-09-03 10:12:07 +01:00
Sam Atkins
c29f4f69ef 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()`.
2024-09-03 10:12:07 +01:00
Sam Atkins
3af6a69f1e 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. :^)
2024-08-21 10:51:48 +01:00
Sam Atkins
37ea4e3b5f 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.
2024-08-21 10:51:48 +01:00
Sam Atkins
4e48afd9a7 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()`.
2024-08-21 10:51:48 +01:00
Sam Atkins
581d00293c 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.
2024-08-21 10:51:48 +01:00
Sam Atkins
f518811f73 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.
2024-08-15 13:58:38 +01:00
Sam Atkins
6a74b01644 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.
2024-08-15 13:58:38 +01:00
Sam Atkins
9559f0f123 LibWeb: Rename IdentifierStyleValue -> CSSKeywordValue
This matches the name in the CSS Typed OM spec.
https://drafts.css-houdini.org/css-typed-om-1/#csskeywordvalue
2024-08-15 13:58:38 +01:00
Sam Atkins
0e3487b9ab 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.
2024-08-15 13:58:38 +01:00
Andreas Kling
a10610a1ca 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.
2024-08-04 11:49:44 +02:00
Andreas Kling
b42b7c8dd0 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.
2024-08-02 20:37:40 +02:00
Andreas Kling
c288bfb404 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.
2024-08-02 20:37:40 +02:00
Aliaksandr Kalenik
4049cce40c 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.
2024-08-02 08:05:31 +02:00
Andreas Kling
4c326fc5f6 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.
2024-07-23 18:03:46 +02:00
Aliaksandr Kalenik
2ead999f2b LibGfx+LibWeb: Remove typeface classes for WOFF fonts
This change removes wrappers inherited from Gfx::Typeface for WOFF and
WOFF2 fonts. The only purpose they served is owning of ttf ByteBuffer
produced by decoding a WOFF/WOFF2 font. Now new FontData class is
responsible for holding ByteBuffer when a font is constructed from
non-externally owned memory.
2024-07-22 15:05:04 +02:00
Sam Atkins
9fb44cb057 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.
2024-07-17 15:08:44 +01:00
Colin Reeder
5c315b532e LibWeb: Add more legacy -webkit- aliases 2024-07-15 15:45:33 +01:00
Aliaksandr Kalenik
c09b5b8df0 LibGfx+LibWeb: Rename Gfx::WOFF2::Font to Gfx::WOFF2::Typeface
It's a leftover from VectorFont -> Typeface renaming
2024-07-13 09:31:02 +02:00
Aliaksandr Kalenik
1d2e559e13 LibGfx+LibWeb: Rename Gfx::WOFF::Font to Gfx::WOFF::Typeface
It's a leftover from VectorFont -> Typeface renaming
2024-07-13 09:31:02 +02:00
Aliaksandr Kalenik
2f515827c0 Everywhere: Rename Gfx::OpenType::Font to Gfx::OpenType::Typeface
It's a leftover from VectorFont -> Typeface renaming
2024-07-13 09:31:02 +02:00
Colin Reeder
d427344f39 LibWeb: Handle inline-start and inline-end as float values
Should resolve #449 for LTR languages at least
2024-07-10 17:41:18 +02:00
Aliaksandr Kalenik
d5926a3231 LibGfx+LibWeb: Rename Gfx::VectorFont to Gfx::Typeface
Typeface is a more widely used name for the data represented by
class previously named VectorFont.

Now:
- Typeface represents decoded font that is not ready for rendering
- ScaledFont represents the combination of typeface and size for
  rendering
2024-06-30 13:09:23 +02:00
Aliaksandr Kalenik
e2726ce8e4 LibGfx+LibWeb: Remove Gfx::Typeface
...and use VectorFont directly in FontDatabase.
2024-06-30 13:09:23 +02:00
Matthew Olsson
7950992fc2 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.
2024-06-16 07:12:46 +02:00
Matthew Olsson
667e313731 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.
2024-06-16 07:12:46 +02:00
Andreas Kling
7f2c833a39 LibWeb: Implement CSSKeyframesRule.cssRuleList
To make this straightforward, CSSKeyframesRule now uses a CSSRuleList
for internal storage.
2024-06-14 20:45:37 +02:00
Andreas Kling
04a6e2f83d LibWeb: Remove Gfx::BitmapFont
This class supported the binary bitmap font file format in SerenityOS,
and isn't something we need in Ladybird.
2024-06-04 18:45:30 +02:00
Andreas Kling
fac126bce9 Ladybird+LibWeb: Stop using Gfx::FontDatabase default fonts
This closes the window at WebContent process startup where we were
relying on Gfx::FontDatabase having some resolvable value in its default
font query.
2024-06-04 18:45:30 +02:00
Matthew Olsson
e2cb25e35c LibWeb: Support interpolation of mixed percentage dimension units 2024-06-02 15:12:17 +02:00
Matthew Olsson
a8ef84f8c3 LibWeb: Use LengthPercentage for calc values in Transformation matrix 2024-05-25 22:19:47 +02:00
Andrew Kaster
b7526a39b0 LibWeb: Expose StyleComputer's FontLoader class publicly
We'll want to explicitly load fonts from FontFace and other Web APIs
in the future. A future refactor should also move this completely away
from StyleComputer and call it something like 'FontCache'.
2024-05-16 08:02:43 +02:00
Timothy Flynn
464d7d5858 LibGfx+LibWeb: Allow inexact size lookups when requesting scaled fonts
For bitmap fonts, we will often not have an exact match for requested
sizes. Return the closest match instead of a nullptr.

LibWeb is currently the only user of this API. If it needs to be
configurable in the future to only allow exact matches, we can add a
parameter or another method at that time.
2024-05-06 23:26:42 +00:00
Andreas Kling
037b395b5d LibWeb: Try to parse WOFF and WOFF2 even if MIME type says otherwise
As it turns out, websites can lie about this, and it doesn't really cost
us much to try decoding as other formats before giving up.
2024-04-15 10:01:05 +02:00
Timothy Flynn
4b1abcf61d LibWeb: Generalize support for dimension attributes
Rather than each element which supports dimension attributes needing to
implement parsing the attributes and setting the appropriate style, we
can generalize this functionality. This will also make each element more
closely resemble the spec text, as we will be effectively declaring, for
example, "The img element supports dimension attributes" in code.
2024-04-11 18:41:57 +02:00
Andreas Kling
c0ea8825b5 LibWeb: Always log debug message about failure to parse CSS fonts
It's always good to know when and why a CSS font fails to parse,
so that we can file issues about missing functionality.
2024-04-07 19:15:23 +02:00
Shannon Booth
18520561e7 LibWeb: Fix crash for calculated transition duration/delays
As the parser was trying to directly unwrap an unresolved duration.
Currently we are outputting the wrong results for the serialized
duration, but this is still a step forwards.

Fixes a crash seen on: https://evaparish.com/blog/how-i-edit
2024-04-06 19:35:27 +01:00
Andreas Kling
906c69c6d1 LibWeb: Don't fall apart on transition: none in CSS
Fixes a crash when loading https://soundcloud.com/
2024-03-30 07:34:02 +01:00
Matthew Olsson
3160733c1a LibWeb: Expand transition longhand values 2024-03-29 21:58:12 +01:00
Matthew Olsson
e4dba9d932 LibWeb: Cache the last CSS play-state value on KeyframeEffect
This way we can just leave it alone if the property hasn't changed.
Notably, if the play-state property has been set to 'paused', and then
the user gets the animation with JS and calls .play() on it, it should
start playing despite the play-state property value.
2024-03-27 09:40:05 -06:00
Matthew Olsson
cf54ba01ac LibWeb: Be more strict about invoking .play() on element animations
We don't want to always invoke the .play() method if an animation is
relevant and had a play state of running, as the play state is
essentially just "paused" or "not paused". We replace that relevancy
check with the inverse of the pause check so we don't constantly call
.play() on animations that are finished.

Also duplicates and moves the temporary context into both blocks, since
most of the time neither condition will be true.
2024-03-26 05:47:09 +01:00
Matthew Olsson
e2dfef90fb LibWeb: Remove useless animation relevancy check
This is already done in Animatable::get_animations()
2024-03-26 05:47:09 +01:00
Andreas Kling
afe6abfc09 LibWeb: Use an ancestor filter to quickly reject many CSS selectors
Given a selector like `.foo .bar #baz`, we know that elements with
the class names `foo` and `bar` must be present in the ancestor chain of
the candidate element, or the selector cannot match.

By keeping track of the current ancestor chain during style computation,
and which strings are used in tag names and attribute names, we can do
a quick check before evaluating the selector itself, to see if all the
required ancestors are present.

The way this works:

1. CSS::Selector now has a cache of up to 8 strings that must be present
   in the ancestor chain of a matching element. Note that we actually
   store string *hashes*, not the strings themselves.

2. When Document performs a recursive style update, we now push and pop
   elements to the ancestor chain stack as they are entered and exited.

3. When entering/exiting an ancestor, StyleComputer collects all the
   relevant string hashes from that ancestor element and updates a
   counting bloom filter.

4. Before evaluating a selector, we first check if any of the hashes
   required by the selector are definitely missing from the ancestor
   filter. If so, it cannot be a match, and we reject it immediately.

5. Otherwise, we carry on and evaluate the selector as usual.

I originally tried doing this with a HashMap, but we ended up losing
a huge chunk of the time saved to HashMap instead. As it turns out,
a simple counting bloom filter is way better at handling this.
The cost is a flat 8KB per StyleComputer, and since it's a bloom filter,
false positives are a thing.

This is extremely efficient, and allows us to quickly reject the
majority of selectors on many huge websites.

Some example rejection rates:
- https://amazon.com: 77%
- https://github.com/SerenityOS/serenity: 61%
- https://nytimes.com: 57%
- https://store.steampowered.com: 55%
- https://en.wikipedia.org: 45%
- https://youtube.com: 32%
- https://shopify.com: 25%

This also yields a chunky 37% speedup on StyleBench. :^)
2024-03-22 18:27:32 +01:00
Matthew Olsson
3dd9f2715f LibWeb: Resolve unresolved style values when animating properties 2024-03-20 09:17:33 +01:00
Matthew Olsson
b2fb9cc7d3 LibWeb: Allow ignoring unresolved style values when iterating properties
When iterating through a @keyframes rule, it isn't possible to resolve
unresolved style properties since there are no elements. This change
allows those properties to simply pass through this helper function.
2024-03-20 09:17:33 +01:00
Matthew Olsson
1f53727a3f LibWeb: Remove Badge from CSS::Parser::resolve_unresolved_style_value
KeyframeEffect needs to use this method to resolve unresolved properties
in the same way that StyleComputer does.
2024-03-20 09:17:33 +01:00