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.
Previously, floating elements computed the width by only using the
`width` property. Now, they will also use the `min-width` and
`max-width` properties. :^)
The new steps are from "10.4. Minimum and maximum widths: 'min-width'
and 'max-width'" in the CSS 2 spec.
Found it when looking at curl.se.
The spec grammar for `text-decoration-line` is:
`none | [ underline || overline || line-through || blink ]`
Which means that it's either `none`, or any combination of the other
values. This patch makes that parse for `text-decoration-line` and
`text-decoration`, stores the results as a Vector, and adjusts
`paint_text_decoration()` to run as a loop over all the values that are
provided.
As noted, storing a Vector of values is a bit wasteful, as they could be
stored as flags in a single `u8`. But I was getting too confused trying
to do that in a nice way.
By the time that property() gets called, we've already given every
single property a value, so we can just return it. This simplifies a
lot of places that were manually handling a lack of value
unnecessarily.
This function was written as if it returned `Optional<CSS::BoxSizing>`
but actually returned a plain `CSS::BoxSizing`, meaning if the property
was not set or was invalid, it would return whichever enum value was
first. This wasn't visible because we don't yet pay any attention to
the `box-sizing` property.
For inline-blocks and inline replaced elements, we previously fell into
a code path that tried to find a corresponding line box fragment to
invalidate. However, we don't need to do any of that, all we need to do
is get the absolute rect from our paintable, and invalidate that.
This makes CRC2D invalidations happen immediately instead of as a side
effect of some other invalidation.
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.
This is a hack that allows block-level replaced elements to be flex
items. Flexbox layout currently assumes (in many places) that it's
always possible to create an independent formatting context for each of
its items.
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().
We were mistakenly treating inline replaced elements as if they are the
start of a regular display:inline element. This meant that we collected
the horizontal start and end metrics from the box model, and then added
those to the inline-level item produced by InlineLevelIterator.
This effectively meant that <img>, <svg> and other replaced elements got
double-sized values for margin/border/padding on the left and right
sides. (Which manifested as a mysterious margin around the element.)
Change "compute" to "calculate" to make clearer that this is unrelated
to the CSS "computed height" concept.
Change "intrinsic" to "auto" to make clearer that this is not the same
as the intrinsic min-content and max-content sizing calculations.
When running the min-content and max-content sizing algorithms and the
target box creates a flex formatting context, we don't need to measure
its children.
FFC has already assigned the content_width and content_height values,
so we just need to pick those up from the container's formatting state.
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.
If white-space is nowrap then we don't want to break a text_node
into multiple line boxes. This fixes the width calculation in the
min-content case for white-space: nowrap elements. Before this
the min-width would be the width of the biggest line box.
We had an issue with computing a width of a block in MaxContent
mode because we would set the width of the containing block to
infinity which would make everything in the try_compute_width
block infinity as well.
This adds a special case for width = 'auto' when
width_of_containing_block is infinity and removes the width of
containing block from the equation entirely.
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.
While calculating the minimum size for main min/max size violations
we were flooring the min size to 0 if the item doesn't have a min
main size. Instead of that determine the intrinsic min main size
of that element.
This fixes the flex: 80% 0 4/1/0 test case in the flex.html
test page.
This case was missed in a previous commit that added the
determine_min_main_size_of_child function
Before if an element didn't have a main min size we would clamp
it to a literal zero. If that element also had a flex-basis 0
it's width would end up being 0.
This patch adds a determine_min_main_size_of_child function that
will calculate the minimum main size for the box based on the
content of the box.
We use the result of that function now instead of clamping
the element main min size to 0.
This also adds one more box to the flex.html test page, which is
the same flex: 0 0 0 box but with flex-direction: column.