When an element is displayed as table, an anonymous table wrapper box
needs to be created for it. Among others, the position property of the
table element is then applied to the anonymous table wrapper box
instead. If the table happens to be positioned absolutely, the table
wrapper box may become the containing block for absolutely positioned
elements inside the table.
In the original code however, anonymous layout nodes were excluded from
becoming the containing block for an absolutely positioned element.
Because of this, the containing block was calculated to be the first
suitable parent block of the table wrapper box.
This incorrect containing block would result in a crash later on when
trying to size the absolutely positioned element inside the table. To
prevent this crash, the anonymous table wrapper box is now allowed to
become the containing block for absolutely positioned elements inside
a table.
The definition of containing block for an absolutely positioned element
in the spec does not mention anything about skipping anonymous boxes.
Additionally the rules for absolute positioning of tables
(https://www.w3.org/TR/css-tables-3/#abspos-boxes-in-table-root) imply
that a table wrapper box is indeed able to be the containing block for
absolutely positioned elements.
Instead just update the existing wrapper with computed values from the
table box, to insure that upside-down "inheritance" works as expected.
This allows table fixup to run on partially updated layout trees without
adding a new layer of unnecessary wrappers every time.
Same again, although rotation is more complicated: `rotate`
is "equivalent to" multiple different transform function depending on
its arguments. So we can parse as one of those instead of the full
`rotate3d()`, but then need to handle this when serializing.
This reverts commit 76daba3069.
We're going to need separate types for the JS-exposed style values, so
it doesn't make sense for us to match their names with our internal
types.
CSS filters work similarly to canvas filters, so it makes sense to have
Gfx::Filter that can be used by both libraries in an analogous way
as Gfx::Color.
Implemented by reusing AddMask display list item that was initially
added for `background-clip` property.
Progress on flashlight effect on https://null.com/games/athena-crisis
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:
* JS::NonnullGCPtr -> GC::Ref
* JS::GCPtr -> GC::Ptr
* JS::HeapFunction -> GC::Function
* JS::CellImpl -> GC::Cell
* JS::Handle -> GC::Root
Now that the heap has no knowledge about a JavaScript realm and is
purely for managing the memory of the heap, it does not make sense
to name this function to say that it is a non-realm variant.
The StyleResolver can find the specified CSS values for the parent
element via the DOM. Forcing everyone to locate specified values for
their parent was completely unnecessary.
Layout nodes now only carry CSS computer values with them. The main
idea here is to give them only what they need to perform layout, and
leave the rest back in the DOM.
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.
Let's start moving away from using raw strings for CSS identifiers.
The idea here is to use IdentifierStyleValue with a CSS::ValueID inside
for all CSS identifier values.
Within the same stacking context, positioned elements must be painted
after non-positioned ones.
I added a Layout::Node::for_each_child_in_paint_order() to help with
this since it's also needed for hit testing.
This is definitely not fully-featured, but basically we now handle
the clear property by forcing the cleared box below the bottom-most
floated box on the relevant side.
I had guessed that floating boxes should somehow be hoisted up to the
nearest block ancestor that creates a block formatting context, but
that's just wrong. They move up to the nearest block ancestor like any
other box that's not absolutely (or fixed) positioned. :^)
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.
Instead of doing a CSS property lookup for the line style of each
border edge during paint, we now cache the final CSS::LineStyle to use
in the Layout::BorderData.