Previously, calling `BlockContainer::paintable_with_lines()` would cast
a `PaintableBox` to a `PaintableWithLines` without verifying that the
cast was valid, which isn't the cast for `FieldsetPaintable`, for
example. This method now returns null if it isn't poossible to cast to
`PaintableWithLines`.
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.
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.
This ensures that percentages resolve against the foreignObject's size
instead of the size of its containing block.
This makes user profile pictures clip correctly in the "Friends" view
of the Discord app.
83b6bc4 went too far by forbidding SVGSVGElement from establishing a
stacking context. This element type does follow the behavior of CSS
boxes, unlike inner SVG elements like `<rect>`, `<circle>`, etc., which
are not supposed to be aware of concepts like stacking contexts,
overflow clipping, scroll offsets, etc.
This change allows us to delete overrides of `before_paint()` and
`after_paint()` in SVGPaintable and SVGSVGPaintable, because display
list recording code has been rearranged to take care of clipping and
scrolling before recursing into SVGSVGPaintable descendants.
`Screenshot/images/css-transform-box-ref.png` expectation is updated and
fixes a bug where a rectangle at the very bottom of the page was not
clipped correctly.
`Screenshot/images/svg-filters-lb-website-ref.png` has a more subtle
difference, but if you look closely, you’ll see it matches other
browsers more closely now.
Whenever we end up with a scrollable overflow rect that goes beyond
either of its axes (i.e. the rect has a negative X or Y position
relative to its parent's absolute padding box position), we need to clip
that rect to prevent going into the "unreachable scrollable overflow".
This fixes the horizontal scrolling on https://ladybird.org (gets more
pronounced if you make the window very narrow).
This is according to the default user-agent style from the SVG2 spec.
In order for this to work correctly, we also have to assign width and
height to foreignObject boxes during SVG layout, since they are handled
manually by SVGFormattingContext.
This patch does two things:
1. Makes TreeBuilder never cross the foreignObject boundary when looking
for an appropriate insertion parent. Before this change, we would
sometimes make things inside the foreignObject DOM subtree have
layout nodes outside the foreignObject.
2. Makes foreignObject boxes participate in the anonymous wrapping of
inline-level boxes. This is particularly imporant for absolutely
positioned elements inside foreignObject, which were previously
getting incorrectly wrapped if there was any text (even empty)
preceding the abspos element.
We were already always doing this, but through an unusual mechanism:
SVG layout creates a BFC on the stack when laying out foreignObject
subtrees.
This change makes the rest of the layout system aware of this, and
also allows it to be reflected in layout dumps.
By the time we calculate the min-content height, the width is already
known, so we can use it to calculate the height based on the natural
aspect ratio.
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.
...with inline children. This fixes an issue when we ignore abspos boxes
contained by PaintableWithLines while calculating overflow rect size.
Lots of layout tests are affected, because now PaintableWithLines has
overflow rect.
`Text/input/DOM/Element-set-scroll-left.html` is also affected and now
matches other browsers.
`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;`.
Spec says that definite grid container size should be used as free space
so there's no need to use `get_free_space()` that does iteration over
tracks and subtracts definite sizes from available space.
`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.
In `InlineLevelIterator`, whenever we call `skip_to_next()` and enter a
node with box model metrics, we could potentially accumulate leading and
trailing metrics. This lead to a weird situation where an element with
`display: inline-block` could adopt the leading metrics of an inline
element that follows it, since we perform the call to
`add_extra_box_model_metrics_to_item()` too late.
Move `skip_to_next()` down so it no longer interferes with the `Item`
we're creating.
The test expectation for
`atomic-inline-with-percentage-vertical-align.html` is updated, although
neither the old nor new results are 100% accurate since either box jumps
one pixel to the right.
There are multiple things happening here which are interconnected:
- We now use AbstractElement to refer to the source of a counter, which
means we also need to pass that around to compute `content`.
- Give AbstractElement new helper methods that are needed by
CountersSet, so it doesn't have to care whether it's dealing with a
true Element or PseudoElement.
- The CountersSet algorithms now walk the layout tree instead of DOM
tree, so TreeBuilder needs to wait until the layout node exists
before it resolves counters for it.
- Resolve counters when creating a pseudo-element's layout node. We
awkwardly compute the `content` value up to twice: Once to figure out
what kind of node we need to make, and then if it's a string, we do
so again after counters are resolved so we can get the true value of
any `counter()` functions. This will need adjusting in the future but
it works for now.
This is one of those cases where the spec says "element" and
means "element or pseudo-element". The easiest way to handle both is to
make these be free functions that take an AbstractElement, and then
give AbstractElement some helper methods so that the caller doesn't
have to care which it's dealing with.
There are some FIXMEs here because PseudoElement doesn't have a
CountersSet yet, and because the CountersSet currently uses a
UniqueNodeID to identify counter sources, which doesn't support
pseudo-elements.