Because we defined `th { text-align: center }` in our UA stylesheet, it
received a higher precedence than inherited (inline) styles. Firefox
deals with this by defining a custom `text-align` value that prioritizes
any inherited value before defaulting to `text-align: center`.
We now do this as well :^)
Before this change, we were always behaving as if box-sizing were
content-box for block-level replaced element widths.
This fixes the squishy logo on https://videolan.org/
For `vertical-align: middle` and `vertical-align: text-bottom`, we used
just the content height of the inline box to determine its alignment
position. This caused incorrect positioning when padding is applied.
This fixes the button alignment on our GitHub page.
Fixes#290.
This fixes an issue where we'd make an absolute mess from nested SVG
roots with display:block. Before this fix, the inner SVG root would
trigger the inline continuation logic and try to split the tree.
Previously the type argument in attr() could be the name of a CSS type
on its own. This has changed, and now only `raw-string`
(previously `string`) or the name of a dimension unit is allowed. Other
types and more complex grammar use the `type()` function, which we
don't yet support.
I've updated the syntax comment, but not the algorithm itself, which
will be reimplemented in a later commit.
Having <link rel=match> in here is confusing. I've also removed the uses
of `length` and `color` as types, as this is no longer valid according
to the spec.
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.
By the time we calculate the min-content height, the width is already
known, so we can use it to calculate the height based on the natural
aspect ratio.
Documents created by DOMParser and fragment documents do not
have an origin set on the document by the spec. These documents
also happen to never become fully active.
By properly implementing the steps for the <img> element to only
update the image data for documents which are fully active, this
fixes a crash for img elements in these types of documents.
Unfortunately, this is not a full fix for the microtask queue case.
This is because it seems possible for node document for an <img>
element to be changed during the microtask queue for that document.
It is not clear to me how this can be fixed in a nice way.
In `InlineLevelIterator`, whenever we call `skip_to_next()` and enter a
node with box model metrics, we could potentially accumulate leading and
trailing metrics. This lead to a weird situation where an element with
`display: inline-block` could adopt the leading metrics of an inline
element that follows it, since we perform the call to
`add_extra_box_model_metrics_to_item()` too late.
Move `skip_to_next()` down so it no longer interferes with the `Item`
we're creating.
The test expectation for
`atomic-inline-with-percentage-vertical-align.html` is updated, although
neither the old nor new results are 100% accurate since either box jumps
one pixel to the right.
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.
The following tests also expose bugs before this PR:
- Layout/input/ol-render-item-values.html: negative ordinal values
- Layout/input/ol-render-deep-hybrid-list-item-list.html: ordinals
deep into the list owner subtree
We assume elsewhere that any abspos element's containing block must be
some kind of Layout::Box, so let's enforce that when deciding if a box
can be such a container.
This fixes a bad downcast on https://serpapi.com/
`BlockFormattingContext::compute_width()` stores the left and right
margins in the layout state at the very end of the function. However,
before doing so, it calls `FormattingContext::calculate_inner_width()`
which ends up calling `FormattingContext::calculate_stretch_fit_width()`
if the current box has `width: fit-content`.
Due to this, `calculate_stretch_fit_width()` would always see the
margins from the layout state as zero and therefore not take them into
account. Subsequently, the calculated width ended up being wrong.
Saving margins on the layout state earlier, before calling
`calculate_inner_width()`, makes sure that the width is calculated
correctly.
An earlier variant of the commit following this one introduced a
regression for the behavior tested here, but did not fail any in-tree
tests. So lets add an explicit regression test to make that easier to
catch in the future.
When marking a part of the layout tree for rebuild, if the subtree root
that we're marking has an anonymous parent, we now mark from the nearest
non-anonymous ancestor instead.
This ensures that subtrees inside anonymous wrappers don't just get
duplicated (i.e recreated but inserted instead of replaced).
This exposed a few bugs which caused the following tests to behave
incorrectly:
- `tab-size-text-wrap.html`: This previously relied on a bug where we
incorrectly treated `white-space: pre` as allowing text wrapping. The
fix here is to implement the text-wrap CSS shorthand property.
- `execCommand-preserveWhitespace.html`: We don't correctly serialize
shorthand properties. This is covered by an existing FIXME in
`CSSStyleProperties::serialized()`
- `white-space-shorthand.html`: The last 5 subtests here fail as we
don't correctly handle shorthand properties in
`CSSStyleProperties::remove_property()`. This is covered by an
existing FIXME in said function.
We used to subtract the maximum right margin of any containing box,
but we want to subtract the entire right margin instead. This yielded
incorrect intrusions for right floats not placed in the root.
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.
Previously floats would be placed next to the highest float that
fitted the new float on its line. However, this violates the rule
that floats should be placed under the preceding float if it does
not fit next to it.
We were previously only testing for network errors, which includes e.g.
DNS resolution and connection errors. It does not include e.g. HTTP 404
responses, which is exercised by Acid 2.
Before this change, we were at the mercy of hashed pointer addresses
when processing fragment relocation in LayoutState::commit().
This made inline fragment order non-deterministic, causing layouts to
shift around seemingly randomly on page reload.
By simply using OrderedHashMap, we automatically get tree order
processing here. This fixes a bunch of flaky tests on WPT.
Originally part of a fix in 15103d172c, it
appears that this is no longer necessary and received a better fix in a
more recent commit. Resolves a visual regression with the ACID3 test.
We would only correct for the left margin of the containing block of the
child box that we are laying out, but we actually need to correct for
all left margins up until the containing block that contains both the
float and the child box.
Fixes#4639.
Browsers such as Chrome and Firefox apply an arbitrary scale to the
current font size if `normal` is used for `line-height`. Firefox uses
1.2 while Chrome uses 1.15. Let's go with the latter for now, it's
relatively easy to change if we ever want to go back on that decision.
This also requires updating the expectations for a lot of layout tests.
The upside of this is that it's a bit easier to compare our layout
results to other browsers', especially Chrome.
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.
In 15103d172c we applied any remaining vertical float clearance to the
BFC's current Y offset for the next block to layout, because a `<br
style="clear: left">` could introduce clearance that would otherwise be
ignored. However, a `<div>` that floats _and_ clears `right` also
introduces this clearance and it is obvious that this should not push
down any subsequent blocks to layout in the current BFC.
Turns out, we don't need this change anymore. Some other later change
also fixed the underlying issue, and by getting rid of the original fix
we can now render https://en.wikipedia.org/wiki/SerenityOS correctly
again.
Fixes#4418.
There's a specific (and thankfully very common!) scenario where we can
actually skip calculating the automatic minimum size for flex items.
In single-line (no wrapping) flex containers, if the sum of all item
flex base sizes is <= the flex container's main size, we know that
none of the items will be shrunk by the layout algorithm.
And so for any flex item with definite main size AND automatic minimum
main size, we can treat the automatic minimum size as 0.
Before this change, we assigned the style sheet's location *after* its
content rules were parsed and added to it. This meant any `@import`s
would try to fetch their style sheet before they knew the URL they
should fetch it relative to.
When determining the content/margin box rects within their ancestor's
coordinate space, we were returning early if the passed in values
already belonged to the requested ancestor. Unfortunately, we had
already applied the used values' offset to the rect, which is the offset
to the ancestor's ancestor.
This simplifies the logic to always apply the rect offset after checking
if we've reached the ancestor. Fixes determining float intrusions inside
block elements with `margin: auto` set.
Fixes#4083.
If a block with inline children ends with a line break clearing any
floats, we not only need to take the introduced clearance into account
for the next line box, but the containing block needs to set the correct
height as well.
Since the spec calls for using the last line box' bottom as the resolved
height (if treated as auto), we now correctly apply the clearance to the
previous line box' bottom coordinate.
Fixes#4058.
We were accidentally providing it with absolute Y-coordinates, messing
up stacked floating boxes that would otherwise intrude on each other.
Fixes#4160.