Bug 1887465 - Use the containing block's writing mode to resolve logical values for CSS float and clear properties. r=layout-reviewers,emilio
And don't resolve them prematurely; the computed value should remain logical, and only be mapped to physical sides at use time. Differential Revision: https://phabricator.services.mozilla.com/D229998
This commit is contained in:
@@ -2467,6 +2467,10 @@ StyleClear nsLayoutUtils::CombineClearType(StyleClear aOrigClearType,
|
||||
case StyleClear::Both:
|
||||
// Do nothing.
|
||||
break;
|
||||
case StyleClear::InlineStart:
|
||||
case StyleClear::InlineEnd:
|
||||
MOZ_ASSERT_UNREACHABLE("should have resolved to physical values");
|
||||
break;
|
||||
}
|
||||
return clearType;
|
||||
}
|
||||
|
||||
@@ -154,7 +154,8 @@ void BRFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
|
||||
}
|
||||
|
||||
// Return our reflow status
|
||||
aStatus.SetInlineLineBreakAfter(aReflowInput.mStyleDisplay->mClear);
|
||||
aStatus.SetInlineLineBreakAfter(
|
||||
aReflowInput.mStyleDisplay->UsedClear(aReflowInput.GetCBWritingMode()));
|
||||
ll->SetLineEndsInBR(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ bool BlockReflowState::FloatAvoidingBlockFitsInAvailSpace(
|
||||
}
|
||||
|
||||
nsFlowAreaRect BlockReflowState::GetFloatAvailableSpaceWithState(
|
||||
nscoord aBCoord, ShapeType aShapeType,
|
||||
WritingMode aCBWM, nscoord aBCoord, ShapeType aShapeType,
|
||||
nsFloatManager::SavedState* aState) const {
|
||||
WritingMode wm = mReflowInput.GetWritingMode();
|
||||
#ifdef DEBUG
|
||||
@@ -319,7 +319,7 @@ nsFlowAreaRect BlockReflowState::GetFloatAvailableSpaceWithState(
|
||||
? nscoord_MAX
|
||||
: std::max(mContentArea.BEnd(wm) - aBCoord, 0);
|
||||
nsFlowAreaRect result = FloatManager()->GetFlowArea(
|
||||
wm, aBCoord, blockSize, BandInfoType::BandFromPoint, aShapeType,
|
||||
aCBWM, wm, aBCoord, blockSize, BandInfoType::BandFromPoint, aShapeType,
|
||||
mContentArea, aState, ContainerSize());
|
||||
// Keep the inline size >= 0 for compatibility with nsSpaceManager.
|
||||
if (result.mRect.ISize(wm) < 0) {
|
||||
@@ -338,7 +338,8 @@ nsFlowAreaRect BlockReflowState::GetFloatAvailableSpaceWithState(
|
||||
}
|
||||
|
||||
nsFlowAreaRect BlockReflowState::GetFloatAvailableSpaceForBSize(
|
||||
nscoord aBCoord, nscoord aBSize, nsFloatManager::SavedState* aState) const {
|
||||
WritingMode aCBWM, nscoord aBCoord, nscoord aBSize,
|
||||
nsFloatManager::SavedState* aState) const {
|
||||
WritingMode wm = mReflowInput.GetWritingMode();
|
||||
#ifdef DEBUG
|
||||
// Verify that the caller setup the coordinate system properly
|
||||
@@ -349,7 +350,7 @@ nsFlowAreaRect BlockReflowState::GetFloatAvailableSpaceForBSize(
|
||||
"bad coord system");
|
||||
#endif
|
||||
nsFlowAreaRect result = FloatManager()->GetFlowArea(
|
||||
wm, aBCoord, aBSize, BandInfoType::WidthWithinHeight,
|
||||
aCBWM, wm, aBCoord, aBSize, BandInfoType::WidthWithinHeight,
|
||||
ShapeType::ShapeOutside, mContentArea, aState, ContainerSize());
|
||||
// Keep the width >= 0 for compatibility with nsSpaceManager.
|
||||
if (result.mRect.ISize(wm) < 0) {
|
||||
@@ -573,9 +574,10 @@ bool BlockReflowState::AddFloat(nsLineLayout* aLineLayout, nsIFrame* aFloat,
|
||||
// LineReflowStatus::RedoMoreFloats. We should use mLineBSize to query the
|
||||
// correct available space.
|
||||
nsFlowAreaRect floatAvailSpace =
|
||||
mLineBSize.isNothing() ? GetFloatAvailableSpace(mBCoord)
|
||||
: GetFloatAvailableSpaceForBSize(
|
||||
mBCoord, mLineBSize.value(), nullptr);
|
||||
mLineBSize.isNothing()
|
||||
? GetFloatAvailableSpace(wm, mBCoord)
|
||||
: GetFloatAvailableSpaceForBSize(wm, mBCoord, mLineBSize.value(),
|
||||
nullptr);
|
||||
LogicalRect availSpace(wm, floatAvailSpace.mRect.IStart(wm), mBCoord,
|
||||
floatAvailSpace.mRect.ISize(wm),
|
||||
floatAvailSpace.mRect.BSize(wm));
|
||||
@@ -710,7 +712,7 @@ BlockReflowState::PlaceFloatResult BlockReflowState::FlowAndPlaceFloat(
|
||||
// when floats are inserted before it.
|
||||
if (StyleClear::None != floatDisplay->mClear) {
|
||||
// XXXldb Does this handle vertical margins correctly?
|
||||
auto [bCoord, result] = ClearFloats(mBCoord, floatDisplay->mClear);
|
||||
auto [bCoord, result] = ClearFloats(mBCoord, floatDisplay->UsedClear(wm));
|
||||
if (result == ClearFloatsResult::FloatsPushedOrSplit) {
|
||||
PushFloatPastBreak(aFloat);
|
||||
return PlaceFloatResult::ShouldPlaceInNextContinuation;
|
||||
@@ -755,7 +757,7 @@ BlockReflowState::PlaceFloatResult BlockReflowState::FlowAndPlaceFloat(
|
||||
// Find a place to place the float. The CSS2 spec doesn't want
|
||||
// floats overlapping each other or sticking out of the containing
|
||||
// block if possible (CSS2 spec section 9.5.1, see the rule list).
|
||||
StyleFloat floatStyle = floatDisplay->mFloat;
|
||||
StyleFloat floatStyle = floatDisplay->UsedFloat(wm);
|
||||
MOZ_ASSERT(StyleFloat::Left == floatStyle || StyleFloat::Right == floatStyle,
|
||||
"Invalid float type!");
|
||||
|
||||
@@ -767,7 +769,7 @@ BlockReflowState::PlaceFloatResult BlockReflowState::FlowAndPlaceFloat(
|
||||
|
||||
// Get the band of available space with respect to margin box.
|
||||
nsFlowAreaRect floatAvailableSpace =
|
||||
GetFloatAvailableSpaceForPlacingFloat(mBCoord);
|
||||
GetFloatAvailableSpaceForPlacingFloat(wm, mBCoord);
|
||||
|
||||
for (;;) {
|
||||
if (mReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE &&
|
||||
@@ -784,7 +786,7 @@ BlockReflowState::PlaceFloatResult BlockReflowState::FlowAndPlaceFloat(
|
||||
|
||||
// Nope. try to advance to the next band.
|
||||
mBCoord += floatAvailableSpace.mRect.BSize(wm);
|
||||
floatAvailableSpace = GetFloatAvailableSpaceForPlacingFloat(mBCoord);
|
||||
floatAvailableSpace = GetFloatAvailableSpaceForPlacingFloat(wm, mBCoord);
|
||||
mustPlaceFloat = false;
|
||||
}
|
||||
|
||||
@@ -974,7 +976,8 @@ void BlockReflowState::PushFloatPastBreak(nsIFrame* aFloat) {
|
||||
// must have their tops below the top of this float)
|
||||
// * don't waste much time trying to reflow this float again until
|
||||
// after the break
|
||||
StyleFloat floatStyle = aFloat->StyleDisplay()->mFloat;
|
||||
WritingMode wm = mReflowInput.GetWritingMode();
|
||||
StyleFloat floatStyle = aFloat->StyleDisplay()->UsedFloat(wm);
|
||||
if (floatStyle == StyleFloat::Left) {
|
||||
FloatManager()->SetPushedLeftFloatPastBreak();
|
||||
} else {
|
||||
@@ -1045,8 +1048,10 @@ BlockReflowState::ClearFloats(nscoord aBCoord, StyleClear aClearType,
|
||||
}
|
||||
|
||||
if (aFloatAvoidingBlock) {
|
||||
auto cbWM = aFloatAvoidingBlock->GetContainingBlock()->GetWritingMode();
|
||||
for (;;) {
|
||||
nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(newBCoord);
|
||||
nsFlowAreaRect floatAvailableSpace =
|
||||
GetFloatAvailableSpace(cbWM, newBCoord);
|
||||
if (FloatAvoidingBlockFitsInAvailSpace(aFloatAvoidingBlock,
|
||||
floatAvailableSpace)) {
|
||||
break;
|
||||
|
||||
@@ -110,6 +110,9 @@ class BlockReflowState {
|
||||
* our coordinate system, which is the content box, with (0, 0) in the
|
||||
* upper left.
|
||||
*
|
||||
* The parameter aCBWM is the containing block's writing mode, which is
|
||||
* NOT necessarily the mode currently being used by the float manager.
|
||||
*
|
||||
* Returns whether there are floats present at the given block-direction
|
||||
* coordinate and within the inline size of the content rect.
|
||||
*
|
||||
@@ -121,21 +124,24 @@ class BlockReflowState {
|
||||
* negative value (in which case a 0-ISize float-avoiding block *should not*
|
||||
* be considered as fitting, because it would intersect some float).
|
||||
*/
|
||||
nsFlowAreaRect GetFloatAvailableSpace() const {
|
||||
return GetFloatAvailableSpace(mBCoord);
|
||||
nsFlowAreaRect GetFloatAvailableSpace(WritingMode aCBWM) const {
|
||||
return GetFloatAvailableSpace(aCBWM, mBCoord);
|
||||
}
|
||||
nsFlowAreaRect GetFloatAvailableSpaceForPlacingFloat(nscoord aBCoord) const {
|
||||
return GetFloatAvailableSpaceWithState(aBCoord, ShapeType::Margin, nullptr);
|
||||
}
|
||||
nsFlowAreaRect GetFloatAvailableSpace(nscoord aBCoord) const {
|
||||
return GetFloatAvailableSpaceWithState(aBCoord, ShapeType::ShapeOutside,
|
||||
nsFlowAreaRect GetFloatAvailableSpaceForPlacingFloat(WritingMode aCBWM,
|
||||
nscoord aBCoord) const {
|
||||
return GetFloatAvailableSpaceWithState(aCBWM, aBCoord, ShapeType::Margin,
|
||||
nullptr);
|
||||
}
|
||||
nsFlowAreaRect GetFloatAvailableSpace(WritingMode aCBWM,
|
||||
nscoord aBCoord) const {
|
||||
return GetFloatAvailableSpaceWithState(aCBWM, aBCoord,
|
||||
ShapeType::ShapeOutside, nullptr);
|
||||
}
|
||||
nsFlowAreaRect GetFloatAvailableSpaceWithState(
|
||||
nscoord aBCoord, ShapeType aShapeType,
|
||||
WritingMode aCBWM, nscoord aBCoord, ShapeType aShapeType,
|
||||
nsFloatManager::SavedState* aState) const;
|
||||
nsFlowAreaRect GetFloatAvailableSpaceForBSize(
|
||||
nscoord aBCoord, nscoord aBSize,
|
||||
WritingMode aCBWM, nscoord aBCoord, nscoord aBSize,
|
||||
nsFloatManager::SavedState* aState) const;
|
||||
|
||||
// @return true if AddFloat was able to place the float; false if the float
|
||||
|
||||
@@ -296,6 +296,11 @@ nscoord SizeComputationInput::ComputeBSizeValue(
|
||||
return nsLayoutUtils::ComputeBSizeValue(aContainingBlockBSize, inside, aSize);
|
||||
}
|
||||
|
||||
WritingMode ReflowInput::GetCBWritingMode() const {
|
||||
return mCBReflowInput ? mCBReflowInput->GetWritingMode()
|
||||
: mFrame->GetContainingBlock()->GetWritingMode();
|
||||
}
|
||||
|
||||
nsSize ReflowInput::ComputedSizeAsContainerIfConstrained() const {
|
||||
LogicalSize size = ComputedSize();
|
||||
if (size.ISize(mWritingMode) == NS_UNCONSTRAINEDSIZE) {
|
||||
@@ -2378,8 +2383,8 @@ void ReflowInput::InitConstraints(
|
||||
// flag.
|
||||
return true;
|
||||
}
|
||||
if (!alignCB->IsGridContainerFrame() && mCBReflowInput &&
|
||||
mCBReflowInput->GetWritingMode().IsOrthogonalTo(mWritingMode)) {
|
||||
if (!alignCB->IsGridContainerFrame() &&
|
||||
mWritingMode.IsOrthogonalTo(GetCBWritingMode())) {
|
||||
// Shrink-wrap blocks that are orthogonal to their container (unless
|
||||
// we're in a grid?)
|
||||
return true;
|
||||
@@ -2605,8 +2610,7 @@ void ReflowInput::CalculateBlockSideMargins() {
|
||||
// case, "CalculateBlock*Side*Margins" will actually end up adjusting
|
||||
// the BStart/BEnd margins; those are the "sides" of the block from its
|
||||
// container's point of view.
|
||||
WritingMode cbWM =
|
||||
mCBReflowInput ? mCBReflowInput->GetWritingMode() : GetWritingMode();
|
||||
WritingMode cbWM = GetCBWritingMode();
|
||||
|
||||
nscoord availISizeCBWM = AvailableSize(cbWM).ISize(cbWM);
|
||||
nscoord computedISizeCBWM = ComputedSize(cbWM).ISize(cbWM);
|
||||
|
||||
@@ -358,6 +358,10 @@ struct ReflowInput : public SizeComputationInput {
|
||||
// unconstrained dimensions replaced by zero.
|
||||
nsSize ComputedSizeAsContainerIfConstrained() const;
|
||||
|
||||
// Get the writing mode of the containing block, to resolve float/clear
|
||||
// logical sides appropriately.
|
||||
WritingMode GetCBWritingMode() const;
|
||||
|
||||
// Our saved containing block dimensions.
|
||||
LogicalSize mContainingBlockSize{mWritingMode};
|
||||
|
||||
|
||||
@@ -2188,4 +2188,32 @@ inline mozilla::StyleContentDistribution nsStylePosition::UsedContentAlignment(
|
||||
return aAxis == mozilla::LogicalAxis::Block ? mAlignContent : mJustifyContent;
|
||||
}
|
||||
|
||||
inline mozilla::StyleFloat nsStyleDisplay::UsedFloat(
|
||||
mozilla::WritingMode aCBWM) const {
|
||||
switch (mFloat) {
|
||||
case mozilla::StyleFloat::InlineStart:
|
||||
return aCBWM.IsBidiLTR() ? mozilla::StyleFloat::Left
|
||||
: mozilla::StyleFloat::Right;
|
||||
case mozilla::StyleFloat::InlineEnd:
|
||||
return aCBWM.IsBidiLTR() ? mozilla::StyleFloat::Right
|
||||
: mozilla::StyleFloat::Left;
|
||||
default:
|
||||
return mFloat;
|
||||
}
|
||||
}
|
||||
|
||||
inline mozilla::StyleClear nsStyleDisplay::UsedClear(
|
||||
mozilla::WritingMode aCBWM) const {
|
||||
switch (mClear) {
|
||||
case mozilla::StyleClear::InlineStart:
|
||||
return aCBWM.IsBidiLTR() ? mozilla::StyleClear::Left
|
||||
: mozilla::StyleClear::Right;
|
||||
case mozilla::StyleClear::InlineEnd:
|
||||
return aCBWM.IsBidiLTR() ? mozilla::StyleClear::Right
|
||||
: mozilla::StyleClear::Left;
|
||||
default:
|
||||
return mClear;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // WritingModes_h_
|
||||
|
||||
@@ -940,7 +940,7 @@ nscoord nsBlockFrame::PrefISize(const IntrinsicSizeInput& aInput) {
|
||||
if (!data.mLineIsEmpty || BlockCanIntersectFloats(kid)) {
|
||||
clearType = StyleClear::Both;
|
||||
} else {
|
||||
clearType = kid->StyleDisplay()->mClear;
|
||||
clearType = kid->StyleDisplay()->UsedClear(GetWritingMode());
|
||||
}
|
||||
data.ForceBreak(clearType);
|
||||
const IntrinsicSizeInput kidInput(aInput, kid->GetWritingMode(),
|
||||
@@ -2920,8 +2920,9 @@ void nsBlockFrame::PropagateFloatDamage(BlockReflowState& aState,
|
||||
} else {
|
||||
bool wasImpactedByFloat = aLine->IsImpactedByFloat();
|
||||
nsFlowAreaRect floatAvailableSpace =
|
||||
aState.GetFloatAvailableSpaceForBSize(aLine->BStart() + aDeltaBCoord,
|
||||
aLine->BSize(), nullptr);
|
||||
aState.GetFloatAvailableSpaceForBSize(
|
||||
aState.mReflowInput.GetWritingMode(),
|
||||
aLine->BStart() + aDeltaBCoord, aLine->BSize(), nullptr);
|
||||
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::PropagateFloatDamage %p was = %d, is=%d\n", this,
|
||||
@@ -3829,7 +3830,7 @@ bool nsBlockFrame::ReflowLine(BlockReflowState& aState, LineIterator aLine,
|
||||
if (aState.mFlags.mCanHaveOverflowMarkers) {
|
||||
WritingMode wm = aLine->mWritingMode;
|
||||
nsFlowAreaRect r = aState.GetFloatAvailableSpaceForBSize(
|
||||
aLine->BStart(), aLine->BSize(), nullptr);
|
||||
wm, aLine->BStart(), aLine->BSize(), nullptr);
|
||||
if (r.HasFloats()) {
|
||||
LogicalRect so = aLine->GetOverflowArea(OverflowType::Scrollable, wm,
|
||||
aLine->mContainerSize);
|
||||
@@ -4168,7 +4169,8 @@ void nsBlockFrame::ReflowBlockFrame(BlockReflowState& aState,
|
||||
// Prepare the block reflow engine
|
||||
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowInput);
|
||||
|
||||
StyleClear clearType = frame->StyleDisplay()->mClear;
|
||||
WritingMode cbWM = frame->GetContainingBlock()->GetWritingMode();
|
||||
StyleClear clearType = frame->StyleDisplay()->UsedClear(cbWM);
|
||||
if (aState.mTrailingClearFromPIF != StyleClear::None) {
|
||||
clearType = nsLayoutUtils::CombineClearType(clearType,
|
||||
aState.mTrailingClearFromPIF);
|
||||
@@ -4353,7 +4355,7 @@ void nsBlockFrame::ReflowBlockFrame(BlockReflowState& aState,
|
||||
|
||||
// Here aState.mBCoord is the block-start border-edge of the block.
|
||||
// Compute the available space for the block
|
||||
nsFlowAreaRect floatAvailableSpace = aState.GetFloatAvailableSpace();
|
||||
nsFlowAreaRect floatAvailableSpace = aState.GetFloatAvailableSpace(cbWM);
|
||||
WritingMode wm = aState.mReflowInput.GetWritingMode();
|
||||
LogicalRect availSpace = aState.ComputeBlockAvailSpace(
|
||||
frame, floatAvailableSpace, (floatAvoidingBlock));
|
||||
@@ -4510,7 +4512,7 @@ void nsBlockFrame::ReflowBlockFrame(BlockReflowState& aState,
|
||||
|
||||
LogicalRect oldFloatAvailableSpaceRect(floatAvailableSpace.mRect);
|
||||
floatAvailableSpace = aState.GetFloatAvailableSpaceForBSize(
|
||||
aState.mBCoord + bStartMargin, brc.GetMetrics().BSize(wm),
|
||||
cbWM, aState.mBCoord + bStartMargin, brc.GetMetrics().BSize(wm),
|
||||
&floatManagerState);
|
||||
NS_ASSERTION(floatAvailableSpace.mRect.BStart(wm) ==
|
||||
oldFloatAvailableSpaceRect.BStart(wm),
|
||||
@@ -4547,7 +4549,7 @@ void nsBlockFrame::ReflowBlockFrame(BlockReflowState& aState,
|
||||
|
||||
// Start over with a new available space rect at the new height.
|
||||
floatAvailableSpace = aState.GetFloatAvailableSpaceWithState(
|
||||
aState.mBCoord, ShapeType::ShapeOutside, &floatManagerState);
|
||||
cbWM, aState.mBCoord, ShapeType::ShapeOutside, &floatManagerState);
|
||||
}
|
||||
|
||||
const LogicalRect oldAvailSpace = availSpace;
|
||||
@@ -4836,7 +4838,8 @@ bool nsBlockFrame::ReflowInlineFrames(BlockReflowState& aState,
|
||||
if (ShouldApplyBStartMargin(aState, aLine)) {
|
||||
aState.mBCoord += aState.mPrevBEndMargin.Get();
|
||||
}
|
||||
nsFlowAreaRect floatAvailableSpace = aState.GetFloatAvailableSpace();
|
||||
nsFlowAreaRect floatAvailableSpace =
|
||||
aState.GetFloatAvailableSpace(GetWritingMode());
|
||||
|
||||
LineReflowStatus lineReflowStatus;
|
||||
do {
|
||||
@@ -5119,7 +5122,7 @@ void nsBlockFrame::DoReflowInlineFrames(
|
||||
aState.mBCoord += aState.mPresContext->DevPixelsToAppUnits(1);
|
||||
}
|
||||
|
||||
aFloatAvailableSpace = aState.GetFloatAvailableSpace();
|
||||
aFloatAvailableSpace = aState.GetFloatAvailableSpace(GetWritingMode());
|
||||
} else {
|
||||
// There's nowhere to retry placing the line, so we want to push
|
||||
// it to the next page/column where its contents can fit not
|
||||
@@ -5365,7 +5368,8 @@ void nsBlockFrame::SplitFloat(BlockReflowState& aState, nsIFrame* aFloat,
|
||||
nextInFlow->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
|
||||
}
|
||||
|
||||
StyleFloat floatStyle = aFloat->StyleDisplay()->mFloat;
|
||||
StyleFloat floatStyle =
|
||||
aFloat->StyleDisplay()->UsedFloat(aState.mReflowInput.GetWritingMode());
|
||||
if (floatStyle == StyleFloat::Left) {
|
||||
aState.FloatManager()->SetSplitLeftFloatAcrossBreak();
|
||||
} else {
|
||||
@@ -5550,10 +5554,10 @@ bool nsBlockFrame::PlaceLine(BlockReflowState& aState,
|
||||
// the old BSize, but including the floats that were added in this line.
|
||||
LogicalRect floatAvailableSpaceWithOldLineBSize =
|
||||
aState.mLineBSize.isNothing()
|
||||
? aState.GetFloatAvailableSpace(aLine->BStart()).mRect
|
||||
? aState.GetFloatAvailableSpace(wm, aLine->BStart()).mRect
|
||||
: aState
|
||||
.GetFloatAvailableSpaceForBSize(
|
||||
aLine->BStart(), aState.mLineBSize.value(), nullptr)
|
||||
wm, aLine->BStart(), aState.mLineBSize.value(), nullptr)
|
||||
.mRect;
|
||||
|
||||
// As we redo for floats, we can't reduce the amount of BSize we're
|
||||
@@ -5561,8 +5565,8 @@ bool nsBlockFrame::PlaceLine(BlockReflowState& aState,
|
||||
aAvailableSpaceBSize = std::max(aAvailableSpaceBSize, aLine->BSize());
|
||||
LogicalRect floatAvailableSpaceWithLineBSize =
|
||||
aState
|
||||
.GetFloatAvailableSpaceForBSize(aLine->BStart(), aAvailableSpaceBSize,
|
||||
nullptr)
|
||||
.GetFloatAvailableSpaceForBSize(wm, aLine->BStart(),
|
||||
aAvailableSpaceBSize, nullptr)
|
||||
.mRect;
|
||||
|
||||
// If the available space between the floats is smaller now that we
|
||||
@@ -5580,7 +5584,7 @@ bool nsBlockFrame::PlaceLine(BlockReflowState& aState,
|
||||
// line is placed.
|
||||
LogicalRect oldFloatAvailableSpace(aFlowArea.mRect);
|
||||
aFlowArea = aState.GetFloatAvailableSpaceForBSize(
|
||||
aLine->BStart(), aAvailableSpaceBSize, aFloatStateBeforeLine);
|
||||
wm, aLine->BStart(), aAvailableSpaceBSize, aFloatStateBeforeLine);
|
||||
|
||||
NS_ASSERTION(
|
||||
aFlowArea.mRect.BStart(wm) == oldFloatAvailableSpace.BStart(wm),
|
||||
@@ -8323,7 +8327,8 @@ void nsBlockFrame::ReflowOutsideMarker(nsIFrame* aMarkerFrame,
|
||||
// they reposition the line.
|
||||
LogicalRect floatAvailSpace =
|
||||
aState
|
||||
.GetFloatAvailableSpaceWithState(aLineTop, ShapeType::ShapeOutside,
|
||||
.GetFloatAvailableSpaceWithState(ri.GetWritingMode(), aLineTop,
|
||||
ShapeType::ShapeOutside,
|
||||
&aState.mFloatManagerStateBefore)
|
||||
.mRect;
|
||||
// FIXME (bug 25888): need to check the entire region that the first
|
||||
|
||||
@@ -108,7 +108,7 @@ void nsFloatManager::Shutdown() {
|
||||
"incompatible writing modes")
|
||||
|
||||
nsFlowAreaRect nsFloatManager::GetFlowArea(
|
||||
WritingMode aWM, nscoord aBCoord, nscoord aBSize,
|
||||
WritingMode aCBWM, WritingMode aWM, nscoord aBCoord, nscoord aBSize,
|
||||
BandInfoType aBandInfoType, ShapeType aShapeType, LogicalRect aContentArea,
|
||||
SavedState* aState, const nsSize& aContainerSize) const {
|
||||
CHECK_BLOCK_AND_LINE_DIR(aWM);
|
||||
@@ -199,7 +199,7 @@ nsFlowAreaRect nsFloatManager::GetFlowArea(
|
||||
// This float is in our band.
|
||||
|
||||
// Shrink our band's width if needed.
|
||||
StyleFloat floatStyle = fi.mFrame->StyleDisplay()->mFloat;
|
||||
StyleFloat floatStyle = fi.mFrame->StyleDisplay()->UsedFloat(aCBWM);
|
||||
|
||||
// When aBandInfoType is BandFromPoint, we're only intended to
|
||||
// consider a point along the y axis rather than a band.
|
||||
@@ -285,7 +285,8 @@ void nsFloatManager::AddFloat(nsIFrame* aFloatFrame,
|
||||
info.mLeftBEnd = nscoord_MIN;
|
||||
info.mRightBEnd = nscoord_MIN;
|
||||
}
|
||||
StyleFloat floatStyle = aFloatFrame->StyleDisplay()->mFloat;
|
||||
WritingMode cbWM = aFloatFrame->GetParent()->GetWritingMode();
|
||||
StyleFloat floatStyle = aFloatFrame->StyleDisplay()->UsedFloat(cbWM);
|
||||
MOZ_ASSERT(floatStyle == StyleFloat::Left || floatStyle == StyleFloat::Right,
|
||||
"Unexpected float style!");
|
||||
nscoord& sideBEnd =
|
||||
@@ -317,7 +318,8 @@ LogicalRect nsFloatManager::CalculateRegionFor(WritingMode aWM,
|
||||
// Preserve the right margin-edge for left floats and the left
|
||||
// margin-edge for right floats
|
||||
const nsStyleDisplay* display = aFloat->StyleDisplay();
|
||||
StyleFloat floatStyle = display->mFloat;
|
||||
WritingMode cbWM = aFloat->GetParent()->GetWritingMode();
|
||||
StyleFloat floatStyle = display->UsedFloat(cbWM);
|
||||
if ((StyleFloat::Left == floatStyle) == aWM.IsBidiLTR()) {
|
||||
region.IStart(aWM) = region.IEnd(aWM);
|
||||
}
|
||||
|
||||
@@ -218,7 +218,8 @@ class nsFloatManager {
|
||||
*/
|
||||
enum class BandInfoType { BandFromPoint, WidthWithinHeight };
|
||||
enum class ShapeType { Margin, ShapeOutside };
|
||||
nsFlowAreaRect GetFlowArea(mozilla::WritingMode aWM, nscoord aBCoord,
|
||||
nsFlowAreaRect GetFlowArea(mozilla::WritingMode aCBWM,
|
||||
mozilla::WritingMode aWM, nscoord aBCoord,
|
||||
nscoord aBSize, BandInfoType aBandInfoType,
|
||||
ShapeType aShapeType,
|
||||
mozilla::LogicalRect aContentArea,
|
||||
|
||||
@@ -6158,7 +6158,8 @@ void nsIFrame::InlinePrefISizeData::ForceBreak(StyleClear aClearType) {
|
||||
|
||||
for (const FloatInfo& floatInfo : mFloats) {
|
||||
const nsStyleDisplay* floatDisp = floatInfo.Frame()->StyleDisplay();
|
||||
StyleClear clearType = floatDisp->mClear;
|
||||
auto cbWM = floatInfo.Frame()->GetParent()->GetWritingMode();
|
||||
StyleClear clearType = floatDisp->UsedClear(cbWM);
|
||||
if (clearType == StyleClear::Left || clearType == StyleClear::Right ||
|
||||
clearType == StyleClear::Both) {
|
||||
nscoord floatsCur = NSCoordSaturatingAdd(floatsCurLeft, floatsCurRight);
|
||||
@@ -6173,7 +6174,7 @@ void nsIFrame::InlinePrefISizeData::ForceBreak(StyleClear aClearType) {
|
||||
}
|
||||
}
|
||||
|
||||
StyleFloat floatStyle = floatDisp->mFloat;
|
||||
StyleFloat floatStyle = floatDisp->UsedFloat(cbWM);
|
||||
nscoord& floatsCur =
|
||||
floatStyle == StyleFloat::Left ? floatsCurLeft : floatsCurRight;
|
||||
nscoord floatISize = floatInfo.ISize();
|
||||
@@ -6207,7 +6208,8 @@ void nsIFrame::InlinePrefISizeData::ForceBreak(StyleClear aClearType) {
|
||||
// no longer any floats we need to keep. See below.
|
||||
for (FloatInfo& floatInfo : Reversed(mFloats)) {
|
||||
const nsStyleDisplay* floatDisp = floatInfo.Frame()->StyleDisplay();
|
||||
if (floatDisp->mFloat != clearFloatType) {
|
||||
auto cbWM = floatInfo.Frame()->GetParent()->GetWritingMode();
|
||||
if (floatDisp->UsedFloat(cbWM) != clearFloatType) {
|
||||
newFloats.AppendElement(floatInfo);
|
||||
} else {
|
||||
// This is a float on the side that this break directly clears
|
||||
@@ -6217,7 +6219,7 @@ void nsIFrame::InlinePrefISizeData::ForceBreak(StyleClear aClearType) {
|
||||
// (earlier) floats on that side would be indirectly cleared
|
||||
// as well. Thus, we should break out of this loop and stop
|
||||
// considering earlier floats to be kept in mFloats.
|
||||
StyleClear clearType = floatDisp->mClear;
|
||||
StyleClear clearType = floatDisp->UsedClear(cbWM);
|
||||
if (clearType != aClearType && clearType != StyleClear::None) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -194,6 +194,10 @@ static void ListFloats(FILE* out, const char* aPrefix,
|
||||
return "right";
|
||||
case StyleClear::Both:
|
||||
return "both";
|
||||
case StyleClear::InlineStart:
|
||||
return "inline-start";
|
||||
case StyleClear::InlineEnd:
|
||||
return "inline-end";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@@ -1329,6 +1329,10 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
||||
return mContainerType != mozilla::StyleContainerType::Normal;
|
||||
}
|
||||
|
||||
// See WritingModes.h for the implementations.
|
||||
inline mozilla::StyleFloat UsedFloat(mozilla::WritingMode aWM) const;
|
||||
inline mozilla::StyleClear UsedClear(mozilla::WritingMode aWM) const;
|
||||
|
||||
private:
|
||||
mozilla::StyleAppearance mAppearance;
|
||||
mozilla::StyleContain mContain;
|
||||
|
||||
@@ -92,11 +92,9 @@ ${helpers.predefined_type(
|
||||
"Float",
|
||||
"computed::Float::None",
|
||||
engines="gecko servo",
|
||||
initial_specified_value="specified::Float::None",
|
||||
spec="https://drafts.csswg.org/css-box/#propdef-float",
|
||||
animation_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-box/#propdef-float",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
gecko_ffi_name="mFloat",
|
||||
affects="layout",
|
||||
)}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ use std::fmt;
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
|
||||
pub use crate::values::specified::box_::{
|
||||
Appearance, BaselineSource, BreakBetween, BreakWithin, Clear as SpecifiedClear, Contain,
|
||||
ContainerName, ContainerType, ContentVisibility, Display, Float as SpecifiedFloat, Overflow,
|
||||
Appearance, BaselineSource, BreakBetween, BreakWithin, Clear, Contain,
|
||||
ContainerName, ContainerType, ContentVisibility, Display, Float, Overflow,
|
||||
OverflowAnchor, OverflowClipBox, OverscrollBehavior, ScrollSnapAlign, ScrollSnapAxis,
|
||||
ScrollSnapStop, ScrollSnapStrictness, ScrollSnapType, ScrollbarGutter, TouchAction, WillChange,
|
||||
};
|
||||
@@ -58,156 +58,6 @@ impl Animate for LineClamp {
|
||||
/// A computed value for the `perspective` property.
|
||||
pub type Perspective = GenericPerspective<NonNegativeLength>;
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
FromPrimitive,
|
||||
Hash,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
/// A computed value for the `float` property.
|
||||
pub enum Float {
|
||||
Left,
|
||||
Right,
|
||||
None,
|
||||
}
|
||||
|
||||
impl Float {
|
||||
/// Returns true if `self` is not `None`.
|
||||
pub fn is_floating(self) -> bool {
|
||||
self != Self::None
|
||||
}
|
||||
}
|
||||
|
||||
impl ToComputedValue for SpecifiedFloat {
|
||||
type ComputedValue = Float;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
let ltr = context.style().writing_mode.is_bidi_ltr();
|
||||
// https://drafts.csswg.org/css-logical-props/#float-clear
|
||||
match *self {
|
||||
SpecifiedFloat::InlineStart => {
|
||||
context
|
||||
.rule_cache_conditions
|
||||
.borrow_mut()
|
||||
.set_writing_mode_dependency(context.builder.writing_mode);
|
||||
if ltr {
|
||||
Float::Left
|
||||
} else {
|
||||
Float::Right
|
||||
}
|
||||
},
|
||||
SpecifiedFloat::InlineEnd => {
|
||||
context
|
||||
.rule_cache_conditions
|
||||
.borrow_mut()
|
||||
.set_writing_mode_dependency(context.builder.writing_mode);
|
||||
if ltr {
|
||||
Float::Right
|
||||
} else {
|
||||
Float::Left
|
||||
}
|
||||
},
|
||||
SpecifiedFloat::Left => Float::Left,
|
||||
SpecifiedFloat::Right => Float::Right,
|
||||
SpecifiedFloat::None => Float::None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedFloat {
|
||||
match *computed {
|
||||
Float::Left => SpecifiedFloat::Left,
|
||||
Float::Right => SpecifiedFloat::Right,
|
||||
Float::None => SpecifiedFloat::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
FromPrimitive,
|
||||
Hash,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
)]
|
||||
/// A computed value for the `clear` property.
|
||||
#[repr(u8)]
|
||||
pub enum Clear {
|
||||
None,
|
||||
Left,
|
||||
Right,
|
||||
Both,
|
||||
}
|
||||
|
||||
impl ToComputedValue for SpecifiedClear {
|
||||
type ComputedValue = Clear;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
let ltr = context.style().writing_mode.is_bidi_ltr();
|
||||
// https://drafts.csswg.org/css-logical-props/#float-clear
|
||||
match *self {
|
||||
SpecifiedClear::InlineStart => {
|
||||
context
|
||||
.rule_cache_conditions
|
||||
.borrow_mut()
|
||||
.set_writing_mode_dependency(context.builder.writing_mode);
|
||||
if ltr {
|
||||
Clear::Left
|
||||
} else {
|
||||
Clear::Right
|
||||
}
|
||||
},
|
||||
SpecifiedClear::InlineEnd => {
|
||||
context
|
||||
.rule_cache_conditions
|
||||
.borrow_mut()
|
||||
.set_writing_mode_dependency(context.builder.writing_mode);
|
||||
if ltr {
|
||||
Clear::Right
|
||||
} else {
|
||||
Clear::Left
|
||||
}
|
||||
},
|
||||
SpecifiedClear::None => Clear::None,
|
||||
SpecifiedClear::Left => Clear::Left,
|
||||
SpecifiedClear::Right => Clear::Right,
|
||||
SpecifiedClear::Both => Clear::Both,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedClear {
|
||||
match *computed {
|
||||
Clear::None => SpecifiedClear::None,
|
||||
Clear::Left => SpecifiedClear::Left,
|
||||
Clear::Right => SpecifiedClear::Right,
|
||||
Clear::Both => SpecifiedClear::Both,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A computed value for the `resize` property.
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
|
||||
@@ -1381,12 +1381,26 @@ impl Parse for ContainerName {
|
||||
/// A specified value for the `perspective` property.
|
||||
pub type Perspective = GenericPerspective<NonNegativeLength>;
|
||||
|
||||
/// https://drafts.csswg.org/css-box/#propdef-float
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, ToShmem,
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
FromPrimitive,
|
||||
Hash,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
/// https://drafts.csswg.org/css-box/#propdef-float
|
||||
#[repr(u8)]
|
||||
pub enum Float {
|
||||
Left,
|
||||
Right,
|
||||
@@ -1396,12 +1410,33 @@ pub enum Float {
|
||||
InlineEnd,
|
||||
}
|
||||
|
||||
impl Float {
|
||||
/// Returns true if `self` is not `None`.
|
||||
pub fn is_floating(self) -> bool {
|
||||
self != Self::None
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css2/#propdef-clear
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, ToShmem,
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
FromPrimitive,
|
||||
Hash,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
/// https://drafts.csswg.org/css2/#propdef-clear
|
||||
#[repr(u8)]
|
||||
pub enum Clear {
|
||||
None,
|
||||
Left,
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
[clear-computed.html]
|
||||
[Property clear value 'inline-start']
|
||||
expected: FAIL
|
||||
|
||||
[Property clear value 'inline-end']
|
||||
expected: FAIL
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
[float-computed.html]
|
||||
[Property float value 'inline-start']
|
||||
expected: FAIL
|
||||
|
||||
[Property float value 'inline-end']
|
||||
expected: FAIL
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
[float-valid.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
@@ -1,2 +0,0 @@
|
||||
[logical-values-float-clear-reftest.html]
|
||||
expected: FAIL
|
||||
@@ -1,14 +0,0 @@
|
||||
[logical-values-float-clear.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Test that 'clear: inline-start' is supported.]
|
||||
expected: FAIL
|
||||
|
||||
[Test that 'clear: inline-end' is supported.]
|
||||
expected: FAIL
|
||||
|
||||
[Test that 'float: inline-start' is supported.]
|
||||
expected: FAIL
|
||||
|
||||
[Test that 'float: inline-end' is supported.]
|
||||
expected: FAIL
|
||||
Reference in New Issue
Block a user