Commit graph

208 commits

Author SHA1 Message Date
Andreas Kling
18b1854aea LibWeb: Add FFC helpers for getting the computed main/cross size of box 2022-07-26 01:53:41 +02:00
Andreas Kling
a4d7dc40bf LibWeb: Move get_pixel_{width,height} helpers into FFC class 2022-07-26 01:53:41 +02:00
Andreas Kling
60ac258a48 LibWeb: Mark flex item cross sizes as definite when spec asks us to
The CSS-FLEXBOX-1 spec gives us two situations in which flex item cross
sizes should be considered definite. Both of them happen *during* flex
layout, which is super finicky but it is what it is.
2022-07-26 01:53:41 +02:00
Andreas Kling
97f53de8a2 LibWeb: Take size constraints into account in fit-content calculations
Also avoid calculating both min-content and max-content sizes when only
one of them is needed.
2022-07-26 01:53:41 +02:00
Andreas Kling
8f35c9a037 LibWeb: Resolve flexbox percent heights against containing block height
Percentage values for `min-height` and `max-height` should be resolved
against the containing block height, not its width.
2022-07-26 01:53:41 +02:00
Andreas Kling
4cbec00c44 LibWeb: Actually check if percentage used flex basis is definite
Previously, we considered all LengthPercentage values for used flex
basis to be definite. This is not accurate, as percentages should only
be considered definite if the reference value they resolve against is
a definite size.

Fix this by checking the flex container's main definite size flag.
2022-07-26 01:53:41 +02:00
Andreas Kling
8bdc6f5390 LibWeb: Don't override main size during flex item cross sizing
There's no need to override the sizes before calculating the cross size.

Besides, by the time we're calculating the hypothetical cross size of
flex items, we may already have established a definite main size anyway,
so overriding it would be wrong.
2022-07-26 01:53:41 +02:00
Andreas Kling
69243947d5 LibWeb: Some flex items have definite size after flexing
This patch implements two of the special "definite size" rules from
the CSS-FLEXBOX-1 spec.

https://drafts.csswg.org/css-flexbox-1/#definite-sizes
2022-07-26 01:53:41 +02:00
Andreas Kling
71a707480c LibWeb: Move "has-definite-width/height" flags to UsedValues
This state is less static than we originally assumed, and there are
special formatting context-specific rules that say certain sizes are
definite in special circumstances.

To be able to support this, we move the has-definite-size flags from
the layout node to the UsedValues struct instead.
2022-07-26 01:53:41 +02:00
Andreas Kling
bd48d9521a LibWeb: Simplify more code with CSS::LengthPercentage::is_auto() 2022-07-26 00:04:21 +02:00
Andreas Kling
fac4529082 LibWeb: Honor flex container sizing constraints in available space 2022-07-25 15:03:18 +02:00
Andreas Kling
050e70cc7e LibWeb: Position abspos children of flex container after parent layout
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.
2022-07-25 15:03:18 +02:00
Andreas Kling
7aa9e03e85 LibWeb: Simplify some code with CSS::LengthPercentage::is_auto() 2022-07-25 15:03:18 +02:00
Andreas Kling
3145f92bc0 LibWeb: Count flex item's *outer* size towards container intrinsic size
This isn't in the spec, but it's visually obvious that we need to count
item margin boxes towards the main intrinsic size of the flex container.
2022-07-25 15:03:18 +02:00
Andreas Kling
237fbe4d54 LibWeb: Remember the used flex basis for each flex item
This will be consulted later on in the flex layout algorithm.
2022-07-21 01:46:26 +02:00
Andreas Kling
b7003194d2 LibWeb: Use right offset for justify-content: flex-end
Offsets in this algorithm are relative to the starting position, so it
should be 0 whether its `flex-start` or `flex-end`.
2022-07-21 01:46:25 +02:00
Andreas Kling
da0cc9d401 LibWeb: Floor hypothetical main size at 0
The spec asks us to do this. It doesn't become relevant until we
implement box-sizing, but might as well do it anyway.
2022-07-21 01:46:25 +02:00
Andreas Kling
ed8930fff5 LibWeb: Add accessors for UsedValues::computed_{width,height}
This is preparation for doing some more work when assigning to these
values.
2022-07-19 15:40:41 +02:00
Andreas Kling
c517dfde12 LibWeb: Honor the flexbox spec's "automatic minimum size" everywhere
`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.
2022-07-19 12:45:50 +02:00
Andreas Kling
52862c72d0 LibWeb: Rename FormattingState to LayoutState
This seems a bit more descriptive (and also a bit shorter).
2022-07-17 14:11:36 +02:00
Andreas Kling
0d8f9019c8 LibWeb: Implement basic stretch alignment for flex-wrap: wrap
We currently ignore the `align-content` property, that's a FIXME
for our future selves.
2022-07-17 14:11:36 +02:00
Andreas Kling
9fc43d5766 LibWeb: Update flex container intrinsic size algorithm to draft spec
The CSSWG draft Flexbox spec is a bit clearer on some details, so let's
update our implementation to match the latest version.
2022-07-17 14:11:36 +02:00
Andreas Kling
884b7fad48 LibWeb: Remove weird is_undefined_or_auto() helper in FFC
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.
2022-07-15 14:11:19 +02:00
Andreas Kling
0636e1db61 LibWeb: Update flex line "remaining free space" when finished
Since we re-use this value later in the layout algorithm, we have to
update it before leaving the "resolve flexible lengths" step.
2022-07-15 14:11:19 +02:00
Andreas Kling
7d7d5f0b1b LibWeb: Use fit-content size for flex items with indefinite cross size 2022-07-12 23:12:11 +02:00
Idan Horowitz
e39514721e LibWeb: Add missing break to avoid fallthrough in FlexFormattingContext
This silences a Clang warning.
2022-07-12 18:11:21 +03:00
Idan Horowitz
c70359ac04 LibWeb: Remove unused variable in FlexFormattingContext 2022-07-12 17:54:55 +03:00
Andreas Kling
dc13ced1a7 LibWeb: Express flex item cross axis alignment as offsets-from-center
This allows us to perform cross axis alignment without knowing the final
cross size of the flex container.
2022-07-12 15:55:43 +02:00
Andreas Kling
5f78e780f5 LibWeb: Actually clamp flex line cross size to min/max-size
We were dropping the result of css_clamp() on the floor, oops!
Let's also mark it [[nodiscard]] so it won't happen again.
2022-07-12 15:55:43 +02:00
Andreas Kling
c81e5c9d82 LibWeb: Floor scaled flex shrink factor at 1 when spec asks us to 2022-07-12 02:46:21 +02:00
Andreas Kling
6ecf7db87b LibWeb: Take margin box into account when justifying flex items
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.
2022-07-12 02:46:21 +02:00
Andreas Kling
2f0657739b LibWeb: Honor align-self over align-items when non-auto on flex item 2022-07-12 02:46:21 +02:00
Andreas Kling
4493702fb2 LibWeb: Honor preferred size as intrinsic cross size of flex items
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.
2022-07-11 18:57:45 +02:00
Andreas Kling
9cae06de09 LibWeb: Implement step 9.2.3 of the flexbox layout algorithm
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.
2022-07-11 18:57:45 +02:00
Andreas Kling
e1dab7b63d LibWeb: Use the *outer* flex base size in intrinsic size calculation 2022-07-11 18:57:45 +02:00
Andreas Kling
aee3d79ad1 LibWeb: Use the "scaled flex shrink factor" where noted by the spec 2022-07-11 18:57:45 +02:00
Andreas Kling
f7750985fa LibWeb: Treat "flex-basis: 0px" like any other definite basis value 2022-07-11 18:57:45 +02:00
Andreas Kling
7b4a86ab80 LibWeb: Use max-content main size for flex items w/ definite cross size
If the main size is indefinite, that is.
2022-07-11 18:57:45 +02:00
Andreas Kling
64959a8504 LibWeb: Express intrinsic size layout via size constraints
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
2022-07-11 18:57:45 +02:00
Andreas Kling
db2d62671f LibWeb: Add FFC helpers for getting intrinsic size of flex items 2022-07-11 18:57:45 +02:00
Andreas Kling
4f6fc3d3a6 LibWeb: Only perform the requested form of intrinsic size calculation
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.
2022-07-11 18:57:44 +02:00
Andreas Kling
496cf39cf5 LibWeb: Make separate functions for calculating min/max content sizes
At first, these are just wrappers around calculate_intrinsic_sizes().
Eventually, we'll make them do only the work necessary for their
specific size.
2022-07-11 18:57:44 +02:00
Andreas Kling
1690d88887 LibWeb: Clamp intrinsic flex item main size contributions to min/max 2022-07-11 18:57:44 +02:00
Andreas Kling
89e65e0ea1 LibWeb: Support flex item cross sizing based on intrinsic aspect ratio
This patch implements case B from the "determine the flex base size
and hypothetical main size of each item" from the flexbox algorithm.

https://drafts.csswg.org/css-flexbox-1/#algo-main-item
2022-07-10 00:47:46 +02:00
Andreas Kling
8eb022a57d LibWeb: Don't include flex line margins in inner flex item cross sizes
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.
2022-07-10 00:04:41 +02:00
Andreas Kling
030dbfd2a9 LibWeb: Improve support for flex-start/end with reversed flex-direction
We now pass the "flex-direction" test from the CSSWG flexbox test suite.
2022-07-10 00:04:41 +02:00
Andreas Kling
cefc931347 LibWeb: Make sure CSS::ComputedValues has initial size values
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.
2022-07-09 22:16:35 +02:00
Andreas Kling
4935055407 LibWeb: Keep the "remaining free space" across flexbox algo steps
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.
2022-07-06 20:31:24 +02:00
Andreas Kling
d2b7d2440f LibWeb: Cache flex item main sizes to avoid relayout during same cycle
This makes twitter.com actually load & render (although not very well.)
2022-07-06 00:22:42 +02:00
Andreas Kling
13b4d91f66 LibWeb: Always apply min/max cross size constraints to flex items
We were neglecting to apply min-size and max-size constraints in the
fast path for flex items with a definite cross size.
2022-07-04 22:30:59 +02:00