For computing height in FormattingContext::calculate_intrinsic_sizes
we were calling into BlockFormattingContext::compute_theoretical_height
which will check if the CSS height property was defined and calculate
the height based on that instead of calculating the intrinsic height
This patch adds a new function calculate_intrinsic_height, which will
call into compute_auto_height_for_block_level_element for a block
element, or into compute_height_for_replaced_element for a replaced
element.
We now position inline-level boxes based on ascent and descent metrics
from the font in use. This makes our basic text layouts look a lot more
like those produced by other browsers. :^)
I've tried to match the terminology used by the CSS Inline Layout spec.
This will regress Acid2 a little bit, and probably various other sites,
but on the whole it's the direction we should be heading, so let's go.
This avoids a bunch of unnecessary work in Painter which not only took
time, but sometimes also led to alignment issues. draw_text_run() will
draw the text where we tell it, and that's it.
Unlike BFC root blocks with height:auto, when the block *isn't* a BFC
root, we don't have to look for the "bottommost" block-level child and
determine the width from that.
Instead, we should just look at the last in-flow block-level child.
This was already indicated in the spec comment next to the code, but
the code itself was wrong.
This makes the body element on Acid3 have the correct height. It also
introduces a small regression on Acid2 that we'll have to track down.
Previously, we only allowed floats to take up its own border box's worth
of horizontal space when laid out inside an IFC.
We should instead consume the full margin box horizonally. This fixes an
issue where a floated box on Acid3 had {width:20px; margin-right:-20px;}
but still consumed 20px of the previously available space, despite being
moved out of the way by its own negative margin.
When doing max-content layout, we were not committing newlines even
though we were supposed to due to white-space:pre*.
This broke the WPT harness due to a VERIFY() in ChunkIterator where we
were assuming the commit would always succeed.
Thanks to Orphis for reporting this! :^)
When the spec tells us to measure from the top content edge of a block,
that just means we should measure from Y=0. We don't need to go looking
for a child box with a negative top offset and measure from there.
This gets us a bit closer to the recommended algorithms in CSS 2.2 and
CSS Table Module 3.
A couple of table heavy websites (e.g. news.ycombinator.com,
html5test.com, etc.) now look quite okay. :^)
Previously, the whitespace collapsing code had a parameter telling it
whether the previous text node ended in whitespace. This was not
actually necessary, so let's get rid of it.
This patch reimplements inset property resolution based on the new
CSS Positioned Layout specification. Nothing should change for
left/right insets, but we gain support for top/bottom. :^)
Relatively positioned boxes should not affect the *layout* of their
siblings. So instead of applying relative inset as a layout-time
translation on the box, we now perform the adjustment at the paintable
level instead.
This makes position:relative actually work as expected, and exposes some
new bugs we need to take care of for Acid2. :^)
Before this the flex layout didn't take into account the applied
borders or padding while laying out the items.
The child's top and left borders would get painted over the
parent's borders, also due to it not taking borders into account,
children with borders would overlap each other.
Due to it not taking padding into account, the children would get
drawn outside the parent element.
...but never allow the resulting height to become negative. This solves
an issue seen on Acid3 where elements with negative vertical margins
expanded the size of their height:auto container instead of shrinking
it, which is the correct behavior. This now works :^)
CSS 2.2 says "Horizontal margins never collapse."
So instead of collapsing them, we now add them together, which makes
negative margins between floating boxes work beautifully.
Instead of TextNode::ChunkIterator having two bool members to remember
things across calls to next(), this patch reorganizes the loop in next()
so that preserved newline/whitespace chunks are emitted right away
instead of in an awkward deferred way.
Instead of emitting a Text item with the "should_force_break" flag set
to true, newlines in newline-preserving text content now timply turn
into ForcedBreak items. This makes the <pre> element work again.
BFC roots with children_are_inline()==true can still have floating boxes
as well. children_are_inline() is only concerned with in-flow children.
For this reason, we have to always consider floats when calculating
height:auto for BFC roots.
Collect all the preceding block-level siblings whose vertical margins
are collapsible. Both margin-top and margin-bottom now (previously,
we only considered the margin-bottom of siblings.)
Use the right margin in part-negative and all-negative situations.
We now distribute the line-height evenly between the space above and
below inline-level boxes. This noticeably improves our baseline
alignment in many cases.
Note that the "vertical-align: <length>" case is quite awkward, as the
extra height added by the offset baseline must count towards the line
box height.
There's a lot of room for improvement here, but this makes the buckets
container on Acid3 show up in the right place, with the right size.
Make sure we use the create_anonymous_wrapper() helper function whenever
wrapping inline content in anonymous wrapper blocks. We were forgetting
to do this in one case, which led to some wrapper blocks having 0px
font-size and line-height.
HTMLObjectElement will need to be both a FormAssociatedElement and a
BrowsingContextContainer. Currently, both of these classes inherit from
HTMLElement. This can work in C++, but is generally frowned upon, and
doesn't play particularly well with the rest of LibWeb.
Instead, we can essentially revert commit 3bb5c62 to remove HTMLElement
from FormAssociatedElement's hierarchy. This means that objects such as
HTMLObjectElement individually inherit from FormAssociatedElement and
HTMLElement now.
Some caveats are:
* FormAssociatedElement still needs to know when the HTMLElement is
inserted into and removed from the DOM. This hook is automatically
injected via a macro now, while still allowing classes like
HTMLInputElement to also know when the element is inserted.
* Casting from a DOM::Element to a FormAssociatedElement is now a
sideways cast, rather than directly following an inheritance chain.
This means static_cast cannot be used here; but we can safely use
dynamic_cast since the only 2 instances of this already use RTTI to
verify the cast.
For things like "line-height: 2" to work, the font size must be assigned
before resolving the line height. Previously, the line-height was
resolved first, which meant that numeric and other relative units were
resolved against the default font-size instead.