Commit graph

175 commits

Author SHA1 Message Date
Aliaksandr Kalenik
853ecb8d8e LibWeb: Narrow width of boxes that create BFC to avoid overlap of float
https://www.w3.org/TR/CSS22/visuren.html#floats says that when a box
establishes BFC it should not overlap with floats. The way to avoid
overlaps is up to implementor. This change implements avoiding overlap
by narrowing width of a box because it seems like what other engines
do (in the scenarios I tested).
2023-05-04 06:14:58 +02:00
Aliaksandr Kalenik
bf41af6b9d LibWeb: Calculate y of a box before resolving width in BFC
Calculating width of a box in BFC requires having resolved y to be able
to check if a box overlaps with any floating boxes.

This change makes compute_width() to be called after finding y
position. That also required to move resolving of vertical metrics
in the beginning of a box layout process to have vertical margins
resolved before finding y position.
2023-05-04 06:14:58 +02:00
Andreas Kling
590723aa3b LibWeb: Implement the "The html element fills the viewport quirk"
Fixes #18037.
2023-05-03 20:44:30 +02:00
Andreas Kling
508927cae2 LibWeb: Take floats into account when measuring automatic width of IFC
When there are floats present inside an IFC, we must coordinate with
the parent BFC to calculate the automatic width of the IFC's block box.
This is because the IFC is not directly aware of floats. Only the BFC
knows enough about them to account for them in automatic sizing.
2023-05-03 19:49:43 +02:00
Aliaksandr Kalenik
09d698e0a0 LibWeb: Exclude table-wrapper margins from table available width
Table should not take up more width than is available inside wrapper
after margins are taken in account.
2023-05-03 15:03:56 +02:00
Aliaksandr Kalenik
f6ff37398c LibWeb: Fix intrinsic sizing when min or max width is specified
Fixes the problem that width is incorrectly computed in intrinsic
sizing mode when there are blocks that have min-width or max-width
specified.

Actually that is just the fix of a symptom of the larger problem that
Length::to_px() returns 0 when value is auto regardless of available
size.
2023-05-02 18:50:26 +02:00
Aliaksandr Kalenik
6cec431720 LibWeb: Set zero underflow when calculating intrinsic width of block
This fix resolves issue where calculating the min size of a block could
result in incorrect value if width of the block's children was
compensated by margins to fit into container width (which is equal to 0
during min size calculation).
2023-05-02 12:41:45 +02:00
Andreas Kling
5236819f58 LibWeb: Resolve horizontal auto margins for images with display: block 2023-04-30 05:52:19 +02:00
Aliaksandr Kalenik
9ee64b5694 LibWeb: Prevent margin double-counting with "collapse through" boxes
If there is a remaining margin-bottom in margin collapsing state
tracker after laying out all boxes in the current BFC, it must be
assigned to the last in-flow child since margin collapsing cannot
occur across a formatting context boundary.

The current issue where margin-bottom may be counted twice due to
"collapse through" margins in the last in-flow child box is addressed
with this fix by excluding such boxes during the search for a box to
assign the remaining margin.

Test case coming with this fix has a layout bug with incorrectly
computed line height.
2023-04-27 07:52:12 +02:00
Andreas Kling
b97229c9b5 LibWeb: Ignore preferred width when calculating intrinsic width of block
When calculating the intrinsic width of a block-level box, we now ignore
the preferred width entirely, and not just when the preferred width
should be treated as auto.

The condition for this was both confused and wrong, as it looked at the
available width around the box, but didn't check for a width constraint
on the box itself.

Just because the available width has an intrinsic sizing constraint
doesn't mean that the box is undergoing intrinsic sizing. It could also
be the box's containing block!
2023-04-06 16:47:40 +02:00
Andreas Kling
4f752ca791 LibWeb: Pass available inner space to BFC root auto height calculation 2023-03-27 23:28:07 +02:00
Andreas Kling
96f8cf2971 LibWeb: Consider inline content (line boxes) when measuring overflow
Fixes #13628
2023-03-22 12:56:44 +01:00
Andreas Kling
00999a245c LibWeb: Let FormattingContext decide the automatic width of its root
Instead of special-casing FlexFormattingContext in the intrinsic sizing
layout helpers, add FormattingContext::automatic_content_width() and let
each context subclass decide what that means.

No behavior change here, just moving this responsibility.
2023-03-20 17:57:58 +01:00
Andreas Kling
db545b51ef LibWeb: Make sure float: left boxes get pushed down if they can't fit 2023-03-15 11:43:54 +01:00
Matthew Olsson
7c0c1c8f49 LibJS+LibWeb: Wrap raw JS::Cell*/& fields in GCPtr/NonnullGCPtr 2023-03-15 08:48:49 +01:00
Andreas Kling
92eaad8f2e LibWeb: Consider entire stack of floated boxes when floating new box
If normal flow layout has caused us to progress past the current
innermost float in the block axis, we still need to consider the floats
stacked outside of it.

Fix this by always walking the currently stacked floats from innermost
to outermost when placing new floats.
2023-03-12 18:10:32 +01:00
Andreas Kling
b71c7a6e44 Userland: Use Font::pixel_size_rounded_up() instead of glyph_height()
The only remaining clients of this API are specific to bitmap fonts and
editing thereof.
2023-03-04 00:29:38 +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
Aliaksandr Kalenik
2ed5415750 LibWeb: Fix clearance to update y offset within current block
If a box has clearance and margin bottom of preceding box is greater
than static y of the box then it should also affect y offset in current
block container so subsequent boxes will get correct y position too.
2023-02-10 20:55:33 +01:00
Aliaksandr Kalenik
0cd63f851e LibWeb: Store y offset of current block container in BFC member
This change should make it possible to access y offset of current block
container in BFC without explicitly passing it using method parameters.
2023-02-10 20:55:33 +01:00
Aliaksandr Kalenik
f43f4feb1e LibWeb: Table wrappers should not be ignored in auto height calculation
Though table wrappers are anonymous block containers (because
TableWrapper is inherited from BlockContainer) with no lines they
should not be skipped in block auto height calculation.
2023-02-07 17:04:38 +01:00
Aliaksandr Kalenik
00f8b5a911 LibWeb: Ignore only anonymous blocks in block auto height calculation
Previously block auto height calculation was changed to skip boxes with
collapsed margins and then condition to skip anonymous boxes with no
lines was also removed in 6c5ba10bb0 to
avoid skipping anonymous wrappers of tables.

Skipping boxes with collapsed margins (currently it's check that
height is 0) is wrong because it makes empty boxes with clearance to
be skipped which is not correct while anonymous boxes with no lines
should be skipped and it's no longer causes problems with tables
(fixed in 87f0e835eb)
2023-01-26 12:34:29 +01:00
Aliaksandr Kalenik
6eb2f4bfee LibWeb: Fix reset of floats y offset
Commit 7dc0edcb86 was supposed to prevent
floats from being placed higher than preceding boxes but the change
turned out to be completely wrong and caused regressions because:
1. Call to `clear()` in `layout_block_level_children` would reset
   floating boxes only after layout of box with _not_ inline children
although the same should happen after layout of IFC.
2. `clear()` causes offset y of floats to be reset but it also clears
   all currently enocuntered floating boxes which means the next box
   that has actual clearance will get wrong y position.
2023-01-26 12:34:29 +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
Aliaksandr Kalenik
56ceb6a106 LibWeb: Fix floats y offset calculation
There is a difference in y offset position calculation for floats when
LineBuilder provides final y position while for blocks it needs to be
adjusted by `y_offset`. This difference already accounted in floating
box position calculation and this patch also makes it accounted in check
whether a floating boxes on the same line intersect between each other.
2023-01-21 14:45:09 +01:00
Aliaksandr Kalenik
87f0e835eb LibWeb: Improve auto height calculation for tables
Change `compute_auto_height_for_block_level_element` to use max height
(`m_automatic_content_height` produced from TFC) for tables with auto
height which is more correct behaviour than treating them like block
containers.
2023-01-20 18:04:17 +01:00
Aliaksandr Kalenik
7dc0edcb86 LibWeb: Prevent floats from being placed higher than preceding blocks
CSS 2.2 section 9.5.1:
The outer top of a floating box may not be higher than the
outer top of any _block_ or floated box generated by an
element earlier in the source document.

Where block is `BlockContainer` in LibWeb type system.
Which means `current_boxes` need to be cleared before
leaving block container.

```html
<style>
.wrapper {
  width: 100px;
  height: 300px;
  background-color: lightgray;
}

.box {
  margin: 10px;
  width: 50px;
  height: 50px;
  float: left;
}

.a { background-color: salmon; }
.b { background-color: slateblue; }
.c { background-color: green; }
</style>
<div class="wrapper">
	<div class="box a"></div>
	<div class="box b"></div>
</div>
<div class="box c">
</div>
```
2023-01-16 09:45:16 +01:00
Aliaksandr Kalenik
709fe01f52 LibWeb: Override width calculation for table wrappers
Introduce `TableWrapper` type so table wrappers could be
distinguished from block containers and override width
calculation for table wrappers (CSS 2.2 spec, section 17.5.2)
 inside BFCs in the way that their width should be equal to
width of table box they wrap.
2023-01-14 19:22:08 +01:00
Aliaksandr Kalenik
30b51b06b9 LibWeb: Fix y position calculation for blocks with clearance
This change fixes problem that y position of blocks with
clearance might not include border_top and padding_top
by changing `place_block_level_element_in_normal_flow_vertically`
to accept y position without `border_box_top` and adding it
on the last step when clearance is already taken in account.

Bug reproducer:
```html
<style>
.a {
    border: 10px salmon solid;
    width: 50px;
    height: 50px;
    float: left;
}
.b {
    clear: both;
    border: 20px slateblue solid;
    width: 50px;
    height: 50px;
}
</style>
<div class="a"></div><div class="b"></div><div class="c"></div>
```
2023-01-10 10:24:05 +01:00
Aliaksandr Kalenik
6c5ba10bb0 LibWeb: Remove redundant check for empty anonymous blocks
It is incorrect to skip anonymous block containers without
line boxes during block auto height calculation because there
might be table roots wrapped in anonymous table boxes after fixup
and their height should be taken in account so leaving just
condition to skip child boxes which margins are "collapsed
through" (`border_box_height() == 0`) sufficient to skip
anonymous blocks without lines but still consider table wrappers.
2023-01-09 11:47:31 +01:00
Sam Atkins
c70dcaefcd LibWeb: Convert LayoutState to new pixel units 2023-01-05 17:42:31 +01:00
Sam Atkins
76047d1932 LibWeb: Convert InlineLevelIterator/LineBox/LineBuilder to new px units 2023-01-05 17:42:31 +01:00
Sam Atkins
ace66d4a3e LibWeb: Convert BlockFormattingContext 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
Sam Atkins
affc8a22ca LibWeb+WebContent: Convert BrowsingContext to new pixel units
This fixes a few glitches. We no longer give the page double the width
it should have, and we mark the correct area of the page as needing
repainting.
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
7088a87f49 LibWeb: Margin top collapsing between parent and first child
Implement collapsing of a box margin-top and first in-flow
child margin-top by saving function that updates y position
of containing block inside BlockMarginState and then for
every child until "non-collapsed through" child is reached
y position of containing block is updated by calling
update_box_waiting_fox_final_y_position_callback.
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
Aliaksandr Kalenik
992b4489ad LibWeb: Fix bug in BFC that independent FC assigned to wrong variable
Bug was introduced in 210bf8adf0c431be05659140fd6de3a2cc5b7d99
It makes new variable for independent_formatting_context instead
of using earlier declared one which means that
parent_context_did_dimension_child_root_box will never be called.
2022-12-16 09:57:37 +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
3922349b71 LibWeb: Use space_used_by_floats to get x offset of box that creates BFC
y of box should be taken in account while calculating space
used by floats.
2022-12-11 22:08:44 +01: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
Aliaksandr Kalenik
7c00619e47 LibWeb: Use calculate_inner_width to compute min and max widths
Use calculate_inner_width that consider box-sizing in compute_width
to resolve min_width and max_width.
2022-11-23 23:11:39 +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
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
Andreas Kling
27b63feae5 LibWeb: Always resolve horizontal padding and borders on block-level boxes
We were neglecting to resolve the used horizontal padding and border
properties on block-level boxes when treating their width as `auto`
during intrinsic sizing.

This led to padding and border not contributing to the intrinsic width
of their containing block
2022-10-27 13:02:27 +02:00
Andreas Kling
4580e054f5 LibWeb: Place block-level boxes in both axes before doing inside layout
This ensures that static position calculations has access to final
box offsets.
2022-10-27 13:02:27 +02:00
Luke Wilde
488a979306 LibWeb: Layout inner floats/abspos boxes after laying out the top float
Calling parent_context_did_dimension_child_root_box immediately after
laying out the inside of the floating box is not correct, as we haven't
worked out the dimensions of the floating box yet.

In particular, this caused the icons in the top bar of Cookie Clicker
to not hug the top of the viewport. This is because the icons are
absolutely positioned elements inside a floating element which has
padding applied to it. Since we laid out the abspos element before
the floating element, it got padding values of 0 from the parent, the
default value, meaning it didn't take away the padding of it's floating
parent.

This follows how abspos boxes layout their inside boxes as well.
2022-10-24 21:12:19 +02:00
Andreas Kling
4b74f36cd0 LibWeb: Resolve vertical margins against containing block width
We were incorrectly resolving them against the available width, which
may or may not be the same as the containing block width.

The specification for these properties says that percentages resolve
against the containing block width, so that's what we should do.
2022-10-10 20:22:50 +02:00