-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LibWeb: Correctly lay out block elements inside inline elements #3276
base: master
Are you sure you want to change the base?
LibWeb: Correctly lay out block elements inside inline elements #3276
Conversation
92e2698
to
e3732e8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have you considered solving the problem on paintable tree level? I suppose webkit has to use continuations on layout tree because they do not have paintable tree concept, while we do and support 1:N relationship between layout and paintable nodes.
6d662fe
to
1f2ee7e
Compare
This allows for easy child removal similar to `DOM::Node::remove()`.
The existing `::unite_horizontally()` and `::unite_vertically()` tests did not properly test the edge cases where left/top in the Rect were updated, so they get re-arranged a bit.
1f2ee7e
to
49dd2f9
Compare
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.
49dd2f9
to
827da96
Compare
@kalenikaliaksandr @awesomekling I've rearranged some things:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add a test for hit-testing just so we can be sure it works as expected when it comes to continuations?
Absolutely, in fact, I'm also working on a bugfix for something depending on this that involves hit-testing. I'll tack on the commit to this PR. |
The contents of inline elements containing a block element were incorrectly ordered, e.g.
...did not render the
<div>
as being in between thefoo
andbaz
fragments.Excerpt from
Web::Layout::TreeBuilder
:Block nodes inside inline nodes are allowed, but to maintain the invariant that either all layout children are
inline or non-inline, we need to rearrange the tree a bit. All inline ancestors up to the node we've inserted are
wrapped in an anonymous block, which is inserted into the nearest non-inline ancestor. We then recreate the inline
ancestors in another anonymous block inserted after the node so we can continue adding children.
Effectively, we try to turn this:
Into this:
To be able to reconstruct their relation after restructuring, layout nodes keep track of their continuation. The
top-most inline node of the "after" wrapper points to the "middle" wrapper, which points to the top-most inline node
of the "before" wrapper. All other inline nodes in the "after" wrapper point to their counterparts in the "before"
wrapper, to make it easier to create the right paintables since a DOM::Node only has a single Layout::Node.
Appending then continues in the "after" tree. If a new block node is then inserted, we can reuse the "middle" wrapper
if no inline siblings exist for node or its ancestors, and leave the existing "after" wrapper alone. Otherwise, we
create new wrappers and extend the continuation chain.
Inspired by: https://webkit.org/blog/115/webcore-rendering-ii-blocks-and-inlines/