Inline formatting contexts in vertical writing modes were measuring
intrinsic width from the line box width. That width still tracks the
line-height-sized horizontal span, so shrink-to-fit abspos sizing could
stay at 50px even when the text fragments only covered 25px.
Measure the physical horizontal extent from the line box fragments
instead, including the float-aware block formatting context path. This
makes orthogonal inline content report the correct intrinsic width.
Use the absolutely positioned box's own grid placement to resolve the
grid-area containing block rectangle instead of inheriting the nearest
in-flow grid item's area.
Keep the grid-specific static-position handling for axes with both
insets auto, but resolve mixed auto and explicit grid placement axes
against the augmented grid for direct children as well as descendants
inside grid items.
This fixes the imported abspos and alignment WPTs for values like
grid-row: 1 and grid-column: auto / 1 while keeping the reduced
descendant regressions passing.
Percentage row tracks in auto-height grids only participated in our
intrinsic sizing pass. We computed the grid container's intrinsic
height from that pass, but never reran row track sizing with the
now-known height, so percentage rows stayed content-sized and the
imported WPTs had recorded failures.
Reset the mutable track sizing state before rerunning the row pass,
rebuild row gap tracks against the resolved container height, and keep
the automatic content height from the intrinsic pass so parent layout
still resolves auto height correctly. Rebaseline the percentage-row
imports and the grid track parsing import that now improve with the
corrected percentage resolution.
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.
Previously, during grid track maximization we used the total number of
grid tracks as the denominator when distributing the available free
space. Using a larger denominator than expected meant that the
algorithm needed a larger number of iterations than necessary to
converge leading to rounding errors in the final track sizes.
Move grid area rectangle computation and validation from layout to the
CSS parser. Named grid areas that don't form filled-in rectangles now
correctly invalidate the declaration per spec.
Implement the `dense` keyword for `grid-auto-flow` so auto-placed items
backfill earlier gaps in the grid. The sparse/dense cursor logic is now
centralized in `place_grid_items()` step 4: dense resets the cursor to
the grid start before each search, while sparse keeps advancing forward.
Also fix a pre-existing bug where `find_unoccupied_place()` and several
placement helpers only checked if a single cell was unoccupied, ignoring
multi-cell spans. Add `OccupationGrid::is_area_occupied()` and use it
throughout to correctly verify the entire rectangular area is available.
Previously, GridFormattingContext handled its own min-height constraints
internally, which caused infinite recursion when min-height was an
intrinsic sizing keyword (e.g., min-height: max-content).
This change moves the responsibility to the parent formatting context
(BFC). When any box establishing an independent formatting context has
auto height but non-auto min-height:
1. BFC measures content height using a throwaway LayoutState
2. If content height < min-height, BFC passes min-height as definite
available height to the child formatting context
3. Child FC runs once with correct constraints, unaware of min-height
Fixes https://github.com/LadybirdBrowser/ladybird/issues/4261 which
is corresponding to stack overflow on https://claude.ai/
When an item is placed with an unpositioned start and a positioned end
(e.g., `grid-row: auto / 1`), allow the start position to be negative.
This correctly creates implicit tracks before the explicit grid.
When distributing item contributions among flexible tracks with
intrinsic min sizing functions, we were skipping distribution entirely
when total_flex == 0. However, tracks like `0fr` (equivalent to
minmax(auto, 0fr)) should still receive the item's contribution
distributed equally among them.
Now we count intrinsic flexible tracks separately and distribute
equally when all flex factors are zero.
This commit includes two interdependent changes that must be applied
together:
- Treat `fit-content()` tracks as having an intrinsic min sizing
function when the limit resolves to zero.
- When clamping growth limit to fit-content limit, use `max(base_size,
fit_content_limit)` instead of just `fit_content_limit` to preserve
intrinsic sizing contributions.
These changes are coupled because the first change causes
`fit-content(0)` tracks to participate in intrinsic sizing, while the
second ensures the base size from that sizing is not discarded during
clamping.
Rewrite
`increase_sizes_to_accommodate_spanning_items_crossing_flexible_tracks`
to follow spec steps more closely:
1. Process all items spanning flexible tracks together (not grouped by
span size), taking the maximum contribution per track
2. Distribute item contributions proportionally to flex factors
3. Subtract non-flexible tracks existing sizes from item contribution
before distributing to flexible tracks
Now elements with position `absolute` properly resolve their position
inside parent elements with `grid`. I also imported some WPT tests
related to that topic.
Part 2 of resolving issues on https://hack4krak.pl
Fixes bug when we didn't use `tracks_to_grow_beyond_limits` and instead
distributed extra space to all affected tracks. Also implements missing
"when accommodating max-content" part.
This brings parsing of grid-row-* and grid-column-* properties (and
their associated shorthands) more inline with spec.
Changes:
- Only set omitted properties for combined-value shorthands (e.g.
`grid-row: a` rather than `grid-row: a / b`) if the single value is
`<custom-ident>`.
- `[ [ <integer [-∞,-1]> | <integer [1,∞]> ] && <custom-ident>? ]`:
- Properly resolve `calc`s for `<integer>` that rely on compute-time
information.
- `[ span && [ <integer [1,∞]> || <custom-ident> ] ]`
- Allow `calc`s for `<integer>`
- Allow `<custom-ident>`
There is still work to be done to properly use these parsed values.
Gains us 46 WPT tests.
Previously, we would allow calc values such as `calc(min(1 2))`, which
would be simplified to `calc(3)` because we assumed that numbers not
separated by an operator represented a sum. We now validate that the
number of operators we see is as we would expect before collecting
these values into a sum node.
`collapse_auto_fit_tracks_if_needed()` had a check that does collapsing
only if auto-fit is used like
`grid-template-columns: repeat(auto-fit, 1px);`, and it didn't work for
valid cases when `repeat(auto-fit)` is placed in the middle of
definition like `grid-template-columns: 1px repeat(auto-fit, 1px) 1px;`.
`getComputedStyle()` for grid tracks returns style value produced during
layout. This is needed to return resolved track sizes values which are
thrown away after layout is done. Now GFC produces more correct style
value by not ignoring grid line names.
Reimplements `grid`, `grid-template`, `grid-template-rows`, and
`grid-template-columns` in a way that uses a separate function for each
grammar rule defined in the specification. This change results in many
additional passing tests from the already imported WPT suite. Most of
the remaining test failures are related to incorrect serialization of
grid properties.
The spec requires us to store properties in their shorthand-expanded
form and in the "specified" order, removing duplicates prefering based
on "cascading order". We already enforced this in `set_property` but
not at creation time (e.g. in stylesheets) or in `set_css_text` (e.g.
updating style attribute).
This commit enforces the spec requirements at all the relevant points.
We no longer include logical properties in the return value of
`getComputedStyle` as they are mapped to their physical equivalents in
`StyleComputer::for_each_property_expanding_shorthands`, but resolving
that requires a relatively large rework of how we handle logical
properties, (namely moving when we map them to their physical
equivalents from parse time to style computation time).
This also exposes two false positive tests in
wpt-import/css/cssom/border-shorthand-serialization.html related to us
not yet supporting the border-image css property.
To be vendor-prefixed, an ident has to start with a '-', then have
another '-' later. If the ident simply starts with a '-' then that's
perfectly fine.
Fixes 62 in-tree WPT subtests. :^)