Currently, we assume any flex item with percentage padding will be
marked as dirty if the percentage basis is changed. However, it is not
true.
To fix it, we cache the flex item's border and padding used in its most
recent final reflow to detect their changes.
dynamic-isize-change-004.html is designed to catch the concern in bug
1700580 comment 12.
Differential Revision: https://phabricator.services.mozilla.com/D125620
This patch introduces a class that caches metrics in flex item's final
reflow. With it, we have a better symmetry for caches, one for measuring
reflow and the other for final reflow. Also, we don't have to explain
that mLastReflowTreatedBSizeAsIndefinite is only meaningful if
mFinalReflowSize is set.
Differential Revision: https://phabricator.services.mozilla.com/D124967
Add `CachedFlexItemData::Update()` with the same arguments as the
constructor to update the existing cache for both the measuring & final
reflow.
`mFinalReflowSize` is going to be renamed in a later patch, so I also
change `UpdateFinalReflowSize()` to `Update()` for consistency with the
new API.
Differential Revision: https://phabricator.services.mozilla.com/D124966
Similar to bug 1728319, a huge main gap size can also make SumOfGaps()
negative due to integer overflow. This patch is to recognize that
scenario.
We still need to annotate the crashtest because it still triggers the
following assertion in nsIFrame.
```
ASSERTION: inline-size less than zero: 'result >= 0'
```
Differential Revision: https://phabricator.services.mozilla.com/D125778
We could fix the testcase in this patch by promoting
`FlexLine::mTotalItemMBP` to `AuCoord64`, but then
`layout/generic/crashtests/1488762-1.html` will start crashing. It is
because `FlexItem::OuterMainSize()` can return negative size due to
integer overflow, and the negative sizes will accumulate in
`mTotalOuterHypotheticalMainSize`.
Instead of promoting more variables to `AuCoord64` to workaround huge
margin/border/padding that we cannot handle gracefully, this patch
tweaks the assertion to check only if `mTotalOuterHypotheticalMainSize`
and `mTotalItemMBP` have valid values.
Differential Revision: https://phabricator.services.mozilla.com/D124409
The assertion is testing the sign of `availableFreeSpace` and `isUsingFlexGrow`.
After we use 64-bit arithmetic, it's likely that the stronger assertion holds.
Differential Revision: https://phabricator.services.mozilla.com/D123519
The idea of this patch is to use 64-bit coord type when resolving the
main size for flex items to avoid integer overflow when individual flex
items have huge hypothetical main sizes, which can happen with
percent-width table-layout:fixed descendants. We have to avoid integer
overflow to shrink flex items properly in that scenario.
Delete the "Note:" in `AddLastItemToMainSizeTotals()` since we remove
`AddChecked()` in favor of regular 64-bit addition for
`mTotalOuterHypotheticalMainSize`.
The wpt testcase is adapted from bug 1469649 comment 12.
Differential Revision: https://phabricator.services.mozilla.com/D123268
The precision of `double` is needed when we are distributing large
`sizeDelta` via `availableFreeSpace * myShareOfRemainingSpace`.
Without this patch, the wpt test added in Part 2 will fail.
Differential Revision: https://phabricator.services.mozilla.com/D123267
In an incremental reflow, if a flex item has a valid bsize cache , we
skip its measuring reflow. However, we may still need to set relevant
bsize flags if the flex container is changing its definiteness in the
block-axis. See bug 1611303 comment 2 for an analysis.
This patch is playing safe by always calling SetHasBSizeChange() if we
override bsize for the item. Of course this can be solved in a more
sophisticated way by checking whether the item really has a block-axis
resize, but that means we'll need to duplicate a lot of logic in
FlexItem::NeedsFinalReflow().
Differential Revision: https://phabricator.services.mozilla.com/D122041
CachedBAxisMeasurement::mAscent caches the ascent of a flex item after
the measuring reflow, but the ascent may change after the final reflow
if the item is stretched and does some vertical alignment internally.
However, we don't cache the new ascent. Therefore, when we reflow the
item incrementally, if the CachedBAxisMeasurement::Key is valid, we just
skip the measuring reflow, and retrieve the wrong ascent from the cache.
Instead of fixing this bug by updating the cached ascent or rejecting
the ascent cache for a stretching flex item in block axis, this patch
removes the cache and sets ReflowOutput's BlockStartAscent() to the flex
item after the item's measuring reflow. (We've done the same after the
item's final reflow.) If the ascent is ReflowOutput::ASK_FOR_BASELINE,
we resolve in FlexItem::ResolvedAscent() anyway.
Differential Revision: https://phabricator.services.mozilla.com/D121404
Our earlier call to nsLayoutUtils::GetFirstLineBaseline/GetLastLineBaseline
works in most cases, but those APIs don't handle every frame type and fails for
text control frames (for example). This new call should handle those cases
by directly asking the frame for its baseline.
Differential Revision: https://phabricator.services.mozilla.com/D121922
This patch doesn't affect behavior; it just refactors some logic to have an
early-return and reduce indentation, to make the next patch in this series
easier/simpler.
While we're at it, this patch also updates & extends some neighboring
code-comments to be more specific & more correct about how this code behaves
and its limitations.
Differential Revision: https://phabricator.services.mozilla.com/D121921
When a flex item's subtree is dirty, we should reject the cached
measurement and perform a measuring reflow for the item to get the
correct ascent. Without this patch, we are going to call
FlexItem::ResolvedAscent() in the flex algorithm based on a dirty flex
item subtree, and get a wrong ascent. (Although we'll still perform the
final reflow for the item, it's too late to get the correct ascent to
compute flex container's ascent.)
With the above modification, it exposes an existing issue that
layout/generic/crashtests/1666592.html can now trigger
`MOZ_ASSERT(!mFinalReflowSize)` in UpdateFinalReflowSize() in
fragmentation scenario. The problem is: when we clone a FlexItem for a
child frame in a flex container's continuation via FlexItem::CloneFor(),
we didn't reset the mHadMeasuringReflow flag, so we wrongly assume it
had a measuring reflow and may update its final reflow size based on the
cached metrics. However, we never run measuring reflow for flex items in
flex container's continuation, so we should reset the flag to prevent it
from falling into wrong path in FlexItem::NeedsFinalReflow().
Differential Revision: https://phabricator.services.mozilla.com/D121405
When a flex item's subtree is dirty, we should reject the cached
measurement and perform a measuring reflow for the item to get the
correct ascent. Without this patch, we are going to call
FlexItem::ResolvedAscent() in the flex algorithm based on a dirty flex
item subtree, and get a wrong ascent. (Although we'll still perform the
final reflow for the item, it's too late to get the correct ascent to
compute flex container's ascent.)
With the above modification, it exposes an existing issue that
layout/generic/crashtests/1666592.html can now trigger
`MOZ_ASSERT(!mFinalReflowSize)` in UpdateFinalReflowSize() in
fragmentation scenario. The problem is: when we clone a FlexItem for a
child frame in a flex container's continuation via FlexItem::CloneFor(),
we didn't reset the mHadMeasuringReflow flag, so we wrongly assume it
had a measuring reflow and may update its final reflow size based on the
cached metrics. However, we never run measuring reflow for flex items in
flex container's continuation, so we should reset the flag to prevent it
from falling into wrong path in FlexItem::NeedsFinalReflow().
Differential Revision: https://phabricator.services.mozilla.com/D121405
CachedBAxisMeasurement::mAscent caches the ascent of a flex item after
the measuring reflow, but the ascent may change after the final reflow
if the item is stretched and does some vertical alignment internally.
However, we don't cache the new ascent. Therefore, when we reflow the
item incrementally, if the CachedBAxisMeasurement::Key is valid, we just
skip the measuring reflow, and retrieve the wrong ascent from the cache.
Instead of fixing this bug by updating the cached ascent or rejecting
the ascent cache for a stretching flex item in block axis, this patch
removes the cache and sets ReflowOutput's BlockStartAscent() to the flex
item after the item's measuring reflow. (We've done the same after the
item's final reflow.) If the ascent is ReflowOutput::ASK_FOR_BASELINE,
we resolve in FlexItem::ResolvedAscent() anyway.
Differential Revision: https://phabricator.services.mozilla.com/D121404
DONTBUILD
This patch doesn't impact behavior; it's just removing code-comments that refer
to a requirement in the spec that we don't honor, & which the CSSWG has now
resolved to remove (which makes our existing behavior correct & no longer
noteworthy).
The CSSWG resolution is in https://github.com/w3c/csswg-drafts/issues/4311 .
The new text is yet-to-be-written, but the main takeaway is that the "fully
inflexible" requirement (which we ignore) has been removed; so now, any flex
item with a definite flex-basis should have its main-size considered to be
definite. (And this matches our implementation.)
Differential Revision: https://phabricator.services.mozilla.com/D121284
The root cause of the crash was that FlexItem::NeedsFinalReflow
returned false even though the item had a non-empty next-in-flow.
This made the flex container skip the item's reflow and consider
the item's reflow status as COMPLETE, which triggers the removal
of the container's own next-in-flow, which causes the assertions
and eventually the crash.
Differential Revision: https://phabricator.services.mozilla.com/D118420
The rect `flexItemMarginBoxBounds` is initialized at position (0, 0),
not the flex container's content-box origin. Inflating its initial value
with flex container's padding is just wrong.
Differential Revision: https://phabricator.services.mozilla.com/D115854
Also, change the loop so that it iterates over flex items because
mFrames can contain out-of-flow placeholders which are not flex items.
This doesn't change the behavior because the out-of-flow placeholders
doesn't have any overflow areas (unless we fixed bug 1460484).
Differential Revision: https://phabricator.services.mozilla.com/D112672
This patch incorporates flex item's margin and flex container's padding
when computing flex container's overflow area in both the inline axis
and block axis.
overflow-top-left.html starts to fail because the test has flex items
with margin contributing to the overflow area now. We leave the test
unchanged for now until the webcompat situation is clear (Bug1698428).
flexbox-overflow-padding-002.html is based on
flexbox-overflow-padding-001.html with `writing-mode: vertical-rl` and
`direction: rtl` added to `.flexContainer`.
Differential Revision: https://phabricator.services.mozilla.com/D107936
This will prevent growing them when introducing fit-content(<length>).
This can _almost_ be derived, if it wasn't because of the quirky stuff.
I think the macro is probably good enough for now but let me know if you
disagree.
Differential Revision: https://phabricator.services.mozilla.com/D106713
This will prevent growing them when introducing fit-content(<length>).
This can _almost_ be derived, if it wasn't because of the quirky stuff.
I think the macro is probably good enough for now but let me know if you
disagree.
Differential Revision: https://phabricator.services.mozilla.com/D106713
Also, suppress a flex item's aspect-ratio by using
StyleSizeOverrides::mAspectRatio added in Part 1. Otherwise,
testing/web-platform/tests/css/css-flexbox/flex-minimum-height-flex-items-023.html
is going to break.
table-as-item-stretch-cross-size-3 is adapted from the testcase in bug
799725 comment 1. Note: stretching in the cross axis that is a block
axis has been fixed by bug 1674302.
Differential Revision: https://phabricator.services.mozilla.com/D106195
The mIsFlexContainerMeasuringBSize flag serves two purposes:
(1) Tell ReflowInput::ComputeMinMaxValues() to treat min-block-size and
max-block-size like the initial value.
We can just set both sizes after creating the ReflowInput, like this
patch does.
(2) Add `ComputeSizeFlag::UseAutoBSize` to mComputeSizeFlags.
Similar to the reasoning in Bug 1674302 Part 2
https://hg.mozilla.org/mozilla-central/rev/23aff0f21a1d, the
UseAutoBSize flag is buggy when used on table flex items because it
never propagates to inner table frame. We can fix it by providing an
'auto' mStyleBSize in StyleSizeOverrides.
This fixed table flex item's content block-size measurement. As
described in table-as-item-specified-height.html, the specified height
on <table> now won't count as another min-height anymore.
Differential Revision: https://phabricator.services.mozilla.com/D106157
This is the main patch of this bug.
When a flex container provides size overrides for a table flex item,
there are two use cases.
(1) When resolving flex base size, we want to use `flex-basis` to
replace the preferred main size on the *inner table frame* directly.
This is how `height` works on a table element. That is, it sets the
height of the inner table frame, not the table wrapper. This patch
invents `mApplyOverridesVerbatim` flag to tell table wrapper frame don't
do any modification.
(2) When overriding main-size/cross-size for a table flex item, the size
is for *table wrapper frame*. To apply the size to inner table frame,
the table wrapper frame needs adjust the size by subtracting the area
occupied by caption, border, and padding (depending on the box-sizing).
This patch fixes the flex base resolution, and implements the logic for
(2).
We use nsLayoutUtils::GetStyleFrame() to dig into inner table's sizing
properties when resolving flex base size, so we can stop inheriting flex
properties to table wrapper frame in ua.css.
We also need to check style frame's StylePosition() in IsCrossSizeAuto()
so that non-'auto' sizes can prevent tables from being stretched in the
cross axis, just as happens with other flex items. Otherwise with this
patch, the table flex item with fixed height in
dom/flex/test/chrome/test_flex_item_rect.html will be wrongly stretched.
Differential Revision: https://phabricator.services.mozilla.com/D103437
`UseAutoISize` flag is buggy when used on table flex items because it
never propagates to inner table frame.
Luckily, we can fix it by replacing the flag with StyleSizeOverrides
emplacing an 'auto' mStyleISize, because when computing the size, the
size overrides already propagates from table wrapper to inner table via
the following path:
`nsTableWrapperFrame::ComputeSize()` [1] ->
`nsTableWrapperFrame::ComputeAutoSize()` ->
`nsTableWrapperFrame::InnerTableShrinkWrapISize()` ->
`nsTableFrame::ComputeSize()`.
Part 3 is going to propagate the size overrides to inner table in
`nsTableWrapperFrame::CreateReflowInputForInnerTable()` during reflow.
This patch fixes the content size suggestion for table flex items.
Combining this patch with Part 3, we can fix those reftests in Part 4.
[1] In this patch, the table wrapper is still using nsContainerFrame's
ComputeSize(), but Part 3 is going to override it.
Differential Revision: https://phabricator.services.mozilla.com/D103438
We don't need to tweak as many ReflowInput flags as we did because
ReflowInput::InitResizeFlags() should've set them accordingly, except
when the item has TreatBSizeAsIndefinite() that ReflowInput isn't aware
of.
Differential Revision: https://phabricator.services.mozilla.com/D101797
FlexItem::StyleCrossSize() hasn't been used in this patch, but it will
be used in a later patch that revises size overrides in flex item's
final reflow.
Differential Revision: https://phabricator.services.mozilla.com/D101796
This patch adds the struct as a parameter to various functions.
The struct is cached in ReflowInput so that we don't need to pass it
down to the internal method where nsIFrame::ComputeSize() is called.
In the subsequent patches, we'll use it to revise the implementation of
flex container's flex base size resolution, and size overrides.
Differential Revision: https://phabricator.services.mozilla.com/D101793
We don't need to tweak as many ReflowInput flags as we did because
ReflowInput::InitResizeFlags() should've set them accordingly, except
when the item has TreatBSizeAsIndefinite() that ReflowInput isn't aware
of.
Differential Revision: https://phabricator.services.mozilla.com/D101797
FlexItem::StyleCrossSize() hasn't been used in this patch, but it will
be used in a later patch that revises size overrides in flex item's
final reflow.
Differential Revision: https://phabricator.services.mozilla.com/D101796
This patch adds the struct as a parameter to various functions.
The struct is cached in ReflowInput so that we don't need to pass it
down to the internal method where nsIFrame::ComputeSize() is called.
In the subsequent patches, we'll use it to revise the implementation of
flex container's flex base size resolution, and size overrides.
Differential Revision: https://phabricator.services.mozilla.com/D101793
* Follow other flags' naming by putting "Is" at the beginning.
* Delete the accessor because we just access other flags directly.
Differential Revision: https://phabricator.services.mozilla.com/D102480