If we wait until after the parent context has laid out the flex
container, abspos children are able to use the final results of the
parent sizing the flex container.
This makes `height:auto` work on abspos children of a flex container.
`min-width: auto` and `min-height: auto` have special behavior on flex
items. We already handled it in many cases but there were two places
where it was incorrectly treated as 0. This fixes that.
This was a leftover from when ComputedValues stored sizes in Optionals.
Now that we've gotten rid of the "undefined" state, there's no need for
this helper, we can just access the size values directly.
Before this patch, we were justifying based on the content box only,
which led to misalignments along the main axis when items had non-zero
padding, borders or margins.
I'm not 100% sure this is on-spec, but it seems to me that flex items
that have a specified non-auto cross size should honor that value in
its min-content and max-contribution.
When sizing the flex container under a min-content or a max-content
constraint, flex items with a used flex basis of "content" should be
sized under the same constraint.
Previously, we had three layout modes:
- Normal:
- Everything uses the computed values from CSS.
- MinContent:
- Containing blocks act as if they have 0 width.
- All line breaking opportunities are taken.
- MaxContent:
- Containing blocks act as if they have infinite width.
- Only forced line breaks are accepted.
The above was based on a set of misunderstandings of CSS sizing.
A major problem with the above was that *all* containing blocks
behaved differently during intrinsic size layout, not just the
relevant one.
With this patch there are only two layout modes:
- Normal:
- Everything uses the computed values from CSS.
- IntrinsicSizeDetermination:
- One or more boxes have size constraints applied.
There are two size constraints per layout box, set here:
- FormattingState::NodeState::width_constraint
- FormattingState::NodeState::height_constraint
They are of type SizeConstraint and can be one of None, MinContent,
or MaxContent. The default is None.
When performing an IntrinsicSizeDetermination layout, we now assign
a size constraint to the box we're trying to determine the intrinsic
size of, which is then honored by using two new helpers to query
the dimensions of containing blocks:
- FormattingContext::containing_block_width_for(Box)
- FormattingContext::containing_block_height_for(Box)
If there's a relevant constraint in effect on the Box, the size of
its containing block is adjusted accordingly.
This is essentially an implementation of the "available space"
constraints from CSS-SIZING-3. I'm sure some things will break from
this, and we'll have to deal with that separately.
Spec: https://drafts.csswg.org/css-sizing-3/#available
Before, querying any of the four intrinsic sizes would cause us to
calculate all of them (the four being min-content width/height, and
max-content width/height).
Now, the helper functions only calculate the specific intrinsic size
requested. It's then cached at the root formatting context level,
so that it's never calculated twice within the same layout pass.
In cases where flex item cross size is based on the flex line cross
size, the spec specifically says to transfer the *outer* cross size of
the line. We were ignoring the "outer" part.
This patch fixes that by subtracting the cross margins from the size.
Instead of using Optional<LengthPercentage>, we now use LengthPercentage
for these values. The initial values are all `auto`.
This avoids having to check `has_value()` in a ton of places.
Instead of recomputing the "remaining free space" per flex line,
remember it after calculating it during the "resolve flexible lengths"
step so we can reuse it later.
We were not applying the distributed space to the used offset of flex
items, as we were only assigning the margins to the layout state of the
box, not the internal FlexItem::margins.
Before we ask a replaced box about its intrinsic dimensions, we have
to "prepare" the box, which tells it to go and work out what its
intrinsic dimensions are.
I've added a FIXME about how this is silly (and clearly bug-prone)
but this patch only patches it locally in FFC for now.
When calling layout_inside() on a flex item that can't have children of
its own, layout_inside() will not return an independent formatting
context, so we need to handle that case here.
AFAICT, css-values-4 tells us that clamping numbers to a range where
min>max is okay. That means we can't use AK::clamp() since it will
VERIFY that max>=min.
This patch adds a css_clamp() helper (locally in FFC for now).
This fixes an issue where a bunch of sites were crashing due to the
VERIFY in AK::clamp().
This patch adds support for MinContent and MaxContent layout to FFC.
This means that an FFC can now calculate intrinsic sizes for the flex
container, to be used by the parent formatting context.
There are some FIXME's as usual, but this already works on basic things.
This builds on the work done by implementing the flex order CSS
property and implements flex reverse layouts by just reversing
the order and the items within each order bucket.