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.
Get rid of the weird old signature:
- int StringType::to_int(bool& ok) const
And replace it with sensible new signature:
- Optional<int> StringType::to_int() const
Skip over absolutely positioned children when laying out the inline
children of a block. This takes them out of the flow and allows them
to be positioned correctly relative to the (absolute) containing block.
Absolutely positioned elements are placed by their containing block.
Instead of trying to compute its own position, LayoutReplaced will
now simply add itself as an absolutely positioned descendant of its
containing block.
Fixed position elements have the ICB as their containing block.
The magic of fixed positioning is implemented at the rendering stage,
where we temporarily translate painting by the current scroll offset.
Note that "absolutely positioned" includes both position:absolute
and position:fixed.
Absolutely positioned blocks now register themselves with their
containing block (and note that the containing block of an absolutely
positioned box is the nearest non-statically positioned block ancestor
or the ICB as fallback.)
Containing blocks then drive the layout of their tracked absolutely
positioned descendants as a separate layout pass.
This is very far from perfect but the general direction seems good.
We now sort the matched rules by the specificity of the first selector
in them. This is not perfect, since a rule can have multiple selectors,
but it is a nice chin-related progression on ACID2. :^)
This makes us at least parse selectors like [foo=bar\ baz] correctly.
The current solution here is quite hackish but the real fix will come
when we implement a spec-compliant CSS parser.
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.
There was a logic mistake in the entity parser that chose the shorter
matching entity instead of the longer. Fix this and make the entity
lists constexpr while we're here.
* 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.
Objects should get the GlobalObject from themselves instead. However,
it's not yet available during construction so this only switches code
that happens after construction.
To support multiple global objects, Interpreter needs to stop holding
on to "the" global object and let each object graph own their global.
This patch introduces support for more than just "absolute px" units in
our Length class. It now also supports "em" and "rem", which are units
relative to the font-size of the current layout node and the <html>
element's layout node respectively.
Now that PageView actually respects the invalidation rect provided by
the layout system, it turns out we were invalidating too little.
Unfortunately, this is not really fixable until the initial containing
block starts having the right size (same as viewport), but that will
require a bunch of work to make overflow work again. So it's a FIXME
for now, and we'll return to this.
When a paint invalidation occurs inside a subframe, it bubbles up to
Frame::set_needs_display(). From there, we call PageView if this is
the main frame, or otherwise invalidate the subframe host element.