1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-10 01:51:03 +09:00
Commit graph

349 commits

Author SHA1 Message Date
Sam Atkins
c3d61020e7 LibWeb/CSS: Make CalculationNodes ref-counted
Calc simplification (which I'm working towards) involves repeatedly
deriving a new calculation tree from an existing one, and in many
cases, either the whole result or a portion of it will be identical to
that of the original. Using RefPtr lets us avoid making unnecessary
copies. As a bonus it will also make it easier to return either `this`
or a new node.

In future we could also cache commonly-used nodes, similar to how we do
so for 1px and 0px LengthStyleValues and various keywords.
2025-01-30 19:31:54 +01:00
Sam Atkins
385c3d273a LibWeb/CSS: Update CalculatedOr API to use CalculationResolutionContext
To be properly compatible with calc(), the resolved() methods all need:
- A length resolution context
- To return an Optional, as the calculation might not be resolvable

A bonus of this is that we can get rid of the overloads of `resolved()`
as they now all behave the same way.

A downside is a scattering of `value_or()` wherever these are used. It
might be the case that all unresolvable calculations have been rejected
before this point, but I'm not confident, and so I'll leave it like
this for now.
2025-01-30 19:31:54 +01:00
Sam Atkins
1d71662f31 LibWeb/CSS: Wrap calc()-resolution data in a struct
Initially I added this to the existing CalculationContext, but in
reality, we have some data at parse-time and different data at
resolve-time, so it made more sense to keep those separate.

Instead of needing a variety of methods for resolving a Foo, depending
on whether we have a Layout::Node available, or a percentage basis, or
a length resolution context... put those in a
CalculationResolutionContext, and just pass that one thing to these
methods. This also removes the need for separate resolve_*_percentage()
methods, because we can just pass the percentage basis in to the regular
resolve_foo() method.

This also corrects the issue that *any* calculation may need to resolve
lengths, but we previously only passed a length resolution context to
specific types in some situations. Now, they can all have one available,
though it's up to the caller to provide it.
2025-01-30 19:31:54 +01:00
Sam Atkins
8877a4f691 LibWeb/CSS: Hide "No property (from N properties) matched foo" message
This greatly reduces the amount of log spam on certain websites.
2025-01-29 12:04:14 +00:00
Aliaksandr Kalenik
d762d16938 LibWeb: Use invalidation sets for :has() invalidation
Prior to this change, we invalidated all elements in the document if it
used any selectors with :has(). This change aims to improve that by
applying a combination of techniques:
- Collect metadata for each element if it was matched against a selector
  with :has() in the subject position. This is needed to invalidate all
  elements that could be affected by selectors like `div:has(.a:empty)`
  because they are not covered by the invalidation sets.
- Use invalidation sets to invalidate elements that are affected by
  selectors with :has() in a non-subject position.

Selectors like `.a:has(.b) + .c` still cause whole-document invalidation
because invalidation sets cover only descendants, not siblings. As a
result, there is no performance improvement on github.com due to this
limitation. However, youtube.com and discord.com benefit from this
change.
2025-01-29 09:30:18 +01:00
Aliaksandr Kalenik
74dc335b28 LibWeb: Allow to early break from InvalidationSet::for_each_property() 2025-01-29 09:30:18 +01:00
Aliaksandr Kalenik
db47fa3db1 LibWeb: Use ancestor filters for hover style invalidation
By using ancestor filters some selectors could be early rejected
skipping selector engine invocation. According to my measurements it's
30-80% hover selectors depending on the website.
2025-01-28 18:55:42 +01:00
Aliaksandr Kalenik
d79bb1aac2 LibWeb: Fix underinvalidation when inline style has custom properties
We have an optimization that allows us to invalidate only the style of
the element itself and mark descendants for inherited properties update
when the "style" attribute changes (unless there are any CSS rules that
use the "style" attribute, then we also invalidate all descendants that
might be affected by those rules). This optimization was not taking into
account that when the inline style has custom properties, we also need
to invalidate all descendants whose style might be affected by them.

This change fixes this bug by saving a flag in Element that indicates
whether its style depends on any custom properties and then invalidating
all descendants with this flag set when the "style" attribute changes.
Unlike font relative lengths invalidation, for elements that depend on
custom properties, we need to actually recompute the style, instead of
individual properties, because values without expanded custom properties
are gone after cascading, and it has to be done again.

The test added for this change is a version of an existing test we had
restructured such that it doesn't trigger aggressive style invalidation
caused by DOM structured changes until the last moment when test results
are printed.
2025-01-28 11:38:06 +00:00
Psychpsyo
67ed676831 LibWeb: Implement CSS 'contain' property 2025-01-28 11:24:40 +00:00
Andreas Kling
c53c781745 LibWeb: Inline CSSStyleValue::to_keyword()
Shaves 120 ms of loading time off of https://wpt.fyi/
2025-01-28 01:12:45 +01:00
Andreas Kling
30cbd4bcfb LibWeb: Avoid unnecessary copies in BorderRadiusStyleValue::absolutize()
Shaves 30ms off of the load time on https://wpt.fyi/
2025-01-28 01:12:45 +01:00
Andreas Kling
b5e70908aa LibWeb: Segregate StyleComputer rule caches per Document-or-ShadowRoot
This means we only need to consider rules from the document and the
current shadow root, instead of the document and *every* shadow root.

Dramatically reduces the amount of rules processed on many pages.

Shaves 2.5 seconds of load time off of https://wpt.fyi/ :^)
2025-01-28 01:12:45 +01:00
Shannon Booth
22a7cd9700 LibWeb: Port Document encoding_parse_url and parse_url to Optional<URL>
This ports two more APIs away from URL::is_valid.
2025-01-27 00:03:07 +00:00
Andreas Kling
a87ae785fd LibWeb: Cache style sheet's default namespace in MatchingRule
This avoids looking up the default namespace rule for every rule we
consider running.

Shaves ~900ms of loading time off of https://wpt.fyi/
2025-01-26 15:07:23 +01:00
Andreas Kling
801b3f434f LibWeb: Avoid calling Element::is_shadow_host() for each CSS rule
Instead just cache the element's shadow root locally, if any. This
shaves ~1 second off the loading time of https://wpt.fyi/
2025-01-26 15:07:23 +01:00
Andreas Kling
e03aedbdf0 LibWeb: Add direct pointer to CSS::Selector in MatchingRule struct
This avoids looking up the selector by index repeatedly, giving us a
~400ms reduction in load time on https://wpt.fyi/
2025-01-26 15:07:23 +01:00
Aliaksandr Kalenik
aaff6f98b1 LibWeb: Fix collection of pseudo class names used in :has()
Before this change we were saving all pseudo class names as used in
:has() regardless of whether they are nested inside :has() or not.
2025-01-26 00:52:38 +01:00
Aliaksandr Kalenik
d5a82040e3 LibWeb: Fix underinvalidation of :nth-child using invalidation sets
For all invalidation properties nested into nth-child argument list we
need to invalidate whole subtree to make sure style of sibling elements
will be recalculated.
2025-01-25 10:16:21 +01:00
Andreas Kling
055f07d742 LibWeb: Avoid copying large MatchingRule objects inside StyleComputer
Instead of creating and passing around Vector<MatchingRule> inside
StyleComputer (internally, not exposed in API), we now use vectors
of pointers/references instead.

Note that we use pointers in case we want to quick_sort() the vectors.

Knocks 4 seconds of loading time off of https://wpt.fyi/
2025-01-24 17:54:34 +01:00
Andreas Kling
4bef0d0aea LibWeb: Don't rebuild rule cache so eagerly to check for :has/:defined
Instead, change the APIs from "has :foo" to "may have :foo" and return
true if we don't have a valid rule cache at the moment.

This allows us to defer the rebuilding of the rule cache until a later
time, for the cost of a wider invalidation at the moment.

Do note that if our rule cache is invalid, the whole document has
invalid style anyway! So this is actually always less work. :^)

Knocks ~1 second of loading time off of https://wpt.fyi/
2025-01-24 17:54:34 +01:00
Andreas Kling
3b3f06ca68 LibWeb: Add per-layer rule caches in StyleComputer
This allows us to filter by layer *once* instead of doing it for every
rule that runs.

Knocks ~2 seconds of loading time off of https://wpt.fyi/
2025-01-24 17:54:34 +01:00
Sam Atkins
e65ca3a7d2 LibWeb/CSS: Add Length::make_px(double) overload
Saves us a round-trip to CSSPixels and back when we already have a
double value.
2025-01-24 13:55:52 +01:00
Sam Atkins
38b037990b LibWeb/CSS: Remove Flex as a percentage basis
`<flex-percentage>` is not a thing.
2025-01-24 13:55:52 +01:00
Sam Atkins
8d3e1b07cd LibWeb/CSS: Remove now-empty PercentageOr.cpp
All the code here was removed in commit
c282138fd0
2025-01-24 13:55:52 +01:00
Sam Atkins
0321d1392c LibWeb/CSS: Leave calc() in transformations unresolved for longer
We don't need to resolve these at this point, and we already don't do so
for lengths, so leave them in their calc() form until they're used.
2025-01-24 13:55:52 +01:00
Sam Atkins
db2e879839 LibWeb/CSS: Remove unused CalculationNode::Type::Unparsed
I missed this in 6969d1eba3
2025-01-24 13:55:52 +01:00
Timothy Flynn
85b424464a AK+Everywhere: Rename verify_cast to as
Follow-up to fc20e61e72.
2025-01-21 11:34:06 -05:00
Aliaksandr Kalenik
3b81d9d91d LibWeb: Delete "names used in attribute selectors" from SelectorInsights
These are no longer needed because it's possible to tell if attribute
name is used in any selector by using invalidation sets.
2025-01-20 18:23:34 +01:00
Aliaksandr Kalenik
34bf833a0a LibWeb: Expand invalidation sets usage to any attribute change
Before this change invalidation sets were only used for "class" and "id"
attribute changes.
2025-01-19 19:54:38 +01:00
Aliaksandr Kalenik
c5f2a88f69 LibWeb: Use invalidation sets to reduce style recalculation
Implements idea described in
https://docs.google.com/document/d/1vEW86DaeVs4uQzNFI5R-_xS9TcS1Cs_EUsHRSgCHGu8

Invalidation sets are used to reduce the number of elements marked for
style recalculation by collecting metadata from style rules about the
dependencies between properties that could affect an element’s style.

Currently, this optimization is only applied to style invalidation
triggered by class list mutations on an element.
2025-01-19 19:54:38 +01:00
Sam Atkins
b3b9eea986 LibWeb/CSS: Merge RotationStyleValue into TransformationStyleValue
Same again, although rotation is more complicated: `rotate`
is "equivalent to" multiple different transform function depending on
its arguments. So we can parse as one of those instead of the full
`rotate3d()`, but then need to handle this when serializing.
2025-01-17 10:12:39 +01:00
Sam Atkins
03a4ecce19 LibWeb/CSS: Merge TranslationStyleValue into TransformationStyleValue
As with ScaleStyleValue, the serialization is the only unique part of
this class, and we can just move it over.
2025-01-17 10:12:39 +01:00
Sam Atkins
ac15e626dd LibWeb/CSS: Merge ScaleStyleValue into TransformationStyleValue
The only ways this varies from the `scale()` function is with parsing
and serialization. Parsing stays separate, and serialization is done by
telling `TransformationStyleValue` which property it is, and overriding
its normal `to_string()` code for properties other than `transform`.
2025-01-17 10:12:39 +01:00
Sam Atkins
bd5d1b092a LibWeb/CSS: Move TransformationSV -> Transformation code into TSV 2025-01-17 10:12:39 +01:00
Sam Atkins
01d782a5ca LibWeb/CSS: Return TransformationStyleValue values by reference
Avoid copying the vector when we read from it.
2025-01-17 10:12:39 +01:00
Sam Atkins
18e0ff6537 LibWeb/CSS: Properly classify calculations inside transform functions
Assuming all calculations produce `<length-percentage>` is a very bad
assumption, and was causing crashes on https://ai.cloudflare.com/
2025-01-15 14:29:08 +00:00
Aliaksandr Kalenik
98691810b1 LibWeb: Fix insert/delete rule invalidation for adopted style sheets
Invalidation for adopted style sheets was broken because we had an
assumption that "active" style sheet is always attached to
StyleSheetList which is not true for adopted style sheets. This change
addresses that by keeping track of all documents/shadow roots that own
a style sheet and notifying them about invalidation instead of going
through the StyleSheetList.
2025-01-13 23:03:07 +01:00
Psychpsyo
bb5d1ac4a3 LibWeb: Fix CSS tag seletor case sensitivity for SVG elements
They can appear in HTML documents but must not be matched
according to the HTML spec.
2025-01-13 12:11:34 +00:00
Psychpsyo
7757df5bb5 LibWeb: Implement CSS 'isolation' property 2025-01-13 11:07:55 +00:00
Sam Atkins
4e1aa96dce LibWeb/CSS: Use CalcSV's context to determine what percentages are
This lets us implement the `matches_number()` and `matches_dimension()`
methods of `CSSNumericType` to spec, instead of being an ad-hoc hack.
2025-01-13 10:59:16 +00:00
Sam Atkins
6f60c258ce LibWeb/CSS: Mark transform property as resolving percentages as lengths 2025-01-13 10:59:16 +00:00
Sam Atkins
a40dbd080d LibWeb/CSS: Remove CSSNumericType::matches_resolution_percentage()
This isn't a spec type.
2025-01-13 10:59:16 +00:00
Sam Atkins
4efdb76857 LibWeb/CSS: Give calc() a CalculationContext for resolving percentages
This is passed in at construction, meaning we will be able to refer to
it later, when we're no longer inside the Parser.
2025-01-13 10:59:16 +00:00
Sam Atkins
bc00ef8314 LibWeb/CSS: Replace Parser "current property" with a stack of contexts
`current_property_id()` is insufficient to determine if a quirk is
allowed. For example, unitless lengths are allowed in certain
properties, but NOT if they are inside a calc() or other function. It's
also incorrect when we are parsing a longhand inside a shorthand. So
instead, replace that with a stack of value-parsing contexts. For now,
this is either properties or CSS functions, but in future can be
expanded to include media features and other places.

This lets us disallow quirks inside functions, like we're supposed to.

It also lays the groundwork for being able to more easily determine
what type a percentage inside a calculation should become, as this is
based on the same stack of contexts.
2025-01-13 10:59:16 +00:00
Shannon Booth
5bed8f4055 LibURL+LibWeb: Make URL::basic_parse return an Optional<URL>
URL::basic_parse has a subtle bug where the resulting URL is not set
to valid when StateOveride is provided and the URL parser early returns
a valid URL.

This has not surfaced as a problem so far, as the only users of the
state override API provide an already valid URL buffer and also ignore
the result of basic parsing with a state override.

However, this bug surfaces implementing the URL pattern spec, which as
part of URL canonicalization:
 * Provides a dummy URL record
 * Basic URL parses that URL with state override
 * Checks the result of the URL parser to validate the URL

While we could set URL validity on every early return of the URL parser
during state override, it has been a long standing FIXME around the code
to try and remove the awkward validity state of the URL class. So this
commit makes the first stage of this change by migrating the basic
parser API to return Optional, which also happens to make this subtle
issue not a problem any more.
2025-01-11 10:08:29 -05:00
Jelle Raaijmakers
2b6a14c5ee LibWeb: Implement "preserves overrides" property of editing commands 2025-01-10 23:33:35 +01:00
Psychpsyo
9370990ff2 LibWeb: Implement user-select
This implements all values of user-select.
2025-01-08 14:37:28 +00:00
Sam Atkins
ba43dfe49a LibWeb/CSS: Remove use of Dimension in calc() parsing
Rather than partly-converting number, dimension, and ident tokens at the
start of parsing a calculation, and then later finishing it off, we can
just do the whole step in convert_to_calculation_node(). This is a
little less code, but mainly means we are left with only a single use
of the Dimension type in the codebase, so that can be removed soon.
2025-01-08 14:28:54 +00:00
Sam Atkins
5cda2ac961 LibWeb/CSS: Remove illegal <number-percentage> type
Various places in the spec allow for `<number> | <percentage>`, but this
is either/or, and they are not allowed to be combined like dimensions
and percentages are. (For example, `calc(12 + 50%)` is never valid.)

User code generally doesn't need to care about this distinction, but it
does now need to check if a calculation resolves to a number, or to a
percentage, instead of a single call.

The existing parse_number_percentage[_value]() methods have been kept
for simplicity, but updated to check for number/percentage separately.
2025-01-08 14:28:54 +00:00
Sam Atkins
ab5ac82db6 LibWeb/CSS: Parse dimension and number types individually
An upcoming change requires that we can determine which property we are
parsing before we parse the value. That's the opposite of what this
code previously did, which was to parse a generic dimension or calc()
and then figure out what property would accept it.
2025-01-08 14:28:54 +00:00