Commit graph

25 commits

Author SHA1 Message Date
Aliaksandr Kalenik
a8c1d12e84 LibWeb: Fix percentage insets resolution for grid items
compute_inset() was incorrectly retrieving the containing block size
because containing_block() is unaware of grid areas that form a
containing block for grid items but do not exist in the layout tree.
With this change, we explicitly pass the containing block into
compute_inset(), allowing it to correctly provide the containing block
sizes for grid items.
2024-11-11 20:20:39 +01:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Andreas Kling
0ecefbff57 LibWeb: Move absolute positioning up to FormattingContext
It seems like both BFC and IFC can have absolutely positioned children.
It's a bit strange, but consider the following HTML:

<html><body>foobar<img style="position: absolute"></body></html>

In such a document, the <img> element is an absolutely positioned child
of a block-level element (<body>) with no block-level children.
An IFC is established for <body>, and needs to handle layout for <img>.
2021-01-06 19:20:49 +01:00
Andreas Kling
2cc39cfb0e LibWeb: Copy some properties from specified style into layout node
Another step towards not having to carry the full specified style with
us everywhere. This isn't the ideal final layout, since we're mixing
computed and used values a bit randomly here, but one step at a time.
2021-01-06 14:58:48 +01:00
Andreas Kling
5721b2a3da LibWeb: Rename LayoutStyle => CSS::ComputedValues
This object represents the CSS "computed values" so let's call it that.
2021-01-06 14:58:48 +01:00
Andreas Kling
07dd73c351 LibWeb: Remove hand-rolled is_foo() helpers in Layout::Node classes 2021-01-01 18:56:49 +01:00
Andreas Kling
17c529e6c5 LibWeb: Generate the CSS::ValueID enum and its helper functions 2020-12-15 20:40:10 +01:00
Andreas Kling
23f70535e2 LibWeb: Dimension inline-block and replaced boxes during splitting
Don't wait until fragment layout to compute width/height of boxes on
the line, just do it while we're splitting into lines.
2020-12-15 19:33:53 +01:00
Andreas Kling
2b8c7faee4 LibWeb: Use the margin box of floating elements for flowing around
Inline content flows around the entire margin box of floating elements,
not just the content box.
2020-12-12 19:59:24 +01:00
Andreas Kling
67732df034 LibWeb: Move replaced element layout out of Layout::ReplacedBox
Replaced elements are now laid out by the current formatting context.
Since the logic is almost identical in BFC and IFC, it's implemented
by static helpers in FormattingContext.
2020-12-11 22:59:46 +01:00
Andreas Kling
3852168c84 LibWeb: Compute final line box width *after* placing all fragments
We were doing this after every fragment instead of after every line.
2020-12-07 21:48:23 +01:00
Andreas Kling
5a57f618ad LibWeb: Resolve width in relative length units on inline-block properly
Element-relative width units like em, ex, etc. should be resolved
against the inline block itself, not against its containing block.
2020-12-07 20:55:44 +01:00
Andreas Kling
70de5fd056 LibWeb: Simplify final line box width computation
The width of a line box is the distance from the left edge of the first
fragment to the right edge of the last fragment. We don't have to loop
over all the fragments to figure this out. :^)
2020-12-07 20:48:26 +01:00
Andreas Kling
59de4adb60 LibWeb: Pass current target box to BFC::run()
The BFC "context box" is now the outer box of the block formatting
context. Previously the context box was always the current target box,
which made it hard to reason about who was really the containing block
of whom in various places.

Note that IFC still has the containing block as its context box, this
change only affects BFC. However, to clarify the situation in IFC,
I've added a containing_block() getter than returns the context_box().
2020-12-06 20:05:04 +01:00
Andreas Kling
31a3ed70f0 LibWeb: Hit test floats using the top of lines, not middle
I don't know why basing the available space between floats on the y
coordinate in the middle of each line seemed like a good idea. It just
creates situations with a few pixels of floats overlapping text!
2020-12-05 23:54:07 +01:00
Andreas Kling
66a053da77 LibWeb: Don't subtract dubious "line spacing" from line y offsets
I'm not sure what this was trying to achieve, but it was moving all
line fragments upwards and a lot of things look a lot better if we
just stop doing that.
2020-12-05 23:17:23 +01:00
Andreas Kling
615a4d4f71 LibWeb: First slightly naive implementation of CSS floats :^)
Boxes can now be floated left or right, which makes text within the
same block formatting context flow around them.

We were creating way too many block formatting contexts. As it turns
out, we don't need one for every new block, but rather there's a set
of rules that determines whether a given block creates a new block
formatting context.

Each BFC keeps track of the floating boxes within it, and IFC's can
then query it to find the available space for line boxes.

There's a huge hack in here where we assume all lines are the exact
line-height. Making this work with vertically non-uniform lines will
require some architectural changes.
2020-12-05 22:51:03 +01:00
Andreas Kling
88ca932fac LibWeb: Make LineBoxFragment store non-const Layout::Node&
This is more honest, since we actually const_cast these layout nodes
during inline layout anyway.
2020-12-04 15:46:58 +01:00
Andreas Kling
d59ec3ab85 LibWeb: Create "empty" line box fragments for inline elements
In order for inline elements (e.g <span>) to contribute padding etc.
to line boxes, we now create special "leading" and "trailing" fragments
for Layout::InlineNode and size them according to the horizontal
padding values.

The height of these fragments is taken from the tallest fragment on the
line. (Perhaps we should stop having per-fragment heights and just keep
a single height per line box, but that's a separate issue.)

In order to make things look nice, we now also adjust the height of all
fragments on a line so that nobody is shorter than the CSS line-height.
2020-12-03 21:45:51 +01:00
Andreas Kling
39c7d9f061 LibWeb: Remove margin/border/padding from inline-block available width 2020-11-29 22:00:44 +01:00
Andreas Kling
d0636291fe LibWeb: Resolve percentage width/height of inline-block boxes
Percentage lengths cannot be to_px()'ed directly, we have to resolve
them against a reference (the containing block) first.

Fixes #4248.
2020-11-29 21:27:41 +01:00
Andreas Kling
b1e75437c9 LibWeb: Keep track of the parent of each formatting context
This will allow us to find the containing block formatting context
when needed later on.
2020-11-25 21:26:58 +01:00
Andreas Kling
5aeab9878e LibWeb: Rename LayoutNode classes and move them into Layout namespace
Bring the names of various boxes closer to spec language. This should
hopefully make things easier to understand and hack on. :^)

Some notable changes:

- LayoutNode -> Layout::Node
- LayoutBox -> Layout::Box
- LayoutBlock -> Layout::BlockBox
- LayoutReplaced -> Layout::ReplacedBox
- LayoutDocument -> Layout::InitialContainingBlockBox
- LayoutText -> Layout::TextNode
- LayoutInline -> Layout::InlineNode

Note that this is not strictly a "box tree" as we also hang inline/text
nodes in the same tree, and they don't generate boxes. (Instead, they
contribute line box fragments to their containing block!)
2020-11-22 15:56:27 +01:00
Andreas Kling
e1a24edfa9 LibWeb: Reorganize layout system in terms of formatting contexts
This is a first (huge) step towards modernizing the layout architecture
and bringing it closer to spec language.

Layout is now performed by a stack of formatting contexts, operating on
the box tree (or layout tree, if you will.)

There are currently three types of formatting context:

- BlockFormattingContext (BFC)
- InlineFormattingContext (IFC)
- TableFormattingContext (TFC)

Document::layout() creates the initial BlockFormattingContext (BFC)
which lays out the initial containing block (ICB), and then we recurse
through the tree, creating BFC, IFC or TFC as appropriate and handing
over control at the context boundaries.

The majority of this patch is just refactoring the old logic spread out
in LayoutBlock and LayoutTableRowGroup, and turning into these context
classes instead. A lot more cleanup will be needed.

There are many architectural wins here, the main one being that layout
is no longer performed by boxes themselves, which gives us much greater
flexibility in the outer/inner layout of a given box.
2020-11-22 14:36:56 +01:00