When laying out a grid item, the tentative block size that is used to
determine the intrinsic inline sizes was different than the one used in
the containing block for the contents. The latter is now used for both
cases.
Testing: A test is now passing.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
With the work to unify the layout logic for replaced and non-replaced
boxes (#37942), I think the `IndependentNonReplacedContents` enum does
no longer make much sense.
Therefore, this removes `IndependentNonReplacedContents`, merging its
values into `IndependentFormattingContextContents`.
The methods defined on `IndependentFormattingContextContents` can now be
on `IndependentFormattingContext`, in particular this implies that the
layout results of a replaced box will now be cached.
Testing: Unneeded (no behavior change)
This part of #37942
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Laying out a float or atomic inline will now use the same logic
regardless of whether it's replaced or not.
This reduces the amount of code, and should have no observable effect.
Testing: Unneeded (no behavior change)
This part of #37942
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
When a style change does not chang the structure of the box tree, it is
possible to skip box tree rebuilding for an element. This change adds
support for reusing old box trees when no element has that type of
damage. In order to make this happen, there needs to be a type of
"empty" `LayoutDamage` that just indicates that a fragment tree layout
is necessary.
This is the first step toward incremental fragment tree layout.
Testing: This should not change observable behavior and thus is covered
by
existing WPT tests. Performance numbers to follow.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Laying out a flex item will now use the same logic regardless of whether
it's replaced or not.
This reduces the amount of code, and should have no observable effect.
Testing: Unneeded (no behavior change)
This part of #37942
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Implement internal pseudo element, which would be resolved as a
"Implemented Pseudo Element" within style computation. This is an
concrete element that would has a primary style after the style
computation, but could match and style resolved like an pseudo element.
Therefore, it would have a different behavior compared to how does
`pseudo`s that `ServoLayoutNode` had. Where they would not have a
concrete element behind it. Note that, due to the nature of these pseudo
elements residing inside a UA widget, these pseudo elements would
therefore not be accessible in JavaScript by default.
This kind of element is required in order to implement the [form control
pseudo element](https://drafts.csswg.org/css-forms-1/#pseudo-elements)
like `::placeholder`, `::color-swatch`, `::field-text`, etc.
See [this docs](https://hackmd.io/@ChaKweTiau/BJ3zRdLQlg) for more
details of the implementation.
Then, the implemented pseudo element is utilized to implement style
matching for input `type=text`.
Servo's side of: https://github.com/servo/stylo/pull/212
Testing: No WPT regression.
---------
Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
`BoxFragment` had 2 fields that are only relevant for block-level boxes:
`clearance` and a boxed `block_margins_collapsed_with_children`.
This moves both pieces of data into a new `BlockLevelLayoutInfo` struct,
which is boxed.
As a result, the size of `BoxFragment` is reduced from 272 to 264 bytes.
Testing: Unneeded (no behavior change)
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Laying out an absolutely or fixedly positioned box will now use the same
logic regardless of whether it's replaced or not.
This reduces the amount of code, and should have no observable effect.
Testing: Unneeded (no behavior change)
This part of #37942
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Previously, anonymous boxes, such for anonymous table parts were not
associated with their non-pseudo ancestor DOM nodes. This presents a
problem when it comes time to clear layout data during incremental
layouts. This change reworks the way that pseudo-elements in general are
stored in their non-pseudo ancestor DOM nodes, allowing for any number
to be placed there.
This trades a bit of performance for space, as just adding a vector to
the node would add something like 24 bytes of storage to every node.
This change should have a neutral runtime memory usage.
Testing: This shouldn't change observable behavior and is thus covered
by
existing WPT tests. It will allow tests to pass in a subsequent PR.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Clearance only applies to block-level boxes, so it was unnecessary to
require it as a parameter. Instead, in block layout we can set it using
the new `.with_clearance()` method.
Testing: Unnecessary (no behavior change)
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
It was very easy to forget about using `.with_specific_layout_info()` to
set the specific layout info, so it's better to make it a parameter.
In fact this already happened in the past: #36993 fixed the missing
specific layout info for flex items.
This patch fixes it for floats and atomic inlines. It also propagates it
in other cases where not doing so was not a big deal because the
specific layout info was None, but that was a fragile assumption.
Testing: Various WPT improvements
Fixes: #37898
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Layout: Add incremental box tree construction for inline floats and
abspos
Due to false positives in the memory benchmark on CI, the previous PR
[37868](https://github.com/servo/servo/pull/37868) reverted. Now it is
resubmitted.
Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
This reverts commit 19ceccc8eb due to a
significant increase in resident memory usage (See
https://github.com/servo/servo/issues/37887).
Testing: This is a revert due to a regression
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
The logic for laying out block-level replaced elements wasn't taking
floats into account when resolving a `stretch` inline size. By handling
them with the same logic as non-replaced elements, we fix that problem,
and reduce the amount of code.
Testing: Adding new tests
Fixes: #37861
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This changes extend the incremental box tree construction for inline
out-of-flow-box, including the
`InlineItem::OutOfFlowAbsolutelyPositionedBox` and
`InlineItem::OutOfFlowFloatBox`.
Testing: This should not change observable behavior and is thus covered
by existing WPT tests.
Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
This changes extend the incremental box tree construction for inline
atomic
Testing: This should not change observable behavior and is thus covered
by existing WPT tests.
Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
Layout: Continue support incremental box tree reconstruction for
flex&taffy level box
This change reuse the flex/taffy level box from old box slot if the box
slot is valid and there is no LayoutDamage to the element.
Testing: This should not change observable behavior and is thus covered
by existing WPT tests.
Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
This change extends incremental box tree updates to table columns.
Testing: This should not change observable behavior and is thus covered
by existing WPT tests.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Previously, our Servo-specific spatial tree scroll offsets were opposite
to
that of WebRender and also the web platform. This is due to the fact,
likely, that `winit` wheel directionality is also flipped. This change
has both the Servo spatial tree and the API take offsets that are
consistent with the web.
Any possible changes to the meaning of wheel directionality will be
handled in a followup change.
This is a breaking change to the Servo API.
Testing: This change updates unit tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This change extends incremental box tree updates to table cells. In
addition, for simplicity this refactors `BoxSlot::take_layout_box()`
into `BoxSlot::take_layout_box_if_undamaged()`.
Testing: This should not change observable behavior and is thus covered
by existing WPT tests.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This change extends incremental box tree updates to table captions. In
addition, calls to `LayoutBox::invalidate_cached_fragment()` are moved
to the damage calculation traversal.
Testing: This should not change observable behavior and is thus covered
by existing WPT tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
In quirks mode, the ::marker of a bare `<li>` should be
`list-style-position: inside`,
Testing: Some WPT improvement
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This change:
- Adds a new type of LayoutDamage that signifies that a box needs its
children recollected, because one or more of them need to be rebuilt.
- During restyle damage propagation, propagate this new damage upward in
the tree. Then box tree construction should be able to preserve any
still-valid box tree nodes from box slots.
- During BlockLevelBox job finalization, if a box slot is valid and
there is not LayoutDamage to the element, use the old box slot,
ensuring that its fragment cache is invalidated.
Testing: This should not change observable behavior and thus is covered
by existing WPT tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: coding-joedow <ibluegalaxy_taoj@163.com>
This improves naming of layout categories and adds tracing for each
layout phase.
Testing: This just adds / adjusts profiling categories, so doesn't need
tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
In layout, some parts of the code were still using parallel iterators
from Rayon even when single-thread layout was activated. This change
modifies those parts to use non-parallel iterators when
`LayoutContext::use_rayon` is not active.
Testing: It's very hard to make an automated test for this, but I've
manually
verified this by building with tracing and observing that layout runs
only on
a single thread now when loading https://servo.org.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This stylesheet was being included both in quirks mode and in limited
quirks mode. It should only be the former.
Testing: adding new test.
Part of #37813
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This implementation is quite confusing as it makes it harder to tell
that we are just looking for the case that `Contents` contains
`NonReplacedContents`.
Testing: This shouldn't have any functional change, so is covered by
existing tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
#37433 didn't handle intrinsic contributions. This patch computes the
correct SizeConstraint to be used as the ConstraintSpace's block size
when computing intrinsic inline sizes.
Testing: Adding new test
Fixes: #37478
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Add methods to retrieve the natural, default and fallback sizes per each
axis (inline or block), rather than computing both simultaneously.
Sometimes we only want one size, and I think it's clearer this way.
Testing: Unnecessary (no behavior change)
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
`FlexContainer::layout()` was forcing `depends_on_block_constraints` to
true for `flex-direction: column`. However, it doesn't make sense to do
that only for `column` but not for `column-reverse`. Also no test is
complaining, so I'm just removing that logic.
Testing: no behavior change is intended, so just existing test coverage
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
The creation of `LayoutContext` does more work than necessary if layout
just needs to do something like make a display list and not restyle and
relayout. This change makes it so that these kind of non-restyle layouts
do not need to create a display list. In addition, the creation of
`LayoutContext` is better encapsulate
Testing: This should not change observable behavior and is thus covered
by existing WPT tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
- Move some of the image handling code to a separate function.
- Move reflow event debugging into layout itself and use the `Debug`
implementation to print the event.
- A few other small cleanups
Testing: This should not change behavior and is thus covered by existing
WPT
tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This reduces the amount of work necessary when running layout, by making
restyle information optional in the `ReflowRequest`. When restyling
isn't
necessary, the option is `None`.
Testing: This shouldn't change any observable behavior and thus is
covered
by existing WPT tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This will allow Servo to add custom types of damage in the near future
which correspond to minor phases layout. The damage exposed by Stylo
only corresponds to the major layout phses. In the future, both phases
will likely be managed by Servo itself and implementors will need to
provide their own damage system entirely.
Testing: This shouldn't change behavior and thus is covered by existing
tests.
Stylo PR: https://github.com/servo/stylo/pull/207
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This is used to capture information about what layout phases are
necessary for a given `ReflowGoal`. It's moved closer to where these
decisions are made and it should be easier to understand what the values
mean. They had gotten a bit out of sync with how queries and layout were
implemented.
Testing: This shouldn't change observable behavior and thus should be
covered
by existing WPT tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Instead of doing a restyle whenever layout is requested, only do one if
script believes that the `Document` has changed in a way that needs a
restyle. In addition, track the different reasons this might be the
case. This will be used later to provide better debugging output.
In layout, when a restyle isn't requested, provide:
- an early return if layout is up-to-date enough for the reflow goal.
- skipping restyle and reflow if it isn't necessary.
Testing: This should not change observable behavior, and thus is covered
by existing tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This change fixes an issue and makes a few more minor improvements to
the `ImageAnimationState`:
1. Image rooting and unrooted now happens in one step from
`Window::update_animations_post_reflow`.
2. The `node_to_animating_image_map` is now stored as a shared `RwLock`
so that it doesn't need to be taken and then replaced in the
`ImageAnimationState` during reflow. This should prevent a hypothetical
issue
where image animations are restarted during empty reflows.
3. General naming and idiomatic Rust usage improvements.
Testing: This doesn't really have any obvious behavioral changes,
because all
reflows currently trigger a restyle. It becomes a serious problem with
#37677
and this change fixes the failing test there.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Now that we are standardizing on the `_traits` crates becoming `_api`
and exposing the API of the crate that they get their name from [^1],
`script_layout_interface` becomes `layout_api` as it exposes the API for
`layout` that is used by `script` This brings the crate in line with the
naming of the other ones in `shared`.
[^1]:
https://servo.zulipchat.com/#narrow/channel/263398-general/topic/Organizing.20*_traits.20crates/with/396893711
Testing: This should not change any behavior and thus is covered by
existing tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
No longer store scroll offsets for elements in the DOM. Instead
consistently get and set these in layout's `ScrollTree`. This more
consistently requires layout to run when querying scroll offsets, which
ensures that they are up-to-date and properly bounded by scrollable
overflow area.
Testing: This causes several WPT tests to start passing, and one to
start
failing. In the case of
`/shadow-dom/scroll-to-the-fragment-in-shadow-tree.html`, I believe the
issue
is that we don't properly handle scrolling and shadow DOM elements.
Before, the
faulty scrolling was hiding this issue.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Add debug option `dump-scroll-tree` to print the scroll tree that had
been stored after each reflow, or log that the scoll tree is not
initialized yet..
To reduce the coupling, the debug print operation will process the
scroll tree node list that have been constructed in the stacking context
tree. It will generate a adjacency list and do preorder traversal. The
order of the tree then will depends on the order of the node in the node
list that has been constructed. Which, in turn, correspond to the
declaration order of the nodes.
This would help with the analysis and development of post composite
queries and its caching.
cc: @xiaochengh
Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
Zero-sized gradient border images cause WebRender to panic, so simply
don't add them to the display list.
Testing: This change adds a WPT crash test.
Fixes: #37432
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Highlights from the devtools trigger reflows. Previously, incremental
layout would notice that nothing about the box tree changed and skip
generating a new display list. This caused the highlights to never be
painted.
Forcing a new DL in this case makes reflows that happen *while* there is
a highlighted DOM node (which did not change since the last reflow)
slightly less efficient. We could check if the highlighted node changed
and only force a new display list if it did, but I'm not sure if
`OpaqueNode`s can be compared like that. It also seems like a very niche
issue.
Testing: This is hard to test for, so there are no tests.
Fixes https://github.com/servo/servo/issues/37500.
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Previously, `rendered_text_collection_steps` ignores
`TextTransformCase::Capitalize` due to limitation of iterator. Now we
handle the case outside.
Testing: Added a new test as not covered by existing wpt-test, except
for the indirectly related WebDriver test.
`./mach test-wpt -r
tests\wpt\tests\webdriver\tests\classic\get_element_text\get.py
--product servodriver`
Fixes: #37469
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Previously, layout was handling scrollable overflow and srolling area
calculation separately, only excluding the "unreachable scrollable
overflow region" at the last step. In addition, `position: absolute` was
not included in scrollable overflow calculation.
This change combines the two concepts into a single scrollable overflow
calculation and starts taking into account `position: absolute`.
Finally, `BoxFragment::scrollable_overflow_for_parent` is converted to
use early returns which reduces the amount of indentation.
Fixes#35928.
Fixes#37204.
Testing: This causes some WPT test to pass, but also two to start
failing:
- `/css/css-masking/clip-path/clip-path-fixed-scroll.html`: This seems
to fail
because script is scrolling past the boundaries of the document. This is
a
failure that was uncovered by the fixed element now being added to the
page's scroll area.
- `/css/css-overflow/overflow-outside-padding.html`: One test has
started to fail
here because now the absolutely positioned element is included in the
scroll area,
and I think there is an issue with how we are placing RTL items with
negative margins.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This amends #37457 so that the min-content and max-content inline sizes
of a replaced element stop depending on the value of the inline sizing
properties.
In practice I don't think this has any observable effect, but now the
code obeys https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes, and
it's simpler.
Testing: Unneeded
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This change aligns Servo with both Blink and WebKit in common cases.
When the `aspect-ratio` property is set to a different value than the
natural ratio, then Blink and WebKit disagree, we match Blink.
Gecko doesn't support intrinsic min/max block sizes at all.
Note this patch doesn't fix the intrinsic contributions, they will need
to be addressed in a follow-up patch.
Testing: Covered by WPT
Fixes: #37433
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
There are currently five places that scroll offsets are stored:
- DOM: A set of scroll offsets used for script.
- Layout: An array of scroll offsets that is used for tracking
layout-side scroll offsets.
- Layout: The scroll offsets stored in the `ScrollTree`. These are
currently unset and unused.
- Compositor: The scroll offsets stored in the `ScrollTree` mirrored
from layout.
- WebRender: The scrolled offsets stored in the WebRender spatial tree.
This change is the first step in combining the first three into the
layout `ScrollTree`. It eliminates the extra array of scroll offsets
stored in layout in favor of the storing them in the `ScrollTree`. A
followup change will eliminate the ones stored in the DOM.
- In addition the `ScrollState` data structure is eliminated as these
are
now stored in a `HashMap` everywhere when passing them via IPC.
- The offsests stored in layout can now never scroll past the boundaries
of the scrolled content.
Testing: This should not change behavior and is thus covered by existing
WPT tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: stevennovaryo <steven.novaryo@gmail.com>