As it turns out, SkPath already behaves the way we need for SVG and HTML
canvas elements. Less work for us, yay! This removes a 5% item from the
profile when scrolling on https://imdb.com/
Note that there's a tiny screenshot test expectation change due to
minor antialiasing differences when we no longer do our redundant
subpath modifications.
Before this change, PropertyNameIterator (used by for..in) and
`Object::enumerable_own_property_names()` (used by `Object.keys()`,
`Object.values()`, and `Object.entries()`) enumerated an object's own
enumerable properties exactly as the spec prescribes:
- Call `internal_own_property_keys()`, allocating a list of JS::Value
keys.
- For each key, call internal_get_own_property() to obtain a
descriptor and check `[[Enumerable]]`.
While that is required in the general case (e.g. for Proxy objects or
platform/exotic objects that override `[[OwnPropertyKeys]]`), it's
overkill for ordinary JS objects that store their own properties in the
shape table and indexed-properties storage.
This change introduces `for_each_own_property_with_enumerability()`,
which, for objects where
`eligible_for_own_property_enumeration_fast_path()` is `true`, lets us
read the enumerability directly from shape metadata (and from
indexed-properties storage) without a per-property descriptor lookup.
When we cannot avoid `internal_get_own_property()`, we still
benefit by skipping the temporary `Vector<Value>` of keys and avoiding
the unnecessary round-trip between PropertyKey and Value.
We now also more closely follow the spec when computing values for
font-weight and we now:
- Support relative lengths in `calc()`s
- Properly clamp `calc()`s
- Support relative keywords (e.g. lighter, bolder)
- Respect that font-weight can be a non-integer number.
This does expose a few false positives in the font-weight-computed.html
WPT test. This is because we don't recompute non-inherited font-weight
within `recompute_inherited_style` which means that relative keyword
values can fall out of sync with their parent's value. These previously
passed as we treated `bolder` and `lighter` as aliases for `bold` and
`normal` respectively.
There are other places we want to convert font-size into it's computed
form than just when we are loading the font (e.g. computing keyframes).
Gains us 36 WPT passes as we now correctly clamp negative calc values.
We already had IC support in PutById for the following cases:
- Changing an existing own property
- Calling a setter located in the prototype chain
This was enough to speed up code where structurally identical objects
(same shape) are processed in a loop:
```js
const arr = [{ a: 1 }, { a: 2 }, { a: 3 }];
for (let obj of arr) {
obj.a += 1;
}
```
However, creating structurally identical objects in a loop was still
slow:
```js
for (let i = 0; i < 10_000_000; i++) {
const o = {};
o.a = 1;
o.b = 2;
o.c = 3;
}
```
This change addresses that by adding a new IC type that caches both the
source and target shapes, allowing property additions to be fast-pathed
by directly jumping to the shape that already includes the new property.
Global Privacy Control aims to be a replacement for Do Not Track. DNT
ended up not being a great solution, as it wasn't enforced by law. This
actually resulted in the DNT header serving as an extra fingerprinting
data point.
GPC is becoming enforced by law in USA states such as California and
Colorado. CA is further working on a bill which requires that browsers
implement such an opt-out preference signal (OOPS):
https://cppa.ca.gov/announcements/2025/20250911.html
This patch replaces DNT with GPC and hooks up the associated settings.
Previously, we were collapsing whitespace in Layout::TextNode and then
passed the resulting string for further processing through ChunkIterator
-> InlineLevelIterator -> InlineFormattingContext -> LineBuilder ->
LineBoxFragment -> PaintableFragment. Our painting tree is where we deal
with things like range offsets into the underlying text nodes, but since
we modified the original string, the offsets were wrong.
This changes the way we generate fragments:
* Layout::TextNode no longer collapses whitespace as part of its
stored "text for rendering", but moves this logic to ChunkIterator
which splits up this text into separate views whenever whitespace
needs to be collapsed.
* Layout::LineBox now only extends the last fragment if its end offset
is equal to the new fragment's start offset. Otherwise, there's a
gap caused by collapsing whitespace and we need to generate a
separate fragment for that in order to have a correct start offset.
Some tests need new baselines because of the fixed start offsets.
Fixes#566.
This makes it so that view-transition pseudo-element styles are
updated before returning them from window.getComputedStyle(). This
is necessary because they could be outdated, in case JS has
modified the styles of the elements they are trying to stay in sync
with since last frame.
The corresponding WPT test has not been imported, since it still
fails for unrelated reasons.
Allows formulas to update on Google Sheets, which uses a Worker to
update them and makes cookie authenticated requests, which was failing
before this commit.
This has the limitation that it has to proxy through the WebContent
process, but that's how the current infrastructure is, which is outside
the scope of this commit.
This also fixes a bug in the view transitions code that was
required to get the imported test to pass. The code for setting
the initial containing block size just did not set the right thing,
since doing so would trigger an error later on.
That later error resulted from walking up the tree, without
considering that the document element has a parent that is not
itself an element. (and then doing element things to it)
...navigable shared attribute processing steps.
After e095bf3a5fhttps://wpt.live/html/rendering/pixel-length-attributes.html ends up in
this function with null navigable, which leads to crash while executing
steps. Adding early return in case iframe's document doesn't have a
navigable is enough to make the test pass again.
This commit doesn't import the WPT test, because it's already imported
and we have it disabled since it takes too much time on CI.
The spec is a bit awkward here: A few algorithms create an "empty"
SourceSet, and then assign its source-size value a few steps later, so
we have a temporary state with no length. In order to avoid complicating
the types with Optional, I've chosen to just assign it to 0px.
Previously we used `auto`, but `auto` is not a valid value here - it is
used inside the "parse a sizes attribute" algorithm, but that always
returns an actual length (or calc).