Row subgrid contribution sizing reused the parent grid's available
width, so descendants in flexible columns could contribute an unwrapped
height and then wrap during layout.
Use the resolved subgrid item width when measuring row contributions.
When collecting row-axis contributions from subgrid descendants,
resolve the subgrid column metrics first so intrinsic height measurement
uses the correct inline size. This prevents text from being measured as
if it had no usable width, which inflated auto row sizes.
When applying style in `Layout::Node::apply_style` we previously ignored
null `rotate`, `translate`, and `scale` values which left the old values
in place in the case of nonnull -> null changes.
Fixes#10125
Instead of operating within the (saturating) CSSPixels constraints,
calculate the expected value using a floating point calculation first
and then create the CSSPixels value.
box_baseline() applied CSS2's bottom margin edge rule for non-visible
overflow to every caller, so flex items with hidden overflow were
baseline-aligned by their margin edge instead of their text. CSS Align
scopes that rule to a box's last baseline set, while flex baseline
alignment and table cells use the first set, which always derives from
content. Parameterize box_baseline() on the requested baseline set and
propagate it through the recursive child lookup.
Move the layout tree from GC allocation to refcounted ownership so
removed layout and paint subtrees are destroyed synchronously instead
of waiting for the next GC sweep. This dramatically reduces GC memory
usage peaks after layout tree churn and makes it easier for memory use
to fall back after large document updates.
Update layout factories, tree traversal, SVG layout node creation,
paintable back-pointers, and pseudo-element layout links to use RefPtr
ownership.
Make display: contents follow the same shape as Blink and WebKit: the
element itself does not create a layout node, and its children are
flattened into the nearest layout parent. Wrap direct non-whitespace
text in an anonymous inline node when the boxless element contributes
inherited style to that text.
Use an internal inline wrapper for display: contents pseudo-elements
so generated content can still participate in layout, painting, hit
testing, and pseudo-element queries. Keep CSSOM reporting the computed
display value from the pseudo style, not the internal wrapper.
Remove the retained out-of-tree layout node list and its testing hook,
since the flattened model does not need a side owner for boxless
elements. Add coverage for inherited text style, dynamic insertion
order, pseudo-element hit testing, and computed style queries.
Stop creating unattached DOM Text nodes for string items in generated
CSS content. These text nodes are layout artifacts, so store their text
directly in a GeneratedTextNode instead of pretending they have DOM
backing.
Teach text shaping and first-letter splitting to read text through the
layout text source while keeping DOM-specific behavior behind an
optional DOM text accessor. This preserves generated first-letter
handling without rooting fake DOM nodes.
Add crash coverage for generated content surviving GC and rebaseline
layout dumps that now identify generated text explicitly.
This isn't strictly correct as it stands currently, since the size
attribute isn't supposed to affect type="time" and others, but those
types currently end up with zero width instead.
Size could probably be applied through shadow DOM style, and the input
layout box would simply allow content sizing.
Problem: Borked layout on (flex-styled) “D&D Beyond” site.
Cause: FormattingContext::box_baseline() was applying the box’s
vertical-align unconditionally. But vertical-align shouldn’t be
consulted for flex items or grid items.
Fix: Skip vertical-align handling in box_baseline() when the box is a
flex or grid item.
Fixes https://github.com/LadybirdBrowser/ladybird/issues/9840
Previously, the UA stylesheet gave range inputs a definite
`width: 20ch`. This prevented range inputs from filling their grid
track. We now source the default width and height from a new
`RangeInputBox` type. This approach matches the implementation of other
input types.
Previously, when no previous sibling has a line box fragment, the
static position for inline-level elements defaulted to (0, 0), ignoring
float intrusion into the line box. We now use
`leftmost_inline_offset_at()` so the hypothetical box is placed on the
float-shortened line.
Subgrids already inherited explicitly named parent grid lines, but not
the implicit line names from named grid areas. Discord places its server
rail and channel list through nested subgrids using those area names, so
the inner subgrid resolved both children against the wrong columns.
Collect the parent's implicit area boundary names, clamp each
overlapping area to the subgrid span, and assign the corresponding
implicit start and end line names on the subgrid. This follows CSS Grid
2's subgrid area inheritance text and lets the inherited names pass
through nested subgrids.
Add a layout test that mirrors the Discord nesting shape and covers
placing items by inherited parent area names through another subgrid.
Use parent grid tracks for subgridded axes, inherit parent line names,
clamp item placement to the subgrid explicit grid, and expose subgrid
children as parent track sizing contributors instead of sizing the
subgrid box itself.
Handle automatic subgrid spans, subgrid gap differences, edge
margin/border/padding contributions, non-applicable subgrid used values,
and row-subgrid auto-placement bounds.
Add focused layout and text coverage for inherited names, parent track
sizing, clamped placement, auto-fill line names, automatic spans,
gutters, and edge space. The text expectations were matched against
Chromium.
Store the static-position insertion point produced by an inline
formatting context and let block layout consume it for originally-inline
absolute boxes that follow an anonymous inline wrapper. This removes the
block formatting context's fragment-walking reconstruction of the same
position.
Keep the calculation in IFC aware of forced breaks, aligned inline
content, trailing inline margins, wrapped lines, RTL inline content, and
vertical writing modes.
Keep regression coverage for the static-position cases covered while
building this model.
When an inline flex fragment raises the line box baseline, include the
parent strut descent in the line box bottom and advance the next line
from that enlarged line box. This keeps following wrapped or broken
lines from overlapping the extra descent.
Add ref and text coverage for inline-flex line height and line
advancement.
Measure anonymous table wrapper grid items against their grid-area
containing block instead of the layout-tree containing block. Recompute
the wrapper width after track spacing and store the grid-area size so
table layout resolves table-root percentages against the same basis.
Treat non-replaced grid item percentage preferred sizes as auto when
computing intrinsic grid track contributions. This matches the CSS
Sizing cyclic percentage contribution rule and avoids inflating auto
rows before the final grid area size is known.
Keep resolving those percentages during final item layout. Update the
new layout tests to cover row inflation and nested overlap.
Add coverage for percentage-height grid items contributing to row
track sizing. These cases mirror nested homepage grids where auto rows
are sized from grid items whose own height is percentage-based.
When a replaced element has no natural width or height but has a
preferred aspect ratio, max-content width fell through to the CSS
Sizing fallback that uses the initial containing block width.
Use a definite used height to derive max-content width through the
aspect ratio before the fallback. Keep the existing natural-height SVG
path first by only doing this for elements without natural height. Add
a focused layout test for the nested flex item case.
A used height computed from an intrinsic sizing keyword like fit-content
does not necessarily establish a definite containing-block height for
percentage descendants.
Preserve indefinite percentage-height resolution both in normal block
layout and in absolutely positioned/fixed layout, including cases where
non-auto top/bottom insets resolve the box’s own used height.
Add regressions for a regular fit-content block container and fixed
fit-content containers with min-height and top/bottom insets.
When an outer <svg> has a viewBox and only one sizing attribute, SVG
Integration keeps the missing dimension as auto while exposing the
specified dimension and intrinsic aspect ratio to CSS sizing.
Teach replaced max-content sizing to resolve that SVG-specific partial
intrinsic size through CSS2 replaced sizing before falling back to the
CSS Sizing rules for replaced elements without natural sizes. This keeps
the generic fallback path intact while avoiding viewport-sized
max-content contributions for SVGs such as height+viewBox logos.
In combination with the previous commit, fixes the layout of logos
on polar.sh
CSS Sizing defines the max-content size of a replaced element without
natural dimensions in terms of the size it would have as a float with an
auto preferred size.
Change max-content width/height calculation to use those fallback rules
for replaced elements that lack a natural size in the queried axis.
Reduced from bad layout of the logo section on polar.sh
When an inline flex/grid container has no line boxes of its own, we
derive its baseline from a child box. The generic recursive path can
then use the child's last wrapped line, even though the flex/grid
baseline should come from the child item's alignment baseline.
Use the selected child's first line box directly for inline flex/grid
containers, avoiding an incorrect baseline when that child wraps.
thead, tbody, tfoot, tr, td, and th all have an `align` presentational
attribute with identical definitions. We previously only supported it
for td and th, and also allowed arbitrary text-align values instead of
the 4 dictated by the spec.
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.
When content-visibility:hidden starts skipping a subtree, clear the
stale layout and paint nodes for its descendants.
Preserve SVG mask, clipPath, and pattern resource boxes only when
they are attached to a referencing layout subtree outside the subtree
being hidden. Resources used inside the hidden subtree are cleared
with that subtree, so they rebuild under the live referencing layout
node when the subtree becomes visible again.
Otherwise observed descendants can keep old paintables around after
the current paint tree has been rebuilt without them.
During intrinsic sizing, compute_width() ran on block descendants with
an intrinsic-sizing available space. For a non-FC-establishing block
with auto width, used_width stayed auto, and the min-width clamp then
compared AvailableSize::min-content against min-width via operator<,
which always returns true when the left side is min-content. The clamp
fired with min-width: 0 and set content_width to 0 permanently.
Skip the min-width clamp when used_width is still auto, mirroring the
max-width clamp a few lines above which already no-ops via
to_px_or_zero. The real width is then set by the IntrinsicSizing branch
in layout_block_level_children.
When resolving grid track sizes, limited min/max-content contributions
should be capped by fixed max track sizing functions, including the
argument to fit-content(). We were instead falling back to the grid
container maximum size, which allowed a grid item with overflowing
contents in a fit-content(0) row to inflate the intrinsic block size of
a nested grid.
That bogus intrinsic height could then be used for the grid's second row
sizing pass, causing unrelated flexible rows to absorb the extra space.
Previously, `run_caption_layout()` passed the table's border-box width
as the available space to the caption's formatting context. The BFC then
used this width directly for inline line breaking, causing text to
overflow the caption's content box by the size of the caption's own
border and padding.
Previously, the select button's text was only refreshed inside the
two non-trivial branches of the selectedness setting algorithm.
Paths that left the select with exactly one selected option hit a
no-op branch and skipped the refresh.
Fix this by implementing the "clone selected option into select
button" algorithm and invoking it whenever the set of selected options
may have changed.
Don't rewrite text input 'width: auto' to 'size()ch' in
'HTMLInputElement::adjust_computed_style()'. That turns the control into
a definite-width flex item and prevents 'align-items: stretch' from
expanding it across the flex container.
Fixes the layout of the input element on the element matrix login page.
This spec note reads to me as explicitly disallowing combining
`<length>` and `<flex>` (i.e. `calc(1px + 1fr)`). This behavior is
already implemented (as it is for all other combination of units i.e.
`<length>` and `<time>`).
The replaced element sizing code was comparing tentative used sizes
min-width/min-height and max-width/max-height. For box-sizing:
border-box, that mixes content-box and border-box measurements, which
can clamp replaced-like elements incorrectly.
This could make, for example search/text inputs with explicit height
and padding render too short.
Resolve min/max constraints with calculate_inner_width() and
calculate_inner_height() before clamping so the comparison uses
the same inner sizing space as the tentative replaced size.
Fixes the sizing of the search bar on:
https://tv.apple.com/se
Stop rebuilding the counter style cache from every style update.
That made unrelated restyles pay the full counter-style cost even when
no relevant stylesheet state had changed.
Dirty the cache when stylesheet rule caches are invalidated and rebuild
it on the first counter-style lookup instead. Also make cold cache
rebuilds include user stylesheets.
Add regression tests covering insertRule() and replaceSync() updates
that should make newly defined counter styles take effect.
Scrollable overflow still assumed a top-left scroll origin and only
added trailing padding on the physical bottom edge. That broke
scrollWidth and scrollHeight for flex containers whose main or cross
axis was reversed by writing-mode, direction, flex-direction, or
wrap-reverse.
Teach flex layout to place wrapped lines using the computed cross-axis
direction and to measure scrollable overflow from the container's
actual scroll origin so reachable reversed overflow is preserved, the
unreachable side is clipped, and end padding is added on the correct
physical edge.
Keep per-item cross-axis placement using the existing behavior.
Applying full cross-axis reversal there regressed baseline alignment
tests, and zero-sized boxes exactly at the scroll origin must still
contribute descendant overflow, so the unreachable-overflow checks
need strict comparisons.
This makes negative-overflow-002 and negative-overflow-003 pass and
improves negative-overflow, align-content-wrap-003, and
overflow-with-padding.