We were always creating an anonymous container for the inline contents
of table cells, but the layout node we spawn for the table cells
themselves already is capable of dealing with inline nodes. Regular
logic should kick in for dealing with the block/inline node invariant.
This patch does two things:
1. Makes TreeBuilder never cross the foreignObject boundary when looking
for an appropriate insertion parent. Before this change, we would
sometimes make things inside the foreignObject DOM subtree have
layout nodes outside the foreignObject.
2. Makes foreignObject boxes participate in the anonymous wrapping of
inline-level boxes. This is particularly imporant for absolutely
positioned elements inside foreignObject, which were previously
getting incorrectly wrapped if there was any text (even empty)
preceding the abspos element.
There are multiple things happening here which are interconnected:
- We now use AbstractElement to refer to the source of a counter, which
means we also need to pass that around to compute `content`.
- Give AbstractElement new helper methods that are needed by
CountersSet, so it doesn't have to care whether it's dealing with a
true Element or PseudoElement.
- The CountersSet algorithms now walk the layout tree instead of DOM
tree, so TreeBuilder needs to wait until the layout node exists
before it resolves counters for it.
- Resolve counters when creating a pseudo-element's layout node. We
awkwardly compute the `content` value up to twice: Once to figure out
what kind of node we need to make, and then if it's a string, we do
so again after counters are resolved so we can get the true value of
any `counter()` functions. This will need adjusting in the future but
it works for now.
This is one of those cases where the spec says "element" and
means "element or pseudo-element". The easiest way to handle both is to
make these be free functions that take an AbstractElement, and then
give AbstractElement some helper methods so that the caller doesn't
have to care which it's dealing with.
There are some FIXMEs here because PseudoElement doesn't have a
CountersSet yet, and because the CountersSet currently uses a
UniqueNodeID to identify counter sources, which doesn't support
pseudo-elements.
When restructuring a block node inside an inline parent, if the
nearest block ancestor is `display: inline-block`, ensure that
the generated anonymous wrappers also have `display: inline-block`.
This fixes layout issues with block elements nested
inside inline-block elements.
Whenever we introduce a block element in a container that at that point
has only had inline children, we create an anonymous wrapper for all the
inline elements so we can keep the invariant that each container
contains either inline or non-inline children. For some reason, we
ignore all the out-of-flow nodes since they are layed out separately and
it was thought that this shouldn't matter.
However, if we are dealing with inline blocks and floating blocks, the
order of the inline contents _including_ out-of-flow nodes becomes very
important: floating blocks need to take the order of nodes into account
when positioning themselves.
Fix this by simply hoisting the out-of-flow nodes into the anonymous
wrapper as well.
Fixes the order of blocks in #4212. The gap is still not present.
The upcoming generated types will match those for pseudo-classes: A
PseudoElementSelector type, that then holds a PseudoElement enum
defining what it is. That enum will be at the top level in the Web::CSS
namespace.
In order to keep the diffs clearer, this commit renames and moves the
types, and then a following one will replace the handwritten enum with
a generated one.
Before this change, the layout tree for slots was only updated after
creating a layout node for the slot itself. This was not enough to
account for partial layout tree rebuilds when the slot content changed.
With this change, we always recurse into the slot content.
Fixes expanding and collapsing of nodes in DOM tree inspector broken in
9b26f7eb0f
This fixes an issue where CSS vertical-align on a table-cell box would
incorrectly apply to both the table-cell box and any inline content it
had inside.
This reduces the number of `.cpp` files that need to be recompiled when
one of the below header files changes as follows:
CSS/ComputedProperties.h: 1113 -> 49
CSS/ComputedValues.h: 1120 -> 209
Having one big `if` to determine whether or not we should restructure an
inline layout node became a bit unwieldy. This extracts the logic into a
separate method.
When restructuring inline nodes because of a block element insertion
during the layout tree build, we might end up with a `display: contents`
element in the ancestor stack that is not part of the actual layout
tree, since it's never actually used as a parent for any node. Because
we were only rewinding the ancestor stack with actual new layout nodes,
it became corrupted and layout nodes were added to the wrong parent.
This new logic leaves the ancestor stack intact, only replacing layout
nodes whenever a new one is created.
Fixes the sidebar on https://reddit.com.
Fixes#3590.
This was mainly a matter of deferring the wrapping of the button's
children until after its internal layout tree has been constructed.
That way we don't lose any pseudo elements spawned along the way.
Fixes#2397.
Fixes#2399.
Our layout tree requires that all containers either have inline or
non-inline children. In order to support the layout of non-inline
elements inside inline elements, we need to do a bit of tree
restructuring. It effectively simulates temporarily closing all inline
nodes, appending the block element, and resumes appending to the last
open inline node.
The acid1.txt expectation needed to be updated to reflect the fact that
we now hoist its <p> elements out of the inline <form> they were in.
Visually, the before and after situations for acid1.html are identical.
DOM nodes now have two additional flags:
- Needs layout tree update
- Child needs layout tree update
These work similarly to the needs-style-update flags, but instead signal
the need to rebuild the corresponding part of the layout tree.
When a specific DOM node needs a layout tree update, we try to create
a new subtree starting at that node, and then replace the subtree in the
old layout tree with the newly created subtree.
This required some refactoring in TreeBuilder so that we can skip over
entire subtrees during a tree update.
Note that no partial updates happen yet (as of this commit) since we
always invalidate the full layout tree still. That will change in the
next commit.
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.
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 main motivation behind this is to remove JS specifics of the Realm
from the implementation of the Heap.
As a side effect of this change, this is a bit nicer to read than the
previous approach, and in my opinion, also makes it a little more clear
that this method is specific to a JavaScript Realm.
This change fixes handling for substep ii of the “F. Name From Content”
step at https://w3c.github.io/accname/#step2F in the “Accessible Name
and Description Computation” spec — to correctly include any ::before
and ::after pseudo-element content in the computation of accessible
names. Otherwise, without this change, accessible names unexpectedly
don’t include that pseudo-element content.
This patch implements the "remove irrelevant boxes" and "generate
missing child wrappers" parts of table fixup.
"Generate missing parents" is left as a task for our future selves.
Various whitespace-related issues have been fixed, and support for the
different CSS white-space values is improved enough that I think we can
stop doing the hack where we just prune whitespace nodes from the tree
and actually let them show up.
This is a nice step forward for correctness with the slight downside of
cluttering up layout tree dumps with tons of whitespace text nodes.
But hey, that's the web we know & love. :^)
Fixes#4427.
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.