Commit graph

166 commits

Author SHA1 Message Date
Matthew Olsson
7c0c1c8f49 LibJS+LibWeb: Wrap raw JS::Cell*/& fields in GCPtr/NonnullGCPtr 2023-03-15 08:48:49 +01:00
Andreas Kling
24d5a9d7df LibWeb: Fix bogus percentage vertical padding with box-sizing:border-box
The padding-top and padding-bottom properties are relative to the
*width* of the containing block, not the height.

It's funny how we keep making this same mistake again and again. :^)
2023-03-10 13:38:34 +01:00
Andreas Kling
7e76a51cb0 LibWeb: Rename Layout::InitialContainingBlock to Layout::Viewport
The name "initial containing block" was wrong for this, as it doesn't
correspond to the HTML element, and that's specifically what it's
supposed to do! :^)
2023-02-28 12:21:56 +01:00
Sam Atkins
dca19b764b LibWeb: Port CSS::Display to new Strings 2023-02-15 12:48:26 -05:00
Andreas Kling
4e06e86438 LibWeb: Make min-content height equivalent to max-content as appropriate
Per CSS-SIZING-3, the min-content block size should be equivalent to the
max-content block size for some boxes.

Honoring this gives more correct results, and avoids unnecessary work in
many cases since the cached max-content size can be reused.
2023-01-24 11:44:03 +01:00
Andreas Kling
8fe748bb89 LibWeb: Make grid containers be Layout::Box
Grid containers were incorrectly represented as BlockContainer before.
Furthermore, GridFormattingContext had a bogus inheritance relationship
with BlockFormattingContext.

This patch brings our architecture closer to spec by making grid
containers be plain boxes and making GFC not inherit from BFC.
2023-01-24 11:44:03 +01:00
Andreas Kling
d5480a44e5 LibWeb: Allow BFC auto height calculation on any Layout::Box
This algorithm is reused in abspos sizing, and so should not be specific
to block containers (even if the name suggests it.)
2023-01-24 11:44:03 +01:00
Andreas Kling
80ce0419b6 LibWeb: Fix abspos flex container with height:auto getting zero height
When laying out abspos boxes, we compute the height twice: before and
after the inside of the box has been laid out.

The first pass allows percentage vertical values inside the box to be
resolved against the box's height. The second pass resolves the final
used value for the height of the box itself.

In cases where the box height depends on the results of inside layout,
we were incorrectly setting the box to having a definite zero height.
This led to incorrect results when sizing an abspos flex container,
since the FFC sizes containers (in row layouts) based on whether the
container has a definite height.

To avoid this problem, this patch adds an enum so we can differentiate
between the two abspos height computation passes. If the first pass
discovers a dependency on the inside layout, we simply bail out of
computing the height, leaving it as indefinite. This allows the FFC
to size its container correctly, and the correct height gets set by
the second pass.
2023-01-06 21:12:55 +01:00
Sam Atkins
c70dcaefcd LibWeb: Convert LayoutState to new pixel units 2023-01-05 17:42:31 +01:00
Sam Atkins
f5f25562d1 LibWeb: Convert FormattingContext to new pixel units
Just FormattingContext and AvailableSpace, and the minor adjustments to
make everything else work.
2023-01-05 17:42:31 +01:00
Aliaksandr Kalenik
8259ff12bd LibWeb: Margin bottom collapsing between parent and last child 2022-12-30 14:21:19 +01:00
Aliaksandr Kalenik
fe8304d5de LibWeb: Introduce structure that maintains collapsible margins in BFC
Previously y position of boxes in block formatting context
was calculated by looking at y position of previous in-flow
sibling and adding collapsed margin of "collapse through"
boxes lying between box currently being laid out and it's
previous in-flow sibling.

Here introduced BlockMarginState structure that maintains
array of currently collapsible margins hence we no longer
need to look at previous sibling to calculate y position
of a box.
2022-12-30 14:21:19 +01:00
Tom
0bbf7a1b54 LibWeb: Refactor should_skip_anonymous_text_runs
This same function was being copied in the {Flex,Grid}FormattingContext,
so unify them in the parent FormattingContext.
2022-12-28 15:04:58 +01:00
Sam Atkins
ab49dbf137 LibWeb: Convert Paintable coordinates to new pixel units
This fixes a few sizing issues too. The page size is now correct in most
cases! \o/

We get to remove some of the `to_type<>()` shenanigans, though it
reappears in some other places.
2022-12-14 16:47:57 +00:00
Aliaksandr Kalenik
daece542f5 LibWeb: Check if block creates BFC even if all it's children are inline
Even if block has all children inline there need to be a check
if it creates BFC because otherwise IFC will be looking in
wrong parent BFC to calculate space used by floats.
2022-12-11 22:08:44 +01:00
Linus Groh
57dc179b1f Everywhere: Rename to_{string => deprecated_string}() where applicable
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.

One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
2022-12-06 08:54:33 +01:00
Aliaksandr Kalenik
2b246d980a LibWeb: Fix typo in calculate_inner_height 2022-11-25 17:06:59 +01:00
Aliaksandr Kalenik
7bc7790912 LibWeb: Flex, grid and table containers should not create BFC
Fixes https://github.com/SerenityOS/serenity/issues/16082
2022-11-25 10:45:37 +01:00
Aliaksandr Kalenik
428db6e766 LibWeb: Return max margin box width from greatest_child_width
Return max margin box width instead of max border box width
from greatest_child_width.

This change fixes:
https://wpt.live/css/CSS2/margin-padding-clear/margin-008.xht
2022-11-23 23:11:39 +01:00
Aliaksandr Kalenik
aa08c825ec LibWeb: Support box-sizing in BFC
Add support for box-sizing in block formatting context, support
for Flex Formatting Context and Grid Formatting Context is missing
2022-11-22 12:43:36 +01:00
Aliaksandr Kalenik
767cdf7b11 LibWeb: Return content box position from calculate_static_position
This change makes calculate_static_position to return content box
for both x and y (at least for the case when children are not inline).
It makes it possible to be consistent about x and y when calculating
box offset inside layout_absolutely_positioned_element.
2022-11-20 21:54:39 +01:00
Aliaksandr Kalenik
1b5b7e3b01 LibWeb: Solve width for absolute positioned elemenent according to spec
https://www.w3.org/TR/css-position-3/#abs-non-replaced-width
If left and width are auto and right is not auto, then
the width is shrink-to-fit. Then solve for left.
2022-11-16 03:10:26 +01:00
Andreas Kling
bc807466f9 LibWeb: Finish half-written comment in abspos height calculation
Apparently I forgot to write the whole comment in the previous commit,
8a87f4fa20.
2022-11-09 16:16:10 +01:00
Andreas Kling
8a87f4fa20 LibWeb: Try to compute height for abspos elements before inside layout
This can resolve height early in some cases, notably this kind of setup:

    position: absolute;
    top: 0px;
    bottom: 0px;

By resolving height before inside layout, descendants of the abspos
element can resolve automatic and relative vertical lengths against it.

This makes the Discord UI occupy the whole window instead of looking
"shrink-to-fit".
2022-11-09 15:48:08 +01:00
Andreas Kling
5e996b461c LibWeb: Actually assign solved value for left in abspos width case 1 2022-11-09 15:48:08 +01:00
Andreas Kling
305cb8a5d1 LibWeb: Treat unresolvable percentage sizes as auto on replaced elements
For replaced elements with percentage width or height, we were treating
them as 0 instead of auto when their containing block had an indefinite
corresponding size.

This produced incorrect layouts in various cases, and although I can't
actually find something about this exact scenario in specs, the new
behavior does match other browsers.
2022-11-03 19:22:40 +01:00
Andreas Kling
db318aece0 LibWeb: Move should_treat_{width,height}_as_auto() to FormattingContext
These are not specific to BFC, so let's move them up to the super class
so that other layout classes can use them.
2022-11-03 19:22:40 +01:00
martinfalisse
f7bd1edde3 LibWeb: Calculate the height of the css grid correctly
Enable the CSS grid height to be calculated correclly.
2022-10-15 16:04:01 +02:00
Andreas Kling
b289f97a65 LibWeb: Split intrinsic heights cache by definite available widths
As it turns out, we sometimes query the intrinsic height of a box before
having fully resolved and/or constrained its containing block. Because
of this, we may enter intrinsic sizing with different amounts of
available width for the same box.

To accommodate this scenario, we now allow caching of multiple intrinsic
heights, separated by the amount of available width provided as input.
2022-10-15 14:01:54 +02:00
Andreas Kling
27a7c5ef40 LibWeb: Implement CSS fit-content algorithm precisely as spec says
We were using the available space in place of the stretch-fit size.
This was an oversight, and this patch fixes that. It's very possible
that this will uncover broken behavior elsewhere.
2022-10-14 19:53:52 +02:00
Andreas Kling
d7d8e3c78b LibWeb: Resolve *all* percentages in abspos height calculation
We were neglecting to resolve() percentages for many values.
2022-10-14 19:52:07 +02:00
Timon Kruiper
8373a14835 LibWeb: Remove code duplication in computing height for abs-pos elements
This refactors the solve_for_{top, bottom, height, etc} lambdas to use a
common solve_for lambda that takes the length to be solved as an
argument. This way some code duplication is removed.
2022-10-12 11:08:29 +02:00
Samuel Bowman
ca0a0b7a93 LibWeb: Add missing else's in absolutely positioned height computation
Rules 1, 2, and 3 use else if, so rules 4, 5, and 6 should too.
2022-10-12 10:32:57 +02:00
Andreas Kling
e6de382679 LibWeb: Constrain abspos element heights by min-height and max-height 2022-10-11 22:31:51 +02:00
Andreas Kling
0e295f727a LibWeb: Fix dumb typos in solver helpers for abspos height 2022-10-11 22:23:13 +02:00
Andreas Kling
84953c5020 LibWeb: Calculate height of absolute-position elements according to spec
This patch implements the full "old model" height algorithm from the
CSS Positioned Layout spec. I went with the old model since we don't
yet have the machinery required to implement the new model.

Also, the width calculations already follow the old model, so this
is symmetric with that. Eventually we should of course implement the new
positioned layout model.
2022-10-11 21:49:48 +02:00
Andreas Kling
0f2d5f91dc LibWeb: Fix two uninitialized variables in FormattingContext 2022-10-10 23:42:35 +02:00
Andreas Kling
b945d164e2 LibWeb: Split intrinsic heights cache based on available width
Now that intrinsic heights (correctly) depend on the amount of available
width, we can't just cache the first calculated min-content and
max-content heights and reuse it without thinking.

Instead, we have to cache three pairs:

- min-content & max-content height with definite available width
- min-content & max-content height with min-content available width
- min-content & max-content height with max-content available width

There might be some more elegant way of solving this, but basically this
makes the cache work correctly when someone's containing block is being
sized under a width constraint.
2022-10-10 20:22:50 +02:00
Andreas Kling
5ff1fc4347 LibWeb: Make sure replaced elements never create a BFC 2022-10-06 18:29:52 +02:00
Andreas Kling
829ba4afb9 LibWeb: Remove unnecessary verify_cast in greatest_child_width() 2022-10-06 18:29:52 +02:00
Andreas Kling
9d50191dca LibWeb: Tidy up FormattingContext::creates_block_formatting_context()
We use comments from MDN here, since the rules for creating a BFC are
inconsistently spread across many different specifications.
2022-10-06 17:15:28 +02:00
Andreas Kling
13834cfdff LibWeb: Use Layout::Node::display() everywhere 2022-10-06 16:25:26 +02:00
Andreas Kling
b13a8706e1 LibWeb: Make intrinsic heights dependent on available width
After speaking with fantasai at CSSWG about this, it turns out I had
misunderstood intrinsic heights. I originally believed all intrinsic
sizes had to be computed with no influence from the surrounding context.

As it turns out, intrinsic heights *are* influenced by the available
width, since it's needed to determine where lines break.

The APIs for calculating min-content and max-content heights now take
the available width as inputs. This instantly improves layout in many
cases where we'd previously make things way too wide.
2022-10-03 23:49:23 +02:00
Andreas Kling
3408f7a3c5 LibWeb: Get rid of FormattingContext::run_intrinsic_sizing()
Now that we have AvailableSpace, it's actually quite convenient to
simply set up the available space and call run() with that directly.
2022-10-03 23:49:23 +02:00
Andreas Kling
de6d012367 LibWeb: Improve placement of abspos boxes with dual-auto insets
When an absolutely positioned box has auto insets on both sides of an
axis, it's placed according to the "static position rectangle". This is,
roughly, the rectangle a box would occupy if it were position:static
instead of position:absolute or position:fixed.

This patch implements a rough, but still significantly better,
estimation of such static positions. It gets pretty hairy in the case
where an abspos box has a parent whose children are inline.
2022-10-02 21:14:02 +02:00
Andreas Kling
46a13c3d2e LibWeb: Add helpful locals in layout_absolutely_positioned_element()
This code had some obnoxiously repetetive call chains.
2022-10-02 21:14:02 +02:00
Andreas Kling
d1d99fda32 LibWeb: Vertical % margins are relative to containing block width
We were messing this up on absolutely positioned elements by using the
containing block height instead.
2022-10-02 21:14:02 +02:00
Andreas Kling
9c44634ca5 LibWeb: Reorganize layout algorithms around available space
This is a big and messy change, and here's the gist:

- AvaliableSpace is now 2x AvailableSize (width and height)

- Layout algorithms are redesigned around the idea of available space

- When doing layout across nested formatting contexts, the parent
  context tells the child context how much space is available for the
  child's root box in both axes.

- "Available space" replaces "containing block width" in most places.

- The width and height in a box's UsedValues are considered to be
  definite after they're assigned to. Marking something as having
  definite size is no longer a separate step,

This probably introduces various regressions, but the big win here is
that our layout system now works with available space, just like the
specs are written. Fixing issues will be much easier going forward,
since you don't need to do nearly as much conversion from "spec logic"
to "LibWeb logic" as you previously did.
2022-10-02 21:14:02 +02:00
Andreas Kling
a0f3e2c9a2 LibWeb: Never claim that flex containers create a BFC
If a flex item is itself a flex container, we were previously lying when
asked if the item created a BFC. It creates an FFC, so stop lying about
this in FormattingContext::creates_block_formatting_context().
2022-09-29 20:10:12 +02:00
Andreas Kling
385657a4bf LibWeb: Add a helper for calculating the stretch-fit width of a box 2022-09-29 18:33:41 +02:00