Const pointers into the DOM was a nice idea, but in practice, there are
too many situations where the layout tree wants to some non-const thing
to the DOM.
LibWeb keeps growing and the Web namespace is filling up fast.
Let's put DOM stuff into Web::DOM, just like we already started doing
with SVG stuff in Web::SVG.
Sometimes people make tables with a specific width. In those cases,
we can't just use the auto-sizing algorithm, but instead have to
respect whatever width the content specifies.
This is a bit rickety right now, since we don't implement generation
of anonymous table boxes.
The basic mechanism here is that block layout (which table-cell uses)
now has a virtual way of asking for the width of the logical containing
block. This is necessary as table-row does not produce a block-level
element and so was previously unable to provide a containing block
width for table-cell layout.
If the table has a non-auto specified width, we now interpret that as
a request to use fixed table layout. This will evolve over time. :^)
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.
Table row layout is now split into two phases:
1. Compute all the column widths (even taking colspan into account!)
2. Place all cells at the correct x,y offsets based on column widths.
Both phases visit all rows and all cells.
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! :^)