Sometimes fixed positioned boxes would extend the viewport's scrollable
overflow, which according to the spec should never happen. There are
some nuances to this, such as properly determining the fixed positioning
containing block for a fixed position box, but for now this prevents
some pages from being overly scrollable.
Fixes horizontal scrollability of https://tweakers.net.
Whenever we introduce a block element in a container that at that point
has only had inline children, we create an anonymous wrapper for all the
inline elements so we can keep the invariant that each container
contains either inline or non-inline children. For some reason, we
ignore all the out-of-flow nodes since they are layed out separately and
it was thought that this shouldn't matter.
However, if we are dealing with inline blocks and floating blocks, the
order of the inline contents _including_ out-of-flow nodes becomes very
important: floating blocks need to take the order of nodes into account
when positioning themselves.
Fix this by simply hoisting the out-of-flow nodes into the anonymous
wrapper as well.
Fixes the order of blocks in #4212. The gap is still not present.
Instead, use the generic create_independent_formatting_context_if_needed
so that unusual situations like image-as-table-caption don't crash.
This logic clearly needs more work, but let's at least do better than
crashing. This gives us 26 new subtest passes on WPT.
We were incorrectly deciding that abspos elements shouldn't treat many
max-width and max-height values as `none`. My best understanding is that
this was a hack in 2023 for an issue that has been solved since then.
By removing the incorrect short-circuit, we stop at least one WPT test
from crashing due to infinite recursion and get ourselves +34 passes.
The special case for anonymous table wrappers actually ended up hurting
correctness by preventing the full ancestor chain from being marked for
for intrinsic size cache invalidation.
Caused Layout/input/table/propagate-style-update-to-wrapper.html to
flake on CI, and was easy to reproduce locally with sanitizers.
The fix here is simply to remove the special handling of anonymous table
wrapper parents, since *all* parents are invalidated automatically
anyway!
Began flaking in fa9c463ffd.
In 15103d172c we applied any remaining vertical float clearance to the
BFC's current Y offset for the next block to layout, because a `<br
style="clear: left">` could introduce clearance that would otherwise be
ignored. However, a `<div>` that floats _and_ clears `right` also
introduces this clearance and it is obvious that this should not push
down any subsequent blocks to layout in the current BFC.
Turns out, we don't need this change anymore. Some other later change
also fixed the underlying issue, and by getting rid of the original fix
we can now render https://en.wikipedia.org/wiki/SerenityOS correctly
again.
Fixes#4418.
We already store the resulting margin box rect for floating boxes
relative to their root coordinate space, so don't calculate them again.
No functional changes.
There's a specific (and thankfully very common!) scenario where we can
actually skip calculating the automatic minimum size for flex items.
In single-line (no wrapping) flex containers, if the sum of all item
flex base sizes is <= the flex container's main size, we know that
none of the items will be shrunk by the layout algorithm.
And so for any flex item with definite main size AND automatic minimum
main size, we can treat the automatic minimum size as 0.
We were calculating the fit-content cross size and then throwing it
away and doing it again. You might think this wasn't so bad since
fit-content relies on cacheable intrinsic sizes *buuuuut* since we're
actually modifying the constraints for the second call, we were indeed
doing completely wasted work here.
Instead of indiscriminately clearing the cache for all anonymous boxes,
we now only clear it for those that were generated by a non-anonymous
box in need of layout update.
This increases the cache hit rate and allows us to avoid more work.
We now cache the containing block (box) once at the start of layout,
which allows Layout::Node::containing_block() to return instantly
instead of doing tree traversal.
Removes a 0.7% profile item on Speedometer 3.
When determining the content/margin box rects within their ancestor's
coordinate space, we were returning early if the passed in values
already belonged to the requested ancestor. Unfortunately, we had
already applied the used values' offset to the rect, which is the offset
to the ancestor's ancestor.
This simplifies the logic to always apply the rect offset after checking
if we've reached the ancestor. Fixes determining float intrusions inside
block elements with `margin: auto` set.
Fixes#4083.
Instead of reaching into the IFC of the LineBuilder from the BFC, we
should let LineBuilder determine how to deal with the running vertical
float clearance. No functional changes.
If a block with inline children ends with a line break clearing any
floats, we not only need to take the introduced clearance into account
for the next line box, but the containing block needs to set the correct
height as well.
Since the spec calls for using the last line box' bottom as the resolved
height (if treated as auto), we now correctly apply the clearance to the
previous line box' bottom coordinate.
Fixes#4058.
We were accidentally providing it with absolute Y-coordinates, messing
up stacked floating boxes that would otherwise intrude on each other.
Fixes#4160.
This is a improved version of a73cd88f0c
The old commit was reverted in 552dd18696
The new version only paints an element into a new layer if background
blend modes other than normal are used. The rasterization performance
of most websites should therefore not suffer.
Co-Authored-By: Alexander Kalenik <kalenik.aliaksandr@gmail.com>
This reverts commit a73cd88f0c.
Emitting SaveLayer for each paintable made rasterization a lot slower
on every website because now Skia has to allocate enormous amounts of
temporary surfaces. Let's revert it for now and figure how to implement
it with less aggressive SaveLayer usage.
Whenever we generate line boxes, we might end up with a residual
vertical float clearance by way of having a `<br>` with `clear: ..` set.
Set the Y offset of the next block level box to place by this vertical
clearance.
Relates to #4058.
We were introducing a line break and applying vertical clearance to the
inline formatting context, but that vertical clearance only applied to
new floating boxes. We should move the current block offset to the
vertical clearance to make sure the next line box starts beyond the
cleared floats.
There was a layout test for `<br>` with `clear: ..` set, but that test
did not actually do anything - removing the `clear` property would
result in the same layout. Replace that test with something that
actually tests float clearing.
Relates to #4058.
Our recent change to get rid of the "move 1px at a time" algorithm in
the float positioning logic introduced the issue that potentially
intersecting float boxes were not evaluated in order anymore. This could
result in float boxes being pushed down further than strictly necessary.
By finding the highest point we can move the floating box to and
repeating the process until we're no longer intersecting any floating
box, we also solve some edge cases like intersecting with very long
floating boxes whose edges lay outside the current box' edges.
This is by no means the most efficient solution, but it is more correct
than what we had until now.
Fixes#4110.