Previously, we would always respect the `text-align` property, even if
the text being aligned was too long for its line box and would be
clipped. This led to seeing the clipped middle/end of strings when we
should instead always see the beginning of the text.
Having one StyleValue for `<number>` and `<integer>` is making user code
more complicated than it needs to be. We know based on the property
being parsed, whether it wants a `<number>` or an `<integer>`, so we
can use separate StyleValue types for these.
If the flex container is being sized under a max-content main size
constraint, there is effectively infinite space available for flex
items. Thus, flex lines should be allowed to be infinitely long.
This is a little awkward, because the spec doesn't mention specifics
about how to resolve flexible lengths during intrninsic sizing.
I've marked the spec deviations with big "AD-HOC" comments.
Instead of just measuring the layout viewport, we now measure overflow
in every box that is a scroll container.
This has the side effect of no longer creating paintables for layout
boxes that didn't participate in layout. (For example, empty/anonymous
boxes that were ignored by flex itemization.)
Such boxes are now marked as "(not painted)" in the layout tree dumps,
as they have no paintable to dump geometry from.
We already clamp these values to zero, so it's actually pretty harmless
when this happens. If someone wants to investigate these issues deeper
and see if they can be fixed earlier in the layout pipeline, they can
enable the spam locally.
These are only used during layout, and always within formatting context
code, so we might as well put them in FormattingContext and avoid having
to pass the LayoutState around all the time.
At one point in the past, we had some functions that were called across
different formatting context types, which necessitated making them
static and taking the LayoutState as a parameter.
In all cases, those functions were used to do incorrect hacks, all of
which we've replaced with more correct solutions. :^)
Separating the paths for replaced and non-replaced floating boxes lost
the logic for margin, padding and border which was done by
compute_width_for_floating_box. Set them the same way as we do for
block-level replaced elements, per the specification.
Solves conflict in layout tree "type system" when elements <label> (or
<button>) can't have `display: table` because Box can't be
Layout::Label (or Layout::ButtonBox) and Layout::TableBox at the same
time.
From spec https://drafts.csswg.org/css-grid/#grid-items:
"Each in-flow child of a grid container becomes a grid item, and each
child text sequence is wrapped in an anonymous block container grid
item."
Fixes the problem that text sequences inside grid containers are
ignored and not displayed.
Fixes the bug that currently we always consider tracks with percentage
size as ones with "fixed" length even when available size is not
definite. With this change tracks with percentage size when available
size is not definite will be considered as "intrinsic" sized.
We were not taking reverse flex directions into account when choosing
the initial offset for flex item placement if justify-content were
either space-around or space-between.
Specifically, stop letting NumericStyleValues holding `0` from
pretending to hold a Length. The parser is now smart enough that we
don't have to do this. :^)
Only NumericStyleValue holds integers.
I'm not sure our current distinction between NumericStyleValue holding
an integer or non-integer is useful given it always returns a float.
:thonk:
In order to support intrinsic size keywords (such as fit-content), we
need to be able to calculate the intrinsic sizes of any element, not
just those that form their own formatting context.
When a non-FC-root element is passed to calculate_some_intrinsic_size(),
we now create a synthetic BFC to handle sizing of them.
The path for floating, replaced elements must not fall through to the
path taken for floating, non-replaced elements. The former works like
inline replaced elements, while the latter uses a completely different
algorithm which doesn't account for intrinsic ratio. Falling through
overrides the correct value computed by the former.
Fixes#19061.
This fixes the issue when margin collapsing state was always reset if
a box has clear property not equal to none even if it does not actually
introduce clearance.
Ignore anonymous block boxes when resolving percentage weights that
would refer to them, per the CSS 2 visual formatting model
specification. This fixes the case when we create an anonymous block
between an image which uses a percentage height relative to a parent
which specifies a definite height.
Fixes#19052.
We now create a flex container inside the input element's UA shadow tree
and add the placeholder and non-placeholder text as flex items (wrapped
in elements whose style we can manipulate).
This fixes the visual glitch where the placeholder would appear below
the bounding box of the input element. It also allows us to align the
text vertically inside the input element (like we're supposed to).
In order to achieve this, I had to make two small architectural changes
to layout tree building:
- Elements can now report that they represent a given pseudo element.
This allows us to instantiate the ::placeholder pseudo element as an
actual DOM element inside the input element's UA shadow tree.
- We no longer create a separate layout node for the shadow root itself.
Instead, children of the shadow root are treated as if they were
children of the DOM element itself for the purpose of layout tree
building.
This fixes the issue where max margin is used to find offset of
floating box although horizonal margins do not collapse so they need
to be summed instead.
This fixes a plethora of rounding problems on many websites.
In the future, we may want to replace this with fixed-point arithmetic
(bug #18566) for performance (and consistency with other engines),
but in the meantime this makes the web look a bit better. :^)
There's a lot more things that could be converted to doubles, which
would reduce the amount of casting necessary in this patch.
We can do that incrementally, however.
Previously, calling `.right()` on a `Gfx::Rect` would return the last
column's coordinate still inside the rectangle, or `left + width - 1`.
This is called 'endpoint inclusive' and does not make a lot of sense for
`Gfx::Rect<float>` where a rectangle of width 5 at position (0, 0) would
return 4 as its right side. This same problem exists for `.bottom()`.
This changes `Gfx::Rect` to be endpoint exclusive, which gives us the
nice property that `width = right - left` and `height = bottom - top`.
It enables us to treat `Gfx::Rect<int>` and `Gfx::Rect<float>` exactly
the same.
All users of `Gfx::Rect` have been updated accordingly.
Before this change, LayoutState essentially had a Vector<UsedValues*>
resized to the exact number of layout nodes in the current document.
When a nested layout is performed (to calculate the intrinsic size of
something), we make a new LayoutState with its own Vector. If an entry
is missing in a nested LayoutState, we check the parent chain all the
way up to the root.
Because each nested LayoutState had to allocate a new Vector with space
for all layout nodes, this could get really nasty on very large pages
(such as the ECMA262 specification).
This patch replaces the Vector with a HashMap. There's now a small cost
to lookups, but what we get in return is the ability to handle huge
layout trees without spending eternity in page faults.
This fixes a crash in box_baseline, due to cells created for
display: table expecting a box child and getting the inline node wrapper
instead.
Fixes#18972.
Using HashTable of grid positions to represent OccupationGrid allows to
simplify positioning code. For example maybe_add_row() and
maybe_add_column() calls are not needed anymore because there is no
Vector<Vector<bool>> that need to be resized.
No observable changes in grid layout are expected :)
Since the specifications indicate that the algorithm for sizing tracks
without any spanning items is a simplified version of the more general
algorithm used for sizing tracks with spanning items, we can reuse the
code to size both cases.
Implements more parts of sizing algorithm for tracks with spanning
items to archive parity with implementation for sizing of tracks
with non-spanning items.
We have to special-case these, otherwise our normal CSS layout algorithm
will see that some SVG roots have width/height assigned, and make those
the used width/height.
When used in an SVG-as-image context, the outermost viewport must be the
authoritative root size.
This allows the painting subsystem to request a bitmap with the exact
size needed for painting, instead of being limited to "just give me a
bitmap" (which was perfectly enough for raster images, but not for
vector graphics).