Commit graph

2171 commits

Author SHA1 Message Date
Sam Atkins
59c79e848c LibWeb: Parse dimension values using TokenStream 2024-04-22 06:47:05 +02:00
Sam Atkins
efce563abd LibWeb: Parse identifier values using TokenStream 2024-04-22 06:47:05 +02:00
Sam Atkins
e8115d6a56 LibWeb: Parse transform values using the existing comma-parsing code
Also add a spec link and grammar comment.
2024-04-22 06:47:05 +02:00
Sam Atkins
e4e048f278 LibWeb: Parse color values using TokenStream 2024-04-22 06:47:05 +02:00
Sam Atkins
710e5c24d3 LibWeb: Parse string values using TokenStream 2024-04-22 06:47:05 +02:00
Sam Atkins
e42f052b00 LibWeb: Parse rect() values using TokenStream 2024-04-22 06:47:05 +02:00
Sam Atkins
e00f41a274 LibWeb: Parse URL values using TokenStream 2024-04-22 06:47:05 +02:00
Sam Atkins
cfa221944c LibWeb: Parse image values using TokenStream 2024-04-22 06:47:05 +02:00
Sam Atkins
384b18b271 LibWeb: Make parse_color_stop_list() a CSS Parser method
This lets us remove the color/dimension-parsing lambdas, since these
always forwarded to the same methods. This will make it easier to later
convert those methods to take a TokenStream.
2024-04-22 06:47:05 +02:00
Andreas Kling
819f2c1df6 LibWeb: Don't redundantly re-sort StyleSheetList on sheet removal
The list is already kept sorted. Removing one sheet anywhere from the
list will not make it unsorted.
2024-04-21 19:32:49 +02:00
PGHales
ded344aa2c LibWeb/DOM: Rename link_color to normal_link_color 2024-04-19 10:58:45 +02:00
Timothy Flynn
bf1c82724f LibWeb: Default to an empty string when a string attr substitution fails
When a string-type attr() substitution produces no value and no fallback
had been specified, the spec mandates we default to the empty string.
2024-04-17 07:13:26 +02:00
Tim Ledbetter
25f8c26624 LibWeb: Flesh out StyleSheetList::add_a_css_style_sheet() steps
This is required to support loading alternative style sheets.
2024-04-17 07:12:44 +02:00
Tim Ledbetter
d5cddd4696 LibWeb: Unset stylesheet properties when removing from a StyleSheetList
Previously, the parent CSS stylesheet, owner node and owner CSS rule
properties were not unset when removing a sheet from a StyleSheetList.

This change moves the methods for adding and removing sheets to and
from a StyleSheetList, directly into the StyleSheetList class and
ensures they are called as required by the CSSOM specification.
2024-04-16 07:41:33 +02:00
Andreas Kling
53d0dd4a2e LibJS+LibWeb: Use new Cell::Visitor helpers to avoid manual iteration 2024-04-16 07:40:01 +02:00
Tim Ledbetter
99b2eff988 LibWeb: Invalidate style when CSSStyleRule selectorText changes
Previously, any change to the selectorText of a CSSStyleRule was not
reflected in the document style.
2024-04-15 22:12:49 +02: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
Matthew Olsson
31341b280a LibWeb: Add calls to JS_{DECLARE,DEFINE}_ALLOCATOR() 2024-04-09 09:13:06 +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
Matthew Olsson
8450041b52 LibWeb: Fix some GCVerifier warnings 2024-04-07 07:03:13 +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
b2a099e647 LibWeb: Don't leak entire realm after parsing CSS @supports rule
Before this change, every CSS @supports rule would keep the containing
JS realm alive via a JS::Handle. This led to a GC reference cycle and
the whole realm leaked.

Since we only need the realm at construction time, we can take it as a
parameter instead, and stop storing it.
2024-04-05 08:14:19 +02:00
Shannon Booth
ccebc7a905 LibWeb: Add stubs for the Screen Orientation API
As defined in: https://w3c.github.io/screen-orientation
2024-04-03 10:09:58 +01:00
Matthew Olsson
87155c7b1d LibWeb: Fix infinite loop in CSS::Parser::parse_transition_value() 2024-03-30 07:34:25 +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
MacDue
03f957dc79 LibWeb: Add the clip-path property and resolve it for SVG elements 2024-03-29 21:59:56 +01:00
Matthew Olsson
3160733c1a LibWeb: Expand transition longhand values 2024-03-29 21:58:12 +01:00
Matthew Olsson
1e6ad075f3 LibWeb: Add transition properties to Properties.json 2024-03-29 21:58:12 +01:00
Matthew Olsson
5dce559ed8 LibWeb: Parse transition style values 2024-03-29 21:58:12 +01:00
Matthew Olsson
911088278d LibWeb: Add the CSSTransition IDL object 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
8d7a1e5654 LibWeb: Skip some redundant UTF-8 validation in CSS tokenizer
If we're just adding code points to a StringBuilder, there's no need to
revalidate the result.
2024-03-24 13:28:24 +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
Timothy Flynn
6e2685f091 LibWeb: Remove FLATTEN attribute from SelectorEngine::fast_matches
This causes compilation time with GCC to increase far too much.
2024-03-20 10:33:16 -04: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
Matthew Olsson
ebfc6c33a6 LibWeb: Remove "resolved" from the name of Keyframe's property map
These will need to store unresolved styles as well, since they may be
built during parsing of a @keyframes rule. In that case there is no
target element or pseudo-element, and thus the value cannot be resolved.
2024-03-20 09:17:33 +01:00
Andreas Kling
f58ca99a66 LibWeb: Parse the ::backdrop pseudo element
We don't do anything with this yet, but let's at least not reject
selectors with ::backdrop in the parser.
2024-03-19 20:59:41 +01:00
Aliaksandr Kalenik
cf7c933312 LibWeb: Add fast path to calculate invalidations for animated css props
- Compare only the animated properties
- Clone only the hash map containing animated properties, instead of
  the entire StyleProperties.

Reduces `KeyframeEffect::update_style_properties()` from 10% to 3% in
GitHub profiles.
2024-03-19 17:30:34 +01:00
Andreas Kling
ce2bfb4a12 LibWeb: Make CSSStyleRule::declaration() return a more specific type
This removes the need for some hot verify_casts in StyleComputer.
2024-03-19 16:48:22 +01:00
Andreas Kling
7c9368f402 LibWeb: Support most simple pseudo classes in the fast selector matcher
Non-recursive pseudo classes are easy to evaluate, so let's allow them
on the fast path.

Increases fast path coverage when loading our GitHub repo from 48% to
56% of all selectors evaluated.
2024-03-19 16:48:22 +01:00
Andreas Kling
3c3e591f03 LibWeb: Add a fast (iterative) selector matcher for trivial selectors
If we determine that a selector is simple enough, we now run it using a
special matching loop that traverses up the DOM ancestor chain without
recursion.

The criteria for this fast path are:

- All combinators involved must be either descendant or child.
- Only tag name, class, ID and attribute selectors allowed.

It's definitely possible to increase the coverage of this fast path,
but this first version already provides a substantial reduction in time
spent evaluating selectors.

48% of the selectors evaluated when loading our GitHub repo are now
using this fast path.

18% speed-up on the "Descendant and child combinators" subtest of
StyleBench. :^)
2024-03-19 16:48:22 +01:00
Andreas Kling
432536f0b3 LibWeb: Make SelectorEngine::matches_namespace() a standalone function
This will allow me to reuse it in the next commit.
2024-03-19 16:48:22 +01:00
Andreas Kling
08a956f544 LibWeb: Ignore all pseudo element rules when matching non-pseudo element 2024-03-19 09:44:25 +01:00
Andreas Kling
4679dbc9df LibWeb: Make Element::inline_style() return specific declaration type
This removes a bunch of RTTI checks in StyleComputer.
2024-03-19 09:44:25 +01:00
Andreas Kling
25c22bb5e5 LibWeb: Reorder MatchingRule members to make it smaller
By packing the members more efficiently, it goes from 64 to 56 bytes.
2024-03-19 09:44:25 +01:00