Commit Graph

507 Commits

Author SHA1 Message Date
Jelle Raaijmakers
1aeb080250 LibCompress: Treat LZW decoding errors as end of stream
The LZW data for both GIF and TIFF images is sometimes intentionally
missing an end-of-information (EOI) code, which technically is a
decoding error, but in practive is handled gracefully by Firefox, Safari
and Chrome for GIFs and Safari for TIFFs. Let's mirror their behavior.

The included WPT test exposes the fact that trailing garbage bytes can
also result in decoding errors. We handle this in the LZW logic rather
than in the image decoding since our LZW implementation is currently
only used by GIF and TIFF decoding. The error is logged behind the
LZW_DEBUG flag.
2026-04-29 20:28:15 +02:00
Andreas Kling
0105d56e6c Tests: Add CSS image-set resolution reftest
Cover image-set() candidate selection by resolution for background
images. The tests cover both source-order-independent selection and
calculated resolution descriptors that require layout context.
2026-04-25 14:54:10 +02:00
Andreas Kling
c1fcb7dc3e Tests: Add CSS image-set background reftest
Cover image-set() painting through background-image with URL-backed
SVG candidates. The test verifies that an unsupported type() candidate
is skipped and the supported image/svg+xml candidate is loaded and
painted.
2026-04-25 14:54:10 +02:00
Tim Ledbetter
30f8e7f80c LibWeb: Include non-auto cross margins in auto-margin resolution
When resolving cross-axis auto margins on a flex item, the outer cross
size calculation omitted all cross-axis margins. We now include
non-auto margins as part of the outer cross size treating auto margins
as zero.
2026-04-25 14:46:12 +02:00
Callum Law
8a547a3f31 LibWeb: Clear counter style cache when CSSCounterStyleRule modified 2026-04-15 11:07:38 +01:00
Callum Law
8d2995c785 LibWeb: Apply correct invalidations when effective counter style changes
The counter style used for an element (in either the `content` or
`list-style-type`) may change despite the computed values of properties
on that element remaining the same (e.g. if a new rule is inserted with
higher cascade precedence).
2026-04-15 11:07:38 +01:00
Callum Law
64ccb9a015 LibWeb: Make @counter-style tree-scoped
This was a pretty straightforward change of storing registered counter
styles on the relevant `StyleScope`s and resolving by following the
process to dereference a global tree-scoped name, the only things of
note are:
 - We only define predefined counter styles (e.g. decimal) on the
   document's scope (since otherwise overrides in outer scopes would
   themselves be overriden).
 - When registering counter styles we don't have the full list of
   extendable styles so we defer fallback to "decimal" for undefined
   styles until `CounterStyle::from_counter_style_definition`.
2026-04-15 11:07:38 +01:00
Tim Ledbetter
eb8943cd55 Tests: Remove imported WPT tests that have been deleted upstream 2026-04-04 23:36:58 +02:00
Tim Ledbetter
504a8e6d1d Tests: Resync imported WPT tests 2026-04-04 23:36:58 +02:00
Tim Ledbetter
dda3cb99b7 Tests: Remove background-image workaround from imported WPT tests
This issue was fixed by #8509, so the workaround is no longer necessary.
2026-04-04 23:36:58 +02:00
Tim Ledbetter
d9079d2078 LibWeb: Apply z-index only to positioned elements
`z-index` values other than `auto` also apply to grid and flex items
because they behave as if their `position` were `relative`.
2026-04-03 23:28:39 +02:00
Andreas Kling
ce4861156b LibWeb: Import more flex abspos WPTs
Import position-absolute-006 through position-absolute-011 from
css/css-flexbox/abspos.

These ref tests pass without local skips or special handling,
which makes them a good fit for this branch while leaving
position-absolute-005 out of the imported set.
2026-04-03 14:29:44 +02:00
Andreas Kling
a61a36b184 LibWeb: Import WPT tests for percentage size with indefinite containers
Import tests covering percentage size resolution when the containing
block has auto/indefinite size.
2026-04-03 14:29:44 +02:00
Andreas Kling
509aecc857 LibWeb: Import WPT tests for percentage sizing in abspos containers
Import flex percentage-heights 004-010 and 014 (ref tests), grid
percentage-rows-indefinite-height 001-002 (testharness), and the
abspos-auto-sizing-fit-content-percentage 001-008 series (ref tests).

All flex and fit-content tests pass. The grid indefinite-height tests
have pre-existing failures (16/120 and 0/4) unrelated to this change.
2026-04-03 14:29:44 +02:00
Andreas Kling
7a122c9767 LibWeb: Import WPT tests for percentage heights in flex and grid
Import flex percentage-heights-004 through -010 and -014 (ref tests),
and grid-percentage-rows-indefinite-height-001 and -002 (testharness).

The flex tests all pass. The grid indefinite-height tests have many
failures (16/120 pass and 0/4 pass respectively), reflecting known
gaps in our grid percentage row handling.
2026-04-03 14:29:44 +02:00
Psychpsyo
a27ec55608 LibWeb: Make image alt text respect CSS-defined font properties
Other browsers also respect this and there's nothing in the spec to
suggest this shouldn't happen. I removed the border since it was
inconsistently drawn only on missing images with alt text.
Other browsers do not have this at all.
2026-03-30 19:23:13 +01:00
Tim Ledbetter
4c48827ed2 LibWeb: Merge duplicate @keyframe rule selector values
Previously, a keyframe with duplicate selector would cause a crash.
2026-03-30 12:42:57 +01:00
Andreas Kling
fd3a09a8ce LibWeb: Don't paint render-blocked iframe documents
Parent document paints could still record and paint a nested iframe's
contents even while the child document was render-blocked. That let
unstyled iframe content leak into the parent display list before the
child's blocking stylesheet had loaded, which matched the FOUC seen in
Speedometer's TodoMVC suites.

Skip painting hosted documents from NavigableContainerViewportPaintable
while they are render-blocked. Add a reftest that keeps an iframe child
render-blocked with a delayed stylesheet and forces a parent repaint;
without the fix the child's inline FAIL text becomes visible.

The new reftest passes with this change, and the existing render-
blocking requestAnimationFrame tests still pass.
2026-03-29 23:50:47 +02:00
Andreas Kling
7fc4571c17 Tests: Import WPT tests for CSS2 floats and floats-clear
Import ref and text tests from css/CSS2/floats,
css/CSS2/floats-clear, css/CSS2/margin-padding-clear, and
css/CSS2/visuren.

These cover float placement, clear behavior, clearance calculations,
and margin collapsing with floats.
2026-03-29 12:05:25 +02:00
Jelle Raaijmakers
c07e92fc7e LibWeb: Apply text-overflow ellipsis as line box post-processing
The previous implementation checked text-overflow and overflow-x
on the text node's direct parent during inline item iteration.
Since these are non-inherited properties, ellipsis only worked
for text directly inside the block container, not when wrapped
in inline elements like <span> or <a>.

Move ellipsis truncation to a post-processing step after line
boxes are constructed, checking the containing block instead.
2026-03-26 00:19:50 +00:00
aguiarcode
49d66867bd LibWeb: Invalidate inline paint caches when text selection state changes 2026-03-24 13:06:15 +00:00
Andreas Kling
97497073e2 LibWeb: Fix SVG <use> forward references in decoded SVG images
When an SVG is loaded as image data (e.g. via <img>), the
XMLDocumentBuilder returns early for decoded SVGs without calling
completely_finish_loading(). This meant that <use> elements which
forward-reference elements parsed after them never got their shadow
trees populated, since:

1. During parsing, the referenced element doesn't exist yet, so
   clone_element_tree_as_our_shadow_tree() receives null.
2. The document_completely_loaded callback never fires.
3. update_use_elements_that_reference_this() returns early because
   is_completely_loaded() is false.

Fix this by calling completely_finish_loading() on the document after
parsing in SVGDecodedImageData::create().
2026-03-22 08:12:19 -05:00
Andreas Kling
cf3d9c1bae LibWeb: Fix static position of inline-level abspos elements in BFC
When an absolutely positioned element's display was inline-level
before blockification, and its preceding sibling is an anonymous
wrapper with inline children, the element's static position should
be at the same vertical position as that wrapper. This matches where
the element would have been placed if it were still inline.

Previously, the static position was always set to the current block
offset (after the preceding block), which placed the element below
the inline content instead of beside it. This caused absolutely
positioned ::after pseudo-elements (like dropdown chevrons) to appear
on the line below the text instead of at the same vertical position.
2026-03-21 21:42:44 -05:00
Andreas Kling
223ca14abc LibWeb: Support :host::part() selectors within shadow DOM stylesheets
The :host::part() pattern allows a shadow DOM's own stylesheet to
style its internal elements that have been exposed via the part
attribute. Previously, ::part() rules were only collected from
ancestor shadow roots (for external part styling), but never from the
element's own containing shadow root.

Fix this by also collecting ::part() rules from the element's own
shadow root in collect_matching_rules(). Additionally, fix the
selector engine's ::part() compound matching to preserve the
shadow_host when the rule originates from the part element's own
shadow root, allowing :host to match correctly in the same compound
selector.

This fixes 2 previously failing WPT tests:
- css/css-shadow-parts/host-part-002.html
- css/css-shadow-parts/host-part-nesting.html
2026-03-21 21:42:44 -05:00
Andreas Kling
3b1bbd7360 LibWeb: Respect box-sizing when computing grid item minimum contribution
When computing the minimum contribution of a grid item with a definite
minimum size (e.g. min-height: 3rem), we must convert the CSS value to
content-box size before adding margin-box sizes. With box-sizing:
border-box, the CSS value already includes padding and border, so
passing it directly to add_margin_box_sizes() double-counted them.

Use calculate_inner_width/calculate_inner_height to properly convert
the minimum size to content-box dimensions, consistent with how
preferred and maximum sizes are already handled in the grid track
sizing algorithm.
2026-03-21 21:42:44 -05:00
Andreas Kling
d1acb6e157 LibWeb: Fix :host() descendant matching for nested shadow hosts
When an element inside a shadow DOM is itself a shadow host, and a
rule from the parent shadow DOM uses a selector like
`:host([attr]) .child`, the combinator traversal needs to reach the
outer shadow host to match `:host([attr])`.

Previously, when the styled element was a shadow host and the rule
came from outside its own shadow root, we set shadow_host_to_use to
nullptr. This caused traverse_up() to use parent() which cannot
cross the shadow boundary, preventing the selector from reaching the
outer :host.

Fix this by using the rule's shadow root's host as the traversal
boundary instead of nullptr. This allows the descendant combinator
to traverse from the element up through the enclosing shadow DOM to
reach the outer shadow host for :host() matching.
2026-03-21 21:42:44 -05:00
Andreas Kling
6eeafd3d7a LibWeb: Support ::slotted() matching through nested slot chains
The CSS Scoping spec says ::slotted() represents elements assigned
"after flattening" to a slot. When a slot element is itself slotted
into another slot (nested slots), the flattened tree resolves the
chain so that the inner content appears in the outermost slot.

Previously, we only collected ::slotted() rules from the directly
assigned slot's shadow root. This meant that styles defined in an
outer shadow DOM's ::slotted() rules would not apply to elements
that were transitively slotted through intermediate slots.

Fix this by walking up the slot assignment chain when collecting
and matching ::slotted() rules, so that rules from every shadow
root in the chain are considered.
2026-03-21 21:42:44 -05:00
Andreas Kling
b07a19e35f LibWeb: Account for letter-spacing when trimming trailing whitespace
When trimming trailing whitespace from line boxes, we were only
subtracting the glyph width of each trimmed character. However, during
text shaping, letter-spacing is added to each glyph's advance width.
We must subtract the full advance (glyph width + letter-spacing) to
get an accurate line width after trimming.

This also fixes a pre-existing precision bug where the glyph width
(a float) was truncated to int, leaving fractional phantom width in
the line box.

Together, these issues caused text with letter-spacing and trailing
HTML whitespace to have an underestimated intrinsic width, leading to
unexpected text wrapping in flex layouts.
2026-03-21 21:42:44 -05:00
Andreas Kling
0c58a6f322 LibWeb: Use slot's shadow host when matching ::slotted() selectors
When matching selectors like `:host ::slotted(div)`, the selector
engine needs to traverse up from the slot element to reach the shadow
host for `:host` matching. Previously, we passed shadow_host_to_use
which was derived from the *slotted element's* DOM position. For
elements in the light DOM (not inside any shadow root), this was null,
causing traverse_up() to use parent() instead of
parent_or_shadow_host_element(). This meant the traversal could never
cross the shadow boundary from inside the shadow tree to reach the
host element.

Fix this by deriving the shadow host from the slot's containing shadow
root, which is the correct scope for combinator traversal within
::slotted() rule matching.
2026-03-21 21:42:44 -05:00
Jelle Raaijmakers
7fed3f9801 LibWeb: Start fetching CSS image resources before document load event
Both Chromium and Gecko delay the document's load event for CSS image
resource requests (background-image, mask-image, etc). We now start
fetching CSS image resources as soon as their stylesheet is associated
with a document, rather than deferring until layout. This is done by
collecting ImageStyleValues during stylesheet parsing and initiating
their fetches when the stylesheet is added to the document.

Fixes #3448
2026-03-21 10:29:54 +01:00
mikiubo
71c4bb1aa8 LibWeb: Support border-radius in clip-path: inset()
Implement support for the 'round' radii in 'clip-path: inset()'
by resolving and normalizing corner radii and generating a path
with elliptical arcs.

Add a screenshot test.
2026-03-21 02:44:49 +00:00
mikiubo
e761d80e9f LibWeb: Skip non-in-flow, non-floated in background-clip:text
Per the CSS Backgrounds spec, background-clip:text clips the
background to the geometry of text in the element and its in-flow
and floated descendants only.

Skip subtrees rooted at paintables that are neither in-flow
nor floated when computing the text clip path, so that
absolutely/fixed positioned descendants (including pseudo-elements)
do not contribute to the clip.

Fixes #7498
2026-03-21 00:06:00 +00:00
Callum Law
5b07dcbd5d LibWeb: Respect @font-feature-values rules 2026-03-20 16:08:32 -05:00
Callum Law
31b5307bec LibWeb: Respect font-variant-alternates: historical-forms 2026-03-20 16:08:32 -05:00
Tim Ledbetter
cd9a76902b LibWeb: Avoid applying viewbox transform multiple times for nested SVGs
The parent's viewBox transform includes both scaling and a centering
offset. For nested <svg> elements, this transform was applied once to
position the nested SVG's box, then again to position children inside
it, double-counting the centering offset.

We now apply the parent's transform to the nested SVG box upfront to
ensure the transform is only applied once.
2026-03-20 15:59:44 -05:00
Tim Ledbetter
60334b3464 LibWeb: Treat percentage insets as auto for indefinite containing blocks 2026-03-20 15:58:50 -05:00
Jelle Raaijmakers
67d822cbbe LibGfx+LibWeb: Implement CanvasTextDrawingStyles.letterSpacing 2026-03-12 17:13:16 +01:00
Jelle Raaijmakers
9814ea28e9 LibWeb: Propagate paint invalidation to anonymous child nodes
Elements that generate anonymous boxes such as `<button>` and
`<fieldset>` need to propagate paint invalidation to them in order to
properly invalidate the style of their inner contents.

Fixes #8347
2026-03-10 15:23:53 +01:00
Tim Ledbetter
483ea12914 LibWeb: Reinitialize TextNode chunk state after collapsing whitespace
When collapsible whitespace is skipped without committing a prior
chunk, the loop would fall through and continue with font information
derived from the last whitespace code point rather than the next
non-whitespace character. Restart the function via recursion so that
these values are reinitialized from the correct code point.
2026-03-09 15:34:34 +01:00
Tim Ledbetter
815e9db05d LibWeb: Take namespace into account when matching *-of-type selectors 2026-03-09 11:48:19 +01:00
desmese
7c87cbc528 LibWeb/SVG: Fix normalized_diagonal_length in SVGCircle
The conversion of sqrt2 into CSSPixels caused the value to change from
1.41... to 1.42... This led to incorrect results. I moved the division
 inside the  sqrt to prevent this conversion step.
2026-03-08 16:27:48 +01:00
Tim Ledbetter
710c44a021 LibWeb: Add vendor-specific aliases for the placeholder pseudoelement 2026-03-06 13:13:44 +01:00
Tim Ledbetter
2fbc4d26ff LibWeb: Allow SVG root elements to participate in inline continuation 2026-03-05 17:16:42 +01:00
Tim Ledbetter
80977b5fea LibWeb: Apply contain constraint in default image sizing algorithm
When an image has no intrinsic dimensions but has an intrinsic aspect
ratio, the CSS default sizing algorithm should resolve its size as a
contain constraint against the default object size. Previously, we
returned the default size directly, which caused such images to stretch
to fill the entire background positioning area. The SVG's default
`preserveAspectRatio` would then center the content within that
oversized viewport, making the image appear horizontally mispositioned.
2026-03-03 17:14:19 +01:00
Michael Watt
1243dbd72f LibWeb: Create absolute container for will-change: position
This fixes:
http://wpt.live/css/css-will-change/will-change-abspos-cb-001.html
2026-03-03 16:52:57 +01:00
mikiubo
bee9d1e19e LibWeb: Add synthetic height for contenteditable elements
Contenteditable elements that would otherwise have zero height now get a
minimum height equal to their line-height.
This ensures they remain clickable and usable for text editing.

This fixes the WPT test:
contenteditable/synthetic-height.html
2026-03-03 16:20:10 +01:00
Tim Ledbetter
936fa1bd60 LibWeb: Apply document stylesheets to SVG use element shadow trees
The SVG spec says document stylesheets should apply inside `<use>`
element shadow trees if the referenced element is from the same
document.
2026-03-02 10:55:07 +01:00
Callum Law
81cb968beb LibWeb: Support symbols() function in <counter-style> 2026-02-27 16:25:53 +00:00
Tim Ledbetter
a762f623bd LibWeb: Implement SVGPatternElement 2026-02-27 17:14:50 +01:00
Tim Ledbetter
000a746b78 LibWeb: Apply SVG transforms to image elements during layout 2026-02-27 17:14:50 +01:00