Add a new struct `LayoutBoxBase`, that will be used throughout the box
tree. The idea of this struct is that we have a place to consistently
store common layout information (style and node information) and also to
cache layout results such as content sizes (inline and maybe later box
sizes) and eventually layout results.
In addition to the addition of this struct,
`IndependentFormattingContext` is flattened slightly so that it directly
holds the contents of both replaced and non-replaced elements.
This is only added to independent formatting contexts, but will later be
added to all block containers as well.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
We were sizing absolutely positioned replaced elements within their
actual containing block instead of the inset-modified containing block.
Then the `stretch` keyword would result in a wrong size.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* Add missing support for some alignment keywords on absolutely positioned elements
Signed-off-by: taniishkaaa <tanishkasingh2004@gmail.com>
* Check the direction of the alignment container, nits, test expectations
In this case we need to check the direction of the static position
containing block, not the actual containing block:
```html
<!DOCTYPE html>
<div style="position: relative">
<div style="display: flex; flex-direction: column; width: 100px; height: 100px; border: solid; direction: rtl">
<div style="position: absolute; width: 20px; height: 20px; background: cyan; top: 20px; align-self: self-start"></div>
<div style="position: absolute; width: 20px; height: 20px; background: magenta; bottom: 20px; align-self: self-end"></div>
</div>
</div>
```
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
---------
Signed-off-by: taniishkaaa <tanishkasingh2004@gmail.com>
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
`AbsoluteAxisSolver::solve()` would compute, among other things, the
position of the absolute positioned element if it had start alignment.
Then, `AbsoluteAxisSolver::origin_for_alignment_or_justification()`
could optionally opt into modifying that alignment if needed.
This was quite convoluted and not easy to follow. It's simpler to not
compute the position in `AbsoluteAxisSolver::solve()`, and instead do it
always in `AbsoluteAxisSolver::origin_for_alignment_or_justification()`,
which I'm renaming to `AbsoluteAxisSolver::origin_for_margin_box()`
because it aligns the margin box of the abspos within its alignment
container.
Then the `Anchor` struct becomes useless and can be removed.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
The containing block for the static position of an absolutely positioned
element in flex layout is established by the flex container. However, if
the flex container has static position, the actual containing block will
be established by another ancestor.
If the flex container and the containing block have different directions,
the static position needs especial handling when aligning the abspos.
We were already trying to do so with the `flip_anchor` flag, but there
were bugs.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* Refactor computation of preferred aspect ratios
Computing min/max-content sizes required a ContainingBlock in order to
resolve the padding and border when determining the preferred aspect
ratio. However, all callers already knew the padding and border, so they
can compute the ratio themselves, and pass it directly instead of
the ContainingBlock.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* Put preferred aspect ratio into ConstraintSpace
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
---------
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
We were using the preferred aspect ratio provided by the `aspect-ratio`
property instead of the natural aspect ratio. However, the preferred
aspect ratio should only be used to size the replaced element. To paint
the replaced contents into that element we need the natural ratio.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* Support justify-self on absolutely positioned elements
Signed-off-by: L Ashwin B <lashwinib@gmail.com>
* updating test expectations
Signed-off-by: L Ashwin B <lashwinib@gmail.com>
---------
Signed-off-by: L Ashwin B <lashwinib@gmail.com>
In order to support size keywords in block layout, we may need to call
`inline_content_sizes()` in order to compute the min/max-content sizes.
But this required a mutable reference in order the update the cache,
and in various places we already had mutable references.
So this switches the cache into a RwLock to avoid needing mutable refs.
Note OnceCell wouldn't work because it's not thread-safe.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
In most cases we already had a LazyCell anyways, since we could need the
value for multiple properties. Instead of passing a callback that forces
the evaluation of the LazyCell, it's simpler to just pass the LazyCell
directly.
Also, this way we no longer need mutable references.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
To compute the min-content and max-content inline sizes of a replaced
element, we were only using the aspect ratio to transfer definite block
sizes resulting from clamping the preferred block size between the min
and max block sizes.
However, if the preferred block size is indefinite, then we weren't
transfering the min and max through the aspect ratio.
This patch adds a `SizeConstraint` enum that can represent these cases,
and a `ConstraintSpace` struct analogous to `IndefiniteContainingBlock`
but with no inline size, and a `SizeConstraint` block size.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This is the second flexbox caching change. It seeks to detect when a
relayout can be avoided in the case of a stretching flex item. This
heuristic can be combined, because currently we still do relayout
sometimes when we do not need to.
For instance currently we always relayout when a flex child is itself a
column flex. This only needs to happen when the grandchildren themselves
grow or shrink. That optimization is perhaps a lower priority as
`flex-grow: 0 / flex-shrink: 1` is the default behavior for flex.
Since this change means we more consistenly zero out the percentage part
of `calc` expressions when they have circular dependencies, this causes one
test to start failing (`/css/css-values/calc-min-height-block-1.html`).
This is related to w3c/csswg-drafts#10969, which is pending on further
discussion in the working group.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This unifies the size resolution into AbsoluteAxisSolver, since it needs
to know the size in order to resolve auto margins correctly anyways.
This will allow adding support for sizing keywords in a follow-up patch.
Also, this avoids doing multiple layouts due to min and max constraints,
improving performance.
Additionally, tables may end up having a custom size, different than
what we would expect by just looking at the sizing properties. This
patch ensures that we resolve margins correctly with the final size,
resulting in 2 tests now passing.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This was only used for serializing inset properties in getComputedStyle,
but it was unnecessary and the logic was wrong anyways: an `auto` size
doesn't imply that we won't be overconstrained, because it won't become
negative even if the insets are big enough.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
The result of `inline_content_sizes()` may depend on the block size of
the containing block, so we were always recomputing in case we got
a different block size.
However, if no content has a vertical percentage or stretches vertically,
then we don't need to recompute: the result will be the same anyways.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This will allow callers to start obeying `min-content`, `max-content`,
`fit-content` and `stretch` in follow-up patches.
The old functionality is kept as deprecated methods that we should
eventually remove.
This patch has very little impact on the existing behavior, just some
very minimal implementation of the keywords for css tables.
This also overhauls fixed-layout-2.html since:
- It had code that wasn't doing anything
- It had wrong expecations in prose
- The logic seemed broken in general
- All browsers were failing one testcase
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This also makes a couple small improvements:
- Rename `IntrinsicSizes` to `NaturalSizes` which reflects more
modern spec language.
- Move the conversion of Stylo's `ImageRendering` to WebRender's
version to a `ToWebRender` trait implementation.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This change removes the `effective_writing_mode` concept and tries to
properly implement right-to-left layout support for all non-inline
writing modes. In general, what needs to happen is that rectangles
need to be converted to physical rectangles using the containing block.
A right-to-left rectangle's inline start is on the right physical side
of the containing block. Likewise a positive inline offset in
right-to-left text is a negative physical one.
The implementation here is pretty good for most layout modes, but floats
are still a bit in process. Currently, floats are processed in the
logical layout of the block container, but there still might be issues
with float interaction with mixed RTL and LTR.
While this does move us closer to supporting vertical writing modes,
this is still unsupported.
New failures:
- Vertical writing mode not supported:
- `/css/CSS2/floats/floats-placement-vertical-001b.xht`
- `/css/CSS2/floats/floats-placement-vertical-001c.xht`
- Absolutes inlines should avoid floats (#33323)
- `/css/css-position/position-absolute-dynamic-static-position-floats-004.html`
- No support for grid
- `/css/css-align/self-alignment/self-align-safe-unsafe-grid-003.html`
- `/css/css-position/static-position/inline-level-absolute-in-block-level-context-009.html`
- `/css/css-position/static-position/inline-level-absolute-in-block-level-context-010.html`
- Cannot reproduce these locally on any platform. Very mysterious:
- `/css/css-tables/row-group-margin-border-padding.html`
- `/css/css-tables/row-margin-border-padding.html`
- Exposes bugs we have related to hanging whitespace in preserved
whitespace inlines:
- `/css/css-text/white-space/trailing-space-and-text-alignment-rtl-003.html`
- `/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-023.html`
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
* Use app unit in `ComputedValuesExt`
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
* Some miscellaneous fixes
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
* remove redundant defination of `containing_block_inline_size`
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
---------
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This implements the requirements outlined in the [flexbox specification]
about how to position absolute children of flex containers. We must
establish a static position rectangle (to use if all insets are auto)
and also align the child into that rectangle.
[flebox specification]: https://drafts.csswg.org/css-flexbox/#abspos-items
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
In particular, this takes into account that flex items may be stretched,
and if they have an aspect ratio, we ma6y need to convert the stretched
size through the ratio.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
When computing the min-content or max-content size of an element we
need to ignore `inline-size`, `min-inline-size` and `max-inline-size`.
However, we should take the block-axis sizing properties into account.
That's because the contents could have percentages depending on them,
which can then affect their inline size via an aspect ratio.
Therefore, this patch adds `IndefiniteContainingBlock`, which is similar
to `ContainingBlock`, but it allows an indefinite inline-size. This
struct is then passed arround during intrinsic sizing.
More refinement will be needed in follow-up patches in order to fully
address the problem.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
We want to selectively enable right-to-left writing modes per layout
context. This change makes that possible by allowing access to
`writing-mode` though an interface that always returns the default
horizontal top-to-bottom (implicitly left-to-right) writing mode.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
This converts all geometry in the FragmentTree into physical geometry,
doing conversions ahead of time instead of when traversing the fragment
tree. This is necessary to properly implement BiDi in Servo as we need
to know what side borders are on in mixed RTL and LTR contexts.
In addition, fragments are laid out in a particular context and only
that context knows its writing mode. There were issues where were using
one writing mode to lay out and another to convert to phyisical
coordinates. This isn't an issue now since we only use the default
writing mode, but starts to be an issue with BiDi text.
Closes#25564.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Refactor inline layout to allow rendering line items in the second stage
to be rendered in any order, independent of their parent inline box.
This will allow line items to be reordered, effectively allowing the
splitting of inline boxes, for the purposes of BiDi and any other inline
reordering feature.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
Make using the logical geometry types more ergonomic by having them all
implement `Copy` (at most 4 64-bit numbers), similar to what `euclid`
does. In addition add an implementation of `Neg` for `LogicalVec` and
`LogicalSides` as it will be used in upcoming table implementation code.
This requires passing through information about whether or not the
element in question is replaced when checking to see if it's
transformable and transitively all functions that make decisions about
containing blocks. A new FragmentFlag is added to help track this -- it
will be set on both the replaced items BoxFragment container as well as
the Fragment for the replaced item itself.
Fixes#31806.
* make margin in pbm use app unit
* Simplification
* Consistently resolve inline margins as Au, like block margins
---------
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* fixed typo in PositioningContext
Signed-off-by: Wepngong Maureen <maureenwepngong@gmail.com>
* fixed unresolved link to unresolved link to adjust_static_position_of_hoisted_fragments function
Signed-off-by: Wepngong Maureen <maureenwepngong@gmail.com>
* fixed unresolved link to unresolved link to len() function of PositioningContext
Signed-off-by: Wepngong Maureen <maureenwepngong@gmail.com>
---------
Signed-off-by: Wepngong Maureen <maureenwepngong@gmail.com>
* Treat indefinite percentages as auto offsets in relative positioning
Instead of just resolving the percentages against zero.
The spec is not clear (https://github.com/w3c/csswg-drafts/issues/9353),
but this way we match Gecko, Blink and WebKit.
* Update test expectations
* Fix size of tables in flow layout
The contents of a table can make it bigger than what we would expect
from its 'width', 'min-width', 'height' and ' min-height' properties.
Also, 'width: auto' doesn't stretch it to fill the containing block.
We had to refactor the resolution of margins to happen after layout,
otherwise 'auto' margins wouldn't align correctly.
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
* Feedback
* Consistently use `containing_block_for_table` in table layout
* Update test result
---------
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This adds support for table rows, columns, rowgroups and colgroups.
There are few additions here:
1. The createion of fragments, which allows script queries and hit
testing to work properly. These fragments are empty as all cells are
still direct descendants of the table fragment.
2. Properly handling size information from tracks and track groups as
well as frustrating rules about reordering rowgroups.
3. Painting a background seemlessly across track groups and groups. This
is a thing that isn't done in legacy layout (nor WebKit)!
Co-authored-by: Oriol Brufau <obrufau@igalia.com>