Commit graph

5570 commits

Author SHA1 Message Date
Timothy Flynn
d40e3af697 AK: Implement UTF-16 string-to-number conversions 2025-07-18 12:45:38 -04:00
Timothy Flynn
6e0290ecaa AK: Define some UTF-16 helper methods
* contains
* escape_html_entities
* replace
* to_ascii_lowercase
* to_ascii_uppercase
* to_ascii_titlecase
* trim
* trim_whitespace
2025-07-18 12:45:38 -04:00
Timothy Flynn
7f069efbc4 AK: Implement a flyweight string for Utf16String
Utf16FlyString more or less works exactly the same as FlyString. It will
store the raw encoded data of the string instance. If the string is a
short ASCII string, Utf16FlyString holds the ShortString bytes; else,
Utf16FlyString holds a pointer to the Utf16StringData.
2025-07-18 12:45:38 -04:00
Timothy Flynn
2803d66d87 AK: Support UTF-16 string formatting
The underlying storage used during string formatting is StringBuilder.
To support UTF-16 strings, this patch allows callers to specify a mode
during StringBuilder construction. The default mode is UTF-8, for which
StringBuilder remains unchanged.

In UTF-16 mode, we treat the StringBuilder's internal ByteBuffer as a
series of u16 code units. Appending a single character will append 2
bytes for that character (cast to a char16_t). Appending a StringView
will transcode the string to UTF-16.

Utf16String also gains the same memory optimization that we added for
String, where we hand-off the underlying buffer to Utf16String to avoid
having to re-allocate.

In the future, we may want to further optimize for ASCII strings. For
example, we could defer committing to the u16-esque storage until we
see a non-ASCII code point.
2025-07-18 12:45:38 -04:00
Timothy Flynn
fe676585f5 AK: Add a UTF-16 string with optimized short- and ASCII-string storage
This is a strictly UTF-16 string with some optimizations for ASCII.

* If created from a short UTF-8 or UTF-16 string that is also ASCII,
  then the string is stored in an inlined byte buffer.

* If created with a long UTF-8 or UTF-16 string that is also ASCII,
  then the string is stored in an outlined char buffer.

* If created with a short or long UTF-8 or UTF-16 string that is not
  ASCII, then the string is stored in an outlined char16 buffer.

We do not store short non-ASCII text in the inlined buffer to avoid
confusion with operations such as `length_in_code_units` and
`code_unit_at`. For example, "😀" would be stored as 4 UTF-8 bytes
in short string form. But we still want `length_in_code_units` to
be 2, and `code_unit_at(0)` to be 0xD83D.
2025-07-18 12:45:38 -04:00
Timothy Flynn
8fbb80fffc AK: Do not fall back to simdutf for UTF-16 ASCII validation
This was a mistake. Consider U+201C (LEFT DOUBLE QUOTATION MARK). This
code point is encoded as the bytes 0x1c 0x20 in UTF-16LE. Both of these
bytes are ASCII if interpreted as UTF-8. But the string itself is most
certainly not ASCII.
2025-07-18 12:45:38 -04:00
Callum Law
4ee8110449 LibWeb: Handle flood-opacity in line with other opacity properties
We now do the proper thing in terms of:
 - Allowing percentages
 - Returning the computed value in getComputedStyle
 - Handling values out of the [0,1] range

Gains us 13 WPT passes in the imported tests.
2025-07-18 11:04:55 -04:00
Jelle Raaijmakers
8dd259b8d8 LibWeb: Stub CSSCounterStyleRule
Just the interface. Adds 6 new WPT subtest passes.
2025-07-18 11:51:41 +01:00
norbiros
7ad01d28a8 LibWeb/CSS: Add basic registered properties with initial values
Add global registry for registered properties and partial support
for `@property` rule. Enables registering properties with initial
values. Also adds basic retrieval via `var()`.

Note: This is not a complete `@property` implementation.
2025-07-18 11:12:39 +01:00
Sam Atkins
0ff61e5e7b LibWeb/CSS: Implement path() basic shape 2025-07-17 13:59:23 -04:00
Sam Atkins
07b5b7ffb6 Tests: Import CSS clip-path: path(...) tests 2025-07-17 13:59:23 -04:00
Jelle Raaijmakers
59a867d3e3 Tests: Enable all screenshot tests on all platforms
Some checks are pending
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
With the newly supported fuzzy matching in our test-web runner, we can
now define the expected maximum color channel and pixel count errors per
failing test and set a baseline they should not exceed.

The figures I added to these tests all come from my macOS M4 machine.
Most discrepancies seem to come from color calculations being slightly
off.
2025-07-17 12:59:11 +01:00
Jelle Raaijmakers
0d856a8fa7 Tests: Implement fuzzy screenshot comparisons in test-web
We now read WPT's `<meta name="fuzzy">` tags if present in tests and
apply them while comparing screenshots.
2025-07-17 12:59:11 +01:00
Jelle Raaijmakers
e4b2253b63 Tests: Replace load-reference-page debug action with internals method
WPT reference tests can add metadata to tests to instruct the test
runner how to interpret the results. Because of this, it is not enough
to have an action that starts loading the (mis)match reference: we need
the test runner to receive the metadata so it can act accordingly.

This sets our test runner up for potentially supporting multiple
(mis)match references, and fuzzy rendering matches - the latter will be
implemented in the following commit.
2025-07-17 12:59:11 +01:00
Jelle Raaijmakers
0f642ecb5c LibGfx: Replace Bitmap::visually_equals() with ::diff()
This produces more granural information on the actual pixel errors
present between two bitmaps. It now also asserts that both bitmaps are
the same size, since we should never compare two differently sized
bitmaps anyway.
2025-07-17 12:59:11 +01:00
Jelle Raaijmakers
115e5f42af LibWeb: Improve graphical list item marker positioning
While 788d5368a7 took care of better text
marker positioning, this improves graphical marker positioning instead.

By looking at how Firefox and Chrome render markers, it's clear that
there are three parts to positioning a graphical marker:

  * The containing space that the marker resides in;
  * The marker dimensions;
  * The distance between the marker and the start of the list item.

The space that the marker can be contained in, is the area to the left
of the list item with a height of the marker's line-height. The marker
dimensions are relative to the marker's font's pixel size: most of them
are a square at 35% of the font size, but the disclosure markers are
sized at 50% instead. Finally, the marker distance is always gauged at
50% of the font size.

So for example, a list item with `list-style-type: disc` and `font-size:
20px`, has 10px between its start and the right side of the marker, and
the marker's dimensions are 7x7.

The percentages I've chosen closely resemble how Firefox lays out its
list item markers.
2025-07-17 09:35:09 +01:00
Callum Law
3d7c5115d8 LibWeb: Move Transformation::to_matrix to new CSV resolve methods
This gains us 2 WPT passes as we now correctly disallow relative lengths
in more places in the `DOMMatrix` constructor.
2025-07-17 08:31:52 +02:00
Sam Atkins
27a666f3b2 LibWeb/CSS: Implement type(<syntax>) in attr()
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Build Dev Container Image / build (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This lets the `attr()` interpret the attribute's contents as an
arbitrary type instead of just as a string or number.
2025-07-16 14:47:45 +01:00
Sam Atkins
ded2207762 LibWeb/CSS: Parse the CSS <syntax> type into a tree
`<syntax>` is a limited subset of the "value definition syntax" used in
CSS specs. It's used for `@property`'s `syntax` descriptor, and for the
`type()` function in `attr()`.
2025-07-16 14:47:45 +01:00
Sam Atkins
5d1ba658c9 Tests: Import attr()-related WPT tests 2025-07-16 14:47:45 +01:00
Callum Law
33cf3d7782 LibWeb: Serialize RGB, HWB and HSL colors with unresolved components
Gains us 44 WPT passes.
2025-07-16 13:05:33 +01:00
Callum Law
a13f6cdf86 LibWeb: Use correct command in reorder_modifiable_descendants
Gains us 7 WPT passes in the imported test
2025-07-16 12:40:38 +02:00
Callum Law
1d3e539c09 LibWeb: Account for logical property groups in set_a_declaration
When setting a declaration for a property in a logical property group,
it should appear after all other declarations which belong to the same
property group but have different mapping logic (are/aren't a logical
alias).

Gains us 1 WPT pass.
2025-07-16 11:16:49 +01:00
Callum Law
47ddc2ea87 LibWeb: Respect logical property groups when serializing shorthands
We should not serialize a group of properties `longhands` as a single
shorthand if there is any property declared between the first and
last property in `longhands` which is not part of `longhands` but
belongs to the same logical property group, and has different mapping
logic to any of property in `longhands`
2025-07-16 11:16:49 +01:00
Jelle Raaijmakers
616a2af23d Tests: Enable screenshot tests on arm64
Of the available 71 screenshot tests that we have, 42 fail on macOS
arm64. Let's make it possible to skip those and run the remaining
succeeding screenshot tests on arm64 anyway.
2025-07-16 08:36:14 +02:00
Callum Law
a1c9b86ad3 LibWeb: Account for non-shorthand sub-properties when serializing border
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
When parsing values in `process_a_keyframes_argument` we don't expand
properties using `StyleComputer::for_each_property_expanding_shorthands`
unlike most other places - this means that if we parse a `border` we end
up with the `border`'s sub-properties (`border-width`, `border-style`,
`border-color`) still in their unexpanded forms (`CSSKeywordValue`,
`LengthStyleValue`, `StyleValueList`, etc) rather than
`ShorthandStyleValue`s which causes a crash when serializing the
`border` value in `KeyframeEffect::get_keyframes`.

The proper fix here is to parse `border`'s sub-properties directly to
`ShorthandStyleValue`s instead of relying on
`StyleComputer::for_each_property_expanding_shorthand` to do this
conversion for us but this may be a while off.

This commit also imports the previously crashing tests.
2025-07-16 06:49:38 +01:00
Luke Wilde
d9cb8185cc LibWeb: Include submitter name and value when constructing FormData
This fixes the SSO buttons on OpenAI's login page giving "Unknown
error"
2025-07-15 20:49:39 +02:00
Jelle Raaijmakers
788d5368a7 LibWeb: Improve list item marker positioning and alpha/roman text
This commit is a three-parter that is hard to separate without breaking
marker rendering:

  1. Any marker style that results in a string, except for a literal
     string (e.g. `list-style-type: "@"`), should get the string ". "
     appended. We forgot to do this for the alpha and roman types.

  2. Instead of using the "pixel size rounded up" from a font and adding
     an arbitrary 1 to that, we now use the exact pixel size for as long
     as possible to improve our vertical positioning of markers.

  3. Instead of always adding a "default marker width" to the marker
     content width, we now only do this if we did not have text metrics
     available (i.e. the marker style is not a text type). This greatly
     improves horizontal positioning of text markers.
2025-07-15 19:05:36 +01:00
Callum Law
93f957051a LibWeb: Handle serialization of invalid border in all contexts
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Previously as we handled this in `get_property_internal` there were some
contexts that we missed, for instance `CSSStyleProperties::serialized`.
2025-07-15 14:26:02 +01:00
Callum Law
927cd969b2 LibWeb: Generically serialize "positional-value-list-shorthand"s
We were previously handling this ad-hoc via logic in
`get_property_internal` but this didn't cover all contexts (for
instance `CSSStyleProperties::serialized`.

Gains us 9 more WPT tests as we now cover properties which weren't
included in the previous ad-hoc approach.
2025-07-15 14:26:02 +01:00
Callum Law
09a5c04e5c LibWeb: Handle serialization of invalid font-variant in all contexts
Previously as we handled this in `get_property_internal` there were some
contexts that we missed, for instance `CSSStyleProperties::serialized`.
2025-07-15 14:26:02 +01:00
Luke Wilde
d08d6b08d3 LibWeb: Use enum for serialization and reimplement interface exposure
Our currently implementation of structured serialization has a design
flaw, where if the serialized/transferred type was not used in the
destination realm, it would not be seen as exposed and thus we would
not re-create the type on the other side.

This is very common, for example, transferring a MessagePort to a just
inserted iframe, or the just inserted iframe transferring a MessagePort
to it's parent. This is what Google reCAPTCHA does.

This flaw occurred due to relying on lazily populated HashMaps of
constructors, namespaces and interfaces. This commit changes it so that
per-type "is exposed" implementations are generated.

Since it no longer relies on interface name strings, this commit
changes serializable types to indicate their type with an enum,
in line with how transferrable types indicate their type.

This makes Google reCAPTCHA work on https://www.google.com/recaptcha/api2/demo
It currently doesn't work on non-Google origins due to a separate
same-origin policy bug.
2025-07-15 09:20:02 -04:00
Shannon Booth
9054ff29f0 LibWeb/CSS: Parse the ::slotted pseudo-element 2025-07-15 13:54:17 +01:00
Jelle Raaijmakers
b56d4e9bab Tests: Rebaseline Layout/input/table/th-default-text-align.html
Needed after edca2ab666.
2025-07-15 11:21:14 +02:00
Sam Atkins
b3abbeab89 LibWeb/CSS: Support inherit custom properties on :root
Make sure we have a parent element before trying to look at it!

I've also pulled out a stub function for getting a custom property's
initial value, so that there's only one place to change once we support
`@property` more.
2025-07-15 10:36:08 +02:00
Jelle Raaijmakers
edca2ab666 LibWeb: Do not create an anonymous container for table cells by default
We were always creating an anonymous container for the inline contents
of table cells, but the layout node we spawn for the table cells
themselves already is capable of dealing with inline nodes. Regular
logic should kick in for dealing with the block/inline node invariant.
2025-07-15 10:06:36 +02:00
Jelle Raaijmakers
9f7447f546 LibWeb: Prioritize inheriting text-align for <th>
Because we defined `th { text-align: center }` in our UA stylesheet, it
received a higher precedence than inherited (inline) styles. Firefox
deals with this by defining a custom `text-align` value that prioritizes
any inherited value before defaulting to `text-align: center`.

We now do this as well :^)
2025-07-15 10:05:48 +02:00
Tim Ledbetter
d1678e03ff LibWeb: Check parent node exists before checking its type 2025-07-15 18:37:50 +12:00
InvalidUsernameException
8002efe780 LibWeb: Don't distort replaced elements with natural size in flex layout
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
When layouting a replaced element with natural width and height (e.g. a
raster graphic), the replaced element would correctly end up with its
natural size in the main-axis dimension. For the cross axis dimension
however, the replaced element was stretched or squished to the flex
containers inner cross size, which is wrong. Instead, we need to respect
the replaced elements aspect ratio.

Since the touched code does not have a direct correspondence to any spec
text, I am not fully certain that the change is completely correct.
However, tests agree with it, so the new code seems more correct than
the old one at least.

This fixes 50 WPT subtests in `css/css-flexbox`, most of which are
already in-tree. I have also created a new test for a scenario that did
not seem to be covered by WPT.
2025-07-15 00:52:50 +02:00
Tim Ledbetter
488333aa4b Tests: Convert an SVG text test to a crash test
This should have been a crash test, but the test runner previously
didn't wait long enough for the test to crash.
2025-07-14 13:05:17 -04:00
Tim Ledbetter
e1f0284fba test-web: Wait longer before completing crash tests
Previously, a lot of imported WPT crash tests wouldn't wait long
enough for a crash to occur.
2025-07-14 13:05:17 -04:00
Aliaksandr Kalenik
eed47acb1f LibWeb: Expand ClipFrame into clip rectangles during display list replay
Until now, every paint phase of every PaintableBox injected its own
clipping sequence into the display list:
```
before_paint: Save
              AddClipRect (1)
              ...clip rectangles for each containing block with clip...
              AddClipRect (N)

paint:        ...paint phase items...

after_paint:  Restore
```

Because we ran that sequence for every phase of every box, Skia had to
rebuild clip stack `paint_phases * paintable_boxes` times. Worse,
usually most paint phases contribute no visible drawing at all, yet we
still had to emit clipping items because `before_paint()` has no way to
know that in advance.

This change takes a different approach:
- Clip information is now attached as metadata `ClipFrame` to each
  DisplayList item.
- `DisplayListPlayer` groups consecutive commands that share a
  `ClipFrame`, applying the clip once at the start of the group and
  restoring it once at the end.

Going from 10 ms to 5 ms in rasterization on Discord might not sound
like much, but keep in mind that for 60fps we have 16 ms per frame and
there is a lot more work besides display list rasterization we do in
each frame.

* https://discord.com/channels/1247070541085671459/1247090064480014443
  - DisplayList items:  81844  -> 3671
  - rasterize time:     10 ms  -> 5 ms
  - record time:        5 ms   -> 3 ms

* https://github.com/LadybirdBrowser/ladybird
  - DisplayList items:  7902  -> 1176
  - rasterize time:     4 ms  -> 4 ms
  - record time:        3 ms  -> 2 ms
2025-07-14 15:48:28 +02:00
Andreas Kling
11fa5fdd47 LibWeb: Honor box-sizing for block-level replaced element widths
Before this change, we were always behaving as if box-sizing were
content-box for block-level replaced element widths.

This fixes the squishy logo on https://videolan.org/
2025-07-14 11:16:13 +02:00
Tim Ledbetter
80ccb12a12 LibWeb: Don't crash when appending to an XML document template element
When the XML parser appends child nodes to a template element, it must
actually append the template element's contents. This special behavior
caused us to return to the wrong parent element after adding child
nodes to a template element, leading to a crash.
2025-07-14 09:15:41 +02:00
Aliaksandr Kalenik
8ae7417445 LibWeb: Add internals call to dump display list
It's useful to have tests that dump display list items, so we can more
easily see how changes to the display list recording process affect the
output. Even the small sample test added in this commit shows that we
currently record an unnecessary AddClipRect item for empty paint phases.

For now, the dump doesn't include every single property of an item, but
we can shape it to include more useful information as we iterate on it.
2025-07-13 19:15:05 +02:00
Tim Ledbetter
941da11ece LibWeb: Avoid accessing opaque origin port during CSP checks 2025-07-13 14:33:33 +02:00
Tim Ledbetter
cd0cadc5e1 LibWasm: Use correct null check when getting iterator method
Some checks are pending
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
2025-07-13 11:28:19 +02:00
Tim Ledbetter
5478361ba0 LibWeb: Avoid division by zero with small aspect ratios
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
2025-07-13 05:41:48 +02:00
Jelle Raaijmakers
1e0013a3bc LibWeb: Use margin box height for inline-block vertical alignment
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
For `vertical-align: middle` and `vertical-align: text-bottom`, we used
just the content height of the inline box to determine its alignment
position. This caused incorrect positioning when padding is applied.

This fixes the button alignment on our GitHub page.

Fixes #290.
2025-07-12 18:03:14 +02:00
Andreas Kling
8e49b69f42 LibWeb: Never split <svg> for inline continuations
This fixes an issue where we'd make an absolute mess from nested SVG
roots with display:block. Before this fix, the inner SVG root would
trigger the inline continuation logic and try to split the tree.
2025-07-12 14:11:41 +02:00