To make this possible, I also had to give each LayoutNode a Document&
so it can resolve document-specific colors correctly. There's probably
ways to avoid having this extra member by resolving colors later, but
this works for now.
CSS defines a very specific paint order. This patch starts steering us
towards respecting that by introducing the PaintPhase enum with values:
- Background
- Border
- Foreground
- Overlay (internal overlays used by inspector)
Basically, to get the right visual result, we have to render the page
multiple times, going one phase at a time.
The box tree and line boxes now all store a relative offset from their
containing block, instead of an absolute (document-relative) position.
This removes a huge pain point from the layout system which was having
to adjust offsets recursively when something moved. It also makes some
layout logic significantly simpler.
Every box can still find its absolute position by walking its chain
of containing blocks and accumulating the translation from the root.
This is currently what we do both for rendering and hit testing.
* A PageView is a view onto a Page object.
* A Page always has a main Frame (root of Frame tree.)
* Page has a PageClient. PageView is a PageClient.
The goal here is to allow building another kind of view onto
a Page while keeping the rest of LibWeb intact.
LayoutReplaced now has intrinsic width, height and ratio. Only some of
the values may be present. The layout algorithm takes the various
configurations into account per the CSS specification.
This is still pretty immature but at least we're moving forward. :^)
We now implement the somewhat fuzzy shrink-to-fit algorithm when laying
out inline-block elements with both block and inline children.
Shrink-to-fit works by doing two speculative layouts of the entire
subtree inside the current block, to compute two things:
1. Preferred minimum width: If we made a line break at every chance we
had, how wide would the widest line be?
2. Preferred width: We break only when explicitly told to (e.g "<br>")
How wide would the widest line be?
We then shrink the width of the inline-block element to an appropriate
value based on the above, taking the available width in the containing
block into consideration (sans all the box model fluff.)
To make the speculative layouts possible, plumb a LayoutMode enum
throughout the layout system since it needs to be respected in various
places.
Note that this is quite hackish and I'm sure there are smarter ways to
do a lot of this. But it does kinda work! :^)