summaryrefslogtreecommitdiffstats
path: root/layout/generic
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
commitd8bbc7858622b6d9c278469aab701ca0b609cddf (patch)
treeeff41dc61d9f714852212739e6b3738b82a2af87 /layout/generic
parentReleasing progress-linux version 125.0.3-1~progress7.99u1. (diff)
downloadfirefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz
firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/generic')
-rw-r--r--layout/generic/AspectRatio.cpp2
-rw-r--r--layout/generic/AspectRatio.h2
-rw-r--r--layout/generic/BRFrame.cpp13
-rw-r--r--layout/generic/CSSAlignUtils.cpp4
-rw-r--r--layout/generic/ColumnSetWrapperFrame.cpp2
-rw-r--r--layout/generic/MiddleCroppingBlockFrame.cpp11
-rw-r--r--layout/generic/PrintedSheetFrame.cpp1
-rw-r--r--layout/generic/ReflowInput.cpp139
-rw-r--r--layout/generic/ReflowInput.h39
-rw-r--r--layout/generic/ScrollGeneration.h5
-rw-r--r--layout/generic/ScrollSnapTargetId.h1
-rw-r--r--layout/generic/ViewportFrame.cpp23
-rw-r--r--layout/generic/WritingModes.h216
-rw-r--r--layout/generic/crashtests/1410243-1.html26
-rw-r--r--layout/generic/crashtests/1741488-1.html23
-rw-r--r--layout/generic/crashtests/1881375-1-helper.html38
-rw-r--r--layout/generic/crashtests/1881375-1.html25
-rw-r--r--layout/generic/crashtests/481921.oggbin42852 -> 0 bytes
-rw-r--r--layout/generic/crashtests/crashtests.list3
-rw-r--r--layout/generic/nsAbsoluteContainingBlock.cpp6
-rw-r--r--layout/generic/nsBackdropFrame.cpp1
-rw-r--r--layout/generic/nsBlockFrame.cpp33
-rw-r--r--layout/generic/nsCanvasFrame.cpp21
-rw-r--r--layout/generic/nsColumnSetFrame.cpp7
-rw-r--r--layout/generic/nsContainerFrame.cpp44
-rw-r--r--layout/generic/nsContainerFrame.h122
-rw-r--r--layout/generic/nsFirstLetterFrame.cpp1
-rw-r--r--layout/generic/nsFlexContainerFrame.cpp205
-rw-r--r--layout/generic/nsFlexContainerFrame.h6
-rw-r--r--layout/generic/nsFloatManager.cpp2
-rw-r--r--layout/generic/nsFrameSelection.cpp30
-rw-r--r--layout/generic/nsFrameSelection.h32
-rw-r--r--layout/generic/nsFrameSetFrame.cpp2
-rw-r--r--layout/generic/nsGfxScrollFrame.cpp40
-rw-r--r--layout/generic/nsGfxScrollFrame.h2
-rw-r--r--layout/generic/nsGridContainerFrame.cpp502
-rw-r--r--layout/generic/nsGridContainerFrame.h12
-rw-r--r--layout/generic/nsHTMLCanvasFrame.cpp3
-rw-r--r--layout/generic/nsIFrame.cpp1167
-rw-r--r--layout/generic/nsIFrame.h29
-rw-r--r--layout/generic/nsIFrameInlines.h2
-rw-r--r--layout/generic/nsImageFrame.cpp5
-rw-r--r--layout/generic/nsInlineFrame.cpp1
-rw-r--r--layout/generic/nsLeafFrame.cpp10
-rw-r--r--layout/generic/nsLineBox.cpp2
-rw-r--r--layout/generic/nsLineBox.h48
-rw-r--r--layout/generic/nsLineLayout.cpp6
-rw-r--r--layout/generic/nsPageContentFrame.cpp1
-rw-r--r--layout/generic/nsPageFrame.cpp84
-rw-r--r--layout/generic/nsPageSequenceFrame.cpp1
-rw-r--r--layout/generic/nsPlaceholderFrame.cpp1
-rw-r--r--layout/generic/nsRubyBaseContainerFrame.cpp1
-rw-r--r--layout/generic/nsRubyFrame.cpp5
-rw-r--r--layout/generic/nsRubyTextContainerFrame.cpp1
-rw-r--r--layout/generic/nsSubDocumentFrame.cpp9
-rw-r--r--layout/generic/nsTextFrame.cpp66
-rw-r--r--layout/generic/nsTextPaintStyle.cpp18
-rw-r--r--layout/generic/nsTextPaintStyle.h1
-rw-r--r--layout/generic/nsTextRunTransformations.cpp20
-rw-r--r--layout/generic/nsTextRunTransformations.h3
-rw-r--r--layout/generic/nsVideoFrame.cpp8
-rw-r--r--layout/generic/test/mochitest.toml37
-rw-r--r--layout/generic/test/selection_cross_shadow_boundary_helper.js28
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_1_backward_click.html36
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_1_backward_drag.html40
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_1_forward_click.html35
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_1_forward_drag.html39
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_2_backward_click.html47
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_2_backward_drag.html48
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_2_forward_click.html46
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_2_forward_drag.html48
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_click.html61
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_drag.html65
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_click.html59
-rw-r--r--layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_drag.html65
75 files changed, 1780 insertions, 2007 deletions
diff --git a/layout/generic/AspectRatio.cpp b/layout/generic/AspectRatio.cpp
index 2fe51fed5e..0a8ef181e4 100644
--- a/layout/generic/AspectRatio.cpp
+++ b/layout/generic/AspectRatio.cpp
@@ -20,7 +20,7 @@ nscoord AspectRatio::ComputeRatioDependentSize(
const LogicalSize& boxSizingAdjust = mUseBoxSizing == UseBoxSizing::No
? LogicalSize(aWM)
: aContentBoxSizeToBoxSizingAdjust;
- return aRatioDependentAxis == LogicalAxis::eLogicalAxisInline
+ return aRatioDependentAxis == LogicalAxis::Inline
? ConvertToWritingMode(aWM).ApplyTo(aRatioDeterminingSize +
boxSizingAdjust.BSize(aWM)) -
boxSizingAdjust.ISize(aWM)
diff --git a/layout/generic/AspectRatio.h b/layout/generic/AspectRatio.h
index 6f48a07da3..daafd06ba8 100644
--- a/layout/generic/AspectRatio.h
+++ b/layout/generic/AspectRatio.h
@@ -22,7 +22,7 @@ struct ParamTraits;
namespace mozilla {
-enum LogicalAxis : uint8_t;
+enum class LogicalAxis : uint8_t;
class LogicalSize;
class WritingMode;
diff --git a/layout/generic/BRFrame.cpp b/layout/generic/BRFrame.cpp
index 52cc3a0b46..13b3fbb9a4 100644
--- a/layout/generic/BRFrame.cpp
+++ b/layout/generic/BRFrame.cpp
@@ -98,7 +98,6 @@ void BRFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
const ReflowInput& aReflowInput, nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("BRFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
WritingMode wm = aReflowInput.GetWritingMode();
@@ -186,18 +185,10 @@ void BRFrame::AddInlinePrefISize(gfxContext* aRenderingContext,
}
/* virtual */
-nscoord BRFrame::GetMinISize(gfxContext* aRenderingContext) {
- nscoord result = 0;
- DISPLAY_MIN_INLINE_SIZE(this, result);
- return result;
-}
+nscoord BRFrame::GetMinISize(gfxContext* aRenderingContext) { return 0; }
/* virtual */
-nscoord BRFrame::GetPrefISize(gfxContext* aRenderingContext) {
- nscoord result = 0;
- DISPLAY_PREF_INLINE_SIZE(this, result);
- return result;
-}
+nscoord BRFrame::GetPrefISize(gfxContext* aRenderingContext) { return 0; }
Maybe<nscoord> BRFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
diff --git a/layout/generic/CSSAlignUtils.cpp b/layout/generic/CSSAlignUtils.cpp
index b88ec8bfa4..7dd8999563 100644
--- a/layout/generic/CSSAlignUtils.cpp
+++ b/layout/generic/CSSAlignUtils.cpp
@@ -68,10 +68,10 @@ nscoord CSSAlignUtils::AlignJustifySelf(const StyleAlignFlags& aAlignment,
// (Note: ReflowInput will have treated "auto" margins as 0, so we
// don't need to do anything special to avoid expanding them.)
hasAutoMarginStart = hasAutoMarginEnd = false;
- } else if (aAxis == eLogicalAxisBlock) {
+ } else if (aAxis == LogicalAxis::Block) {
hasAutoMarginStart = styleMargin.GetBStart(wm).IsAuto();
hasAutoMarginEnd = styleMargin.GetBEnd(wm).IsAuto();
- } else { /* aAxis == eLogicalAxisInline */
+ } else { /* aAxis == LogicalAxis::Inline */
hasAutoMarginStart = styleMargin.GetIStart(wm).IsAuto();
hasAutoMarginEnd = styleMargin.GetIEnd(wm).IsAuto();
}
diff --git a/layout/generic/ColumnSetWrapperFrame.cpp b/layout/generic/ColumnSetWrapperFrame.cpp
index 7717f14df8..9f22222925 100644
--- a/layout/generic/ColumnSetWrapperFrame.cpp
+++ b/layout/generic/ColumnSetWrapperFrame.cpp
@@ -151,7 +151,6 @@ void ColumnSetWrapperFrame::MarkIntrinsicISizesDirty() {
nscoord ColumnSetWrapperFrame::GetMinISize(gfxContext* aRenderingContext) {
nscoord iSize = 0;
- DISPLAY_MIN_INLINE_SIZE(this, iSize);
if (Maybe<nscoord> containISize =
ContainIntrinsicISize(NS_UNCONSTRAINEDSIZE)) {
@@ -193,7 +192,6 @@ nscoord ColumnSetWrapperFrame::GetMinISize(gfxContext* aRenderingContext) {
nscoord ColumnSetWrapperFrame::GetPrefISize(gfxContext* aRenderingContext) {
nscoord iSize = 0;
- DISPLAY_PREF_INLINE_SIZE(this, iSize);
if (Maybe<nscoord> containISize =
ContainIntrinsicISize(NS_UNCONSTRAINEDSIZE)) {
diff --git a/layout/generic/MiddleCroppingBlockFrame.cpp b/layout/generic/MiddleCroppingBlockFrame.cpp
index 4cbbb684aa..75dc205a4f 100644
--- a/layout/generic/MiddleCroppingBlockFrame.cpp
+++ b/layout/generic/MiddleCroppingBlockFrame.cpp
@@ -57,18 +57,11 @@ void MiddleCroppingBlockFrame::UpdateDisplayedValueToUncroppedValue(
}
nscoord MiddleCroppingBlockFrame::GetMinISize(gfxContext* aRenderingContext) {
- nscoord result;
- DISPLAY_MIN_INLINE_SIZE(this, result);
-
// Our min inline size is our pref inline size
- result = GetPrefISize(aRenderingContext);
- return result;
+ return GetPrefISize(aRenderingContext);
}
nscoord MiddleCroppingBlockFrame::GetPrefISize(gfxContext* aRenderingContext) {
- nscoord result;
- DISPLAY_PREF_INLINE_SIZE(this, result);
-
nsAutoString prevValue;
bool restoreOldValue = false;
@@ -79,7 +72,7 @@ nscoord MiddleCroppingBlockFrame::GetPrefISize(gfxContext* aRenderingContext) {
UpdateDisplayedValueToUncroppedValue(false);
}
- result = nsBlockFrame::GetPrefISize(aRenderingContext);
+ nscoord result = nsBlockFrame::GetPrefISize(aRenderingContext);
if (restoreOldValue) {
UpdateDisplayedValue(prevValue, /* aIsCropped = */ true, false);
diff --git a/layout/generic/PrintedSheetFrame.cpp b/layout/generic/PrintedSheetFrame.cpp
index 5b8151bbd0..384e63e361 100644
--- a/layout/generic/PrintedSheetFrame.cpp
+++ b/layout/generic/PrintedSheetFrame.cpp
@@ -86,7 +86,6 @@ void PrintedSheetFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("PrintedSheetFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aReflowOutput, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
// If we have a prev-in-flow, take its overflowing content:
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
index ed7dbd2656..c642c77b2c 100644
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -13,10 +13,8 @@
#include "CounterStyleManager.h"
#include "LayoutLogging.h"
#include "mozilla/dom/HTMLInputElement.h"
-#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/WritingModes.h"
#include "nsBlockFrame.h"
-#include "nsCSSAnonBoxes.h"
#include "nsFlexContainerFrame.h"
#include "nsFontInflationData.h"
#include "nsFontMetrics.h"
@@ -31,7 +29,6 @@
#include "nsLineBox.h"
#include "nsPresContext.h"
#include "nsStyleConsts.h"
-#include "nsTableCellFrame.h"
#include "nsTableFrame.h"
#include "StickyScrollContainer.h"
@@ -1238,11 +1235,11 @@ static bool AxisPolarityFlipped(LogicalAxis aThisAxis, WritingMode aThisWm,
}
static bool InlinePolarityFlipped(WritingMode aThisWm, WritingMode aOtherWm) {
- return AxisPolarityFlipped(eLogicalAxisInline, aThisWm, aOtherWm);
+ return AxisPolarityFlipped(LogicalAxis::Inline, aThisWm, aOtherWm);
}
static bool BlockPolarityFlipped(WritingMode aThisWm, WritingMode aOtherWm) {
- return AxisPolarityFlipped(eLogicalAxisBlock, aThisWm, aOtherWm);
+ return AxisPolarityFlipped(LogicalAxis::Block, aThisWm, aOtherWm);
}
// Calculate the position of the hypothetical box that the element would have
@@ -1292,7 +1289,6 @@ void ReflowInput::CalculateHypotheticalPosition(
// For non-replaced inline-level elements the 'inline size' property
// doesn't apply, so we don't know what the inline size would have
// been without reflowing it
-
} else {
// It's either a replaced inline-level element or a block-level element
@@ -1301,17 +1297,17 @@ void ReflowInput::CalculateHypotheticalPosition(
// been in the flow. Note that we ignore any 'auto' and 'inherit'
// values
nscoord insideBoxISizing, outsideBoxISizing;
- CalculateBorderPaddingMargin(eLogicalAxisInline, blockContentSize.ISize(wm),
- &insideBoxISizing, &outsideBoxISizing);
+ CalculateBorderPaddingMargin(LogicalAxis::Inline,
+ blockContentSize.ISize(wm), &insideBoxISizing,
+ &outsideBoxISizing);
if (mFlags.mIsReplaced && isAutoISize) {
- // It's a replaced element with an 'auto' inline size so the box
- // inline size is its intrinsic size plus any border/padding/margin
+ // It's a replaced element with an 'auto' inline size so the box inline
+ // size is its intrinsic size plus any border/padding/margin
if (intrinsicSize) {
boxISize.emplace(LogicalSize(wm, *intrinsicSize).ISize(wm) +
outsideBoxISizing + insideBoxISizing);
}
-
} else if (isAutoISize) {
// The box inline size is the containing block inline size
boxISize.emplace(blockContentSize.ISize(wm));
@@ -1320,7 +1316,7 @@ void ReflowInput::CalculateHypotheticalPosition(
// percentage based this computed value may be different from the computed
// value calculated using the absolute containing block width
nscoord insideBoxBSizing, dummy;
- CalculateBorderPaddingMargin(eLogicalAxisBlock,
+ CalculateBorderPaddingMargin(LogicalAxis::Block,
blockContentSize.ISize(wm),
&insideBoxBSizing, &dummy);
boxISize.emplace(
@@ -1500,7 +1496,7 @@ void ReflowInput::CalculateHypotheticalPosition(
// been in the flow. Note that we ignore any 'auto' and 'inherit'
// values.
nscoord insideBoxSizing, outsideBoxSizing;
- CalculateBorderPaddingMargin(eLogicalAxisBlock, blockContentSize.BSize(wm),
+ CalculateBorderPaddingMargin(LogicalAxis::Block, blockContentSize.BSize(wm),
&insideBoxSizing, &outsideBoxSizing);
nscoord boxBSize;
@@ -1627,7 +1623,7 @@ LogicalSize ReflowInput::CalculateAbsoluteSizeWithResolvedAutoBlockSize(
: LogicalSize(wm);
auto transferredISize =
mStylePosition->mAspectRatio.ToLayoutRatio().ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, wm, aAutoBSize, boxSizingAdjust);
+ LogicalAxis::Inline, wm, aAutoBSize, boxSizingAdjust);
resultSize.ISize(wm) = ApplyMinMaxISize(transferredISize);
MOZ_ASSERT(mFlags.mIsBSizeSetByAspectRatio,
@@ -2167,8 +2163,6 @@ void ReflowInput::InitConstraints(
WritingMode wm = GetWritingMode();
LogicalSize cbSize = aContainingBlockSize.valueOr(
LogicalSize(mWritingMode, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE));
- DISPLAY_INIT_CONSTRAINTS(mFrame, this, cbSize.ISize(wm), cbSize.BSize(wm),
- aBorder, aPadding);
// If this is a reflow root, then set the computed width and
// height equal to the available space
@@ -2239,7 +2233,7 @@ void ReflowInput::InitConstraints(
// eStyleUnit_Auto;" used to be called exclusively.
if (mFlags.mIsReplaced && mStyleDisplay->IsInlineOutsideStyle()) {
// Get the containing block's reflow input
- NS_ASSERTION(nullptr != cbri, "no containing block");
+ NS_ASSERTION(cbri, "no containing block");
// in quirks mode, get the cb height using the special quirk method
if (!wm.IsVertical() &&
eCompatibility_NavQuirks == aPresContext->CompatibilityMode()) {
@@ -2359,46 +2353,79 @@ void ReflowInput::InitConstraints(
} else {
AutoMaybeDisableFontInflation an(mFrame);
- const bool isBlockLevel =
- ((!mStyleDisplay->IsInlineOutsideStyle() &&
- // internal table values on replaced elements behaves as inline
- // https://drafts.csswg.org/css-tables-3/#table-structure
- // "... it is handled instead as though the author had declared
- // either 'block' (for 'table' display) or 'inline' (for all
- // other values)"
- !(mFlags.mIsReplaced && (mStyleDisplay->IsInnerTableStyle() ||
- mStyleDisplay->DisplayOutside() ==
- StyleDisplayOutside::TableCaption))) ||
- // The inner table frame always fills its outer wrapper table frame,
- // even for 'inline-table'.
- mFrame->IsTableFrame()) &&
- // XXX abs.pos. continuations treated like blocks, see comment in
- // the else-if condition above.
- (!mFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) ||
- mStyleDisplay->IsAbsolutelyPositionedStyle());
-
- if (!isBlockLevel) {
- mComputeSizeFlags += ComputeSizeFlag::ShrinkWrap;
- }
+ nsIFrame* const alignCB = [&] {
+ nsIFrame* cb = mFrame->GetParent();
+ if (cb->IsTableWrapperFrame()) {
+ nsIFrame* alignCBParent = cb->GetParent();
+ if (alignCBParent && alignCBParent->IsGridContainerFrame()) {
+ return alignCBParent;
+ }
+ }
+ return cb;
+ }();
- nsIFrame* alignCB = mFrame->GetParent();
- if (alignCB->IsTableWrapperFrame()) {
- nsIFrame* alignCBParent = alignCB->GetParent();
- if (alignCBParent && alignCBParent->IsGridContainerFrame()) {
- alignCB = alignCBParent;
+ const bool isInlineLevel = [&] {
+ if (mFrame->IsTableFrame()) {
+ // An inner table frame is not inline-level, even if it happens to
+ // have 'display:inline-table'. (That makes its table-wrapper frame be
+ // inline-level, but not the inner table frame)
+ return false;
}
- }
- if (!alignCB->IsGridContainerFrame()) {
- // Shrink-wrap blocks that are orthogonal to their container.
- if (isBlockLevel && mCBReflowInput &&
+ if (mStyleDisplay->IsInlineOutsideStyle()) {
+ return true;
+ }
+ if (mFlags.mIsReplaced && (mStyleDisplay->IsInnerTableStyle() ||
+ mStyleDisplay->DisplayOutside() ==
+ StyleDisplayOutside::TableCaption)) {
+ // Internal table values on replaced elements behave as inline
+ // https://drafts.csswg.org/css-tables-3/#table-structure
+ //
+ // ... it is handled instead as though the author had declared
+ // either 'block' (for 'table' display) or 'inline' (for all
+ // other values)"
+ //
+ // FIXME(emilio): The only test that covers this is
+ // table-anonymous-objects-211.xht, which fails on other browsers (but
+ // differently to us, if you just remove this condition).
+ return true;
+ }
+ if (mFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) &&
+ !mStyleDisplay->IsAbsolutelyPositionedStyle()) {
+ // Floats are treated as inline-level and also shrink-wrap.
+ return true;
+ }
+ return false;
+ }();
+
+ const bool shouldShrinkWrap = [&] {
+ if (isInlineLevel) {
+ return true;
+ }
+ if (mFlags.mIsReplaced && !alignCB->IsFlexOrGridContainer()) {
+ // Shrink-wrap replaced elements when in-flow (out of flows are
+ // handled above). We exclude replaced elements in grid or flex
+ // contexts, where we don't want to shrink-wrap unconditionally (so
+ // that stretching can happen). When grid/flex explicitly want
+ // shrink-wrapping, they can request it directly using the relevant
+ // flag.
+ return true;
+ }
+ if (!alignCB->IsGridContainerFrame() && mCBReflowInput &&
mCBReflowInput->GetWritingMode().IsOrthogonalTo(mWritingMode)) {
- mComputeSizeFlags += ComputeSizeFlag::ShrinkWrap;
+ // Shrink-wrap blocks that are orthogonal to their container (unless
+ // we're in a grid?)
+ return true;
}
+ return false;
+ }();
+
+ if (shouldShrinkWrap) {
+ mComputeSizeFlags += ComputeSizeFlag::ShrinkWrap;
}
if (cbSize.ISize(wm) == NS_UNCONSTRAINEDSIZE) {
- // For orthogonal flows, where we found a parent orthogonal-limit
- // for AvailableISize() in Init(), we'll use the same here as well.
+ // For orthogonal flows, where we found a parent orthogonal-limit for
+ // AvailableISize() in Init(), we'll use the same here as well.
cbSize.ISize(wm) = AvailableISize();
}
@@ -2418,10 +2445,7 @@ void ReflowInput::InitConstraints(
size.mAspectRatioUsage == nsIFrame::AspectRatioUsage::ToComputeBSize;
const bool shouldCalculateBlockSideMargins = [&]() {
- if (!isBlockLevel) {
- return false;
- }
- if (mStyleDisplay->mDisplay == StyleDisplay::InlineTable) {
+ if (isInlineLevel) {
return false;
}
if (mFrame->IsTableFrame()) {
@@ -2475,7 +2499,6 @@ void SizeComputationInput::InitOffsets(WritingMode aCBWM, nscoord aPercentBasis,
const Maybe<LogicalMargin>& aBorder,
const Maybe<LogicalMargin>& aPadding,
const nsStyleDisplay* aDisplay) {
- DISPLAY_INIT_OFFSETS(mFrame, this, aPercentBasis, aCBWM, aBorder, aPadding);
nsPresContext* presContext = mFrame->PresContext();
// Compute margins from the specified margin style information. These
@@ -2533,7 +2556,7 @@ void SizeComputationInput::InitOffsets(WritingMode aCBWM, nscoord aPercentBasis,
}
mComputedPadding.Side(side, wm) += val;
needPaddingProp = true;
- if (aAxis == eLogicalAxisBlock && val > 0) {
+ if (aAxis == LogicalAxis::Block && val > 0) {
// We have a baseline-adjusted block-axis start padding, so
// we need this to mark lines dirty when mIsBResize is true:
this->mFrame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
@@ -2541,10 +2564,10 @@ void SizeComputationInput::InitOffsets(WritingMode aCBWM, nscoord aPercentBasis,
}
};
if (!aFlags.contains(ComputeSizeFlag::IsGridMeasuringReflow)) {
- ApplyBaselinePadding(eLogicalAxisBlock, nsIFrame::BBaselinePadProperty());
+ ApplyBaselinePadding(LogicalAxis::Block, nsIFrame::BBaselinePadProperty());
}
if (!aFlags.contains(ComputeSizeFlag::ShrinkWrap)) {
- ApplyBaselinePadding(eLogicalAxisInline, nsIFrame::IBaselinePadProperty());
+ ApplyBaselinePadding(LogicalAxis::Inline, nsIFrame::IBaselinePadProperty());
}
LogicalMargin border(wm);
diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h
index 620ad0f413..ba49edcaf6 100644
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -178,20 +178,6 @@ struct SizeComputationInput {
const mozilla::Maybe<mozilla::LogicalMargin>& aPadding =
mozilla::Nothing());
-#ifdef DEBUG
- // Reflow trace methods. Defined in nsFrame.cpp so they have access
- // to the display-reflow infrastructure.
- static void* DisplayInitOffsetsEnter(nsIFrame* aFrame,
- SizeComputationInput* aState,
- nscoord aPercentBasis,
- mozilla::WritingMode aCBWritingMode,
- const nsMargin* aBorder,
- const nsMargin* aPadding);
- static void DisplayInitOffsetsExit(nsIFrame* aFrame,
- SizeComputationInput* aState,
- void* aValue);
-#endif
-
private:
/**
* Computes margin values from the specified margin style information, and
@@ -367,6 +353,16 @@ struct ReflowInput : public SizeComputationInput {
mozilla::LogicalSize AvailableSize() const { return mAvailableSize; }
mozilla::LogicalSize ComputedSize() const { return mComputedSize; }
+
+ template <typename F>
+ mozilla::LogicalSize ComputedSizeWithBSizeFallback(F&& aFallback) const {
+ auto size = mComputedSize;
+ if (size.BSize(mWritingMode) == NS_UNCONSTRAINEDSIZE) {
+ size.BSize(mWritingMode) = ApplyMinMaxBSize(aFallback());
+ }
+ return size;
+ }
+
mozilla::LogicalSize ComputedMinSize() const { return mComputedMinSize; }
mozilla::LogicalSize ComputedMaxSize() const { return mComputedMaxSize; }
@@ -888,21 +884,6 @@ struct ReflowInput : public SizeComputationInput {
LogicalMargin& aMargin,
LogicalMargin& aOffsets);
-#ifdef DEBUG
- // Reflow trace methods. Defined in nsFrame.cpp so they have access
- // to the display-reflow infrastructure.
- static void* DisplayInitConstraintsEnter(nsIFrame* aFrame,
- ReflowInput* aState,
- nscoord aCBISize, nscoord aCBBSize,
- const nsMargin* aBorder,
- const nsMargin* aPadding);
- static void DisplayInitConstraintsExit(nsIFrame* aFrame, ReflowInput* aState,
- void* aValue);
- static void* DisplayInitFrameTypeEnter(nsIFrame* aFrame, ReflowInput* aState);
- static void DisplayInitFrameTypeExit(nsIFrame* aFrame, ReflowInput* aState,
- void* aValue);
-#endif
-
protected:
void InitCBReflowInput();
void InitResizeFlags(nsPresContext* aPresContext,
diff --git a/layout/generic/ScrollGeneration.h b/layout/generic/ScrollGeneration.h
index 90eb243e9e..5f14844e33 100644
--- a/layout/generic/ScrollGeneration.h
+++ b/layout/generic/ScrollGeneration.h
@@ -7,6 +7,7 @@
#include <cstdint>
#include <iosfwd>
+#include <tuple>
namespace mozilla {
@@ -23,7 +24,7 @@ std::ostream& operator<<(std::ostream& aStream,
const ScrollGeneration<Tag>& aGen);
template <typename Tag>
-struct ScrollGeneration {
+struct ScrollGeneration final {
friend struct ScrollGenerationCounter;
private:
@@ -43,6 +44,8 @@ struct ScrollGeneration {
friend std::ostream& operator<< <>(std::ostream& aStream,
const ScrollGeneration<Tag>& aGen);
+ auto MutTiedFields() { return std::tie(mValue); }
+
private:
uint64_t mValue;
};
diff --git a/layout/generic/ScrollSnapTargetId.h b/layout/generic/ScrollSnapTargetId.h
index f53e736fa1..a4a281f5e7 100644
--- a/layout/generic/ScrollSnapTargetId.h
+++ b/layout/generic/ScrollSnapTargetId.h
@@ -17,6 +17,7 @@ namespace mozilla {
enum class ScrollSnapTargetId : uintptr_t {
None = 0,
};
+inline constexpr bool IsEnumCase(ScrollSnapTargetId) { return true; }
struct ScrollSnapTargetIds {
CopyableTArray<ScrollSnapTargetId> mIdsOnX;
diff --git a/layout/generic/ViewportFrame.cpp b/layout/generic/ViewportFrame.cpp
index 812aaa8e33..d71842d013 100644
--- a/layout/generic/ViewportFrame.cpp
+++ b/layout/generic/ViewportFrame.cpp
@@ -271,26 +271,16 @@ void ViewportFrame::RemoveFrame(DestroyContext& aContext, ChildListID aListID,
/* virtual */
nscoord ViewportFrame::GetMinISize(gfxContext* aRenderingContext) {
- nscoord result;
- DISPLAY_MIN_INLINE_SIZE(this, result);
- if (mFrames.IsEmpty())
- result = 0;
- else
- result = mFrames.FirstChild()->GetMinISize(aRenderingContext);
-
- return result;
+ return mFrames.IsEmpty()
+ ? 0
+ : mFrames.FirstChild()->GetMinISize(aRenderingContext);
}
/* virtual */
nscoord ViewportFrame::GetPrefISize(gfxContext* aRenderingContext) {
- nscoord result;
- DISPLAY_PREF_INLINE_SIZE(this, result);
- if (mFrames.IsEmpty())
- result = 0;
- else
- result = mFrames.FirstChild()->GetPrefISize(aRenderingContext);
-
- return result;
+ return mFrames.IsEmpty()
+ ? 0
+ : mFrames.FirstChild()->GetPrefISize(aRenderingContext);
}
nsPoint ViewportFrame::AdjustReflowInputForScrollbars(
@@ -330,7 +320,6 @@ void ViewportFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("ViewportFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
NS_FRAME_TRACE_REFLOW_IN("ViewportFrame::Reflow");
diff --git a/layout/generic/WritingModes.h b/layout/generic/WritingModes.h
index e84c5e276d..0fcf47f1d0 100644
--- a/layout/generic/WritingModes.h
+++ b/layout/generic/WritingModes.h
@@ -46,20 +46,22 @@ struct IMENotification;
} // namespace widget
// Logical axis, edge, side and corner constants for use in various places.
-enum LogicalAxis : uint8_t {
- eLogicalAxisBlock = 0x0,
- eLogicalAxisInline = 0x1
+enum class LogicalAxis : uint8_t {
+ Block,
+ Inline,
};
enum LogicalEdge { eLogicalEdgeStart = 0x0, eLogicalEdgeEnd = 0x1 };
-enum LogicalSide : uint8_t {
- eLogicalSideBStart = (eLogicalAxisBlock << 1) | eLogicalEdgeStart, // 0x0
- eLogicalSideBEnd = (eLogicalAxisBlock << 1) | eLogicalEdgeEnd, // 0x1
- eLogicalSideIStart = (eLogicalAxisInline << 1) | eLogicalEdgeStart, // 0x2
- eLogicalSideIEnd = (eLogicalAxisInline << 1) | eLogicalEdgeEnd // 0x3
+
+enum class LogicalSide : uint8_t {
+ BStart,
+ BEnd,
+ IStart,
+ IEnd,
};
+
constexpr auto AllLogicalSides() {
- return mozilla::MakeInclusiveEnumeratedRange(eLogicalSideBStart,
- eLogicalSideIEnd);
+ return mozilla::MakeInclusiveEnumeratedRange(LogicalSide::BStart,
+ LogicalSide::IEnd);
}
enum class LogicalCorner : uint8_t {
@@ -82,16 +84,23 @@ enum class PhysicalAxes : uint8_t {
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PhysicalAxes)
inline LogicalAxis GetOrthogonalAxis(LogicalAxis aAxis) {
- return aAxis == eLogicalAxisBlock ? eLogicalAxisInline : eLogicalAxisBlock;
+ return aAxis == LogicalAxis::Block ? LogicalAxis::Inline : LogicalAxis::Block;
+}
+
+inline bool IsInline(LogicalSide aSide) {
+ return (aSide == LogicalSide::IStart) || (aSide == LogicalSide::IEnd);
}
-inline bool IsInline(LogicalSide aSide) { return aSide & 0x2; }
inline bool IsBlock(LogicalSide aSide) { return !IsInline(aSide); }
-inline bool IsEnd(LogicalSide aSide) { return aSide & 0x1; }
+
+inline bool IsEnd(LogicalSide aSide) {
+ return (aSide == LogicalSide::BEnd) || (aSide == LogicalSide::IEnd);
+}
+
inline bool IsStart(LogicalSide aSide) { return !IsEnd(aSide); }
inline LogicalAxis GetAxis(LogicalSide aSide) {
- return IsInline(aSide) ? eLogicalAxisInline : eLogicalAxisBlock;
+ return IsInline(aSide) ? LogicalAxis::Inline : LogicalAxis::Block;
}
inline LogicalEdge GetEdge(LogicalSide aSide) {
@@ -104,7 +113,7 @@ inline LogicalEdge GetOppositeEdge(LogicalEdge aEdge) {
}
inline LogicalSide MakeLogicalSide(LogicalAxis aAxis, LogicalEdge aEdge) {
- return LogicalSide((aAxis << 1) | aEdge);
+ return LogicalSide((uint8_t(aAxis) << 1) | aEdge);
}
inline LogicalSide GetOppositeSide(LogicalSide aSide) {
@@ -113,20 +122,20 @@ inline LogicalSide GetOppositeSide(LogicalSide aSide) {
enum LogicalSideBits {
eLogicalSideBitsNone = 0,
- eLogicalSideBitsBStart = 1 << eLogicalSideBStart,
- eLogicalSideBitsBEnd = 1 << eLogicalSideBEnd,
- eLogicalSideBitsIEnd = 1 << eLogicalSideIEnd,
- eLogicalSideBitsIStart = 1 << eLogicalSideIStart,
+ eLogicalSideBitsBStart = 1 << static_cast<uint8_t>(LogicalSide::BStart),
+ eLogicalSideBitsBEnd = 1 << static_cast<uint8_t>(LogicalSide::BEnd),
+ eLogicalSideBitsIEnd = 1 << static_cast<uint8_t>(LogicalSide::IEnd),
+ eLogicalSideBitsIStart = 1 << static_cast<uint8_t>(LogicalSide::IStart),
eLogicalSideBitsBBoth = eLogicalSideBitsBStart | eLogicalSideBitsBEnd,
eLogicalSideBitsIBoth = eLogicalSideBitsIStart | eLogicalSideBitsIEnd,
eLogicalSideBitsAll = eLogicalSideBitsBBoth | eLogicalSideBitsIBoth
};
enum LineRelativeDir {
- eLineRelativeDirOver = eLogicalSideBStart,
- eLineRelativeDirUnder = eLogicalSideBEnd,
- eLineRelativeDirLeft = eLogicalSideIStart,
- eLineRelativeDirRight = eLogicalSideIEnd
+ eLineRelativeDirOver = static_cast<uint8_t>(LogicalSide::BStart),
+ eLineRelativeDirUnder = static_cast<uint8_t>(LogicalSide::BEnd),
+ eLineRelativeDirLeft = static_cast<uint8_t>(LogicalSide::IStart),
+ eLineRelativeDirRight = static_cast<uint8_t>(LogicalSide::IEnd)
};
/**
@@ -329,11 +338,12 @@ class WritingMode {
static_assert(uint8_t(StyleWritingModeProperty::HorizontalTb) == 0 &&
uint8_t(StyleWritingModeProperty::VerticalRl) == 1 &&
uint8_t(StyleWritingModeProperty::VerticalLr) == 3 &&
- eLogicalAxisBlock == 0 && eLogicalAxisInline == 1 &&
- eAxisVertical == 0 && eAxisHorizontal == 1,
+ uint8_t(LogicalAxis::Block) == 0 &&
+ uint8_t(LogicalAxis::Inline) == 1 && eAxisVertical == 0 &&
+ eAxisHorizontal == 1,
"unexpected writing-mode, logical axis or physical axis "
"constant values");
- return mozilla::PhysicalAxis((aWritingModeValue ^ aAxis) & 0x1);
+ return mozilla::PhysicalAxis((aWritingModeValue ^ uint8_t(aAxis)) & 0x1);
}
mozilla::PhysicalAxis PhysicalAxis(LogicalAxis aAxis) const {
@@ -445,38 +455,38 @@ class WritingMode {
static const LogicalSide kPhysicalToLogicalSides[][4] = {
// top right
// bottom left
- { eLogicalSideBStart, eLogicalSideIEnd,
- eLogicalSideBEnd, eLogicalSideIStart }, // horizontal-tb ltr
- { eLogicalSideIStart, eLogicalSideBStart,
- eLogicalSideIEnd, eLogicalSideBEnd }, // vertical-rl ltr
- { eLogicalSideBStart, eLogicalSideIStart,
- eLogicalSideBEnd, eLogicalSideIEnd }, // horizontal-tb rtl
- { eLogicalSideIEnd, eLogicalSideBStart,
- eLogicalSideIStart, eLogicalSideBEnd }, // vertical-rl rtl
- { eLogicalSideBEnd, eLogicalSideIStart,
- eLogicalSideBStart, eLogicalSideIEnd }, // (horizontal-bt) (inv) ltr
- { eLogicalSideIStart, eLogicalSideBEnd,
- eLogicalSideIEnd, eLogicalSideBStart }, // vertical-lr sw-left rtl
- { eLogicalSideBEnd, eLogicalSideIEnd,
- eLogicalSideBStart, eLogicalSideIStart }, // (horizontal-bt) (inv) rtl
- { eLogicalSideIEnd, eLogicalSideBEnd,
- eLogicalSideIStart, eLogicalSideBStart }, // vertical-lr sw-left ltr
- { eLogicalSideBStart, eLogicalSideIEnd,
- eLogicalSideBEnd, eLogicalSideIStart }, // horizontal-tb (inv) rtl
- { eLogicalSideIStart, eLogicalSideBStart,
- eLogicalSideIEnd, eLogicalSideBEnd }, // vertical-rl sw-left rtl
- { eLogicalSideBStart, eLogicalSideIStart,
- eLogicalSideBEnd, eLogicalSideIEnd }, // horizontal-tb (inv) ltr
- { eLogicalSideIEnd, eLogicalSideBStart,
- eLogicalSideIStart, eLogicalSideBEnd }, // vertical-rl sw-left ltr
- { eLogicalSideBEnd, eLogicalSideIEnd,
- eLogicalSideBStart, eLogicalSideIStart }, // (horizontal-bt) ltr
- { eLogicalSideIStart, eLogicalSideBEnd,
- eLogicalSideIEnd, eLogicalSideBStart }, // vertical-lr ltr
- { eLogicalSideBEnd, eLogicalSideIStart,
- eLogicalSideBStart, eLogicalSideIEnd }, // (horizontal-bt) rtl
- { eLogicalSideIEnd, eLogicalSideBEnd,
- eLogicalSideIStart, eLogicalSideBStart }, // vertical-lr rtl
+ { LogicalSide::BStart, LogicalSide::IEnd,
+ LogicalSide::BEnd, LogicalSide::IStart }, // horizontal-tb ltr
+ { LogicalSide::IStart, LogicalSide::BStart,
+ LogicalSide::IEnd, LogicalSide::BEnd }, // vertical-rl ltr
+ { LogicalSide::BStart, LogicalSide::IStart,
+ LogicalSide::BEnd, LogicalSide::IEnd }, // horizontal-tb rtl
+ { LogicalSide::IEnd, LogicalSide::BStart,
+ LogicalSide::IStart, LogicalSide::BEnd }, // vertical-rl rtl
+ { LogicalSide::BEnd, LogicalSide::IStart,
+ LogicalSide::BStart, LogicalSide::IEnd }, // (horizontal-bt) (inv) ltr
+ { LogicalSide::IStart, LogicalSide::BEnd,
+ LogicalSide::IEnd, LogicalSide::BStart }, // vertical-lr sw-left rtl
+ { LogicalSide::BEnd, LogicalSide::IEnd,
+ LogicalSide::BStart, LogicalSide::IStart }, // (horizontal-bt) (inv) rtl
+ { LogicalSide::IEnd, LogicalSide::BEnd,
+ LogicalSide::IStart, LogicalSide::BStart }, // vertical-lr sw-left ltr
+ { LogicalSide::BStart, LogicalSide::IEnd,
+ LogicalSide::BEnd, LogicalSide::IStart }, // horizontal-tb (inv) rtl
+ { LogicalSide::IStart, LogicalSide::BStart,
+ LogicalSide::IEnd, LogicalSide::BEnd }, // vertical-rl sw-left rtl
+ { LogicalSide::BStart, LogicalSide::IStart,
+ LogicalSide::BEnd, LogicalSide::IEnd }, // horizontal-tb (inv) ltr
+ { LogicalSide::IEnd, LogicalSide::BStart,
+ LogicalSide::IStart, LogicalSide::BEnd }, // vertical-rl sw-left ltr
+ { LogicalSide::BEnd, LogicalSide::IEnd,
+ LogicalSide::BStart, LogicalSide::IStart }, // (horizontal-bt) ltr
+ { LogicalSide::IStart, LogicalSide::BEnd,
+ LogicalSide::IEnd, LogicalSide::BStart }, // vertical-lr ltr
+ { LogicalSide::BEnd, LogicalSide::IStart,
+ LogicalSide::BStart, LogicalSide::IEnd }, // (horizontal-bt) rtl
+ { LogicalSide::IEnd, LogicalSide::BEnd,
+ LogicalSide::IStart, LogicalSide::BStart }, // vertical-lr rtl
};
// clang-format on
@@ -732,7 +742,7 @@ class LogicalPoint {
return mPoint.y;
}
nscoord Pos(LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == eLogicalAxisInline ? I(aWM) : B(aWM);
+ return aAxis == LogicalAxis::Inline ? I(aWM) : B(aWM);
}
nscoord LineRelative(WritingMode aWritingMode,
const nsSize& aContainerSize) const // line-axis
@@ -761,7 +771,7 @@ class LogicalPoint {
return mPoint.y;
}
nscoord& Pos(LogicalAxis aAxis, WritingMode aWM) {
- return aAxis == eLogicalAxisInline ? I(aWM) : B(aWM);
+ return aAxis == LogicalAxis::Inline ? I(aWM) : B(aWM);
}
/**
@@ -952,7 +962,7 @@ class LogicalSize {
return mSize.height;
}
nscoord Size(LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == eLogicalAxisInline ? ISize(aWM) : BSize(aWM);
+ return aAxis == LogicalAxis::Inline ? ISize(aWM) : BSize(aWM);
}
nscoord Width(WritingMode aWritingMode) const {
@@ -978,7 +988,7 @@ class LogicalSize {
return mSize.height;
}
nscoord& Size(LogicalAxis aAxis, WritingMode aWM) {
- return aAxis == eLogicalAxisInline ? ISize(aWM) : BSize(aWM);
+ return aAxis == LogicalAxis::Inline ? ISize(aWM) : BSize(aWM);
}
/**
@@ -1234,10 +1244,10 @@ class LogicalMargin {
return mMargin.bottom;
}
nscoord Start(LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == eLogicalAxisInline ? IStart(aWM) : BStart(aWM);
+ return aAxis == LogicalAxis::Inline ? IStart(aWM) : BStart(aWM);
}
nscoord End(LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == eLogicalAxisInline ? IEnd(aWM) : BEnd(aWM);
+ return aAxis == LogicalAxis::Inline ? IEnd(aWM) : BEnd(aWM);
}
nscoord& IStart(WritingMode aWritingMode) // inline-start margin
@@ -1261,10 +1271,10 @@ class LogicalMargin {
return mMargin.bottom;
}
nscoord& Start(LogicalAxis aAxis, WritingMode aWM) {
- return aAxis == eLogicalAxisInline ? IStart(aWM) : BStart(aWM);
+ return aAxis == LogicalAxis::Inline ? IStart(aWM) : BStart(aWM);
}
nscoord& End(LogicalAxis aAxis, WritingMode aWM) {
- return aAxis == eLogicalAxisInline ? IEnd(aWM) : BEnd(aWM);
+ return aAxis == LogicalAxis::Inline ? IEnd(aWM) : BEnd(aWM);
}
nscoord IStartEnd(WritingMode aWritingMode) const // inline margins
@@ -1278,18 +1288,18 @@ class LogicalMargin {
return mMargin.TopBottom();
}
nscoord StartEnd(LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == eLogicalAxisInline ? IStartEnd(aWM) : BStartEnd(aWM);
+ return aAxis == LogicalAxis::Inline ? IStartEnd(aWM) : BStartEnd(aWM);
}
nscoord Side(LogicalSide aSide, WritingMode aWM) const {
switch (aSide) {
- case eLogicalSideBStart:
+ case LogicalSide::BStart:
return BStart(aWM);
- case eLogicalSideBEnd:
+ case LogicalSide::BEnd:
return BEnd(aWM);
- case eLogicalSideIStart:
+ case LogicalSide::IStart:
return IStart(aWM);
- case eLogicalSideIEnd:
+ case LogicalSide::IEnd:
return IEnd(aWM);
}
@@ -1298,13 +1308,13 @@ class LogicalMargin {
}
nscoord& Side(LogicalSide aSide, WritingMode aWM) {
switch (aSide) {
- case eLogicalSideBStart:
+ case LogicalSide::BStart:
return BStart(aWM);
- case eLogicalSideBEnd:
+ case LogicalSide::BEnd:
return BEnd(aWM);
- case eLogicalSideIStart:
+ case LogicalSide::IStart:
return IStart(aWM);
- case eLogicalSideIEnd:
+ case LogicalSide::IEnd:
return IEnd(aWM);
}
@@ -1646,13 +1656,13 @@ class LogicalRect {
}
nscoord Start(LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == eLogicalAxisInline ? IStart(aWM) : BStart(aWM);
+ return aAxis == LogicalAxis::Inline ? IStart(aWM) : BStart(aWM);
}
nscoord End(LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == eLogicalAxisInline ? IEnd(aWM) : BEnd(aWM);
+ return aAxis == LogicalAxis::Inline ? IEnd(aWM) : BEnd(aWM);
}
nscoord Size(LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == eLogicalAxisInline ? ISize(aWM) : BSize(aWM);
+ return aAxis == LogicalAxis::Inline ? ISize(aWM) : BSize(aWM);
}
/**
@@ -1680,10 +1690,10 @@ class LogicalRect {
return mBSize;
}
nscoord& Start(LogicalAxis aAxis, WritingMode aWM) {
- return aAxis == eLogicalAxisInline ? IStart(aWM) : BStart(aWM);
+ return aAxis == LogicalAxis::Inline ? IStart(aWM) : BStart(aWM);
}
nscoord& Size(LogicalAxis aAxis, WritingMode aWM) {
- return aAxis == eLogicalAxisInline ? ISize(aWM) : BSize(aWM);
+ return aAxis == LogicalAxis::Inline ? ISize(aWM) : BSize(aWM);
}
/**
@@ -2055,22 +2065,22 @@ const T& StyleRect<T>::Get(WritingMode aWM, LogicalSide aSide) const {
template <typename T>
const T& StyleRect<T>::GetIStart(WritingMode aWM) const {
- return Get(aWM, eLogicalSideIStart);
+ return Get(aWM, LogicalSide::IStart);
}
template <typename T>
const T& StyleRect<T>::GetBStart(WritingMode aWM) const {
- return Get(aWM, eLogicalSideBStart);
+ return Get(aWM, LogicalSide::BStart);
}
template <typename T>
const T& StyleRect<T>::GetIEnd(WritingMode aWM) const {
- return Get(aWM, eLogicalSideIEnd);
+ return Get(aWM, LogicalSide::IEnd);
}
template <typename T>
const T& StyleRect<T>::GetBEnd(WritingMode aWM) const {
- return Get(aWM, eLogicalSideBEnd);
+ return Get(aWM, LogicalSide::BEnd);
}
template <typename T>
@@ -2080,38 +2090,38 @@ T& StyleRect<T>::Get(WritingMode aWM, LogicalSide aSide) {
template <typename T>
T& StyleRect<T>::GetIStart(WritingMode aWM) {
- return Get(aWM, eLogicalSideIStart);
+ return Get(aWM, LogicalSide::IStart);
}
template <typename T>
T& StyleRect<T>::GetBStart(WritingMode aWM) {
- return Get(aWM, eLogicalSideBStart);
+ return Get(aWM, LogicalSide::BStart);
}
template <typename T>
T& StyleRect<T>::GetIEnd(WritingMode aWM) {
- return Get(aWM, eLogicalSideIEnd);
+ return Get(aWM, LogicalSide::IEnd);
}
template <typename T>
T& StyleRect<T>::GetBEnd(WritingMode aWM) {
- return Get(aWM, eLogicalSideBEnd);
+ return Get(aWM, LogicalSide::BEnd);
}
template <typename T>
const T& StyleRect<T>::Start(mozilla::LogicalAxis aAxis,
mozilla::WritingMode aWM) const {
- return Get(aWM, aAxis == mozilla::eLogicalAxisInline
- ? mozilla::eLogicalSideIStart
- : mozilla::eLogicalSideBStart);
+ return Get(aWM, aAxis == mozilla::LogicalAxis::Inline
+ ? mozilla::LogicalSide::IStart
+ : mozilla::LogicalSide::BStart);
}
template <typename T>
const T& StyleRect<T>::End(mozilla::LogicalAxis aAxis,
mozilla::WritingMode aWM) const {
- return Get(aWM, aAxis == mozilla::eLogicalAxisInline
- ? mozilla::eLogicalSideIEnd
- : mozilla::eLogicalSideBEnd);
+ return Get(aWM, aAxis == mozilla::LogicalAxis::Inline
+ ? mozilla::LogicalSide::IEnd
+ : mozilla::LogicalSide::BEnd);
}
inline AspectRatio AspectRatio::ConvertToWritingMode(
@@ -2147,15 +2157,15 @@ inline const mozilla::StyleMaxSize& nsStylePosition::MaxBSize(
}
inline const mozilla::StyleSize& nsStylePosition::Size(
mozilla::LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == mozilla::eLogicalAxisInline ? ISize(aWM) : BSize(aWM);
+ return aAxis == mozilla::LogicalAxis::Inline ? ISize(aWM) : BSize(aWM);
}
inline const mozilla::StyleSize& nsStylePosition::MinSize(
mozilla::LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == mozilla::eLogicalAxisInline ? MinISize(aWM) : MinBSize(aWM);
+ return aAxis == mozilla::LogicalAxis::Inline ? MinISize(aWM) : MinBSize(aWM);
}
inline const mozilla::StyleMaxSize& nsStylePosition::MaxSize(
mozilla::LogicalAxis aAxis, WritingMode aWM) const {
- return aAxis == mozilla::eLogicalAxisInline ? MaxISize(aWM) : MaxBSize(aWM);
+ return aAxis == mozilla::LogicalAxis::Inline ? MaxISize(aWM) : MaxBSize(aWM);
}
inline bool nsStylePosition::ISizeDependsOnContainer(WritingMode aWM) const {
@@ -2205,26 +2215,26 @@ inline bool nsStyleMargin::HasInlineAxisAuto(mozilla::WritingMode aWM) const {
}
inline bool nsStyleMargin::HasAuto(mozilla::LogicalAxis aAxis,
mozilla::WritingMode aWM) const {
- return aAxis == mozilla::eLogicalAxisInline ? HasInlineAxisAuto(aWM)
- : HasBlockAxisAuto(aWM);
+ return aAxis == mozilla::LogicalAxis::Inline ? HasInlineAxisAuto(aWM)
+ : HasBlockAxisAuto(aWM);
}
inline mozilla::StyleAlignFlags nsStylePosition::UsedSelfAlignment(
mozilla::LogicalAxis aAxis, const mozilla::ComputedStyle* aParent) const {
- return aAxis == mozilla::eLogicalAxisBlock ? UsedAlignSelf(aParent)._0
- : UsedJustifySelf(aParent)._0;
+ return aAxis == mozilla::LogicalAxis::Block ? UsedAlignSelf(aParent)._0
+ : UsedJustifySelf(aParent)._0;
}
inline mozilla::StyleContentDistribution nsStylePosition::UsedContentAlignment(
mozilla::LogicalAxis aAxis) const {
- return aAxis == mozilla::eLogicalAxisBlock ? mAlignContent : mJustifyContent;
+ return aAxis == mozilla::LogicalAxis::Block ? mAlignContent : mJustifyContent;
}
inline mozilla::StyleContentDistribution nsStylePosition::UsedTracksAlignment(
mozilla::LogicalAxis aAxis, uint32_t aIndex) const {
using T = mozilla::StyleAlignFlags;
const auto& tracksAlignment =
- aAxis == mozilla::eLogicalAxisBlock ? mAlignTracks : mJustifyTracks;
+ aAxis == mozilla::LogicalAxis::Block ? mAlignTracks : mJustifyTracks;
if (MOZ_LIKELY(tracksAlignment.IsEmpty())) {
// An empty array encodes the initial value, 'normal', which behaves as
// 'start' for Grid containers.
diff --git a/layout/generic/crashtests/1410243-1.html b/layout/generic/crashtests/1410243-1.html
new file mode 100644
index 0000000000..42a005e85b
--- /dev/null
+++ b/layout/generic/crashtests/1410243-1.html
@@ -0,0 +1,26 @@
+<!-- //DDBEGIN -->
+<style>
+* { margin-bottom: -1em; font-size: xx-large; }
+.cl1 { Max-height: 93; column-width: 0; position: fixed; }
+</style>
+<script>
+function eventhandler1() {
+try { htmlvar0002.style.setProperty("display", "grid"); } catch(e) { }
+try { svgvar0001.clientWidth; } catch(e) { }
+try { htmlvar0002.style.setProperty("grid-template", "0px/0px"); } catch(e) { }
+}
+</script>
+<details class="cl1" open="" ontoggle="eventhandler1()">
+<summary id="svgvar0001"/></summary>
+<a>
+<ol id="htmlvar0002">
+<keygen>
+>
+A
+AA
+A
+A
+A
+A
+<a>
+<!-- //DDEND -->
diff --git a/layout/generic/crashtests/1741488-1.html b/layout/generic/crashtests/1741488-1.html
new file mode 100644
index 0000000000..74d7c49feb
--- /dev/null
+++ b/layout/generic/crashtests/1741488-1.html
@@ -0,0 +1,23 @@
+<html class="reftest-wait">
+<style>
+#b {
+ writing-mode: vertical-rl;
+ content: url(data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=);
+}
+</style>
+<script>
+let pp;
+document.addEventListener("MozReftestInvalidate", () => {
+ a.after("1")
+ a.insertAdjacentHTML("afterEnd", b.outerHTML);
+ pp = SpecialPowers.wrap(self).printPreview();
+ setTimeout(function() {
+ pp.close();
+ document.documentElement.className = "";
+ }, 400);
+})
+</script>
+<math>
+<munder>
+<mn id="a">2</mn>
+<dl id="b"></dl>
diff --git a/layout/generic/crashtests/1881375-1-helper.html b/layout/generic/crashtests/1881375-1-helper.html
new file mode 100644
index 0000000000..5c79e4981f
--- /dev/null
+++ b/layout/generic/crashtests/1881375-1-helper.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<script>
+// Notify our parent and reload ourselves.
+function notifyAndReload() {
+ if (window.parent) {
+ window.parent.postMessage("reloaded", "*");
+ }
+ window.location.reload(true)
+}
+</script>
+<style>
+*:nth-child(even) {
+ height: 16em;
+ list-style-image: url(data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=);
+}
+#a {
+ display: inline-grid;
+ grid-auto-flow: column dense;
+}
+#b {
+ padding-top: 8192vmax;
+}
+* {
+ align-content: center;
+ column-width: 1em;
+ float: inline-end;
+}
+</style>
+<body onload="setTimeout(notifyAndReload, 0)">
+<picture></picture>
+<iframe></iframe>
+<isindex>
+<svg></svg>
+<samp id="a">
+<q>
+<a id="b">
+</q>
+<li>
diff --git a/layout/generic/crashtests/1881375-1.html b/layout/generic/crashtests/1881375-1.html
new file mode 100644
index 0000000000..8cef260433
--- /dev/null
+++ b/layout/generic/crashtests/1881375-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<script>
+// Loop count for the handler below. This value seems to be enough for the
+// crashtest to be likely to trigger the crash.
+const MAX_LOADS = 3;
+let loadCount = 0;
+
+// Handler which gets invoked by the iframe whenever it completes a load
+// (and dynamically reloads itself). This lets us allow the testcase to
+// reload over and over (as seems to be required to trigger the crash),
+// while also keeping the test duration reasonably bounded.
+window.addEventListener(
+ "message",
+ (event) => {
+ if (loadCount++ == MAX_LOADS) {
+ // After MAX_LOADS reloads of the iframe, call ourselves done.
+ myIframe.remove();
+ document.documentElement.className = "";
+ }
+ }
+);
+
+</script>
+<iframe id="myIframe" src="1881375-1-helper.html"></iframe>
diff --git a/layout/generic/crashtests/481921.ogg b/layout/generic/crashtests/481921.ogg
deleted file mode 100644
index 0c41c3cd6b..0000000000
--- a/layout/generic/crashtests/481921.ogg
+++ /dev/null
Binary files differ
diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list
index 1c184739d7..2aea090a6f 100644
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -678,6 +678,7 @@ load 1405443.html
load 1405813.html
load 1405896.html
load 1406252-1.html
+asserts(2) load 1410243-1.html # assertion is bug 574889
load 1415185.html
load 1416544.html
load 1427824.html
@@ -804,6 +805,7 @@ load 1728319.html
asserts(2-8) load 1730506.html # asserts from integer overflow & bogus sizes
asserts(1-4) load 1730570.html # asserts from integer overflow & bogus sizes
load 1734015.html
+skip-if(Android) load 1741488-1.html # printPreview doesn't work on android
load 1776079.html
asserts(0-2) load 1791606.html
load 1799749.html
@@ -812,3 +814,4 @@ load 1816574.html
load 1821603.html
load 1822118.html
load 1825434.html
+asserts(0-85) load 1881375-1.html # bug 1890687 - assertions about fragmentation invariants, failing many times because the test runs in a loop
diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp
index 3cfe7b5b2d..4f561688bf 100644
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -522,7 +522,7 @@ static nscoord OffsetToAlignedStaticPos(const ReflowInput& aKidReflowInput,
return 0; // (leave the child at the start of its alignment container)
}
- nscoord alignAreaSizeInAxis = (pcAxis == eLogicalAxisInline)
+ nscoord alignAreaSizeInAxis = (pcAxis == LogicalAxis::Inline)
? alignAreaSize.ISize(pcWM)
: alignAreaSize.BSize(pcWM);
@@ -619,7 +619,7 @@ void nsAbsoluteContainingBlock::ResolveSizeDependentOffsets(
placeholderContainer = GetPlaceholderContainer(aKidReflowInput.mFrame);
nscoord offset = OffsetToAlignedStaticPos(
aKidReflowInput, aKidSize, logicalCBSizeOuterWM, placeholderContainer,
- outerWM, eLogicalAxisInline);
+ outerWM, LogicalAxis::Inline);
// Shift IStart from its current position (at start corner of the
// alignment container) by the returned offset. And set IEnd to the
// distance between the kid's end edge to containing block's end edge.
@@ -639,7 +639,7 @@ void nsAbsoluteContainingBlock::ResolveSizeDependentOffsets(
}
nscoord offset = OffsetToAlignedStaticPos(
aKidReflowInput, aKidSize, logicalCBSizeOuterWM, placeholderContainer,
- outerWM, eLogicalAxisBlock);
+ outerWM, LogicalAxis::Block);
// Shift BStart from its current position (at start corner of the
// alignment container) by the returned offset. And set BEnd to the
// distance between the kid's end edge to containing block's end edge.
diff --git a/layout/generic/nsBackdropFrame.cpp b/layout/generic/nsBackdropFrame.cpp
index 20d3fcd368..178caa3e0c 100644
--- a/layout/generic/nsBackdropFrame.cpp
+++ b/layout/generic/nsBackdropFrame.cpp
@@ -70,7 +70,6 @@ void nsBackdropFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsBackdropFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
// Note that this frame is a child of the viewport frame.
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index a25e4e996e..4582c29e0b 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -813,8 +813,6 @@ nscoord nsBlockFrame::GetMinISize(gfxContext* aRenderingContext) {
return firstInFlow->GetMinISize(aRenderingContext);
}
- DISPLAY_MIN_INLINE_SIZE(this, mCachedMinISize);
-
CheckIntrinsicCacheAgainstShrinkWrapState();
if (mCachedMinISize != NS_INTRINSIC_ISIZE_UNKNOWN) {
@@ -902,8 +900,6 @@ nscoord nsBlockFrame::GetPrefISize(gfxContext* aRenderingContext) {
return firstInFlow->GetPrefISize(aRenderingContext);
}
- DISPLAY_PREF_INLINE_SIZE(this, mCachedPrefISize);
-
CheckIntrinsicCacheAgainstShrinkWrapState();
if (mCachedPrefISize != NS_INTRINSIC_ISIZE_UNKNOWN) {
@@ -1348,7 +1344,6 @@ void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsBlockFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
#ifdef DEBUG
@@ -1453,14 +1448,18 @@ void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
// maintain when doing text-wrap: balance.
struct BalanceTarget {
// If line-clamp is in effect, mContent and mOffset indicate the starting
- // position of the first line after the clamp limit. If line-clamp is not
- // in use, mContent is null and mOffset is the total number of lines that
- // the block must contain.
+ // position of the first line after the clamp limit, and mBlockCoord is the
+ // block-axis offset of its position.
+ // If line-clamp is not in use, mContent is null, mOffset is the total
+ // number of lines that the block must contain, and mBlockCoord is its end
+ // edge in the block direction.
nsIContent* mContent = nullptr;
int32_t mOffset = -1;
+ nscoord mBlockCoord = 0;
bool operator==(const BalanceTarget& aOther) const {
- return mContent == aOther.mContent && mOffset == aOther.mOffset;
+ return mContent == aOther.mContent && mOffset == aOther.mOffset &&
+ mBlockCoord == aOther.mBlockCoord;
}
bool operator!=(const BalanceTarget& aOther) const {
return !(*this == aOther);
@@ -1506,7 +1505,7 @@ void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
auto* textFrame = static_cast<nsTextFrame*>(firstChild);
offset = textFrame->GetContentOffset();
}
- return BalanceTarget{content, offset};
+ return BalanceTarget{content, offset, iter.get()->BStart()};
};
// "balancing" is implemented by shortening the effective inline-size of the
@@ -1545,6 +1544,7 @@ void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
// no balancing is needed; just break from the balance loop.
break;
}
+ balanceTarget.mBlockCoord = mLines.back()->BEnd();
// Initialize the amount of inset to try, and the iteration step size.
balanceStep = aReflowInput.ComputedISize() / balanceTarget.mOffset;
trialState.ResetForBalance(balanceStep);
@@ -1581,7 +1581,8 @@ void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
}
int32_t numLines =
countLinesUpTo(StaticPrefs::layout_css_text_wrap_balance_limit());
- return numLines == balanceTarget.mOffset;
+ return numLines == balanceTarget.mOffset &&
+ mLines.back()->BEnd() == balanceTarget.mBlockCoord;
};
// If we're in the process of a balance operation, check whether we've
@@ -2817,7 +2818,7 @@ void nsBlockFrame::PropagateFloatDamage(BlockReflowState& aState,
static bool LineHasClear(nsLineBox* aLine) {
return aLine->IsBlock()
- ? (aLine->HasForcedLineBreakBefore() ||
+ ? (aLine->HasFloatClearTypeBefore() ||
aLine->mFirstChild->HasAnyStateBits(
NS_BLOCK_HAS_CLEAR_CHILDREN) ||
!nsBlockFrame::BlockCanIntersectFloats(aLine->mFirstChild))
@@ -2984,7 +2985,7 @@ bool nsBlockFrame::ReflowDirtyLines(BlockReflowState& aState) {
// We have to reflow the line if it's a block whose clearance
// might have changed, so detect that.
if (!line->IsDirty() &&
- (line->HasForcedLineBreakBefore() || floatAvoidingBlock)) {
+ (line->HasFloatClearTypeBefore() || floatAvoidingBlock)) {
nscoord curBCoord = aState.mBCoord;
// See where we would be after applying any clearance due to
// BRs.
@@ -3934,9 +3935,9 @@ bool nsBlockFrame::IsSelfEmpty() {
const nsStyleBorder* border = StyleBorder();
const nsStylePadding* padding = StylePadding();
- if (border->GetComputedBorderWidth(wm.PhysicalSide(eLogicalSideBStart)) !=
+ if (border->GetComputedBorderWidth(wm.PhysicalSide(LogicalSide::BStart)) !=
0 ||
- border->GetComputedBorderWidth(wm.PhysicalSide(eLogicalSideBEnd)) != 0 ||
+ border->GetComputedBorderWidth(wm.PhysicalSide(LogicalSide::BEnd)) != 0 ||
!nsLayoutUtils::IsPaddingZero(padding->mPadding.GetBStart(wm)) ||
!nsLayoutUtils::IsPaddingZero(padding->mPadding.GetBEnd(wm))) {
return false;
@@ -4051,7 +4052,7 @@ void nsBlockFrame::ReflowBlockFrame(BlockReflowState& aState,
// Clear past floats before the block if the clear style is not none
aLine->ClearForcedLineBreak();
if (clearType != StyleClear::None) {
- aLine->SetForcedLineBreakBefore(clearType);
+ aLine->SetFloatClearTypeBefore(clearType);
}
// See if we should apply the block-start margin. If the block frame being
diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp
index 64c56b1c00..b4b108905f 100644
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -606,24 +606,16 @@ void nsCanvasFrame::PaintFocus(DrawTarget* aDrawTarget, nsPoint aPt) {
/* virtual */
nscoord nsCanvasFrame::GetMinISize(gfxContext* aRenderingContext) {
- nscoord result;
- DISPLAY_MIN_INLINE_SIZE(this, result);
- if (mFrames.IsEmpty())
- result = 0;
- else
- result = mFrames.FirstChild()->GetMinISize(aRenderingContext);
- return result;
+ return mFrames.IsEmpty()
+ ? 0
+ : mFrames.FirstChild()->GetMinISize(aRenderingContext);
}
/* virtual */
nscoord nsCanvasFrame::GetPrefISize(gfxContext* aRenderingContext) {
- nscoord result;
- DISPLAY_PREF_INLINE_SIZE(this, result);
- if (mFrames.IsEmpty())
- result = 0;
- else
- result = mFrames.FirstChild()->GetPrefISize(aRenderingContext);
- return result;
+ return mFrames.IsEmpty()
+ ? 0
+ : mFrames.FirstChild()->GetPrefISize(aRenderingContext);
}
void nsCanvasFrame::Reflow(nsPresContext* aPresContext,
@@ -632,7 +624,6 @@ void nsCanvasFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsCanvasFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
NS_FRAME_TRACE_REFLOW_IN("nsCanvasFrame::Reflow");
diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp
index cd97519a98..a9d3e28138 100644
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -408,7 +408,6 @@ static void MoveChildTo(nsIFrame* aChild, LogicalPoint aOrigin, WritingMode aWM,
nscoord nsColumnSetFrame::GetMinISize(gfxContext* aRenderingContext) {
nscoord iSize = 0;
- DISPLAY_MIN_INLINE_SIZE(this, iSize);
if (mFrames.FirstChild()) {
// We want to ignore this in the case that we're size contained
@@ -443,8 +442,6 @@ nscoord nsColumnSetFrame::GetPrefISize(gfxContext* aRenderingContext) {
// the child's preferred width, times the number of columns, plus the width
// of any required column gaps
// XXX what about forced column breaks here?
- nscoord result = 0;
- DISPLAY_PREF_INLINE_SIZE(this, result);
const nsStyleColumn* colStyle = StyleColumn();
nscoord colISize;
@@ -466,8 +463,7 @@ nscoord nsColumnSetFrame::GetPrefISize(gfxContext* aRenderingContext) {
? 1
: colStyle->mColumnCount;
nscoord colGap = ColumnUtils::GetColumnGap(this, NS_UNCONSTRAINEDSIZE);
- result = ColumnUtils::IntrinsicISize(numColumns, colGap, colISize);
- return result;
+ return ColumnUtils::IntrinsicISize(numColumns, colGap, colISize);
}
nsColumnSetFrame::ColumnBalanceData nsColumnSetFrame::ReflowColumns(
@@ -1202,7 +1198,6 @@ void nsColumnSetFrame::Reflow(nsPresContext* aPresContext,
nsPresContext::InterruptPreventer noInterrupts(aPresContext);
DO_GLOBAL_REFLOW_COUNT("nsColumnSetFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
MOZ_ASSERT(aReflowInput.mCBReflowInput->mFrame->StyleColumn()
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
index 2577a7a00d..2c9e707830 100644
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -814,8 +814,7 @@ LogicalSize nsContainerFrame::ComputeAutoSize(
LogicalSize result(aWM, 0xdeadbeef, NS_UNCONSTRAINEDSIZE);
nscoord availBased =
aAvailableISize - aMargin.ISize(aWM) - aBorderPadding.ISize(aWM);
- // replaced elements always shrink-wrap
- if (aFlags.contains(ComputeSizeFlag::ShrinkWrap) || IsReplaced()) {
+ if (aFlags.contains(ComputeSizeFlag::ShrinkWrap)) {
// Only bother computing our 'auto' ISize if the result will be used.
const auto& styleISize = aSizeOverrides.mStyleISize
? *aSizeOverrides.mStyleISize
@@ -2201,9 +2200,9 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
// This variable only gets meaningfully set if isFlexItem is true. It
// indicates which axis (in this frame's own WM) corresponds to its
// flex container's main axis.
- LogicalAxis flexMainAxis = eLogicalAxisBlock;
+ LogicalAxis flexMainAxis = LogicalAxis::Block;
if (isFlexItem && nsFlexContainerFrame::IsItemInlineAxisMainAxis(this)) {
- flexMainAxis = eLogicalAxisInline;
+ flexMainAxis = LogicalAxis::Inline;
}
// Handle intrinsic sizes and their interaction with
@@ -2263,8 +2262,8 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
aSizeOverrides, aFlags)
.mISize;
} else if (MOZ_UNLIKELY(isGridItem) &&
- !parentFrame->IsMasonry(isOrthogonal ? eLogicalAxisBlock
- : eLogicalAxisInline)) {
+ !parentFrame->IsMasonry(isOrthogonal ? LogicalAxis::Block
+ : LogicalAxis::Inline)) {
MOZ_ASSERT(!IsTrueOverflowContainer());
// 'auto' inline-size for grid-level box - apply 'stretch' as needed:
auto cbSize = aCBSize.ISize(aWM);
@@ -2291,7 +2290,7 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
const auto& maxISizeCoord = stylePos->MaxISize(aWM);
if (!maxISizeCoord.IsNone() &&
- !(isFlexItem && flexMainAxis == eLogicalAxisInline)) {
+ !(isFlexItem && flexMainAxis == LogicalAxis::Inline)) {
maxISize = ComputeISizeValue(aRenderingContext, aWM, aCBSize,
boxSizingAdjust, boxSizingToMarginEdgeISize,
maxISizeCoord, aSizeOverrides, aFlags)
@@ -2307,7 +2306,7 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
const auto& minISizeCoord = stylePos->MinISize(aWM);
if (!minISizeCoord.IsAuto() &&
- !(isFlexItem && flexMainAxis == eLogicalAxisInline)) {
+ !(isFlexItem && flexMainAxis == LogicalAxis::Inline)) {
minISize = ComputeISizeValue(aRenderingContext, aWM, aCBSize,
boxSizingAdjust, boxSizingToMarginEdgeISize,
minISizeCoord, aSizeOverrides, aFlags)
@@ -2326,8 +2325,8 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
boxSizingAdjust.BSize(aWM),
styleBSize.AsLengthPercentage());
} else if (MOZ_UNLIKELY(isGridItem) &&
- !parentFrame->IsMasonry(isOrthogonal ? eLogicalAxisInline
- : eLogicalAxisBlock)) {
+ !parentFrame->IsMasonry(isOrthogonal ? LogicalAxis::Inline
+ : LogicalAxis::Block)) {
MOZ_ASSERT(!IsTrueOverflowContainer());
// 'auto' block-size for grid-level box - apply 'stretch' as needed:
auto cbSize = aCBSize.BSize(aWM);
@@ -2354,7 +2353,7 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
const auto& maxBSizeCoord = stylePos->MaxBSize(aWM);
if (!nsLayoutUtils::IsAutoBSize(maxBSizeCoord, aCBSize.BSize(aWM)) &&
- !(isFlexItem && flexMainAxis == eLogicalAxisBlock)) {
+ !(isFlexItem && flexMainAxis == LogicalAxis::Block)) {
maxBSize = nsLayoutUtils::ComputeBSizeValue(
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
maxBSizeCoord.AsLengthPercentage());
@@ -2365,7 +2364,7 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
const auto& minBSizeCoord = stylePos->MinBSize(aWM);
if (!nsLayoutUtils::IsAutoBSize(minBSizeCoord, aCBSize.BSize(aWM)) &&
- !(isFlexItem && flexMainAxis == eLogicalAxisBlock)) {
+ !(isFlexItem && flexMainAxis == LogicalAxis::Block)) {
minBSize = nsLayoutUtils::ComputeBSizeValue(
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
minBSizeCoord.AsLengthPercentage());
@@ -2389,8 +2388,7 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
tentISize = intrinsicISize;
} else if (hasIntrinsicBSize && aspectRatio) {
tentISize = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, intrinsicBSize,
- boxSizingAdjust);
+ LogicalAxis::Inline, aWM, intrinsicBSize, boxSizingAdjust);
} else if (aspectRatio) {
tentISize =
aCBSize.ISize(aWM) - boxSizingToMarginEdgeISize; // XXX scrollbar?
@@ -2413,7 +2411,7 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
tentBSize = intrinsicBSize;
} else if (aspectRatio) {
tentBSize = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisBlock, aWM, tentISize, boxSizingAdjust);
+ LogicalAxis::Block, aWM, tentISize, boxSizingAdjust);
} else {
tentBSize = fallbackIntrinsicSize.BSize(aWM);
}
@@ -2431,29 +2429,29 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
} else if (stretchB == eStretchPreservingRatio && aspectRatio) {
// 'normal' / 'stretch'
tentBSize = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisBlock, aWM, iSize, boxSizingAdjust);
+ LogicalAxis::Block, aWM, iSize, boxSizingAdjust);
}
} else if (stretchB == eStretch) {
tentBSize = bSize; // 'stretch' / * (except 'stretch')
if (stretchI == eStretchPreservingRatio && aspectRatio) {
// 'stretch' / 'normal'
tentISize = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
+ LogicalAxis::Inline, aWM, bSize, boxSizingAdjust);
}
} else if (stretchI == eStretchPreservingRatio && aspectRatio) {
tentISize = iSize; // * (except 'stretch') / 'normal'
tentBSize = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisBlock, aWM, iSize, boxSizingAdjust);
+ LogicalAxis::Block, aWM, iSize, boxSizingAdjust);
if (stretchB == eStretchPreservingRatio && tentBSize > bSize) {
// Stretch within the CB size with preserved intrinsic ratio.
tentBSize = bSize; // 'normal' / 'normal'
tentISize = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
+ LogicalAxis::Inline, aWM, bSize, boxSizingAdjust);
}
} else if (stretchB == eStretchPreservingRatio && aspectRatio) {
tentBSize = bSize; // 'normal' / * (except 'normal' and 'stretch')
tentISize = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
+ LogicalAxis::Inline, aWM, bSize, boxSizingAdjust);
}
// ComputeAutoSizeWithIntrinsicDimensions preserves the ratio when
@@ -2480,7 +2478,7 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
if (stretchI != eStretch) {
if (aspectRatio) {
iSize = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
+ LogicalAxis::Inline, aWM, bSize, boxSizingAdjust);
} else if (hasIntrinsicISize) {
if (!(aFlags.contains(ComputeSizeFlag::IClampMarginBoxMinSize) &&
intrinsicISize > iSize)) {
@@ -2498,8 +2496,8 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
iSize = NS_CSS_MINMAX(iSize, minISize, maxISize);
if (stretchB != eStretch) {
if (aspectRatio) {
- bSize = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisBlock, aWM, iSize, boxSizingAdjust);
+ bSize = aspectRatio.ComputeRatioDependentSize(LogicalAxis::Block, aWM,
+ iSize, boxSizingAdjust);
} else if (hasIntrinsicBSize) {
if (!(aFlags.contains(ComputeSizeFlag::BClampMarginBoxMinSize) &&
intrinsicBSize > bSize)) {
diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h
index 09f6cf76f5..cb0a09db20 100644
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -1076,126 +1076,4 @@ class nsOverflowContinuationTracker {
bool mWalkOOFFrames;
};
-// Start Display Reflow Debugging
-#ifdef DEBUG
-
-struct DR_cookie {
- DR_cookie(nsPresContext* aPresContext, nsIFrame* aFrame,
- const mozilla::ReflowInput& aReflowInput,
- mozilla::ReflowOutput& aMetrics, nsReflowStatus& aStatus);
- ~DR_cookie();
- void Change() const;
-
- nsPresContext* mPresContext;
- nsIFrame* mFrame;
- const mozilla::ReflowInput& mReflowInput;
- mozilla::ReflowOutput& mMetrics;
- nsReflowStatus& mStatus;
- void* mValue;
-};
-
-struct DR_layout_cookie {
- explicit DR_layout_cookie(nsIFrame* aFrame);
- ~DR_layout_cookie();
-
- nsIFrame* mFrame;
- void* mValue;
-};
-
-struct DR_intrinsic_inline_size_cookie {
- DR_intrinsic_inline_size_cookie(nsIFrame* aFrame, const char* aType,
- nscoord& aResult);
- ~DR_intrinsic_inline_size_cookie();
-
- nsIFrame* mFrame;
- const char* mType;
- nscoord& mResult;
- void* mValue;
-};
-
-struct DR_intrinsic_size_cookie {
- DR_intrinsic_size_cookie(nsIFrame* aFrame, const char* aType,
- nsSize& aResult);
- ~DR_intrinsic_size_cookie();
-
- nsIFrame* mFrame;
- const char* mType;
- nsSize& mResult;
- void* mValue;
-};
-
-struct DR_init_constraints_cookie {
- DR_init_constraints_cookie(
- nsIFrame* aFrame, mozilla::ReflowInput* aState, nscoord aCBWidth,
- nscoord aCBHeight, const mozilla::Maybe<mozilla::LogicalMargin> aBorder,
- const mozilla::Maybe<mozilla::LogicalMargin> aPadding);
- ~DR_init_constraints_cookie();
-
- nsIFrame* mFrame;
- mozilla::ReflowInput* mState;
- void* mValue;
-};
-
-struct DR_init_offsets_cookie {
- DR_init_offsets_cookie(nsIFrame* aFrame,
- mozilla::SizeComputationInput* aState,
- nscoord aPercentBasis,
- mozilla::WritingMode aCBWritingMode,
- const mozilla::Maybe<mozilla::LogicalMargin> aBorder,
- const mozilla::Maybe<mozilla::LogicalMargin> aPadding);
- ~DR_init_offsets_cookie();
-
- nsIFrame* mFrame;
- mozilla::SizeComputationInput* mState;
- void* mValue;
-};
-
-# define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, \
- dr_rf_metrics, dr_rf_status) \
- DR_cookie dr_cookie(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, \
- dr_rf_status);
-# define DISPLAY_REFLOW_CHANGE() dr_cookie.Change();
-# define DISPLAY_LAYOUT(dr_frame) DR_layout_cookie dr_cookie(dr_frame);
-# define DISPLAY_MIN_INLINE_SIZE(dr_frame, dr_result) \
- DR_intrinsic_inline_size_cookie dr_cookie(dr_frame, "Min", dr_result)
-# define DISPLAY_PREF_INLINE_SIZE(dr_frame, dr_result) \
- DR_intrinsic_inline_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
-# define DISPLAY_PREF_SIZE(dr_frame, dr_result) \
- DR_intrinsic_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
-# define DISPLAY_MIN_SIZE(dr_frame, dr_result) \
- DR_intrinsic_size_cookie dr_cookie(dr_frame, "Min", dr_result)
-# define DISPLAY_MAX_SIZE(dr_frame, dr_result) \
- DR_intrinsic_size_cookie dr_cookie(dr_frame, "Max", dr_result)
-# define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, dr_bdr, \
- dr_pad) \
- DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
- dr_bdr, dr_pad)
-# define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr, \
- dr_pad) \
- DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_pb, dr_cbwm, \
- dr_bdr, dr_pad)
-
-#else
-
-# define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, \
- dr_rf_metrics, dr_rf_status)
-# define DISPLAY_REFLOW_CHANGE()
-# define DISPLAY_LAYOUT(dr_frame) PR_BEGIN_MACRO PR_END_MACRO
-# define DISPLAY_MIN_INLINE_SIZE(dr_frame, dr_result) \
- PR_BEGIN_MACRO PR_END_MACRO
-# define DISPLAY_PREF_INLINE_SIZE(dr_frame, dr_result) \
- PR_BEGIN_MACRO PR_END_MACRO
-# define DISPLAY_PREF_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
-# define DISPLAY_MIN_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
-# define DISPLAY_MAX_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
-# define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, dr_bdr, \
- dr_pad) \
- PR_BEGIN_MACRO PR_END_MACRO
-# define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr, \
- dr_pad) \
- PR_BEGIN_MACRO PR_END_MACRO
-
-#endif
-// End Display Reflow Debugging
-
#endif /* nsContainerFrame_h___ */
diff --git a/layout/generic/nsFirstLetterFrame.cpp b/layout/generic/nsFirstLetterFrame.cpp
index fe294652c7..28d1b08a30 100644
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -197,7 +197,6 @@ void nsFirstLetterFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aReflowStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsFirstLetterFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aReflowStatus);
MOZ_ASSERT(aReflowStatus.IsEmpty(),
"Caller should pass a fresh reflow status!");
diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp
index e5a719fee2..66f1e79609 100644
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -14,14 +14,12 @@
#include "mozilla/Baseline.h"
#include "mozilla/ComputedStyle.h"
#include "mozilla/CSSOrderAwareFrameIterator.h"
-#include "mozilla/FloatingPoint.h"
#include "mozilla/Logging.h"
#include "mozilla/PresShell.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/WritingModes.h"
#include "nsBlockFrame.h"
#include "nsContentUtils.h"
-#include "nsCSSAnonBoxes.h"
#include "nsDebug.h"
#include "nsDisplayList.h"
#include "nsFieldSetFrame.h"
@@ -43,10 +41,25 @@ using CachedBAxisMeasurement = nsFlexContainerFrame::CachedBAxisMeasurement;
using CachedFlexItemData = nsFlexContainerFrame::CachedFlexItemData;
static mozilla::LazyLogModule gFlexContainerLog("FlexContainer");
-#define FLEX_LOG(...) \
- MOZ_LOG(gFlexContainerLog, LogLevel::Debug, (__VA_ARGS__));
-#define FLEX_LOGV(...) \
- MOZ_LOG(gFlexContainerLog, LogLevel::Verbose, (__VA_ARGS__));
+
+// FLEX_LOG is a top-level general log print.
+#define FLEX_LOG(message, ...) \
+ MOZ_LOG(gFlexContainerLog, LogLevel::Debug, (message, ##__VA_ARGS__));
+
+// FLEX_ITEM_LOG is a top-level log print for flex item.
+#define FLEX_ITEM_LOG(item_frame, message, ...) \
+ MOZ_LOG(gFlexContainerLog, LogLevel::Debug, \
+ ("Flex item %p: " message, item_frame, ##__VA_ARGS__));
+
+// FLEX_LOGV is a verbose log print with built-in two spaces indentation. The
+// convention to use FLEX_LOGV is that FLEX_LOGV statements should generally be
+// preceded by one FLEX_LOG or FLEX_ITEM_LOG so that there's no need to repeat
+// information presented in the preceding LOG statement. If you want extra level
+// of indentation, just add two extra spaces at the start of the message string.
+#define FLEX_LOGV(message, ...) \
+ MOZ_LOG(gFlexContainerLog, LogLevel::Verbose, (" " message, ##__VA_ARGS__));
+
+static const char* BoolToYesNo(bool aArg) { return aArg ? "yes" : "no"; }
// Returns true if aFlexContainer is a frame for some element that has
// display:-webkit-{inline-}box (or -moz-{inline-}box). aFlexContainer is
@@ -143,10 +156,10 @@ class MOZ_STACK_CLASS nsFlexContainerFrame::FlexboxAxisTracker {
// Accessors:
LogicalAxis MainAxis() const {
- return IsRowOriented() ? eLogicalAxisInline : eLogicalAxisBlock;
+ return IsRowOriented() ? LogicalAxis::Inline : LogicalAxis::Block;
}
LogicalAxis CrossAxis() const {
- return IsRowOriented() ? eLogicalAxisBlock : eLogicalAxisInline;
+ return IsRowOriented() ? LogicalAxis::Block : LogicalAxis::Inline;
}
LogicalSide MainAxisStartSide() const;
@@ -308,7 +321,7 @@ class MOZ_STACK_CLASS nsFlexContainerFrame::FlexboxAxisTracker {
: StyleAlignFlags::END;
}
- MOZ_ASSERT(MainAxis() == eLogicalAxisInline,
+ MOZ_ASSERT(MainAxis() == LogicalAxis::Inline,
"Row-oriented flex container's main axis should be parallel to "
"line-left <-> line-right axis!");
@@ -682,9 +695,8 @@ class nsFlexContainerFrame::FlexItem final {
// to the [min,max] range:
mMainSize = NS_CSS_MINMAX(mFlexBaseSize, mMainMinSize, mMainMaxSize);
- FLEX_LOGV(
- "Set flex base size: %d, hypothetical main size: %d for flex item %p",
- mFlexBaseSize, mMainSize, mFrame);
+ FLEX_ITEM_LOG(mFrame, "Set flex base size: %d, hypothetical main size: %d",
+ mFlexBaseSize, mMainSize);
}
// Setters used while we're resolving flexible lengths
@@ -1305,7 +1317,7 @@ StyleAlignFlags nsFlexContainerFrame::CSSAlignmentForAbsPosChild(
// block axis), then the caller is really asking about our *main* axis.
// Otherwise, the caller is asking about our cross axis.
const bool isMainAxis =
- (axisTracker.IsRowOriented() == (aLogicalAxis == eLogicalAxisInline));
+ (axisTracker.IsRowOriented() == (aLogicalAxis == LogicalAxis::Inline));
const nsStylePosition* containerStylePos = StylePosition();
const bool isAxisReversed = isMainAxis ? axisTracker.IsMainAxisReversed()
: axisTracker.IsCrossAxisReversed();
@@ -1592,7 +1604,7 @@ static nscoord PartiallyResolveAutoMinSize(
if (specifiedSizeSuggestion != nscoord_MAX) {
// We have the specified size suggestion. Return it now since we don't need
// to consider transferred size suggestion.
- FLEX_LOGV(" Specified size suggestion: %d", specifiedSizeSuggestion);
+ FLEX_LOGV("Specified size suggestion: %d", specifiedSizeSuggestion);
return specifiedSizeSuggestion;
}
@@ -1611,7 +1623,7 @@ static nscoord PartiallyResolveAutoMinSize(
transferredSizeSuggestion = aFlexItem.ClampMainSizeViaCrossAxisConstraints(
transferredSizeSuggestion, aItemReflowInput);
- FLEX_LOGV(" Transferred size suggestion: %d", transferredSizeSuggestion);
+ FLEX_LOGV("Transferred size suggestion: %d", transferredSizeSuggestion);
return transferredSizeSuggestion;
}
@@ -1638,8 +1650,10 @@ void nsFlexContainerFrame::ResolveAutoFlexBasisAndMinSize(
return;
}
- FLEX_LOGV("Resolving auto main size or auto min main size for flex item %p",
- aFlexItem.Frame());
+ FLEX_ITEM_LOG(
+ aFlexItem.Frame(),
+ "Resolving auto main size? %s; resolving auto min main size? %s",
+ BoolToYesNo(isMainSizeAuto), BoolToYesNo(isMainMinSizeAuto));
nscoord resolvedMinSize; // (only set/used if isMainMinSizeAuto==true)
bool minSizeNeedsToMeasureContent = false; // assume the best
@@ -1725,7 +1739,7 @@ void nsFlexContainerFrame::ResolveAutoFlexBasisAndMinSize(
contentSizeSuggestion, aItemReflowInput);
}
- FLEX_LOGV(" Content size suggestion: %d", contentSizeSuggestion);
+ FLEX_LOGV("Content size suggestion: %d", contentSizeSuggestion);
resolvedMinSize = std::min(resolvedMinSize, contentSizeSuggestion);
// Clamp the resolved min main size by the max main size if it's definite.
@@ -1739,7 +1753,7 @@ void nsFlexContainerFrame::ResolveAutoFlexBasisAndMinSize(
// nscoord_MAX sentinel value if we reach this point).
resolvedMinSize = nscoord_MAX;
}
- FLEX_LOGV(" Resolved auto min main size: %d", resolvedMinSize);
+ FLEX_LOGV("Resolved auto min main size: %d", resolvedMinSize);
if (resolvedMinSize == contentSizeSuggestion) {
// When we are here, we've measured the item's content-based size, and
@@ -1992,12 +2006,16 @@ const CachedBAxisMeasurement& nsFlexContainerFrame::MeasureBSizeForFlexItem(
if (cachedData && cachedData->mBAxisMeasurement) {
if (!aItem.Frame()->IsSubtreeDirty() &&
cachedData->mBAxisMeasurement->IsValidFor(aChildReflowInput)) {
- FLEX_LOG("[perf] MeasureBSizeForFlexItem accepted cached value");
+ FLEX_ITEM_LOG(aItem.Frame(),
+ "[perf] Accepted cached measurement: block-size %d",
+ cachedData->mBAxisMeasurement->BSize());
return *(cachedData->mBAxisMeasurement);
}
- FLEX_LOG("[perf] MeasureBSizeForFlexItem rejected cached value");
+ FLEX_ITEM_LOG(aItem.Frame(),
+ "[perf] Rejected cached measurement: block-size %d",
+ cachedData->mBAxisMeasurement->BSize());
} else {
- FLEX_LOG("[perf] MeasureBSizeForFlexItem didn't have a cached value");
+ FLEX_ITEM_LOG(aItem.Frame(), "[perf] No cached measurement");
}
// CachedFlexItemData is stored in item's writing mode, so we pass
@@ -2055,7 +2073,7 @@ void nsFlexContainerFrame::MarkIntrinsicISizesDirty() {
nscoord nsFlexContainerFrame::MeasureFlexItemContentBSize(
FlexItem& aFlexItem, bool aForceBResizeForMeasuringReflow,
const ReflowInput& aParentReflowInput) {
- FLEX_LOG("Measuring flex item's content block-size");
+ FLEX_ITEM_LOG(aFlexItem.Frame(), "Measuring item's content block-size");
// Set up a reflow input for measuring the flex item's content block-size:
WritingMode wm = aFlexItem.Frame()->GetWritingMode();
@@ -2070,7 +2088,7 @@ nscoord nsFlexContainerFrame::MeasureFlexItemContentBSize(
// block-size, because that would prevent us from measuring the content
// block-size.
sizeOverrides.mAspectRatio.emplace(AspectRatio());
- FLEX_LOGV(" Cross size override: %d", aFlexItem.CrossSize());
+ FLEX_LOGV("Cross size override: %d", aFlexItem.CrossSize());
}
sizeOverrides.mStyleBSize.emplace(StyleSize::Auto());
@@ -2234,7 +2252,7 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput, float aFlexGrow,
// getting the physical side that corresponds to these axes' "logical
// start" sides, and we compare those physical sides to find out if
// they're the same vs. opposite.
- mozilla::Side itemBlockStartSide = mWM.PhysicalSide(eLogicalSideBStart);
+ mozilla::Side itemBlockStartSide = mWM.PhysicalSide(LogicalSide::BStart);
// (Note: this is *not* the "flex-start" side; rather, it's the *logical*
// i.e. WM-relative block-start or inline-start side.)
@@ -2363,7 +2381,7 @@ nscoord FlexItem::BaselineOffsetFromOuterCrossEdge(
"Only expecting to be doing baseline computations when the "
"cross axis is the block axis");
- mozilla::Side itemBlockStartSide = mWM.PhysicalSide(eLogicalSideBStart);
+ mozilla::Side itemBlockStartSide = mWM.PhysicalSide(LogicalSide::BStart);
nscoord marginBStartToBaseline = ResolvedAscent(aUseFirstLineBaseline) +
PhysicalMargin().Side(itemBlockStartSide);
@@ -2537,18 +2555,17 @@ static bool FrameHasRelativeBSizeDependency(nsIFrame* aFrame) {
bool FlexItem::NeedsFinalReflow(const ReflowInput& aParentReflowInput) const {
if (!StaticPrefs::layout_flexbox_item_final_reflow_optimization_enabled()) {
- FLEX_LOG(
- "[perf] Flex item %p needed a final reflow due to optimization being "
- "disabled via the preference",
- mFrame);
+ FLEX_ITEM_LOG(mFrame,
+ "[perf] Item needed a final reflow due to optimization being "
+ "disabled via the preference");
return true;
}
// NOTE: We can have continuations from an earlier constrained reflow.
if (mFrame->GetPrevInFlow() || mFrame->GetNextInFlow()) {
// This is an item has continuation(s). Reflow it.
- FLEX_LOG("[frag] Flex item %p needed a final reflow due to continuation(s)",
- mFrame);
+ FLEX_ITEM_LOG(mFrame,
+ "[frag] Item needed a final reflow due to continuation(s)");
return true;
}
@@ -2560,10 +2577,9 @@ bool FlexItem::NeedsFinalReflow(const ReflowInput& aParentReflowInput) const {
// prevent triggering O(n^2) behavior when printing a deeply-nested flex
// container.
if (aParentReflowInput.IsInFragmentedContext()) {
- FLEX_LOG(
- "[frag] Flex item %p needed both a measuring reflow and a final "
- "reflow due to being in a fragmented context.",
- mFrame);
+ FLEX_ITEM_LOG(mFrame,
+ "[frag] Item needed both a measuring reflow and a final "
+ "reflow due to being in a fragmented context");
return true;
}
@@ -2579,10 +2595,9 @@ bool FlexItem::NeedsFinalReflow(const ReflowInput& aParentReflowInput) const {
if (finalSize != mFrame->ContentSize(mWM)) {
// The measuring reflow left the item with a different size than its
// final flexed size. So, we need to reflow to give it the correct size.
- FLEX_LOG(
- "[perf] Flex item %p needed both a measuring reflow and a final "
- "reflow due to measured size disagreeing with final size",
- mFrame);
+ FLEX_ITEM_LOG(mFrame,
+ "[perf] Item needed both a measuring reflow and a final "
+ "reflow due to measured size disagreeing with final size");
return true;
}
@@ -2590,10 +2605,9 @@ bool FlexItem::NeedsFinalReflow(const ReflowInput& aParentReflowInput) const {
// This item has descendants with relative BSizes who may care that its
// size may now be considered "definite" in the final reflow (whereas it
// was indefinite during the measuring reflow).
- FLEX_LOG(
- "[perf] Flex item %p needed both a measuring reflow and a final "
- "reflow due to BSize potentially becoming definite",
- mFrame);
+ FLEX_ITEM_LOG(mFrame,
+ "[perf] Item needed both a measuring reflow and a final "
+ "reflow due to BSize potentially becoming definite");
return true;
}
@@ -2621,10 +2635,9 @@ bool FlexItem::NeedsFinalReflow(const ReflowInput& aParentReflowInput) const {
// definiteness.
// Let's check for each condition that would still require us to reflow:
if (mFrame->IsSubtreeDirty()) {
- FLEX_LOG(
- "[perf] Flex item %p needed a final reflow due to its subtree "
- "being dirty",
- mFrame);
+ FLEX_ITEM_LOG(
+ mFrame,
+ "[perf] Item needed a final reflow due to its subtree being dirty");
return true;
}
@@ -2634,19 +2647,17 @@ bool FlexItem::NeedsFinalReflow(const ReflowInput& aParentReflowInput) const {
// Did we cache the metrics from its most recent "final reflow"?
auto* cache = mFrame->GetProperty(CachedFlexItemData::Prop());
if (!cache || !cache->mFinalReflowMetrics) {
- FLEX_LOG(
- "[perf] Flex item %p needed a final reflow due to lacking a "
- "cached mFinalReflowMetrics (maybe cache was cleared)",
- mFrame);
+ FLEX_ITEM_LOG(mFrame,
+ "[perf] Item needed a final reflow due to lacking a cached "
+ "mFinalReflowMetrics (maybe cache was cleared)");
return true;
}
// Does the cached size match our current size?
if (cache->mFinalReflowMetrics->Size() != finalSize) {
- FLEX_LOG(
- "[perf] Flex item %p needed a final reflow due to having a "
- "different content box size vs. its most recent final reflow",
- mFrame);
+ FLEX_ITEM_LOG(mFrame,
+ "[perf] Item needed a final reflow due to having a different "
+ "content box size vs. its most recent final reflow");
return true;
}
@@ -2659,10 +2670,9 @@ bool FlexItem::NeedsFinalReflow(const ReflowInput& aParentReflowInput) const {
// reflow.
if (cache->mFinalReflowMetrics->BorderPadding() !=
BorderPadding().ConvertTo(mWM, mCBWM)) {
- FLEX_LOG(
- "[perf] Flex item %p needed a final reflow due to having a "
- "different border and padding vs. its most recent final reflow",
- mFrame);
+ FLEX_ITEM_LOG(mFrame,
+ "[perf] Item needed a final reflow due to having a different "
+ "border and padding vs. its most recent final reflow");
return true;
}
@@ -2672,10 +2682,9 @@ bool FlexItem::NeedsFinalReflow(const ReflowInput& aParentReflowInput) const {
if (cache->mFinalReflowMetrics->TreatBSizeAsIndefinite() !=
mTreatBSizeAsIndefinite &&
FrameHasRelativeBSizeDependency(mFrame)) {
- FLEX_LOG(
- "[perf] Flex item %p needed a final reflow due to having "
- "its BSize change definiteness & having a rel-BSize child",
- mFrame);
+ FLEX_ITEM_LOG(mFrame,
+ "[perf] Item needed a final reflow due to having its BSize "
+ "change definiteness & having a rel-BSize child");
return true;
}
@@ -2683,7 +2692,7 @@ bool FlexItem::NeedsFinalReflow(const ReflowInput& aParentReflowInput) const {
// dirty, and our current conditions are sufficiently similar to the most
// recent "final reflow" that it should have left our subtree in the correct
// state.)
- FLEX_LOG("[perf] Flex item %p didn't need a final reflow", mFrame);
+ FLEX_ITEM_LOG(mFrame, "[perf] Item didn't need a final reflow");
return false;
}
@@ -2757,7 +2766,7 @@ class MOZ_STACK_CLASS PositionTracker {
const WritingMode mWM;
// The axis along which we're moving.
- const LogicalAxis mAxis = eLogicalAxisInline;
+ const LogicalAxis mAxis = LogicalAxis::Inline;
// Is the axis along which we're moving reversed (e.g. LTR vs RTL) with
// respect to the corresponding axis on the flex container's WM?
@@ -3150,8 +3159,8 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
availableFreeSpace -= item.MainSize();
}
- FLEX_LOG(" available free space: %" PRId64 "; flex items should \"%s\"",
- availableFreeSpace.value, isUsingFlexGrow ? "grow" : "shrink");
+ FLEX_LOGV("Available free space: %" PRId64 "; flex items should \"%s\"",
+ availableFreeSpace.value, isUsingFlexGrow ? "grow" : "shrink");
// The sign of our free space should agree with the type of flexing
// (grow/shrink) that we're doing. Any disagreement should've made us use
@@ -3276,7 +3285,7 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
}
}
- FLEX_LOG(" Distributing available space:");
+ FLEX_LOGV("Distributing available space:");
// Since this loop only operates on unfrozen flex items, we can break as
// soon as we have seen all of them.
numUnfrozenItemsToBeSeen = NumItems() - mNumFrozenItems;
@@ -3323,8 +3332,8 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
item.SetMainSize(item.MainSize() +
nscoord(sizeDelta.ToMinMaxClamped()));
- FLEX_LOG(" flex item %p receives %" PRId64 ", for a total of %d",
- item.Frame(), sizeDelta.value, item.MainSize());
+ FLEX_LOGV(" Flex item %p receives %" PRId64 ", for a total of %d",
+ item.Frame(), sizeDelta.value, item.MainSize());
}
}
@@ -3360,7 +3369,7 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
// Fix min/max violations:
nscoord totalViolation = 0; // keeps track of adjustments for min/max
- FLEX_LOG(" Checking for violations:");
+ FLEX_LOGV("Checking for violations:");
// Since this loop only operates on unfrozen flex items, we can break as
// soon as we have seen all of them.
@@ -3392,7 +3401,7 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
FreezeOrRestoreEachFlexibleSize(totalViolation,
iterationCounter + 1 == NumItems());
- FLEX_LOG(" Total violation: %d", totalViolation);
+ FLEX_LOGV("Total violation: %d", totalViolation);
if (mNumFrozenItems == NumItems()) {
break;
@@ -3952,7 +3961,7 @@ void SingleLineCrossAxisPositionTracker::EnterAlignPackingSpace(
if (alignSelf == StyleAlignFlags::SELF_START ||
alignSelf == StyleAlignFlags::SELF_END) {
const LogicalAxis logCrossAxis =
- aAxisTracker.IsRowOriented() ? eLogicalAxisBlock : eLogicalAxisInline;
+ aAxisTracker.IsRowOriented() ? LogicalAxis::Block : LogicalAxis::Inline;
const WritingMode cWM = aAxisTracker.GetWritingMode();
const bool sameStart =
cWM.ParallelAxisStartsOnSameSide(logCrossAxis, aItem.GetWritingMode());
@@ -4560,7 +4569,6 @@ void nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsFlexContainerFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aReflowOutput, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
MOZ_ASSERT(aPresContext == PresContext());
NS_WARNING_ASSERTION(
@@ -4568,7 +4576,7 @@ void nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
"Unconstrained inline size; this should only result from huge sizes "
"(not intrinsic sizing w/ orthogonal flows)");
- FLEX_LOG("Reflow() for nsFlexContainerFrame %p", this);
+ FLEX_LOG("Reflowing flex container frame %p ...", this);
if (IsFrameTreeTooDeep(aReflowInput, aReflowOutput, aStatus)) {
return;
@@ -5276,8 +5284,8 @@ nsFlexContainerFrame::FlexLayoutResult nsFlexContainerFrame::DoFlexLayout(
} else {
sizeOverrides.mStyleBSize.emplace(item.StyleMainSize());
}
- FLEX_LOG("Sizing flex item %p in cross axis", item.Frame());
- FLEX_LOGV(" Main size override: %d", item.MainSize());
+ FLEX_ITEM_LOG(item.Frame(), "Sizing item in cross axis");
+ FLEX_LOGV("Main size override: %d", item.MainSize());
const WritingMode wm = item.GetWritingMode();
LogicalSize availSize = aReflowInput.ComputedSize(wm);
@@ -5640,10 +5648,10 @@ std::tuple<nscoord, nsReflowStatus> nsFlexContainerFrame::ReflowChildren(
// block-size and add it to
// PerFragmentFlexData::mCumulativeContentBoxBSize even if we are not
// laying out any child.
- FLEX_LOG(
- "[frag] Flex item %p needed to be pushed to container's "
- "next-in-flow due to position below available space's block-end",
- item.Frame());
+ FLEX_ITEM_LOG(
+ item.Frame(),
+ "[frag] Item needed to be pushed to container's next-in-flow due "
+ "to being positioned beyond block-end edge of available space");
pushedItems.Insert(item.Frame());
itemInPushedItems = true;
} else if (item.NeedsFinalReflow(aReflowInput)) {
@@ -5680,11 +5688,10 @@ std::tuple<nscoord, nsReflowStatus> nsFlexContainerFrame::ReflowChildren(
return true;
}();
if (shouldPushItem) {
- FLEX_LOG(
- "[frag] Flex item %p needed to be pushed to container's "
- "next-in-flow because its block-size is larger than the "
- "available space",
- item.Frame());
+ FLEX_ITEM_LOG(
+ item.Frame(),
+ "[frag] Item needed to be pushed to container's next-in-flow "
+ "because its block-size is larger than the available space");
pushedItems.Insert(item.Frame());
itemInPushedItems = true;
} else if (childReflowStatus.IsIncomplete()) {
@@ -6050,8 +6057,8 @@ void nsFlexContainerFrame::MoveFlexItemToFinalPosition(
logicalOffsets, &pos, aContainerSize);
}
- FLEX_LOG("Moving flex item %p to its desired position %s", aItem.Frame(),
- ToString(pos).c_str());
+ FLEX_ITEM_LOG(aItem.Frame(), "Moving item to its desired position %s",
+ ToString(pos).c_str());
aItem.Frame()->SetPosition(outerWM, pos, aContainerSize);
PositionFrameView(aItem.Frame());
PositionChildViews(aItem.Frame());
@@ -6061,7 +6068,7 @@ nsReflowStatus nsFlexContainerFrame::ReflowFlexItem(
const FlexboxAxisTracker& aAxisTracker, const ReflowInput& aReflowInput,
const FlexItem& aItem, const LogicalPoint& aFramePos,
const LogicalSize& aAvailableSize, const nsSize& aContainerSize) {
- FLEX_LOG("Doing final reflow for flex item %p", aItem.Frame());
+ FLEX_ITEM_LOG(aItem.Frame(), "Doing final reflow");
// Returns true if we should use 'auto' in block axis's StyleSizeOverrides to
// allow fragmentation-imposed block-size growth.
@@ -6131,15 +6138,15 @@ nsReflowStatus nsFlexContainerFrame::ReflowFlexItem(
// Override flex item's main size.
if (aItem.IsInlineAxisMainAxis()) {
sizeOverrides.mStyleISize.emplace(aItem.StyleMainSize());
- FLEX_LOGV(" Main size (inline-size) override: %d", aItem.MainSize());
+ FLEX_LOGV("Main size (inline-size) override: %d", aItem.MainSize());
} else {
overrideBSizeWithAuto = ComputeBSizeOverrideWithAuto();
if (overrideBSizeWithAuto) {
sizeOverrides.mStyleBSize.emplace(StyleSize::Auto());
- FLEX_LOGV(" Main size (block-size) override: Auto");
+ FLEX_LOGV("Main size (block-size) override: Auto");
} else {
sizeOverrides.mStyleBSize.emplace(aItem.StyleMainSize());
- FLEX_LOGV(" Main size (block-size) override: %d", aItem.MainSize());
+ FLEX_LOGV("Main size (block-size) override: %d", aItem.MainSize());
}
}
@@ -6148,15 +6155,15 @@ nsReflowStatus nsFlexContainerFrame::ReflowFlexItem(
if (aItem.IsStretched()) {
if (aItem.IsInlineAxisCrossAxis()) {
sizeOverrides.mStyleISize.emplace(aItem.StyleCrossSize());
- FLEX_LOGV(" Cross size (inline-size) override: %d", aItem.CrossSize());
+ FLEX_LOGV("Cross size (inline-size) override: %d", aItem.CrossSize());
} else {
overrideBSizeWithAuto = ComputeBSizeOverrideWithAuto();
if (overrideBSizeWithAuto) {
sizeOverrides.mStyleBSize.emplace(StyleSize::Auto());
- FLEX_LOGV(" Cross size (block-size) override: Auto");
+ FLEX_LOGV("Cross size (block-size) override: Auto");
} else {
sizeOverrides.mStyleBSize.emplace(aItem.StyleCrossSize());
- FLEX_LOGV(" Cross size (block-size) override: %d", aItem.CrossSize());
+ FLEX_LOGV("Cross size (block-size) override: %d", aItem.CrossSize());
}
}
}
@@ -6203,8 +6210,8 @@ nsReflowStatus nsFlexContainerFrame::ReflowFlexItem(
// after this point, because some of its methods (e.g. SetComputedWidth)
// internally call InitResizeFlags and stomp on mVResize & mHResize.
- FLEX_LOG("Reflowing flex item %p at its desired position %s", aItem.Frame(),
- ToString(aFramePos).c_str());
+ FLEX_ITEM_LOG(aItem.Frame(), "Reflowing item at its desired position %s",
+ ToString(aFramePos).c_str());
// CachedFlexItemData is stored in item's writing mode, so we pass
// aChildReflowInput into ReflowOutput's constructor.
@@ -6332,7 +6339,6 @@ nscoord nsFlexContainerFrame::IntrinsicISize(gfxContext* aRenderingContext,
/* virtual */
nscoord nsFlexContainerFrame::GetMinISize(gfxContext* aRenderingContext) {
- DISPLAY_MIN_INLINE_SIZE(this, mCachedMinISize);
if (mCachedMinISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
if (Maybe<nscoord> containISize = ContainIntrinsicISize()) {
mCachedMinISize = *containISize;
@@ -6347,7 +6353,6 @@ nscoord nsFlexContainerFrame::GetMinISize(gfxContext* aRenderingContext) {
/* virtual */
nscoord nsFlexContainerFrame::GetPrefISize(gfxContext* aRenderingContext) {
- DISPLAY_PREF_INLINE_SIZE(this, mCachedPrefISize);
if (mCachedPrefISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
if (Maybe<nscoord> containISize = ContainIntrinsicISize()) {
mCachedPrefISize = *containISize;
diff --git a/layout/generic/nsFlexContainerFrame.h b/layout/generic/nsFlexContainerFrame.h
index 30e440b401..14f91ae064 100644
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -12,15 +12,9 @@
#include <tuple>
#include "mozilla/dom/FlexBinding.h"
-#include "mozilla/UniquePtr.h"
#include "nsContainerFrame.h"
#include "nsILineIterator.h"
-namespace mozilla {
-class LogicalPoint;
-class PresShell;
-} // namespace mozilla
-
nsContainerFrame* NS_NewFlexContainerFrame(mozilla::PresShell* aPresShell,
mozilla::ComputedStyle* aStyle);
diff --git a/layout/generic/nsFloatManager.cpp b/layout/generic/nsFloatManager.cpp
index b6612ca6f5..e1866b35c1 100644
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -2507,7 +2507,7 @@ nsFloatManager::ShapeInfo::CreateBasicShape(const StyleBasicShape& aBasicShape,
case StyleBasicShape::Tag::Rect:
return CreateInset(aBasicShape, aShapeMargin, aFrame, aShapeBoxRect, aWM,
aContainerSize);
- case StyleBasicShape::Tag::Path:
+ case StyleBasicShape::Tag::PathOrShape:
MOZ_ASSERT_UNREACHABLE("Unsupported basic shape");
}
return nullptr;
diff --git a/layout/generic/nsFrameSelection.cpp b/layout/generic/nsFrameSelection.cpp
index f1a8c7e27c..ca4e3d647e 100644
--- a/layout/generic/nsFrameSelection.cpp
+++ b/layout/generic/nsFrameSelection.cpp
@@ -156,9 +156,10 @@ PeekOffsetStruct::PeekOffsetStruct(nsSelectionAmount aAmount,
} // namespace mozilla
-// Array which contains index of each SelecionType in Selection::mDOMSelections.
-// For avoiding using if nor switch to retrieve the index, this needs to have
-// -1 for SelectionTypes which won't be created its Selection instance.
+// Array which contains index of each SelectionType in
+// Selection::mDOMSelections. For avoiding using if nor switch to retrieve the
+// index, this needs to have -1 for SelectionTypes which won't be created its
+// Selection instance.
static const int8_t kIndexOfSelections[] = {
-1, // SelectionType::eInvalid
-1, // SelectionType::eNone
@@ -172,6 +173,7 @@ static const int8_t kIndexOfSelections[] = {
7, // SelectionType::eFind
8, // SelectionType::eURLSecondary
9, // SelectionType::eURLStrikeout
+ 10, // SelectionType::eTargetText
-1, // SelectionType::eHighlight
};
@@ -539,7 +541,11 @@ nsresult nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(
NS_ENSURE_STATE(mPresShell);
RefPtr<PresShell> presShell = mPresShell;
- nsIContent* anchorRoot = anchorContent->GetSelectionRootContent(presShell);
+ nsIContent* anchorRoot =
+ anchorContent
+ ->GetSelectionRootContent(
+ presShell,
+ StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() /* aAllowCrossShadowBoundary */);
NS_ENSURE_TRUE(anchorRoot, NS_ERROR_UNEXPECTED);
//
@@ -549,7 +555,10 @@ nsresult nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(
nsCOMPtr<nsIContent> content = aFrame->GetContent();
if (content) {
- nsIContent* contentRoot = content->GetSelectionRootContent(presShell);
+ nsIContent* contentRoot =
+ content->GetSelectionRootContent(
+ presShell, StaticPrefs::
+ dom_shadowdom_selection_across_boundary_enabled() /* aAllowCrossShadowBoundary */);
NS_ENSURE_TRUE(contentRoot, NS_ERROR_UNEXPECTED);
if (anchorRoot == contentRoot) {
@@ -573,8 +582,9 @@ nsresult nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(
if (cursorFrame && cursorFrame->PresShell() == presShell) {
nsCOMPtr<nsIContent> cursorContent = cursorFrame->GetContent();
NS_ENSURE_TRUE(cursorContent, NS_ERROR_FAILURE);
- nsIContent* cursorContentRoot =
- cursorContent->GetSelectionRootContent(presShell);
+ nsIContent* cursorContentRoot = cursorContent->GetSelectionRootContent(
+ presShell, StaticPrefs::
+ dom_shadowdom_selection_across_boundary_enabled() /* aAllowCrossShadowBoundary */);
NS_ENSURE_TRUE(cursorContentRoot, NS_ERROR_UNEXPECTED);
if (cursorContentRoot == anchorRoot) {
*aRetFrame = cursorFrame;
@@ -1493,11 +1503,11 @@ void nsFrameSelection::SetDragState(bool aState) {
// Notify that reason is mouse up.
SetChangeReasons(nsISelectionListener::MOUSEUP_REASON);
- // flag is set to false in `NotifySelectionListeners`.
+ // flag is set to NotApplicable in `Selection::NotifySelectionListeners`.
// since this function call is part of click event, this would immediately
// reset the flag, rendering it useless.
- AutoRestore<bool> restoreIsDoubleClickSelectionFlag(
- mIsDoubleClickSelection);
+ AutoRestore<ClickSelectionType> restoreClickSelectionType(
+ mClickSelectionType);
// Be aware, the Selection instance may be destroyed after this call.
NotifySelectionListeners(SelectionType::eNormal);
}
diff --git a/layout/generic/nsFrameSelection.h b/layout/generic/nsFrameSelection.h
index e8c55d53b5..3ba6fa72ca 100644
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -200,6 +200,7 @@ class SelectionChangeEventDispatcher;
namespace dom {
class Highlight;
class Selection;
+enum class ClickSelectionType { NotApplicable, Double, Triple };
} // namespace dom
/**
@@ -259,14 +260,17 @@ class nsFrameSelection final {
public:
/**
- * Sets flag to true if a selection is created by doubleclick or
- * long tapping a word.
+ * Sets the type of the selection based on whether a selection is created
+ * by doubleclick, long tapping a word or tripleclick.
*
- * @param aIsDoubleClickSelection True if the selection is created by
- * doubleclick or long tap over a word.
+ * @param aClickSelectionType ClickSelectionType::Double if the selection
+ * is created by doubleclick,
+ * ClickSelectionType::Triple if the selection
+ * is created by tripleclick.
*/
- void SetIsDoubleClickSelection(bool aIsDoubleClickSelection) {
- mIsDoubleClickSelection = aIsDoubleClickSelection;
+ void SetClickSelectionType(
+ mozilla::dom::ClickSelectionType aClickSelectionType) {
+ mClickSelectionType = aClickSelectionType;
}
/**
@@ -274,7 +278,14 @@ class nsFrameSelection final {
* long tap over a word.
*/
[[nodiscard]] bool IsDoubleClickSelection() const {
- return mIsDoubleClickSelection;
+ return mClickSelectionType == mozilla::dom::ClickSelectionType::Double;
+ }
+
+ /**
+ * Returns true if the selection was created by triple click
+ */
+ [[nodiscard]] bool IsTripleClickSelection() const {
+ return mClickSelectionType == mozilla::dom::ClickSelectionType::Triple;
}
/**
@@ -1102,11 +1113,12 @@ class nsFrameSelection final {
bool mDragState = false; // for drag purposes
bool mAccessibleCaretEnabled = false;
- // Records if a selection was created by doubleclicking a word.
- // This information is needed later on to determine if a leading
+ // Records if a selection was created by doubleclicking or tripleclicking
+ // a word. This information is needed later on to determine if a leading
// or trailing whitespace needs to be removed as well to achieve
// native behaviour on macOS.
- bool mIsDoubleClickSelection{false};
+ mozilla::dom::ClickSelectionType mClickSelectionType =
+ mozilla::dom::ClickSelectionType::NotApplicable;
};
/**
diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp
index f292988c55..be561a6c32 100644
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -760,7 +760,6 @@ void nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
mozilla::PresShell* presShell = aPresContext->PresShell();
@@ -1312,7 +1311,6 @@ void nsHTMLFramesetBorderFrame::Reflow(nsPresContext* aPresContext,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) {
DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetBorderFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
// Override Reflow(), since we don't want to deal with what our
diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp
index 361847b753..2b0c53efe1 100644
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -170,7 +170,7 @@ class nsHTMLScrollFrame::ScrollEvent : public Runnable {
class nsHTMLScrollFrame::ScrollEndEvent : public Runnable {
public:
NS_DECL_NSIRUNNABLE
- explicit ScrollEndEvent(nsHTMLScrollFrame* aHelper);
+ explicit ScrollEndEvent(nsHTMLScrollFrame* aHelper, bool aDelayed);
void Revoke() { mHelper = nullptr; }
private:
@@ -1265,17 +1265,7 @@ nsMargin nsHTMLScrollFrame::ComputeStableScrollbarGutter(
// Legacy, this sucks!
static bool IsMarqueeScrollbox(const nsIFrame& aScrollFrame) {
- if (!aScrollFrame.GetContent()) {
- return false;
- }
- if (MOZ_LIKELY(!aScrollFrame.GetContent()->HasBeenInUAWidget())) {
- return false;
- }
- MOZ_ASSERT(aScrollFrame.GetParent() &&
- aScrollFrame.GetParent()->GetContent());
- return aScrollFrame.GetParent() &&
- HTMLMarqueeElement::FromNodeOrNull(
- aScrollFrame.GetParent()->GetContent());
+ return HTMLMarqueeElement::FromNodeOrNull(aScrollFrame.GetContent());
}
/* virtual */
@@ -1290,7 +1280,6 @@ nscoord nsHTMLScrollFrame::GetMinISize(gfxContext* aRenderingContext) {
return mScrolledFrame->GetMinISize(aRenderingContext);
}();
- DISPLAY_MIN_INLINE_SIZE(this, result);
return result + IntrinsicScrollbarGutterSizeAtInlineEdges();
}
@@ -1300,7 +1289,6 @@ nscoord nsHTMLScrollFrame::GetPrefISize(gfxContext* aRenderingContext) {
nscoord result = containISize
? *containISize
: mScrolledFrame->GetPrefISize(aRenderingContext);
- DISPLAY_PREF_INLINE_SIZE(this, result);
return NSCoordSaturatingAdd(result,
IntrinsicScrollbarGutterSizeAtInlineEdges());
}
@@ -1497,7 +1485,6 @@ void nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsHTMLScrollFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
HandleScrollbarStyleSwitching();
@@ -5429,23 +5416,31 @@ nsresult nsHTMLScrollFrame::FireScrollPortEvent() {
return EventDispatcher::Dispatch(content, presContext, &event);
}
-void nsHTMLScrollFrame::PostScrollEndEvent() {
+void nsHTMLScrollFrame::PostScrollEndEvent(bool aDelayed) {
if (mScrollEndEvent) {
return;
}
// The ScrollEndEvent constructor registers itself with the refresh driver.
- mScrollEndEvent = new ScrollEndEvent(this);
+ mScrollEndEvent = new ScrollEndEvent(this, aDelayed);
}
void nsHTMLScrollFrame::FireScrollEndEvent() {
- MOZ_ASSERT(GetContent());
- MOZ_ASSERT(mScrollEndEvent);
+ RefPtr<nsIContent> content = GetContent();
+ MOZ_ASSERT(content);
- RefPtr<nsPresContext> presContext = PresContext();
+ MOZ_ASSERT(mScrollEndEvent);
mScrollEndEvent->Revoke();
mScrollEndEvent = nullptr;
+ if (content->GetComposedDoc() &&
+ content->GetComposedDoc()->EventHandlingSuppressed()) {
+ content->GetComposedDoc()->SetHasDelayedRefreshEvent();
+ PostScrollEndEvent(/* aDelayed = */ true);
+ return;
+ }
+
+ RefPtr<nsPresContext> presContext = PresContext();
nsEventStatus status = nsEventStatus_eIgnore;
WidgetGUIEvent event(true, eScrollend, nullptr);
event.mFlags.mBubbles = mIsRoot;
@@ -5895,9 +5890,10 @@ nsHTMLScrollFrame::ScrollEvent::Run() {
return NS_OK;
}
-nsHTMLScrollFrame::ScrollEndEvent::ScrollEndEvent(nsHTMLScrollFrame* aHelper)
+nsHTMLScrollFrame::ScrollEndEvent::ScrollEndEvent(nsHTMLScrollFrame* aHelper,
+ bool aDelayed)
: Runnable("nsHTMLScrollFrame::ScrollEndEvent"), mHelper(aHelper) {
- mHelper->PresContext()->RefreshDriver()->PostScrollEvent(this);
+ mHelper->PresContext()->RefreshDriver()->PostScrollEvent(this, aDelayed);
}
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h
index ce2a75a3df..9d619de4e5 100644
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -500,7 +500,7 @@ class nsHTMLScrollFrame : public nsContainerFrame,
OverflowState GetOverflowState() const;
MOZ_CAN_RUN_SCRIPT nsresult FireScrollPortEvent();
- void PostScrollEndEvent();
+ void PostScrollEndEvent(bool aDelayed = false);
MOZ_CAN_RUN_SCRIPT void FireScrollEndEvent();
void PostOverflowEvent();
diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp
index 5eb9cde7da..bb6e2150ce 100644
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -28,6 +28,7 @@
#include "nsCSSFrameConstructor.h"
#include "nsDisplayList.h"
#include "nsFieldSetFrame.h"
+#include "nsHTMLButtonControlFrame.h"
#include "nsGfxScrollFrame.h"
#include "nsHashKeys.h"
#include "nsIFrameInlines.h" // for nsIFrame::GetLogicalNormalPosition (don't remove)
@@ -168,7 +169,7 @@ static nscoord ResolveToDefiniteSize(const StyleTrackBreadth& aBreadth,
// block axis; e.g. for English horizontal-tb text, a traditional baseline
// would be a y-axis measurement. But in some cases (e.g. orthogonal WMs), we
// may need to synthesize a baseline in a child's inline axis, which is when
-// this function might receive an aAxis of eLogicalAxisInline. In that case, we
+// this function might receive an aAxis of LogicalAxis::Inline. In that case, we
// assume that the writing mode's preference for central vs. alphabetic
// baselines is irrelevant, since that's a choice about its block-axis
// baselines, and we just unconditionally use the alphabetic baseline
@@ -178,7 +179,7 @@ static nscoord SynthesizeBaselineFromBorderBox(BaselineSharingGroup aGroup,
LogicalAxis aAxis,
nscoord aBorderBoxSize) {
const bool useAlphabeticBaseline =
- (aAxis == eLogicalAxisInline) ? true : aWM.IsAlphabeticalBaseline();
+ (aAxis == LogicalAxis::Inline) ? true : aWM.IsAlphabeticalBaseline();
if (aGroup == BaselineSharingGroup::First) {
return useAlphabeticBaseline ? aBorderBoxSize : aBorderBoxSize / 2;
@@ -218,7 +219,7 @@ struct RepeatTrackSizingInput {
// We can use zero percentage basis since this is only called from
// intrinsic sizing code.
const nscoord percentageBasis = 0;
- if (aAxis == eLogicalAxisInline) {
+ if (aAxis == LogicalAxis::Inline) {
bp = std::max(padding.GetIStart(aWM).Resolve(percentageBasis), 0) +
std::max(padding.GetIEnd(aWM).Resolve(percentageBasis), 0) +
border.IStartEnd(aWM);
@@ -234,17 +235,17 @@ struct RepeatTrackSizingInput {
nscoord& size = mSize.Size(aAxis, aWM);
nscoord& max = mMax.Size(aAxis, aWM);
const auto& minCoord =
- aAxis == eLogicalAxisInline ? pos->MinISize(aWM) : pos->MinBSize(aWM);
+ aAxis == LogicalAxis::Inline ? pos->MinISize(aWM) : pos->MinBSize(aWM);
if (minCoord.ConvertsToLength()) {
min = adjustForBoxSizing(minCoord.ToLength());
}
const auto& maxCoord =
- aAxis == eLogicalAxisInline ? pos->MaxISize(aWM) : pos->MaxBSize(aWM);
+ aAxis == LogicalAxis::Inline ? pos->MaxISize(aWM) : pos->MaxBSize(aWM);
if (maxCoord.ConvertsToLength()) {
max = std::max(min, adjustForBoxSizing(maxCoord.ToLength()));
}
const auto& sizeCoord =
- aAxis == eLogicalAxisInline ? pos->ISize(aWM) : pos->BSize(aWM);
+ aAxis == LogicalAxis::Inline ? pos->ISize(aWM) : pos->BSize(aWM);
if (sizeCoord.ConvertsToLength()) {
size = Clamp(adjustForBoxSizing(sizeCoord.ToLength()), min, max);
}
@@ -576,10 +577,10 @@ struct nsGridContainerFrame::GridArea {
: mCols(aCols), mRows(aRows) {}
bool IsDefinite() const { return mCols.IsDefinite() && mRows.IsDefinite(); }
LineRange& LineRangeForAxis(LogicalAxis aAxis) {
- return aAxis == eLogicalAxisInline ? mCols : mRows;
+ return aAxis == LogicalAxis::Inline ? mCols : mRows;
}
const LineRange& LineRangeForAxis(LogicalAxis aAxis) const {
- return aAxis == eLogicalAxisInline ? mCols : mRows;
+ return aAxis == LogicalAxis::Inline ? mCols : mRows;
}
LineRange mCols;
LineRange mRows;
@@ -665,12 +666,12 @@ struct nsGridContainerFrame::GridItemInfo {
*/
GridItemInfo Transpose() const {
GridItemInfo info(mFrame, GridArea(mArea.mRows, mArea.mCols));
- info.mState[eLogicalAxisBlock] = mState[eLogicalAxisInline];
- info.mState[eLogicalAxisInline] = mState[eLogicalAxisBlock];
- info.mBaselineOffset[eLogicalAxisBlock] =
- mBaselineOffset[eLogicalAxisInline];
- info.mBaselineOffset[eLogicalAxisInline] =
- mBaselineOffset[eLogicalAxisBlock];
+ info.mState[LogicalAxis::Block] = mState[LogicalAxis::Inline];
+ info.mState[LogicalAxis::Inline] = mState[LogicalAxis::Block];
+ info.mBaselineOffset[LogicalAxis::Block] =
+ mBaselineOffset[LogicalAxis::Inline];
+ info.mBaselineOffset[LogicalAxis::Inline] =
+ mBaselineOffset[LogicalAxis::Block];
return info;
}
@@ -684,7 +685,7 @@ struct nsGridContainerFrame::GridItemInfo {
// Is this item a subgrid in either axis?
bool IsSubgrid() const {
- return IsSubgrid(eLogicalAxisInline) || IsSubgrid(eLogicalAxisBlock);
+ return IsSubgrid(LogicalAxis::Inline) || IsSubgrid(LogicalAxis::Block);
}
// Return the (inner) grid container frame associated with this subgrid item.
@@ -725,7 +726,7 @@ struct nsGridContainerFrame::GridItemInfo {
bool ShouldApplyAutoMinSize(WritingMode aContainerWM,
LogicalAxis aContainerAxis,
nscoord aPercentageBasis) const {
- const bool isInlineAxis = aContainerAxis == eLogicalAxisInline;
+ const bool isInlineAxis = aContainerAxis == LogicalAxis::Inline;
const auto* pos =
mFrame->IsTableWrapperFrame()
? mFrame->PrincipalChildList().FirstChild()->StylePosition()
@@ -793,9 +794,9 @@ struct nsGridContainerFrame::GridItemInfo {
return isContinuationA;
}
auto masonryA = a->mArea.mRows.mStart;
- auto gridA = a->mState[eLogicalAxisInline] & StateBits::eAutoPlacement;
+ auto gridA = a->mState[LogicalAxis::Inline] & StateBits::eAutoPlacement;
auto masonryB = b->mArea.mRows.mStart;
- auto gridB = b->mState[eLogicalAxisInline] & StateBits::eAutoPlacement;
+ auto gridB = b->mState[LogicalAxis::Inline] & StateBits::eAutoPlacement;
return (masonryA == 0 ? masonryB != 0 : (masonryB != 0 && gridA < gridB)) &&
!a->mFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW);
}
@@ -804,9 +805,9 @@ struct nsGridContainerFrame::GridItemInfo {
MOZ_ASSERT(!a->mFrame->GetPrevInFlow() && !b->mFrame->GetPrevInFlow(),
"fragmentation not supported in inline axis");
auto masonryA = a->mArea.mCols.mStart;
- auto gridA = a->mState[eLogicalAxisBlock] & StateBits::eAutoPlacement;
+ auto gridA = a->mState[LogicalAxis::Block] & StateBits::eAutoPlacement;
auto masonryB = b->mArea.mCols.mStart;
- auto gridB = b->mState[eLogicalAxisBlock] & StateBits::eAutoPlacement;
+ auto gridB = b->mState[LogicalAxis::Block] & StateBits::eAutoPlacement;
return (masonryA == 0 ? masonryB != 0 : (masonryB != 0 && gridA < gridB)) &&
!a->mFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW);
}
@@ -847,20 +848,20 @@ MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ItemState)
GridItemInfo::GridItemInfo(nsIFrame* aFrame, const GridArea& aArea)
: mFrame(aFrame), mArea(aArea), mBaselineOffset{0, 0} {
- mState[eLogicalAxisBlock] =
+ mState[LogicalAxis::Block] =
StateBits(mArea.mRows.mStart == kAutoLine ? eAutoPlacement : 0);
- mState[eLogicalAxisInline] =
+ mState[LogicalAxis::Inline] =
StateBits(mArea.mCols.mStart == kAutoLine ? eAutoPlacement : 0);
if (auto* gridFrame = GetGridContainerFrame(mFrame)) {
auto parentWM = aFrame->GetParent()->GetWritingMode();
bool isOrthogonal = parentWM.IsOrthogonalTo(gridFrame->GetWritingMode());
if (gridFrame->IsColSubgrid()) {
- mState[isOrthogonal ? eLogicalAxisBlock : eLogicalAxisInline] |=
+ mState[isOrthogonal ? LogicalAxis::Block : LogicalAxis::Inline] |=
StateBits::eIsSubgrid;
}
if (gridFrame->IsRowSubgrid()) {
- mState[isOrthogonal ? eLogicalAxisInline : eLogicalAxisBlock] |=
+ mState[isOrthogonal ? LogicalAxis::Inline : LogicalAxis::Block] |=
StateBits::eIsSubgrid;
}
}
@@ -884,7 +885,7 @@ void GridItemInfo::InhibitSubgrid(nsGridContainerFrame* aParent,
MOZ_ASSERT(IsSubgrid(aAxis));
auto bit = NS_STATE_GRID_IS_COL_SUBGRID;
if (aParent->GetWritingMode().IsOrthogonalTo(mFrame->GetWritingMode()) !=
- (aAxis == eLogicalAxisBlock)) {
+ (aAxis == LogicalAxis::Block)) {
bit = NS_STATE_GRID_IS_ROW_SUBGRID;
}
MOZ_ASSERT(SubgridFrame()->HasAnyStateBits(bit));
@@ -894,16 +895,18 @@ void GridItemInfo::InhibitSubgrid(nsGridContainerFrame* aParent,
void GridItemInfo::MaybeInhibitSubgridInMasonry(nsGridContainerFrame* aParent,
uint32_t aGridAxisTrackCount) {
- if (IsSubgrid(eLogicalAxisInline) && aParent->IsMasonry(eLogicalAxisBlock) &&
- mArea.mRows.mStart != 0 && mArea.mCols.Extent() != aGridAxisTrackCount &&
- (mState[eLogicalAxisInline] & eAutoPlacement)) {
- InhibitSubgrid(aParent, eLogicalAxisInline);
+ if (IsSubgrid(LogicalAxis::Inline) &&
+ aParent->IsMasonry(LogicalAxis::Block) && mArea.mRows.mStart != 0 &&
+ mArea.mCols.Extent() != aGridAxisTrackCount &&
+ (mState[LogicalAxis::Inline] & eAutoPlacement)) {
+ InhibitSubgrid(aParent, LogicalAxis::Inline);
return;
}
- if (IsSubgrid(eLogicalAxisBlock) && aParent->IsMasonry(eLogicalAxisInline) &&
- mArea.mCols.mStart != 0 && mArea.mRows.Extent() != aGridAxisTrackCount &&
- (mState[eLogicalAxisBlock] & eAutoPlacement)) {
- InhibitSubgrid(aParent, eLogicalAxisBlock);
+ if (IsSubgrid(LogicalAxis::Block) &&
+ aParent->IsMasonry(LogicalAxis::Inline) && mArea.mCols.mStart != 0 &&
+ mArea.mRows.Extent() != aGridAxisTrackCount &&
+ (mState[LogicalAxis::Block] & eAutoPlacement)) {
+ InhibitSubgrid(aParent, LogicalAxis::Block);
}
}
@@ -1061,9 +1064,9 @@ void nsGridContainerFrame::GridItemInfo::Dump() const {
printf("\n");
};
printf("grid-row: %d %d\n", mArea.mRows.mStart, mArea.mRows.mEnd);
- Dump1(" grid block-axis: ", eLogicalAxisBlock);
+ Dump1(" grid block-axis: ", LogicalAxis::Block);
printf("grid-column: %d %d\n", mArea.mCols.mStart, mArea.mCols.mEnd);
- Dump1(" grid inline-axis: ", eLogicalAxisInline);
+ Dump1(" grid inline-axis: ", LogicalAxis::Inline);
}
#endif
@@ -1150,8 +1153,9 @@ struct nsGridContainerFrame::TrackSizingFunctions {
parent->GetWritingMode().ParallelAxisStartsOnSameSide(parentAxis,
grandParentWM);
if (MOZ_UNLIKELY(!isSameDirInAxis)) {
- auto end = parentAxis == eLogicalAxisBlock ? parentSubgrid->mGridRowEnd
- : parentSubgrid->mGridColEnd;
+ auto end = parentAxis == LogicalAxis::Block
+ ? parentSubgrid->mGridRowEnd
+ : parentSubgrid->mGridColEnd;
range.ReverseDirection(end);
// range is now in the same direction as the grand-parent's axis
}
@@ -1166,7 +1170,7 @@ struct nsGridContainerFrame::TrackSizingFunctions {
parent = grandParent;
}
const auto* pos = parent->StylePosition();
- const auto isInlineAxis = parentAxis == eLogicalAxisInline;
+ const auto isInlineAxis = parentAxis == LogicalAxis::Inline;
const auto& szf =
isInlineAxis ? pos->mGridTemplateRows : pos->mGridTemplateColumns;
const auto& autoSizing =
@@ -2707,7 +2711,7 @@ struct nsGridContainerFrame::Tracks {
* gap before aRow to zero (and shift all rows after it by the removed gap).
*/
void BreakBeforeRow(uint32_t aRow) {
- MOZ_ASSERT(mAxis == eLogicalAxisBlock,
+ MOZ_ASSERT(mAxis == LogicalAxis::Block,
"Should only be fragmenting in the block axis (between rows)");
nscoord prevRowEndPos = 0;
if (aRow != 0) {
@@ -2728,7 +2732,7 @@ struct nsGridContainerFrame::Tracks {
* Set the size of aRow to aSize and adjust the position of all rows after it.
*/
void ResizeRow(uint32_t aRow, nscoord aNewSize) {
- MOZ_ASSERT(mAxis == eLogicalAxisBlock,
+ MOZ_ASSERT(mAxis == LogicalAxis::Block,
"Should only be fragmenting in the block axis (between rows)");
MOZ_ASSERT(aNewSize >= 0);
auto& sz = mSizes[aRow];
@@ -2775,7 +2779,7 @@ struct nsGridContainerFrame::Tracks {
#ifdef DEBUG
void nsGridContainerFrame::Tracks::Dump() const {
printf("%zu %s %s ", mSizes.Length(), mIsMasonry ? "masonry" : "grid",
- mAxis == eLogicalAxisBlock ? "rows" : "columns");
+ mAxis == LogicalAxis::Block ? "rows" : "columns");
TrackSize::DumpStateBits(mStateUnion);
printf("\n");
for (uint32_t i = 0, len = mSizes.Length(); i < len; ++i) {
@@ -2805,8 +2809,8 @@ void nsGridContainerFrame::Tracks::Dump() const {
*/
struct nsGridContainerFrame::SharedGridData {
SharedGridData()
- : mCols(eLogicalAxisInline),
- mRows(eLogicalAxisBlock),
+ : mCols(LogicalAxis::Inline),
+ mRows(LogicalAxis::Block),
mGenerateComputedGridInfo(false) {}
Tracks mCols;
Tracks mRows;
@@ -2884,7 +2888,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
}
}
if (mStartRow == numRows ||
- aGridContainerFrame->IsMasonry(eLogicalAxisBlock)) {
+ aGridContainerFrame->IsMasonry(LogicalAxis::Block)) {
// All of the grid's rows fit inside of previous grid-container fragments,
// or it's a masonry axis.
mFragBStart = aConsumedBSize;
@@ -2904,8 +2908,8 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
aGridContainerFrame->SetProperty(UsedTrackSizes::Prop(), prop);
}
prop->mCanResolveLineRangeSize = {true, true};
- prop->mSizes[eLogicalAxisInline].Assign(mCols.mSizes);
- prop->mSizes[eLogicalAxisBlock].Assign(mRows.mSizes);
+ prop->mSizes[LogicalAxis::Inline].Assign(mCols.mSizes);
+ prop->mSizes[LogicalAxis::Block].Assign(mRows.mSizes);
}
// Copy item data from each child's first-in-flow data in mSharedGridData.
@@ -2921,18 +2925,19 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
mGridItems.AppendElement(GridItemInfo(child, itemInfo.mArea));
// Copy the item's baseline data so that the item's last fragment can
// do 'last baseline' alignment if necessary.
- item->mState[eLogicalAxisBlock] |=
- itemInfo.mState[eLogicalAxisBlock] & ItemState::eAllBaselineBits;
- item->mState[eLogicalAxisInline] |=
- itemInfo.mState[eLogicalAxisInline] & ItemState::eAllBaselineBits;
- item->mBaselineOffset[eLogicalAxisBlock] =
- itemInfo.mBaselineOffset[eLogicalAxisBlock];
- item->mBaselineOffset[eLogicalAxisInline] =
- itemInfo.mBaselineOffset[eLogicalAxisInline];
- item->mState[eLogicalAxisBlock] |=
- itemInfo.mState[eLogicalAxisBlock] & ItemState::eAutoPlacement;
- item->mState[eLogicalAxisInline] |=
- itemInfo.mState[eLogicalAxisInline] & ItemState::eAutoPlacement;
+ item->mState[LogicalAxis::Block] |=
+ itemInfo.mState[LogicalAxis::Block] & ItemState::eAllBaselineBits;
+ item->mState[LogicalAxis::Inline] |=
+ itemInfo.mState[LogicalAxis::Inline] &
+ ItemState::eAllBaselineBits;
+ item->mBaselineOffset[LogicalAxis::Block] =
+ itemInfo.mBaselineOffset[LogicalAxis::Block];
+ item->mBaselineOffset[LogicalAxis::Inline] =
+ itemInfo.mBaselineOffset[LogicalAxis::Inline];
+ item->mState[LogicalAxis::Block] |=
+ itemInfo.mState[LogicalAxis::Block] & ItemState::eAutoPlacement;
+ item->mState[LogicalAxis::Inline] |=
+ itemInfo.mState[LogicalAxis::Inline] & ItemState::eAutoPlacement;
break;
}
}
@@ -2975,7 +2980,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
/**
* Return the percentage basis for a grid item in its writing-mode.
- * If aAxis is eLogicalAxisInline then we return NS_UNCONSTRAINEDSIZE in
+ * If aAxis is LogicalAxis::Inline then we return NS_UNCONSTRAINEDSIZE in
* both axes since we know all track sizes are indefinite at this point
* (we calculate column sizes before row sizes). Otherwise, assert that
* column sizes are known and calculate the size for aGridItem.mArea.mCols
@@ -3218,10 +3223,10 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
}
Tracks& TracksFor(LogicalAxis aAxis) {
- return aAxis == eLogicalAxisBlock ? mRows : mCols;
+ return aAxis == LogicalAxis::Block ? mRows : mCols;
}
const Tracks& TracksFor(LogicalAxis aAxis) const {
- return aAxis == eLogicalAxisBlock ? mRows : mCols;
+ return aAxis == LogicalAxis::Block ? mRows : mCols;
}
CSSOrderAwareFrameIterator mIter;
@@ -3275,13 +3280,13 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
const nsStylePosition* aGridStyle, const WritingMode& aWM)
: mIter(aFrame, FrameChildListID::Principal),
mGridStyle(aGridStyle),
- mCols(eLogicalAxisInline),
- mRows(eLogicalAxisBlock),
+ mCols(LogicalAxis::Inline),
+ mRows(LogicalAxis::Block),
mColFunctions(mGridStyle->mGridTemplateColumns,
mGridStyle->mGridAutoColumns,
- aFrame->IsSubgrid(eLogicalAxisInline)),
+ aFrame->IsSubgrid(LogicalAxis::Inline)),
mRowFunctions(mGridStyle->mGridTemplateRows, mGridStyle->mGridAutoRows,
- aFrame->IsSubgrid(eLogicalAxisBlock)),
+ aFrame->IsSubgrid(LogicalAxis::Block)),
mReflowInput(aReflowInput),
mRenderingContext(aRenderingContext),
mFrame(aFrame),
@@ -3299,8 +3304,8 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
mSkipSides = aFrame->PreReflowBlockLevelLogicalSkipSides();
mBorderPadding.ApplySkipSides(mSkipSides);
}
- mCols.mIsMasonry = aFrame->IsMasonry(eLogicalAxisInline);
- mRows.mIsMasonry = aFrame->IsMasonry(eLogicalAxisBlock);
+ mCols.mIsMasonry = aFrame->IsMasonry(LogicalAxis::Inline);
+ mRows.mIsMasonry = aFrame->IsMasonry(LogicalAxis::Block);
MOZ_ASSERT(!(mCols.mIsMasonry && mRows.mIsMasonry),
"can't have masonry layout in both axes");
}
@@ -3463,7 +3468,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::Grid {
* @param aFromIndex the zero-based index to start counting from
* @param aLineNameList the explicit named lines
* @param aSide the axis+edge we're resolving names for (e.g. if we're
- resolving a grid-row-start line, pass eLogicalSideBStart)
+ resolving a grid-row-start line, pass LogicalSide::BStart)
* @param aExplicitGridEnd the last line in the explicit grid
* @param aStyle the StylePosition() for the grid container
* @return a definite line (1-based), clamped to
@@ -3546,7 +3551,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::Grid {
if (!mParentGrid) {
return nullptr;
}
- bool isRows = aIsOrthogonal == (aAxis == eLogicalAxisInline);
+ bool isRows = aIsOrthogonal == (aAxis == LogicalAxis::Inline);
return isRows ? mParentGrid->mRowNameMap : mParentGrid->mColNameMap;
}
@@ -3684,38 +3689,56 @@ static Subgrid* SubgridComputeMarginBorderPadding(
SizeComputationInput sz(subgridFrame, nullptr, cbWM, pmPercentageBasis);
subgrid->mMarginBorderPadding =
sz.ComputedLogicalMargin(cbWM) + sz.ComputedLogicalBorderPadding(cbWM);
+ if (aGridItem.mFrame == subgridFrame) {
+ return subgrid;
+ }
- if (aGridItem.mFrame != subgridFrame) {
- nsHTMLScrollFrame* scrollFrame =
- do_QueryFrame(aGridItem.mFrame->GetScrollTargetFrame());
- if (scrollFrame) {
- MOZ_ASSERT(
- sz.ComputedLogicalMargin(cbWM) == LogicalMargin(cbWM) &&
- sz.ComputedLogicalBorder(cbWM) == LogicalMargin(cbWM),
- "A scrolled inner frame should not have any margin or border!");
-
- // Add the margin and border from the (outer) scroll frame.
- SizeComputationInput szScrollFrame(aGridItem.mFrame, nullptr, cbWM,
- pmPercentageBasis);
- subgrid->mMarginBorderPadding +=
- szScrollFrame.ComputedLogicalMargin(cbWM) +
- szScrollFrame.ComputedLogicalBorder(cbWM);
-
- nsMargin ssz = scrollFrame->IntrinsicScrollbarGutterSize();
+ bool scroller = false;
+ nsIFrame* outerFrame = [&]() -> nsIFrame* {
+ if (nsHTMLScrollFrame* scrollFrame =
+ do_QueryFrame(aGridItem.mFrame->GetScrollTargetFrame())) {
+ scroller = true;
+ return scrollFrame;
+ }
+ if (nsHTMLButtonControlFrame* f = do_QueryFrame(aGridItem.mFrame)) {
+ return f;
+ }
+ return nullptr;
+ }();
+
+ if (outerFrame) {
+ MOZ_ASSERT(sz.ComputedLogicalMargin(cbWM) == LogicalMargin(cbWM) &&
+ sz.ComputedLogicalBorder(cbWM) == LogicalMargin(cbWM),
+ "A scrolled inner frame / button content frame "
+ "should not have any margin or border / padding!");
+
+ // Add the margin and border from the (outer) frame. Padding is factored-in
+ // for scrollers already (except for the scrollbar gutter), but not for
+ // button-content.
+ SizeComputationInput szOuterFrame(outerFrame, nullptr, cbWM,
+ pmPercentageBasis);
+ subgrid->mMarginBorderPadding += szOuterFrame.ComputedLogicalMargin(cbWM) +
+ szOuterFrame.ComputedLogicalBorder(cbWM);
+ if (scroller) {
+ nsMargin ssz = static_cast<nsHTMLScrollFrame*>(outerFrame)
+ ->IntrinsicScrollbarGutterSize();
subgrid->mMarginBorderPadding += LogicalMargin(cbWM, ssz);
+ } else {
+ subgrid->mMarginBorderPadding +=
+ szOuterFrame.ComputedLogicalPadding(cbWM);
}
+ }
- if (aGridItem.mFrame->IsFieldSetFrame()) {
- const auto* f = static_cast<nsFieldSetFrame*>(aGridItem.mFrame);
- const auto* inner = f->GetInner();
- auto wm = inner->GetWritingMode();
- LogicalPoint pos = inner->GetLogicalPosition(aGridItem.mFrame->GetSize());
- // The legend is always on the BStart side and it inflates the fieldset's
- // "border area" size. The inner frame's b-start pos equals that size.
- LogicalMargin offsets(wm, pos.B(wm), 0, 0, 0);
- subgrid->mMarginBorderPadding += offsets.ConvertTo(cbWM, wm);
- }
+ if (nsFieldSetFrame* f = do_QueryFrame(aGridItem.mFrame)) {
+ const auto* inner = f->GetInner();
+ auto wm = inner->GetWritingMode();
+ LogicalPoint pos = inner->GetLogicalPosition(aGridItem.mFrame->GetSize());
+ // The legend is always on the BStart side and it inflates the fieldset's
+ // "border area" size. The inner frame's b-start pos equals that size.
+ LogicalMargin offsets(wm, pos.B(wm), 0, 0, 0);
+ subgrid->mMarginBorderPadding += offsets.ConvertTo(cbWM, wm);
}
+
return subgrid;
}
@@ -3727,8 +3750,9 @@ static void CopyUsedTrackSizes(nsTArray<TrackSize>& aResult,
LogicalAxis aSubgridAxis) {
MOZ_ASSERT(aSubgridFrame->ParentGridContainerForSubgrid() ==
aUsedTrackSizesFrame);
- aResult.SetLength(aSubgridAxis == eLogicalAxisInline ? aSubgrid->mGridColEnd
- : aSubgrid->mGridRowEnd);
+ aResult.SetLength(aSubgridAxis == LogicalAxis::Inline
+ ? aSubgrid->mGridColEnd
+ : aSubgrid->mGridRowEnd);
auto parentAxis =
aSubgrid->mIsOrthogonal ? GetOrthogonalAxis(aSubgridAxis) : aSubgridAxis;
const auto& parentSizes = aUsedTrackSizes->mSizes[parentAxis];
@@ -3740,7 +3764,7 @@ static void CopyUsedTrackSizes(nsTArray<TrackSize>& aResult,
const auto cbwm = aUsedTrackSizesFrame->GetWritingMode();
const auto wm = aSubgridFrame->GetWritingMode();
// Recompute the MBP to resolve percentages against the resolved track sizes.
- if (parentAxis == eLogicalAxisInline) {
+ if (parentAxis == LogicalAxis::Inline) {
// Find the subgrid's grid item frame in its parent grid container. This
// is usually the same as aSubgridFrame but it may also have a ScrollFrame,
// FieldSetFrame etc. We just loop until we see the first ancestor
@@ -3856,7 +3880,7 @@ void nsGridContainerFrame::UsedTrackSizes::ResolveSubgridTrackSizesForAxis(
grid.mGridRowEnd = aSubgrid->mGridRowEnd;
state.CalculateTrackSizesForAxis(aAxis, grid, aContentBoxSize,
SizingConstraint::NoConstraint);
- const auto& tracks = aAxis == eLogicalAxisInline ? state.mCols : state.mRows;
+ const auto& tracks = aAxis == LogicalAxis::Inline ? state.mCols : state.mRows;
mSizes[aAxis].Assign(tracks.mSizes);
mCanResolveLineRangeSize[aAxis] = tracks.mCanResolveLineRangeSize;
MOZ_ASSERT(mCanResolveLineRangeSize[aAxis]);
@@ -3865,11 +3889,11 @@ void nsGridContainerFrame::UsedTrackSizes::ResolveSubgridTrackSizesForAxis(
void nsGridContainerFrame::GridReflowInput::CalculateTrackSizesForAxis(
LogicalAxis aAxis, const Grid& aGrid, nscoord aContentBoxSize,
SizingConstraint aConstraint) {
- auto& tracks = aAxis == eLogicalAxisInline ? mCols : mRows;
+ auto& tracks = aAxis == LogicalAxis::Inline ? mCols : mRows;
const auto& sizingFunctions =
- aAxis == eLogicalAxisInline ? mColFunctions : mRowFunctions;
- const auto& gapStyle = aAxis == eLogicalAxisInline ? mGridStyle->mColumnGap
- : mGridStyle->mRowGap;
+ aAxis == LogicalAxis::Inline ? mColFunctions : mRowFunctions;
+ const auto& gapStyle = aAxis == LogicalAxis::Inline ? mGridStyle->mColumnGap
+ : mGridStyle->mRowGap;
if (tracks.mIsMasonry) {
// See comment on nsGridContainerFrame::MasonryLayout().
tracks.Initialize(sizingFunctions, gapStyle, 2, aContentBoxSize);
@@ -3877,7 +3901,7 @@ void nsGridContainerFrame::GridReflowInput::CalculateTrackSizesForAxis(
return;
}
uint32_t gridEnd =
- aAxis == eLogicalAxisInline ? aGrid.mGridColEnd : aGrid.mGridRowEnd;
+ aAxis == LogicalAxis::Inline ? aGrid.mGridColEnd : aGrid.mGridRowEnd;
Maybe<TrackSizingFunctions> fallbackTrackSizing;
bool useParentGaps = false;
@@ -3919,7 +3943,7 @@ void nsGridContainerFrame::GridReflowInput::CalculateTrackSizesForAxis(
*this, mGridItems,
fallbackTrackSizing ? *fallbackTrackSizing : sizingFunctions,
aContentBoxSize,
- aAxis == eLogicalAxisInline ? &GridArea::mCols : &GridArea::mRows,
+ aAxis == LogicalAxis::Inline ? &GridArea::mCols : &GridArea::mRows,
aConstraint);
if (hasSubgridItems &&
@@ -3976,9 +4000,9 @@ void nsGridContainerFrame::GridReflowInput::CalculateTrackSizesForAxis(
void nsGridContainerFrame::GridReflowInput::CalculateTrackSizes(
const Grid& aGrid, const LogicalSize& aContentBox,
SizingConstraint aConstraint) {
- CalculateTrackSizesForAxis(eLogicalAxisInline, aGrid, aContentBox.ISize(mWM),
+ CalculateTrackSizesForAxis(LogicalAxis::Inline, aGrid, aContentBox.ISize(mWM),
aConstraint);
- CalculateTrackSizesForAxis(eLogicalAxisBlock, aGrid, aContentBox.BSize(mWM),
+ CalculateTrackSizesForAxis(LogicalAxis::Block, aGrid, aContentBox.BSize(mWM),
aConstraint);
}
@@ -3999,7 +4023,7 @@ static void AlignJustifySelf(StyleAlignFlags aAlignment, LogicalAxis aAxis,
// Set the position (aPos) for the requested alignment.
if (offset != 0) {
WritingMode wm = aRI.GetWritingMode();
- nscoord& pos = aAxis == eLogicalAxisBlock ? aPos->B(wm) : aPos->I(wm);
+ nscoord& pos = aAxis == LogicalAxis::Block ? aPos->B(wm) : aPos->I(wm);
pos += MOZ_LIKELY(aFlags & AlignJustifyFlags::SameSide) ? offset : -offset;
}
}
@@ -4016,7 +4040,7 @@ static void AlignSelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
aAlignSelf &= ~StyleAlignFlags::FLAG_BITS;
WritingMode childWM = aRI.GetWritingMode();
- if (aCBWM.ParallelAxisStartsOnSameSide(eLogicalAxisBlock, childWM)) {
+ if (aCBWM.ParallelAxisStartsOnSameSide(LogicalAxis::Block, childWM)) {
flags |= AlignJustifyFlags::SameSide;
}
@@ -4032,12 +4056,12 @@ static void AlignSelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
nscoord baselineAdjust = 0;
if (aAlignSelf == StyleAlignFlags::BASELINE ||
aAlignSelf == StyleAlignFlags::LAST_BASELINE) {
- aAlignSelf = aGridItem.GetSelfBaseline(aAlignSelf, eLogicalAxisBlock,
+ aAlignSelf = aGridItem.GetSelfBaseline(aAlignSelf, LogicalAxis::Block,
&baselineAdjust);
}
bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
- LogicalAxis axis = isOrthogonal ? eLogicalAxisInline : eLogicalAxisBlock;
+ LogicalAxis axis = isOrthogonal ? LogicalAxis::Inline : LogicalAxis::Block;
AlignJustifySelf(aAlignSelf, axis, flags, baselineAdjust, aCBSize, aRI, aSize,
aPos);
}
@@ -4054,7 +4078,7 @@ static void JustifySelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
aJustifySelf &= ~StyleAlignFlags::FLAG_BITS;
WritingMode childWM = aRI.GetWritingMode();
- if (aCBWM.ParallelAxisStartsOnSameSide(eLogicalAxisInline, childWM)) {
+ if (aCBWM.ParallelAxisStartsOnSameSide(LogicalAxis::Inline, childWM)) {
flags |= AlignJustifyFlags::SameSide;
}
@@ -4073,12 +4097,12 @@ static void JustifySelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
aCBWM.IsBidiLTR() ? StyleAlignFlags::END : StyleAlignFlags::START;
} else if (aJustifySelf == StyleAlignFlags::BASELINE ||
aJustifySelf == StyleAlignFlags::LAST_BASELINE) {
- aJustifySelf = aGridItem.GetSelfBaseline(aJustifySelf, eLogicalAxisInline,
+ aJustifySelf = aGridItem.GetSelfBaseline(aJustifySelf, LogicalAxis::Inline,
&baselineAdjust);
}
bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
- LogicalAxis axis = isOrthogonal ? eLogicalAxisBlock : eLogicalAxisInline;
+ LogicalAxis axis = isOrthogonal ? LogicalAxis::Block : LogicalAxis::Inline;
AlignJustifySelf(aJustifySelf, axis, flags, baselineAdjust, aCBSize, aRI,
aSize, aPos);
}
@@ -4245,8 +4269,8 @@ void nsGridContainerFrame::InitImplicitNamedAreas(
AddImplicitNamedAreas(aTemplate.AsSubgrid()->line_names.AsSpan());
}
};
- Add(aStyle->mGridTemplateColumns, IsSubgrid(eLogicalAxisInline));
- Add(aStyle->mGridTemplateRows, IsSubgrid(eLogicalAxisBlock));
+ Add(aStyle->mGridTemplateColumns, IsSubgrid(LogicalAxis::Inline));
+ Add(aStyle->mGridTemplateRows, IsSubgrid(LogicalAxis::Block));
if (areas && areas->count() == 0) {
RemoveProperty(ImplicitNamedAreasProperty());
}
@@ -4485,10 +4509,10 @@ nsGridContainerFrame::GridArea nsGridContainerFrame::Grid::PlaceDefinite(
const nsStylePosition* itemStyle = aChild->StylePosition();
return GridArea(
ResolveLineRange(itemStyle->mGridColumnStart, itemStyle->mGridColumnEnd,
- aColLineNameMap, eLogicalAxisInline, mExplicitGridColEnd,
- aStyle),
+ aColLineNameMap, LogicalAxis::Inline,
+ mExplicitGridColEnd, aStyle),
ResolveLineRange(itemStyle->mGridRowStart, itemStyle->mGridRowEnd,
- aRowLineNameMap, eLogicalAxisBlock, mExplicitGridRowEnd,
+ aRowLineNameMap, LogicalAxis::Block, mExplicitGridRowEnd,
aStyle));
}
@@ -4548,11 +4572,11 @@ nsGridContainerFrame::GridArea nsGridContainerFrame::Grid::PlaceAbsPos(
int32_t gridRowStart = 1 - mExplicitGridOffsetRow;
return GridArea(ResolveAbsPosLineRange(
itemStyle->mGridColumnStart, itemStyle->mGridColumnEnd,
- aColLineNameMap, eLogicalAxisInline, mExplicitGridColEnd,
+ aColLineNameMap, LogicalAxis::Inline, mExplicitGridColEnd,
gridColStart, mGridColEnd, aStyle),
ResolveAbsPosLineRange(
itemStyle->mGridRowStart, itemStyle->mGridRowEnd,
- aRowLineNameMap, eLogicalAxisBlock, mExplicitGridRowEnd,
+ aRowLineNameMap, LogicalAxis::Block, mExplicitGridRowEnd,
gridRowStart, mGridRowEnd, aStyle));
}
@@ -4736,10 +4760,10 @@ void nsGridContainerFrame::Grid::SubgridPlaceGridItems(
MOZ_ASSERT(aGridItem.mArea.IsDefinite() ||
aGridItem.mFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW),
"the subgrid's lines should be resolved by now");
- if (aGridItem.IsSubgrid(eLogicalAxisInline)) {
+ if (aGridItem.IsSubgrid(LogicalAxis::Inline)) {
aParentState.mFrame->AddStateBits(NS_STATE_GRID_HAS_COL_SUBGRID_ITEM);
}
- if (aGridItem.IsSubgrid(eLogicalAxisBlock)) {
+ if (aGridItem.IsSubgrid(LogicalAxis::Block)) {
aParentState.mFrame->AddStateBits(NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM);
}
auto* childGrid = aGridItem.SubgridFrame();
@@ -4787,11 +4811,11 @@ void nsGridContainerFrame::Grid::SubgridPlaceGridItems(
// computing them otherwise.
RepeatTrackSizingInput repeatSizing(state.mWM);
if (!childGrid->IsColSubgrid() && state.mColFunctions.mHasRepeatAuto) {
- repeatSizing.InitFromStyle(eLogicalAxisInline, state.mWM,
+ repeatSizing.InitFromStyle(LogicalAxis::Inline, state.mWM,
state.mFrame->Style());
}
if (!childGrid->IsRowSubgrid() && state.mRowFunctions.mHasRepeatAuto) {
- repeatSizing.InitFromStyle(eLogicalAxisBlock, state.mWM,
+ repeatSizing.InitFromStyle(LogicalAxis::Block, state.mWM,
state.mFrame->Style());
}
@@ -4812,8 +4836,8 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
if (aState.mFrame->HasSubgridItems() || aState.mFrame->IsSubgrid()) {
if (auto* uts = aState.mFrame->GetUsedTrackSizes()) {
uts->mCanResolveLineRangeSize = {false, false};
- uts->mSizes[eLogicalAxisInline].ClearAndRetainStorage();
- uts->mSizes[eLogicalAxisBlock].ClearAndRetainStorage();
+ uts->mSizes[LogicalAxis::Inline].ClearAndRetainStorage();
+ uts->mSizes[LogicalAxis::Block].ClearAndRetainStorage();
}
}
@@ -4847,11 +4871,11 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
uint32_t extent = subgridRange->Extent();
mExplicitGridColEnd = extent + 1; // the grid is 1-based at this point
parentLineNameMap =
- ParentLineMapForAxis(subgrid->mIsOrthogonal, eLogicalAxisInline);
+ ParentLineMapForAxis(subgrid->mIsOrthogonal, LogicalAxis::Inline);
auto parentWM =
aState.mFrame->ParentGridContainerForSubgrid()->GetWritingMode();
subgridAxisIsSameDirection =
- aState.mWM.ParallelAxisStartsOnSameSide(eLogicalAxisInline, parentWM);
+ aState.mWM.ParallelAxisStartsOnSameSide(LogicalAxis::Inline, parentWM);
}
mGridColEnd = mExplicitGridColEnd;
LineNameMap colLineNameMap(gridStyle, mAreas, aState.mColFunctions,
@@ -4882,11 +4906,11 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
uint32_t extent = subgridRange->Extent();
mExplicitGridRowEnd = extent + 1; // the grid is 1-based at this point
parentLineNameMap =
- ParentLineMapForAxis(subgrid->mIsOrthogonal, eLogicalAxisBlock);
+ ParentLineMapForAxis(subgrid->mIsOrthogonal, LogicalAxis::Block);
auto parentWM =
aState.mFrame->ParentGridContainerForSubgrid()->GetWritingMode();
subgridAxisIsSameDirection =
- aState.mWM.ParallelAxisStartsOnSameSide(eLogicalAxisBlock, parentWM);
+ aState.mWM.ParallelAxisStartsOnSameSide(LogicalAxis::Block, parentWM);
}
mGridRowEnd = mExplicitGridRowEnd;
LineNameMap rowLineNameMap(gridStyle, mAreas, aState.mRowFunctions,
@@ -4900,16 +4924,16 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
if (isSubgridOrItemInSubgrid) {
const auto& area = aItem.mArea;
if (area.mCols.mStart == 0) {
- aItem.mState[eLogicalAxisInline] |= ItemState::eStartEdge;
+ aItem.mState[LogicalAxis::Inline] |= ItemState::eStartEdge;
}
if (area.mCols.mEnd == mGridColEnd) {
- aItem.mState[eLogicalAxisInline] |= ItemState::eEndEdge;
+ aItem.mState[LogicalAxis::Inline] |= ItemState::eEndEdge;
}
if (area.mRows.mStart == 0) {
- aItem.mState[eLogicalAxisBlock] |= ItemState::eStartEdge;
+ aItem.mState[LogicalAxis::Block] |= ItemState::eStartEdge;
}
if (area.mRows.mEnd == mGridRowEnd) {
- aItem.mState[eLogicalAxisBlock] |= ItemState::eEndEdge;
+ aItem.mState[LogicalAxis::Block] |= ItemState::eEndEdge;
}
}
};
@@ -4945,8 +4969,8 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
aState.mRowFunctions.mExplicitGridOffset = mExplicitGridOffsetRow;
const int32_t offsetToColZero = int32_t(mExplicitGridOffsetCol) - 1;
const int32_t offsetToRowZero = int32_t(mExplicitGridOffsetRow) - 1;
- const bool isRowMasonry = aState.mFrame->IsMasonry(eLogicalAxisBlock);
- const bool isColMasonry = aState.mFrame->IsMasonry(eLogicalAxisInline);
+ const bool isRowMasonry = aState.mFrame->IsMasonry(LogicalAxis::Block);
+ const bool isColMasonry = aState.mFrame->IsMasonry(LogicalAxis::Inline);
const bool isMasonry = isColMasonry || isRowMasonry;
mGridColEnd += offsetToColZero;
mGridRowEnd += offsetToRowZero;
@@ -5100,7 +5124,7 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
// Force all items into the 1st/2nd track and have span 1 in the masonry axis.
// (See comment on nsGridContainerFrame::MasonryLayout().)
if (isMasonry) {
- auto masonryAxis = isRowMasonry ? eLogicalAxisBlock : eLogicalAxisInline;
+ auto masonryAxis = isRowMasonry ? LogicalAxis::Block : LogicalAxis::Inline;
aState.mIter.Reset();
for (; !aState.mIter.AtEnd(); aState.mIter.Next()) {
auto& item = aState.mGridItems[aState.mIter.ItemIndex()];
@@ -5168,16 +5192,16 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
// An abs.pos. subgrid with placement auto/1 or -1/auto technically
// doesn't span any parent tracks. Inhibit subgridding in this case.
- if (info->IsSubgrid(eLogicalAxisInline)) {
+ if (info->IsSubgrid(LogicalAxis::Inline)) {
if (info->mArea.mCols.mStart == zeroOffsetGridColEnd.SavedValue() ||
info->mArea.mCols.mEnd == 0) {
- info->InhibitSubgrid(aState.mFrame, eLogicalAxisInline);
+ info->InhibitSubgrid(aState.mFrame, LogicalAxis::Inline);
}
}
- if (info->IsSubgrid(eLogicalAxisBlock)) {
+ if (info->IsSubgrid(LogicalAxis::Block)) {
if (info->mArea.mRows.mStart == zeroOffsetGridRowEnd.SavedValue() ||
info->mArea.mRows.mEnd == 0) {
- info->InhibitSubgrid(aState.mFrame, eLogicalAxisBlock);
+ info->InhibitSubgrid(aState.mFrame, LogicalAxis::Block);
}
}
@@ -5219,18 +5243,18 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
// Adjust the line numbers in the grid areas.
for (auto& item : aState.mGridItems) {
if (numEmptyCols) {
- item.AdjustForRemovedTracks(eLogicalAxisInline, *colAdjust);
+ item.AdjustForRemovedTracks(LogicalAxis::Inline, *colAdjust);
}
if (numEmptyRows) {
- item.AdjustForRemovedTracks(eLogicalAxisBlock, *rowAdjust);
+ item.AdjustForRemovedTracks(LogicalAxis::Block, *rowAdjust);
}
}
for (auto& item : aState.mAbsPosItems) {
if (numEmptyCols) {
- item.AdjustForRemovedTracks(eLogicalAxisInline, *colAdjust);
+ item.AdjustForRemovedTracks(LogicalAxis::Inline, *colAdjust);
}
if (numEmptyRows) {
- item.AdjustForRemovedTracks(eLogicalAxisBlock, *rowAdjust);
+ item.AdjustForRemovedTracks(LogicalAxis::Block, *rowAdjust);
}
}
// Adjust the grid size.
@@ -5258,11 +5282,11 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
LineRange columnLines =
ResolveLineRange(lineStartAndEnd, lineStartAndEnd, colLineNameMap,
- eLogicalAxisInline, mExplicitGridColEnd, gridStyle);
+ LogicalAxis::Inline, mExplicitGridColEnd, gridStyle);
LineRange rowLines =
ResolveLineRange(lineStartAndEnd, lineStartAndEnd, rowLineNameMap,
- eLogicalAxisBlock, mExplicitGridRowEnd, gridStyle);
+ LogicalAxis::Block, mExplicitGridRowEnd, gridStyle);
// Put the resolved line indices back into the area structure.
areaInfo.columns.start = columnLines.mStart + mExplicitGridOffsetCol;
@@ -5322,7 +5346,7 @@ static nscoord MeasuringReflow(nsIFrame* aChild,
ComputeSizeFlags csFlags = ComputeSizeFlag::IsGridMeasuringReflow;
// Shrink-wrap grid items that will be aligned (rather than stretched) in
// their own inline axis.
- if (!parent->GridItemShouldStretch(aChild, eLogicalAxisInline)) {
+ if (!parent->GridItemShouldStretch(aChild, LogicalAxis::Inline)) {
csFlags += ComputeSizeFlag::ShrinkWrap;
}
if (aAvailableSize.ISize(wm) == INFINITE_ISIZE_COORD) {
@@ -5434,7 +5458,7 @@ static void PostReflowStretchChild(
}
ReflowInput ri(pc, aReflowInput, aChild, aAvailableSize, Some(aCBSize), {},
{}, csFlags);
- if (aChildAxis == eLogicalAxisBlock) {
+ if (aChildAxis == LogicalAxis::Block) {
ri.SetComputedBSize(ri.ApplyMinMaxBSize(aNewContentBoxSize));
} else {
ri.SetComputedISize(ri.ApplyMinMaxISize(aNewContentBoxSize));
@@ -5542,18 +5566,18 @@ static nscoord ContentContribution(
auto subgridAxis = aCBWM.IsOrthogonalTo(subgridFrame->GetWritingMode())
? GetOrthogonalAxis(aAxis)
: aAxis;
- auto& gapStyle = subgridAxis == eLogicalAxisBlock
+ auto& gapStyle = subgridAxis == LogicalAxis::Block
? subgridFrame->StylePosition()->mRowGap
: subgridFrame->StylePosition()->mColumnGap;
if (!gapStyle.IsNormal()) {
- auto subgridExtent = subgridAxis == eLogicalAxisBlock
+ auto subgridExtent = subgridAxis == LogicalAxis::Block
? subgrid->mGridRowEnd
: subgrid->mGridColEnd;
if (subgridExtent > 1) {
nscoord subgridGap =
nsLayoutUtils::ResolveGapToLength(gapStyle, NS_UNCONSTRAINEDSIZE);
auto& tracks =
- aAxis == eLogicalAxisBlock ? aState.mRows : aState.mCols;
+ aAxis == LogicalAxis::Block ? aState.mRows : aState.mCols;
auto gapDelta = subgridGap - tracks.mGridGap;
if (!itemEdgeBits) {
extraMargin += gapDelta;
@@ -5572,7 +5596,7 @@ static nscoord ContentContribution(
auto childWM = child->GetWritingMode();
const bool isOrthogonal = childWM.IsOrthogonalTo(aCBWM);
auto childAxis = isOrthogonal ? GetOrthogonalAxis(aAxis) : aAxis;
- if (size == NS_INTRINSIC_ISIZE_UNKNOWN && childAxis == eLogicalAxisBlock) {
+ if (size == NS_INTRINSIC_ISIZE_UNKNOWN && childAxis == LogicalAxis::Block) {
// We need to reflow the child to find its BSize contribution.
// XXX this will give mostly correct results for now (until bug 1174569).
nscoord availISize = INFINITE_ISIZE_COORD;
@@ -5595,8 +5619,8 @@ static nscoord ContentContribution(
}
// The grid-item's inline-axis as expressed in the subgrid's WM.
auto subgridAxis = childWM.IsOrthogonalTo(subgridFrame->GetWritingMode())
- ? eLogicalAxisBlock
- : eLogicalAxisInline;
+ ? LogicalAxis::Block
+ : LogicalAxis::Inline;
uts->ResolveTrackSizesForAxis(subgridFrame, subgridAxis, *aRC);
if (uts->mCanResolveLineRangeSize[subgridAxis]) {
auto* subgrid =
@@ -5642,7 +5666,7 @@ static nscoord ContentContribution(
}
}
}
- if (isOrthogonal == (aAxis == eLogicalAxisInline)) {
+ if (isOrthogonal == (aAxis == LogicalAxis::Inline)) {
bMinSizeClamp = aMinSizeClamp;
} else {
iMinSizeClamp = aMinSizeClamp;
@@ -5739,7 +5763,8 @@ static nscoord MinSize(const GridItemInfo& aGridItem,
StyleSize sizeStyle =
axis == eAxisHorizontal ? stylePos->mWidth : stylePos->mHeight;
- auto ourInlineAxis = child->GetWritingMode().PhysicalAxis(eLogicalAxisInline);
+ auto ourInlineAxis =
+ child->GetWritingMode().PhysicalAxis(LogicalAxis::Inline);
// max-content and min-content should behave as initial value in block axis.
// FIXME: Bug 567039: moz-fit-content and -moz-available are not supported
// for block size dimension on sizing properties (e.g. height), so we
@@ -6006,7 +6031,7 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselines(
const auto childWM = child->GetWritingMode();
const bool isOrthogonal = containerWM.IsOrthogonalTo(childWM);
- const bool isInlineAxis = mAxis == eLogicalAxisInline; // i.e. columns
+ const bool isInlineAxis = mAxis == LogicalAxis::Inline; // i.e. columns
// XXX update the line below to include orthogonal grid/table boxes
// XXX since they have baselines in both dimensions. And flexbox with
@@ -6281,7 +6306,7 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselinesInMasonryAxis(
auto state = ItemState(0);
auto childWM = child->GetWritingMode();
const bool isOrthogonal = wm.IsOrthogonalTo(childWM);
- const bool isInlineAxis = mAxis == eLogicalAxisInline; // i.e. columns
+ const bool isInlineAxis = mAxis == LogicalAxis::Inline; // i.e. columns
// XXX update the line below to include orthogonal grid/table boxes
// XXX since they have baselines in both dimensions. And flexbox with
// XXX reversed main/cross axis?
@@ -6449,10 +6474,10 @@ void nsGridContainerFrame::Tracks::AlignBaselineSubtree(
const bool isFirstBaseline = state & ItemState::eFirstBaseline;
if (isFirstBaseline) {
baselineTrack =
- mAxis == eLogicalAxisBlock ? area.mRows.mStart : area.mCols.mStart;
+ mAxis == LogicalAxis::Block ? area.mRows.mStart : area.mCols.mStart;
} else {
baselineTrack =
- (mAxis == eLogicalAxisBlock ? area.mRows.mEnd : area.mCols.mEnd) - 1;
+ (mAxis == LogicalAxis::Block ? area.mRows.mEnd : area.mCols.mEnd) - 1;
}
const TrackSize& sz = mSizes[baselineTrack];
auto baselineGroup = isFirstBaseline ? BaselineSharingGroup::First
@@ -6855,7 +6880,7 @@ float nsGridContainerFrame::Tracks::FindUsedFlexFraction(
nscoord spaceToFill = ContentContribution(item, aState, rc, wm, mAxis, pb,
IntrinsicISizeType::PrefISize);
const LineRange& range =
- mAxis == eLogicalAxisInline ? item.mArea.mCols : item.mArea.mRows;
+ mAxis == LogicalAxis::Inline ? item.mArea.mCols : item.mArea.mRows;
MOZ_ASSERT(range.Extent() >= 1);
const auto spannedGaps = range.Extent() - 1;
if (spannedGaps > 0) {
@@ -6898,10 +6923,10 @@ void nsGridContainerFrame::Tracks::StretchFlexibleTracks(
nscoord maxSize = NS_UNCONSTRAINEDSIZE;
if (aState.mReflowInput) {
auto* ri = aState.mReflowInput;
- minSize = mAxis == eLogicalAxisBlock ? ri->ComputedMinBSize()
- : ri->ComputedMinISize();
- maxSize = mAxis == eLogicalAxisBlock ? ri->ComputedMaxBSize()
- : ri->ComputedMaxISize();
+ minSize = mAxis == LogicalAxis::Block ? ri->ComputedMinBSize()
+ : ri->ComputedMinISize();
+ maxSize = mAxis == LogicalAxis::Block ? ri->ComputedMaxBSize()
+ : ri->ComputedMaxISize();
}
Maybe<CopyableAutoTArray<TrackSize, 32>> origSizes;
bool applyMinMax = (minSize != 0 || maxSize != NS_UNCONSTRAINEDSIZE) &&
@@ -6958,7 +6983,7 @@ void nsGridContainerFrame::Tracks::StretchFlexibleTracks(
void nsGridContainerFrame::Tracks::AlignJustifyContent(
const nsStylePosition* aStyle, StyleContentDistribution aAligmentStyleValue,
WritingMode aWM, nscoord aContentBoxSize, bool aIsSubgriddedAxis) {
- const bool isAlign = mAxis == eLogicalAxisBlock;
+ const bool isAlign = mAxis == LogicalAxis::Block;
// Align-/justify-content doesn't apply in a subgridded axis.
// Gap properties do apply though so we need to stretch/position the tracks
// to center-align the gaps with the parent's gaps.
@@ -7223,25 +7248,25 @@ LogicalSize nsGridContainerFrame::GridReflowInput::PercentageBasisFor(
if (auto* uts = subgridFrame->GetUsedTrackSizes()) {
auto subgridWM = subgridFrame->GetWritingMode();
LogicalSize cbSize(subgridWM, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
- if (!subgridFrame->IsSubgrid(eLogicalAxisInline) &&
- uts->mCanResolveLineRangeSize[eLogicalAxisInline]) {
+ if (!subgridFrame->IsSubgrid(LogicalAxis::Inline) &&
+ uts->mCanResolveLineRangeSize[LogicalAxis::Inline]) {
// NOTE: At this point aGridItem.mArea is in this->mFrame coordinates
// and thus may have been transposed. The range values in a non-
// subgridded axis still has its original values in subgridFrame's
// coordinates though.
- auto rangeAxis = subgridWM.IsOrthogonalTo(mWM) ? eLogicalAxisBlock
- : eLogicalAxisInline;
+ auto rangeAxis = subgridWM.IsOrthogonalTo(mWM) ? LogicalAxis::Block
+ : LogicalAxis::Inline;
const auto& range = aGridItem.mArea.LineRangeForAxis(rangeAxis);
cbSize.ISize(subgridWM) =
- range.ToLength(uts->mSizes[eLogicalAxisInline]);
+ range.ToLength(uts->mSizes[LogicalAxis::Inline]);
}
- if (!subgridFrame->IsSubgrid(eLogicalAxisBlock) &&
- uts->mCanResolveLineRangeSize[eLogicalAxisBlock]) {
- auto rangeAxis = subgridWM.IsOrthogonalTo(mWM) ? eLogicalAxisInline
- : eLogicalAxisBlock;
+ if (!subgridFrame->IsSubgrid(LogicalAxis::Block) &&
+ uts->mCanResolveLineRangeSize[LogicalAxis::Block]) {
+ auto rangeAxis = subgridWM.IsOrthogonalTo(mWM) ? LogicalAxis::Inline
+ : LogicalAxis::Block;
const auto& range = aGridItem.mArea.LineRangeForAxis(rangeAxis);
cbSize.BSize(subgridWM) =
- range.ToLength(uts->mSizes[eLogicalAxisBlock]);
+ range.ToLength(uts->mSizes[LogicalAxis::Block]);
}
return cbSize.ConvertTo(wm, subgridWM);
}
@@ -7249,7 +7274,7 @@ LogicalSize nsGridContainerFrame::GridReflowInput::PercentageBasisFor(
return LogicalSize(wm, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
- if (aAxis == eLogicalAxisInline || !mCols.mCanResolveLineRangeSize) {
+ if (aAxis == LogicalAxis::Inline || !mCols.mCanResolveLineRangeSize) {
return LogicalSize(wm, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
// Note: for now, we only resolve transferred percentages to row sizing.
@@ -7428,7 +7453,7 @@ void nsGridContainerFrame::GridReflowInput::AlignJustifyTracksInMasonryAxis(
ContainingBlockFor(item->mArea).Size(wm).ConvertTo(childWM, wm);
LogicalSize availableSize = cb;
cb.Size(masonryChildAxis, childWM) = alignmentContainerSize;
- availableSize.Size(eLogicalAxisBlock, childWM) =
+ availableSize.Size(LogicalAxis::Block, childWM) =
NS_UNCONSTRAINEDSIZE;
const auto& bp = child->GetLogicalUsedBorderAndPadding(childWM);
newSize -= bp.StartEnd(masonryChildAxis, childWM);
@@ -7626,9 +7651,9 @@ void nsGridContainerFrame::ReflowInFlowChild(
aChild->RemoveProperty(aProp);
}
};
- SetProp(eLogicalAxisBlock,
+ SetProp(LogicalAxis::Block,
isOrthogonal ? IBaselinePadProperty() : BBaselinePadProperty());
- SetProp(eLogicalAxisInline,
+ SetProp(LogicalAxis::Inline,
isOrthogonal ? BBaselinePadProperty() : IBaselinePadProperty());
} else {
// By convention, for frames that perform CSS Box Alignment, we position
@@ -7654,9 +7679,9 @@ void nsGridContainerFrame::ReflowInFlowChild(
ComputeSizeFlags csFlags;
if (aGridItemInfo) {
const auto childIAxisInWM =
- isOrthogonal ? eLogicalAxisBlock : eLogicalAxisInline;
+ isOrthogonal ? LogicalAxis::Block : LogicalAxis::Inline;
// Clamp during reflow if we're stretching in that axis.
- if (GridItemShouldStretch(aChild, eLogicalAxisInline)) {
+ if (GridItemShouldStretch(aChild, LogicalAxis::Inline)) {
if (aGridItemInfo->mState[childIAxisInWM] &
ItemState::eClampMarginBoxMinSize) {
csFlags += ComputeSizeFlag::IClampMarginBoxMinSize;
@@ -7666,7 +7691,7 @@ void nsGridContainerFrame::ReflowInFlowChild(
}
const auto childBAxisInWM = GetOrthogonalAxis(childIAxisInWM);
- if (GridItemShouldStretch(aChild, eLogicalAxisBlock) &&
+ if (GridItemShouldStretch(aChild, LogicalAxis::Block) &&
aGridItemInfo->mState[childBAxisInWM] &
ItemState::eClampMarginBoxMinSize) {
csFlags += ComputeSizeFlag::BClampMarginBoxMinSize;
@@ -7702,7 +7727,7 @@ void nsGridContainerFrame::ReflowInFlowChild(
// nsBlockFrame::ComputeFinalSize the size.
if (isConstrainedBSize && !wm.IsOrthogonalTo(childWM)) {
const bool stretch = childRI.mStylePosition->BSize(childWM).IsAuto() &&
- GridItemShouldStretch(aChild, eLogicalAxisBlock);
+ GridItemShouldStretch(aChild, LogicalAxis::Block);
if (stretch) {
aChild->SetProperty(FragStretchBSizeProperty(), *aStretchBSize);
} else {
@@ -7750,7 +7775,7 @@ void nsGridContainerFrame::ReflowInFlowChild(
? StyleAlignFlags::SELF_START
: StyleAlignFlags::SELF_END};
}
- if (aAxis == eLogicalAxisBlock) {
+ if (aAxis == LogicalAxis::Block) {
AlignSelf(*aGridItemInfo, align, aCBSize, wm, childRI, size, flags,
&childPos);
} else {
@@ -7759,10 +7784,10 @@ void nsGridContainerFrame::ReflowInFlowChild(
}
};
if (aStatus.IsComplete()) {
- applyItemSelfAlignment(eLogicalAxisBlock,
+ applyItemSelfAlignment(LogicalAxis::Block,
cb.BSize(wm) - consumedGridAreaBSize);
}
- applyItemSelfAlignment(eLogicalAxisInline, cb.ISize(wm));
+ applyItemSelfAlignment(LogicalAxis::Inline, cb.ISize(wm));
} // else, nsAbsoluteContainingBlock.cpp will handle align/justify-self.
FinishReflowChild(aChild, pc, childSize, &childRI, childWM, childPos,
@@ -8006,7 +8031,7 @@ nscoord nsGridContainerFrame::ReflowRowsInFragmentainer(
const auto rowCount = aState.mRows.mSizes.Length();
nscoord masonryAxisGap;
const auto wm = aState.mWM;
- const bool isColMasonry = IsMasonry(eLogicalAxisInline);
+ const bool isColMasonry = IsMasonry(LogicalAxis::Inline);
if (isColMasonry) {
for (auto& sz : aState.mCols.mSizes) {
sz.mPosition = 0;
@@ -8174,15 +8199,15 @@ nscoord nsGridContainerFrame::ReflowRowsInFragmentainer(
}
if (isColMasonry) {
auto childWM = child->GetWritingMode();
- auto childAxis =
- !childWM.IsOrthogonalTo(wm) ? eLogicalAxisInline : eLogicalAxisBlock;
+ auto childAxis = !childWM.IsOrthogonalTo(wm) ? LogicalAxis::Inline
+ : LogicalAxis::Block;
auto normalPos = child->GetLogicalNormalPosition(wm, aContainerSize);
auto sz =
- childAxis == eLogicalAxisBlock ? child->BSize() : child->ISize();
- auto pos = normalPos.Pos(eLogicalAxisInline, wm) + sz +
+ childAxis == LogicalAxis::Block ? child->BSize() : child->ISize();
+ auto pos = normalPos.Pos(LogicalAxis::Inline, wm) + sz +
child->GetLogicalUsedMargin(childWM).End(childAxis, childWM);
masonryAxisPos.ref()[row] =
- pos + masonryAxisGap - aContentArea.Start(eLogicalAxisInline, wm);
+ pos + masonryAxisGap - aContentArea.Start(LogicalAxis::Inline, wm);
}
}
@@ -8281,7 +8306,7 @@ nscoord nsGridContainerFrame::MasonryLayout(GridReflowInput& aState,
aState.mIter.Reset(CSSOrderAwareFrameIterator::ChildFilter::IncludeAll);
size_t absposIndex = 0;
const LogicalAxis masonryAxis =
- IsMasonry(eLogicalAxisBlock) ? eLogicalAxisBlock : eLogicalAxisInline;
+ IsMasonry(LogicalAxis::Block) ? LogicalAxis::Block : LogicalAxis::Inline;
const auto wm = aState.mWM;
for (; !aState.mIter.AtEnd(); aState.mIter.Next()) {
nsIFrame* child = *aState.mIter;
@@ -8323,7 +8348,7 @@ nscoord nsGridContainerFrame::MasonryLayout(GridReflowInput& aState,
const auto masonryAutoFlow = aState.mGridStyle->mMasonryAutoFlow;
const bool definiteFirst =
masonryAutoFlow.order == StyleMasonryItemOrder::DefiniteFirst;
- if (masonryAxis == eLogicalAxisBlock) {
+ if (masonryAxis == LogicalAxis::Block) {
std::stable_sort(sortedItems.begin(), sortedItems.end(),
definiteFirst ? GridItemInfo::RowMasonryDefiniteFirst
: GridItemInfo::RowMasonryOrdered);
@@ -8366,8 +8391,8 @@ nscoord nsGridContainerFrame::MasonryLayout(GridReflowInput& aState,
lastItems.SetLength(gridAxisTrackCount);
PodZero(lastItems.Elements(), gridAxisTrackCount);
const nscoord gap = nsLayoutUtils::ResolveGapToLength(
- masonryAxis == eLogicalAxisBlock ? aState.mGridStyle->mRowGap
- : aState.mGridStyle->mColumnGap,
+ masonryAxis == LogicalAxis::Block ? aState.mGridStyle->mRowGap
+ : aState.mGridStyle->mColumnGap,
masonryTracks.mContentBoxSize);
masonryTracks.mGridGap = gap;
uint32_t cursor = 0;
@@ -8495,7 +8520,7 @@ nscoord nsGridContainerFrame::MasonryLayout(GridReflowInput& aState,
auto childAxis = !childWM.IsOrthogonalTo(wm) ? masonryAxis : gridAxis;
auto normalPos = aChild->GetLogicalNormalPosition(wm, aContainerSize);
auto sz =
- childAxis == eLogicalAxisBlock ? aChild->BSize() : aChild->ISize();
+ childAxis == LogicalAxis::Block ? aChild->BSize() : aChild->ISize();
return containerToMasonryBoxOffset + normalPos.Pos(masonryAxis, wm) + sz +
aChild->GetLogicalUsedMargin(childWM).End(childAxis, childWM);
};
@@ -8668,7 +8693,7 @@ nscoord nsGridContainerFrame::MasonryLayout(GridReflowInput& aState,
consumeAllSpace ? toFragmentainerEnd : offsetToMarginBoxEnd(child);
} else {
LogicalSize percentBasis(
- aState.PercentageBasisFor(eLogicalAxisInline, *item));
+ aState.PercentageBasisFor(LogicalAxis::Inline, *item));
IntrinsicISizeType type = aConstraint == SizingConstraint::MaxContent
? IntrinsicISizeType::PrefISize
: IntrinsicISizeType::MinISize;
@@ -8775,19 +8800,19 @@ nscoord nsGridContainerFrame::ReflowChildren(GridReflowInput& aState,
// so we let ReflowInFragmentainer() deal with grid-axis fragmentation
// in the else-clause below.
if (IsMasonry() &&
- !(IsMasonry(eLogicalAxisInline) && fragmentainer.isSome())) {
+ !(IsMasonry(LogicalAxis::Inline) && fragmentainer.isSome())) {
aState.mInFragmentainer = fragmentainer.isSome();
nscoord sz = MasonryLayout(
aState, aContentArea, SizingConstraint::NoConstraint, aDesiredSize,
aStatus, fragmentainer.ptrOr(nullptr), aContainerSize);
- if (IsMasonry(eLogicalAxisBlock)) {
+ if (IsMasonry(LogicalAxis::Block)) {
bSize = aState.mReflowInput->ComputedBSize();
if (bSize == NS_UNCONSTRAINEDSIZE) {
bSize = aState.mReflowInput->ApplyMinMaxBSize(sz);
}
}
} else if (MOZ_UNLIKELY(fragmentainer.isSome())) {
- if (IsMasonry(eLogicalAxisInline) && !GetPrevInFlow()) {
+ if (IsMasonry(LogicalAxis::Inline) && !GetPrevInFlow()) {
// First we do an unconstrained reflow to resolve the item placement
// which is then kept as-is in the constrained reflow below.
MasonryLayout(aState, aContentArea, SizingConstraint::NoConstraint,
@@ -8804,10 +8829,12 @@ nscoord nsGridContainerFrame::ReflowChildren(GridReflowInput& aState,
if (!child->IsPlaceholderFrame()) {
info = &aState.mGridItems[aState.mIter.ItemIndex()];
}
+ nsReflowStatus childStatus;
ReflowInFlowChild(child, info, aContainerSize, Nothing(), nullptr, aState,
- aContentArea, aDesiredSize, aStatus);
- MOZ_ASSERT(aStatus.IsComplete(),
+ aContentArea, aDesiredSize, childStatus);
+ MOZ_ASSERT(childStatus.IsComplete(),
"child should be complete in unconstrained reflow");
+ aStatus.MergeCompletionStatusFrom(childStatus);
}
}
@@ -8868,7 +8895,6 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsGridContainerFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
if (IsFrameTreeTooDeep(aReflowInput, aDesiredSize, aStatus)) {
@@ -8952,11 +8978,11 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
if (containBSize) {
bSize = *containBSize;
} else {
- if (IsMasonry(eLogicalAxisBlock)) {
+ if (IsMasonry(LogicalAxis::Block)) {
bSize = computedBSize;
} else {
const auto& rowSizes = gridReflowInput.mRows.mSizes;
- if (MOZ_LIKELY(!IsSubgrid(eLogicalAxisBlock))) {
+ if (MOZ_LIKELY(!IsSubgrid(LogicalAxis::Block))) {
// Note: we can't use GridLineEdge here since we haven't calculated
// the rows' mPosition yet (happens in AlignJustifyContent below).
for (const auto& sz : rowSizes) {
@@ -9025,7 +9051,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
}
// Save the final row sizes for use by subgrids, if needed.
if (HasSubgridItems() || IsSubgrid()) {
- StoreUsedTrackSizes(eLogicalAxisBlock, rowSizes);
+ StoreUsedTrackSizes(LogicalAxis::Block, rowSizes);
}
}
@@ -9122,8 +9148,8 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
}
// TODO: fix align-tracks alignment in fragments
- if ((IsMasonry(eLogicalAxisBlock) && !prevInFlow) ||
- IsMasonry(eLogicalAxisInline)) {
+ if ((IsMasonry(LogicalAxis::Block) && !prevInFlow) ||
+ IsMasonry(LogicalAxis::Inline)) {
gridReflowInput.AlignJustifyTracksInMasonryAxis(
contentArea.Size(wm), aDesiredSize.PhysicalSize());
}
@@ -9221,7 +9247,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
// the ComputedGridTrackInfo and related properties
const auto* subgrid = GetProperty(Subgrid::Prop());
- const auto* subgridColRange = subgrid && IsSubgrid(eLogicalAxisInline)
+ const auto* subgridColRange = subgrid && IsSubgrid(LogicalAxis::Inline)
? &subgrid->SubgridCols()
: nullptr;
@@ -9252,7 +9278,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
// taken by rvalue, but computing the size first prevents any changes in the
// argument types of the constructor from breaking this.
const uint32_t numColExplicitTracks =
- IsSubgrid(eLogicalAxisInline)
+ IsSubgrid(LogicalAxis::Inline)
? colTrackSizes.Length()
: gridReflowInput.mColFunctions.NumExplicitTracks();
ComputedGridTrackInfo* colInfo = new ComputedGridTrackInfo(
@@ -9261,10 +9287,10 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
std::move(colTrackStates), std::move(colRemovedRepeatTracks),
gridReflowInput.mColFunctions.mRepeatAutoStart,
colLineNameMap.GetResolvedLineNamesForComputedGridTrackInfo(),
- IsSubgrid(eLogicalAxisInline), IsMasonry(eLogicalAxisInline));
+ IsSubgrid(LogicalAxis::Inline), IsMasonry(LogicalAxis::Inline));
SetProperty(GridColTrackInfo(), colInfo);
- const auto* subgridRowRange = subgrid && IsSubgrid(eLogicalAxisBlock)
+ const auto* subgridRowRange = subgrid && IsSubgrid(LogicalAxis::Block)
? &subgrid->SubgridRows()
: nullptr;
LineNameMap rowLineNameMap(
@@ -9294,7 +9320,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
// taken by rvalue, but computing the size first prevents any changes in the
// argument types of the constructor from breaking this.
const uint32_t numRowExplicitTracks =
- IsSubgrid(eLogicalAxisBlock)
+ IsSubgrid(LogicalAxis::Block)
? rowTrackSizes.Length()
: gridReflowInput.mRowFunctions.NumExplicitTracks();
// Row info has to accommodate fragmentation of the grid, which may happen
@@ -9307,7 +9333,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
std::move(rowRemovedRepeatTracks),
gridReflowInput.mRowFunctions.mRepeatAutoStart,
rowLineNameMap.GetResolvedLineNamesForComputedGridTrackInfo(),
- IsSubgrid(eLogicalAxisBlock), IsMasonry(eLogicalAxisBlock));
+ IsSubgrid(LogicalAxis::Block), IsMasonry(LogicalAxis::Block));
SetProperty(GridRowTrackInfo(), rowInfo);
if (prevInFlow) {
@@ -9613,16 +9639,16 @@ nscoord nsGridContainerFrame::IntrinsicISize(gfxContext* aRenderingContext,
// They're only used for auto-repeat so we skip computing them otherwise.
RepeatTrackSizingInput repeatSizing(state.mWM);
if (!IsColSubgrid() && state.mColFunctions.mHasRepeatAuto) {
- repeatSizing.InitFromStyle(eLogicalAxisInline, state.mWM,
+ repeatSizing.InitFromStyle(LogicalAxis::Inline, state.mWM,
state.mFrame->Style());
}
if ((!IsRowSubgrid() && state.mRowFunctions.mHasRepeatAuto &&
!(state.mGridStyle->mGridAutoFlow & StyleGridAutoFlow::ROW)) ||
- IsMasonry(eLogicalAxisInline)) {
+ IsMasonry(LogicalAxis::Inline)) {
// Only 'grid-auto-flow:column' can create new implicit columns, so that's
// the only case where our block-size can affect the number of columns.
// Masonry layout always depends on how many rows we have though.
- repeatSizing.InitFromStyle(eLogicalAxisBlock, state.mWM,
+ repeatSizing.InitFromStyle(LogicalAxis::Block, state.mWM,
state.mFrame->Style());
}
@@ -9640,13 +9666,13 @@ nscoord nsGridContainerFrame::IntrinsicISize(gfxContext* aRenderingContext,
auto constraint = aType == IntrinsicISizeType::MinISize
? SizingConstraint::MinContent
: SizingConstraint::MaxContent;
- if (IsMasonry(eLogicalAxisInline)) {
+ if (IsMasonry(LogicalAxis::Inline)) {
ReflowOutput desiredSize(state.mWM);
nsSize containerSize;
LogicalRect contentArea(state.mWM);
nsReflowStatus status;
state.mRows.mSizes.SetLength(grid.mGridRowEnd);
- state.CalculateTrackSizesForAxis(eLogicalAxisInline, grid,
+ state.CalculateTrackSizesForAxis(LogicalAxis::Inline, grid,
NS_UNCONSTRAINEDSIZE, constraint);
return MasonryLayout(state, contentArea, constraint, desiredSize, status,
nullptr, containerSize);
@@ -9656,7 +9682,7 @@ nscoord nsGridContainerFrame::IntrinsicISize(gfxContext* aRenderingContext,
return nscoord(0);
}
- state.CalculateTrackSizesForAxis(eLogicalAxisInline, grid,
+ state.CalculateTrackSizesForAxis(LogicalAxis::Inline, grid,
NS_UNCONSTRAINEDSIZE, constraint);
if (MOZ_LIKELY(!IsSubgrid())) {
@@ -9672,7 +9698,6 @@ nscoord nsGridContainerFrame::GetMinISize(gfxContext* aRC) {
return f->GetMinISize(aRC);
}
- DISPLAY_MIN_INLINE_SIZE(this, mCachedMinISize);
if (mCachedMinISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
Maybe<nscoord> containISize = ContainIntrinsicISize();
mCachedMinISize = containISize
@@ -9688,7 +9713,6 @@ nscoord nsGridContainerFrame::GetPrefISize(gfxContext* aRC) {
return f->GetPrefISize(aRC);
}
- DISPLAY_PREF_INLINE_SIZE(this, mCachedPrefISize);
if (mCachedPrefISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
Maybe<nscoord> containISize = ContainIntrinsicISize();
mCachedPrefISize = containISize
@@ -9770,7 +9794,7 @@ StyleAlignFlags nsGridContainerFrame::CSSAlignmentForAbsPosChild(
"This method should only be called for abspos children");
StyleAlignFlags alignment =
- (aLogicalAxis == eLogicalAxisInline)
+ (aLogicalAxis == LogicalAxis::Inline)
? aChildRI.mStylePosition->UsedJustifySelf(Style())._0
: aChildRI.mStylePosition->UsedAlignSelf(Style())._0;
@@ -9792,7 +9816,7 @@ StyleAlignFlags nsGridContainerFrame::CSSAlignmentForAbsPosChild(
alignment = StyleAlignFlags::END;
} else if (alignment == StyleAlignFlags::LEFT ||
alignment == StyleAlignFlags::RIGHT) {
- if (aLogicalAxis == eLogicalAxisInline) {
+ if (aLogicalAxis == LogicalAxis::Inline) {
const bool isLeft = (alignment == StyleAlignFlags::LEFT);
WritingMode wm = GetWritingMode();
alignment = (isLeft == wm.IsBidiLTR()) ? StyleAlignFlags::START
@@ -9827,7 +9851,7 @@ nscoord nsGridContainerFrame::SynthesizeBaseline(
nscoord start;
nscoord size;
- if (aAxis == eLogicalAxisBlock) {
+ if (aAxis == LogicalAxis::Block) {
start = child->GetLogicalNormalPosition(aCBWM, aCBPhysicalSize).B(aCBWM);
size = child->BSize(aCBWM);
if (grid && aGridOrderItem.mIsInEdgeTrack) {
@@ -9836,13 +9860,13 @@ nscoord nsGridContainerFrame::SynthesizeBaseline(
} else if (!isOrthogonal && aGridOrderItem.mIsInEdgeTrack) {
// This assertion is mostly for documentation purposes; it must hold,
// given the checks in our 'if' statements. (We know aAxis is
- // eLogicalAxisBlock, and isOrthogonal is false, which means childAxis
- // must be eLogicalAxisBlock). If instead we got here with a childAxis of
- // eLogicalAxisInline, then our call to
+ // LogicalAxis::Block, and isOrthogonal is false, which means childAxis
+ // must be LogicalAxis::Block). If instead we got here with a childAxis of
+ // LogicalAxis::Inline, then our call to
// Baseline::SynthesizeBaselineFromBorderBox might incorrectly think
// it makes sense to use a central baseline, in an axis where that
// doesn't make sense.
- MOZ_ASSERT(childAxis == eLogicalAxisBlock, "unexpected childAxis");
+ MOZ_ASSERT(childAxis == LogicalAxis::Block, "unexpected childAxis");
baseline = child
->GetNaturalBaselineBOffset(childWM, aGroup,
BaselineExportContext::Other)
@@ -9893,8 +9917,8 @@ void nsGridContainerFrame::CalculateBaselines(
} else if (firstBaseline == NS_INTRINSIC_ISIZE_UNKNOWN) {
FindItemInGridOrderResult gridOrderFirstItem = FindFirstItemInGridOrder(
*aIter, *aGridItems,
- axis == eLogicalAxisBlock ? &GridArea::mRows : &GridArea::mCols,
- axis == eLogicalAxisBlock ? &GridArea::mCols : &GridArea::mRows,
+ axis == LogicalAxis::Block ? &GridArea::mRows : &GridArea::mCols,
+ axis == LogicalAxis::Block ? &GridArea::mCols : &GridArea::mRows,
aFragmentStartTrack);
mBaseline[axis][BaselineSharingGroup::First] = SynthesizeBaseline(
gridOrderFirstItem, axis, BaselineSharingGroup::First, aCBPhysicalSize,
@@ -9929,8 +9953,8 @@ void nsGridContainerFrame::CalculateBaselines(
iter.SetItemCount(aGridItems->Length());
FindItemInGridOrderResult gridOrderLastItem = FindLastItemInGridOrder(
iter, *aGridItems,
- axis == eLogicalAxisBlock ? &GridArea::mRows : &GridArea::mCols,
- axis == eLogicalAxisBlock ? &GridArea::mCols : &GridArea::mRows,
+ axis == LogicalAxis::Block ? &GridArea::mRows : &GridArea::mCols,
+ axis == LogicalAxis::Block ? &GridArea::mCols : &GridArea::mRows,
aFragmentStartTrack, aFirstExcludedTrack);
mBaseline[axis][BaselineSharingGroup::Last] =
SynthesizeBaseline(gridOrderLastItem, axis, BaselineSharingGroup::Last,
@@ -10124,7 +10148,7 @@ bool nsGridContainerFrame::GridItemShouldStretch(const nsIFrame* aChild,
}
const auto* pos = aChild->StylePosition();
- const auto alignment = (aAxis == eLogicalAxisInline) == !isOrthogonal
+ const auto alignment = (aAxis == LogicalAxis::Inline) == !isOrthogonal
? pos->UsedJustifySelf(Style())._0
: pos->UsedAlignSelf(Style())._0;
return alignment == StyleAlignFlags::NORMAL ||
diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h
index cf3a3b5776..cb3eef68c3 100644
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -233,12 +233,12 @@ class nsGridContainerFrame final : public nsContainerFrame,
/** Return true if this frame is subgridded in its aAxis. */
bool IsSubgrid(LogicalAxis aAxis) const {
- return HasAnyStateBits(aAxis == mozilla::eLogicalAxisBlock
+ return HasAnyStateBits(aAxis == mozilla::LogicalAxis::Block
? NS_STATE_GRID_IS_ROW_SUBGRID
: NS_STATE_GRID_IS_COL_SUBGRID);
}
- bool IsColSubgrid() const { return IsSubgrid(mozilla::eLogicalAxisInline); }
- bool IsRowSubgrid() const { return IsSubgrid(mozilla::eLogicalAxisBlock); }
+ bool IsColSubgrid() const { return IsSubgrid(mozilla::LogicalAxis::Inline); }
+ bool IsRowSubgrid() const { return IsSubgrid(mozilla::LogicalAxis::Block); }
/** Return true if this frame is subgridded in any axis. */
bool IsSubgrid() const {
return HasAnyStateBits(NS_STATE_GRID_IS_ROW_SUBGRID |
@@ -247,7 +247,7 @@ class nsGridContainerFrame final : public nsContainerFrame,
/** Return true if this frame has an item that is subgridded in our aAxis. */
bool HasSubgridItems(LogicalAxis aAxis) const {
- return HasAnyStateBits(aAxis == mozilla::eLogicalAxisBlock
+ return HasAnyStateBits(aAxis == mozilla::LogicalAxis::Block
? NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM
: NS_STATE_GRID_HAS_COL_SUBGRID_ITEM);
}
@@ -375,10 +375,10 @@ class nsGridContainerFrame final : public nsContainerFrame,
mozilla::IntrinsicISizeType aConstraint);
nscoord GetBBaseline(BaselineSharingGroup aBaselineGroup) const {
- return mBaseline[mozilla::eLogicalAxisBlock][aBaselineGroup];
+ return mBaseline[mozilla::LogicalAxis::Block][aBaselineGroup];
}
nscoord GetIBaseline(BaselineSharingGroup aBaselineGroup) const {
- return mBaseline[mozilla::eLogicalAxisInline][aBaselineGroup];
+ return mBaseline[mozilla::LogicalAxis::Inline][aBaselineGroup];
}
/**
diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp
index 07aeabec07..4b646359e5 100644
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -382,7 +382,6 @@ nscoord nsHTMLCanvasFrame::GetMinISize(gfxContext* aRenderingContext) {
result = nsPresContext::CSSPixelsToAppUnits(
vertical ? GetCanvasSize().height : GetCanvasSize().width);
}
- DISPLAY_MIN_INLINE_SIZE(this, result);
return result;
}
@@ -398,7 +397,6 @@ nscoord nsHTMLCanvasFrame::GetPrefISize(gfxContext* aRenderingContext) {
result = nsPresContext::CSSPixelsToAppUnits(
vertical ? GetCanvasSize().height : GetCanvasSize().width);
}
- DISPLAY_PREF_INLINE_SIZE(this, result);
return result;
}
@@ -438,7 +436,6 @@ void nsHTMLCanvasFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsHTMLCanvasFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
NS_FRAME_TRACE(
NS_FRAME_TRACE_CALLS,
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
index 479c26d18b..27f09b84f6 100644
--- a/layout/generic/nsIFrame.cpp
+++ b/layout/generic/nsIFrame.cpp
@@ -2017,6 +2017,12 @@ bool nsIFrame::GetShapeBoxBorderRadii(nscoord aRadii[8]) const {
}
}
+nscoord nsIFrame::OneEmInAppUnits() const {
+ return StyleFont()
+ ->mFont.size.ScaledBy(nsLayoutUtils::FontSizeInflationFor(this))
+ .ToAppUnits();
+}
+
ComputedStyle* nsIFrame::GetAdditionalComputedStyle(int32_t aIndex) const {
MOZ_ASSERT(aIndex >= 0, "invalid index number");
return nullptr;
@@ -2396,6 +2402,15 @@ already_AddRefed<ComputedStyle> nsIFrame::ComputeHighlightSelectionStyle(
*element, PseudoStyleType::highlight, aHighlightName, Style());
}
+already_AddRefed<ComputedStyle> nsIFrame::ComputeTargetTextStyle() const {
+ const Element* element = FindElementAncestorForMozSelection(GetContent());
+ if (!element) {
+ return nullptr;
+ }
+ return PresContext()->StyleSet()->ProbePseudoElementStyle(
+ *element, PseudoStyleType::targetText, nullptr, Style());
+}
+
template <typename SizeOrMaxSize>
static inline bool IsIntrinsicKeyword(const SizeOrMaxSize& aSize) {
// All keywords other than auto/none/-moz-available depend on intrinsic sizes.
@@ -4039,6 +4054,13 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
return;
}
+ nsIFrame* child = aChild;
+ auto* placeholder = child->IsPlaceholderFrame()
+ ? static_cast<nsPlaceholderFrame*>(child)
+ : nullptr;
+ nsIFrame* childOrOutOfFlow =
+ placeholder ? placeholder->GetOutOfFlowFrame() : child;
+
// If we're generating a display list for printing, include Link items for
// frames that correspond to HTML link elements so that we can have active
// links in saved PDF output. Note that the state of "within a link" is
@@ -4050,17 +4072,10 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
Maybe<nsDisplayListBuilder::Linkifier> linkifier;
if (StaticPrefs::print_save_as_pdf_links_enabled() &&
aBuilder->IsForPrinting()) {
- linkifier.emplace(aBuilder, aChild, aLists.Content());
- linkifier->MaybeAppendLink(aBuilder, aChild);
+ linkifier.emplace(aBuilder, childOrOutOfFlow, aLists.Content());
+ linkifier->MaybeAppendLink(aBuilder, childOrOutOfFlow);
}
- nsIFrame* child = aChild;
- auto* placeholder = child->IsPlaceholderFrame()
- ? static_cast<nsPlaceholderFrame*>(child)
- : nullptr;
- nsIFrame* childOrOutOfFlow =
- placeholder ? placeholder->GetOutOfFlowFrame() : child;
-
nsIFrame* parent = childOrOutOfFlow->GetParent();
const auto* parentDisplay = parent->StyleDisplay();
const auto overflowClipAxes =
@@ -5120,7 +5135,9 @@ nsresult nsIFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
return rv;
}
if (aAmountBack == eSelectWord) {
- frameSelection->SetIsDoubleClickSelection(true);
+ frameSelection->SetClickSelectionType(ClickSelectionType::Double);
+ } else if (aAmountBack == eSelectParagraph) {
+ frameSelection->SetClickSelectionType(ClickSelectionType::Triple);
}
// maintain selection
@@ -5989,18 +6006,10 @@ void nsIFrame::MarkSubtreeDirty() {
}
/* virtual */
-nscoord nsIFrame::GetMinISize(gfxContext* aRenderingContext) {
- nscoord result = 0;
- DISPLAY_MIN_INLINE_SIZE(this, result);
- return result;
-}
+nscoord nsIFrame::GetMinISize(gfxContext* aRenderingContext) { return 0; }
/* virtual */
-nscoord nsIFrame::GetPrefISize(gfxContext* aRenderingContext) {
- nscoord result = 0;
- DISPLAY_PREF_INLINE_SIZE(this, result);
- return result;
-}
+nscoord nsIFrame::GetPrefISize(gfxContext* aRenderingContext) { return 0; }
/* virtual */
void nsIFrame::AddInlineMinISize(gfxContext* aRenderingContext,
@@ -6319,14 +6328,12 @@ static MinMaxSize ComputeTransferredMinMaxInlineSize(
if (aMinMaxBSize.mMinSize > 0) {
transferredISize.mMinSize = aAspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, aMinMaxBSize.mMinSize,
- aBoxSizingAdjustment);
+ LogicalAxis::Inline, aWM, aMinMaxBSize.mMinSize, aBoxSizingAdjustment);
}
if (aMinMaxBSize.mMaxSize != NS_UNCONSTRAINEDSIZE) {
transferredISize.mMaxSize = aAspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, aMinMaxBSize.mMaxSize,
- aBoxSizingAdjustment);
+ LogicalAxis::Inline, aWM, aMinMaxBSize.mMaxSize, aBoxSizingAdjustment);
}
// Minimum size wins over maximum size.
@@ -6393,11 +6400,11 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
// indicates which axis (in this frame's own WM) corresponds to its
// flex container's main axis.
LogicalAxis flexMainAxis =
- eLogicalAxisInline; // (init to make valgrind happy)
+ LogicalAxis::Inline; // (init to make valgrind happy)
if (isFlexItem) {
flexMainAxis = nsFlexContainerFrame::IsItemInlineAxisMainAxis(this)
- ? eLogicalAxisInline
- : eLogicalAxisBlock;
+ ? LogicalAxis::Inline
+ : LogicalAxis::Block;
}
const bool isOrthogonal = aWM.IsOrthogonalTo(alignCB->GetWritingMode());
@@ -6426,8 +6433,8 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
bool mayUseAspectRatio = aspectRatio && !isAutoBSize;
if (!aFlags.contains(ComputeSizeFlag::ShrinkWrap) &&
!StyleMargin()->HasInlineAxisAuto(aWM) &&
- !alignCB->IsMasonry(isOrthogonal ? eLogicalAxisBlock
- : eLogicalAxisInline)) {
+ !alignCB->IsMasonry(isOrthogonal ? LogicalAxis::Block
+ : LogicalAxis::Inline)) {
auto inlineAxisAlignment =
isOrthogonal ? StylePosition()->UsedAlignSelf(alignCB->Style())._0
: StylePosition()->UsedJustifySelf(alignCB->Style())._0;
@@ -6451,7 +6458,7 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
styleBSize.AsLengthPercentage());
result.ISize(aWM) = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
+ LogicalAxis::Inline, aWM, bSize, boxSizingAdjust);
aspectRatioUsage = AspectRatioUsage::ToComputeISize;
}
@@ -6468,7 +6475,7 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
styleBSize.AsLengthPercentage());
result.ISize(aWM) = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
+ LogicalAxis::Inline, aWM, bSize, boxSizingAdjust);
aspectRatioUsage = AspectRatioUsage::ToComputeISize;
}
@@ -6523,7 +6530,7 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
// flex container's main-axis. (Those properties get applied later in
// the flexbox algorithm.)
const bool isFlexItemInlineAxisMainAxis =
- isFlexItem && flexMainAxis == eLogicalAxisInline;
+ isFlexItem && flexMainAxis == LogicalAxis::Inline;
// Grid items that are subgridded in inline-axis also ignore their min & max
// sizing properties in that axis.
const bool shouldIgnoreMinMaxISize =
@@ -6602,8 +6609,8 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
} else if (MOZ_UNLIKELY(isGridItem) && styleBSize.IsAuto() &&
!aFlags.contains(ComputeSizeFlag::IsGridMeasuringReflow) &&
!IsTrueOverflowContainer() &&
- !alignCB->IsMasonry(isOrthogonal ? eLogicalAxisInline
- : eLogicalAxisBlock)) {
+ !alignCB->IsMasonry(isOrthogonal ? LogicalAxis::Inline
+ : LogicalAxis::Block)) {
auto cbSize = aCBSize.BSize(aWM);
if (cbSize != NS_UNCONSTRAINEDSIZE) {
// 'auto' block-size for grid-level box - fill the CB for 'stretch' /
@@ -6628,8 +6635,7 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
// https://drafts.csswg.org/css-grid/#grid-item-sizing
if (!stretch && mayUseAspectRatio) {
result.BSize(aWM) = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisBlock, aWM, result.ISize(aWM),
- boxSizingAdjust);
+ LogicalAxis::Block, aWM, result.ISize(aWM), boxSizingAdjust);
MOZ_ASSERT(aspectRatioUsage == AspectRatioUsage::None);
aspectRatioUsage = AspectRatioUsage::ToComputeBSize;
}
@@ -6651,8 +6657,7 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
// applied (so aspectRatioUsage flag is set as expected). That's why we
// apply aspect-ratio unconditionally for auto block size here.
result.BSize(aWM) = aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisBlock, aWM, result.ISize(aWM),
- boxSizingAdjust);
+ LogicalAxis::Block, aWM, result.ISize(aWM), boxSizingAdjust);
MOZ_ASSERT(aspectRatioUsage == AspectRatioUsage::None);
aspectRatioUsage = AspectRatioUsage::ToComputeBSize;
}
@@ -6662,7 +6667,7 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
// container's main-axis. (Those properties get applied later in the flexbox
// algorithm.)
const bool isFlexItemBlockAxisMainAxis =
- isFlexItem && flexMainAxis == eLogicalAxisBlock;
+ isFlexItem && flexMainAxis == LogicalAxis::Block;
// Grid items that are subgridded in block-axis also ignore their min & max
// sizing properties in that axis.
const bool shouldIgnoreMinMaxBSize =
@@ -6789,7 +6794,7 @@ Maybe<nscoord> nsIFrame::ComputeInlineSizeFromAspectRatio(
aCBSize.BSize(aWM), aContentEdgeToBoxSizing.BSize(aWM),
styleBSize.AsLengthPercentage());
return Some(aspectRatio.ComputeRatioDependentSize(
- LogicalAxis::eLogicalAxisInline, aWM, bSize, aContentEdgeToBoxSizing));
+ LogicalAxis::Inline, aWM, bSize, aContentEdgeToBoxSizing));
}
nsIFrame::ISizeComputationResult nsIFrame::ComputeISizeValue(
@@ -8560,6 +8565,12 @@ const nsFrameSelection* nsIFrame::GetConstFrameSelection() const {
bool nsIFrame::IsFrameSelected() const {
NS_ASSERTION(!GetContent() || GetContent()->IsMaybeSelected(),
"use the public IsSelected() instead");
+ if (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled()) {
+ if (const ShadowRoot* shadowRoot =
+ GetContent()->GetShadowRootForSelection()) {
+ return shadowRoot->IsSelected(0, shadowRoot->GetChildCount());
+ }
+ }
return GetContent()->IsSelected(0, GetContent()->GetChildCount());
}
@@ -8983,6 +8994,13 @@ nsresult nsIFrame::PeekOffsetForParagraph(PeekOffsetStruct* aPos) {
if (reachedLimit) { // no "stop frame" found
aPos->mResultContent = frame->GetContent();
+ if (ShadowRoot* shadowRoot =
+ aPos->mResultContent->GetShadowRootForSelection()) {
+ // Even if there's no children for this node,
+ // the elements inside the shadow root is still
+ // selectable
+ aPos->mResultContent = shadowRoot;
+ }
if (aPos->mDirection == eDirPrevious) {
aPos->mContentOffset = 0;
} else if (aPos->mResultContent) {
@@ -10698,21 +10716,27 @@ ComputedStyle* nsIFrame::DoGetParentComputedStyle(
}
void nsIFrame::GetLastLeaf(nsIFrame** aFrame) {
- if (!aFrame || !*aFrame) return;
- nsIFrame* child = *aFrame;
- // if we are a block frame then go for the last line of 'this'
- while (1) {
- child = child->PrincipalChildList().FirstChild();
- if (!child) return; // nothing to do
- nsIFrame* siblingFrame;
- nsIContent* content;
- // ignore anonymous elements, e.g. mozTableAdd* mozTableRemove*
- // see bug 278197 comment #12 #13 for details
- while ((siblingFrame = child->GetNextSibling()) &&
- (content = siblingFrame->GetContent()) &&
- !content->IsRootOfNativeAnonymousSubtree())
- child = siblingFrame;
- *aFrame = child;
+ if (!aFrame || !*aFrame) {
+ return;
+ }
+ for (nsIFrame* maybeLastLeaf = (*aFrame)->PrincipalChildList().LastChild();
+ maybeLastLeaf;) {
+ nsIFrame* lastChildNotInSubTree = nullptr;
+ for (nsIFrame* child = maybeLastLeaf; child;
+ child = child->GetPrevSibling()) {
+ nsIContent* content = child->GetContent();
+ // ignore anonymous elements, e.g. mozTableAdd* mozTableRemove*
+ // see bug 278197 comment #12 #13 for details
+ if (content && !content->IsRootOfNativeAnonymousSubtree()) {
+ lastChildNotInSubTree = child;
+ break;
+ }
+ }
+ if (!lastChildNotInSubTree) {
+ return;
+ }
+ *aFrame = lastChildNotInSubTree;
+ maybeLastLeaf = lastChildNotInSubTree->PrincipalChildList().LastChild();
}
}
@@ -10907,7 +10931,7 @@ void nsIFrame::UpdateStyleOfChildAnonBox(nsIFrame* aChildFrame,
// Now that we've updated the style on aChildFrame, check whether it itself
// has anon boxes to deal with.
ServoRestyleState childrenState(*aChildFrame, aRestyleState, childHint,
- ServoRestyleState::Type::InFlow);
+ ServoRestyleState::CanUseHandledHints::Yes);
aChildFrame->UpdateStyleOfOwnedAnonBoxes(childrenState);
// Assuming anon boxes don't have ::backdrop associated with them... if that
@@ -11655,1037 +11679,6 @@ void nsIFrame::VerifyDirtyBitSet(const nsFrameList& aFrameList) {
}
}
-// Start Display Reflow
-DR_cookie::DR_cookie(nsPresContext* aPresContext, nsIFrame* aFrame,
- const ReflowInput& aReflowInput, ReflowOutput& aMetrics,
- nsReflowStatus& aStatus)
- : mPresContext(aPresContext),
- mFrame(aFrame),
- mReflowInput(aReflowInput),
- mMetrics(aMetrics),
- mStatus(aStatus) {
- MOZ_COUNT_CTOR(DR_cookie);
- mValue = nsIFrame::DisplayReflowEnter(aPresContext, mFrame, mReflowInput);
-}
-
-DR_cookie::~DR_cookie() {
- MOZ_COUNT_DTOR(DR_cookie);
- nsIFrame::DisplayReflowExit(mPresContext, mFrame, mMetrics, mStatus, mValue);
-}
-
-DR_layout_cookie::DR_layout_cookie(nsIFrame* aFrame) : mFrame(aFrame) {
- MOZ_COUNT_CTOR(DR_layout_cookie);
- mValue = nsIFrame::DisplayLayoutEnter(mFrame);
-}
-
-DR_layout_cookie::~DR_layout_cookie() {
- MOZ_COUNT_DTOR(DR_layout_cookie);
- nsIFrame::DisplayLayoutExit(mFrame, mValue);
-}
-
-DR_intrinsic_inline_size_cookie::DR_intrinsic_inline_size_cookie(
- nsIFrame* aFrame, const char* aType, nscoord& aResult)
- : mFrame(aFrame), mType(aType), mResult(aResult) {
- MOZ_COUNT_CTOR(DR_intrinsic_inline_size_cookie);
- mValue = nsIFrame::DisplayIntrinsicISizeEnter(mFrame, mType);
-}
-
-DR_intrinsic_inline_size_cookie::~DR_intrinsic_inline_size_cookie() {
- MOZ_COUNT_DTOR(DR_intrinsic_inline_size_cookie);
- nsIFrame::DisplayIntrinsicISizeExit(mFrame, mType, mResult, mValue);
-}
-
-DR_intrinsic_size_cookie::DR_intrinsic_size_cookie(nsIFrame* aFrame,
- const char* aType,
- nsSize& aResult)
- : mFrame(aFrame), mType(aType), mResult(aResult) {
- MOZ_COUNT_CTOR(DR_intrinsic_size_cookie);
- mValue = nsIFrame::DisplayIntrinsicSizeEnter(mFrame, mType);
-}
-
-DR_intrinsic_size_cookie::~DR_intrinsic_size_cookie() {
- MOZ_COUNT_DTOR(DR_intrinsic_size_cookie);
- nsIFrame::DisplayIntrinsicSizeExit(mFrame, mType, mResult, mValue);
-}
-
-DR_init_constraints_cookie::DR_init_constraints_cookie(
- nsIFrame* aFrame, ReflowInput* aState, nscoord aCBWidth, nscoord aCBHeight,
- const mozilla::Maybe<mozilla::LogicalMargin> aBorder,
- const mozilla::Maybe<mozilla::LogicalMargin> aPadding)
- : mFrame(aFrame), mState(aState) {
- MOZ_COUNT_CTOR(DR_init_constraints_cookie);
- nsMargin border;
- if (aBorder) {
- border = aBorder->GetPhysicalMargin(aFrame->GetWritingMode());
- }
- nsMargin padding;
- if (aPadding) {
- padding = aPadding->GetPhysicalMargin(aFrame->GetWritingMode());
- }
- mValue = ReflowInput::DisplayInitConstraintsEnter(
- mFrame, mState, aCBWidth, aCBHeight, aBorder ? &border : nullptr,
- aPadding ? &padding : nullptr);
-}
-
-DR_init_constraints_cookie::~DR_init_constraints_cookie() {
- MOZ_COUNT_DTOR(DR_init_constraints_cookie);
- ReflowInput::DisplayInitConstraintsExit(mFrame, mState, mValue);
-}
-
-DR_init_offsets_cookie::DR_init_offsets_cookie(
- nsIFrame* aFrame, SizeComputationInput* aState, nscoord aPercentBasis,
- WritingMode aCBWritingMode,
- const mozilla::Maybe<mozilla::LogicalMargin> aBorder,
- const mozilla::Maybe<mozilla::LogicalMargin> aPadding)
- : mFrame(aFrame), mState(aState) {
- MOZ_COUNT_CTOR(DR_init_offsets_cookie);
- nsMargin border;
- if (aBorder) {
- border = aBorder->GetPhysicalMargin(aFrame->GetWritingMode());
- }
- nsMargin padding;
- if (aPadding) {
- padding = aPadding->GetPhysicalMargin(aFrame->GetWritingMode());
- }
- mValue = SizeComputationInput::DisplayInitOffsetsEnter(
- mFrame, mState, aPercentBasis, aCBWritingMode,
- aBorder ? &border : nullptr, aPadding ? &padding : nullptr);
-}
-
-DR_init_offsets_cookie::~DR_init_offsets_cookie() {
- MOZ_COUNT_DTOR(DR_init_offsets_cookie);
- SizeComputationInput::DisplayInitOffsetsExit(mFrame, mState, mValue);
-}
-
-struct DR_Rule;
-
-struct DR_FrameTypeInfo {
- DR_FrameTypeInfo(LayoutFrameType aFrameType, const char* aFrameNameAbbrev,
- const char* aFrameName);
- ~DR_FrameTypeInfo();
-
- LayoutFrameType mType;
- char mNameAbbrev[16];
- char mName[32];
- nsTArray<DR_Rule*> mRules;
-
- private:
- DR_FrameTypeInfo& operator=(const DR_FrameTypeInfo&) = delete;
-};
-
-struct DR_FrameTreeNode;
-struct DR_Rule;
-
-struct DR_State {
- DR_State();
- ~DR_State();
- void Init();
- void AddFrameTypeInfo(LayoutFrameType aFrameType,
- const char* aFrameNameAbbrev, const char* aFrameName);
- DR_FrameTypeInfo* GetFrameTypeInfo(LayoutFrameType aFrameType);
- DR_FrameTypeInfo* GetFrameTypeInfo(char* aFrameName);
- void InitFrameTypeTable();
- DR_FrameTreeNode* CreateTreeNode(nsIFrame* aFrame,
- const ReflowInput* aReflowInput);
- void FindMatchingRule(DR_FrameTreeNode& aNode);
- bool RuleMatches(DR_Rule& aRule, DR_FrameTreeNode& aNode);
- bool GetToken(FILE* aFile, char* aBuf, size_t aBufSize);
- DR_Rule* ParseRule(FILE* aFile);
- void ParseRulesFile();
- void AddRule(nsTArray<DR_Rule*>& aRules, DR_Rule& aRule);
- bool IsWhiteSpace(int c);
- bool GetNumber(char* aBuf, int32_t& aNumber);
- void PrettyUC(nscoord aSize, char* aBuf, int aBufSize);
- void PrintMargin(const char* tag, const nsMargin* aMargin);
- void DisplayFrameTypeInfo(nsIFrame* aFrame, int32_t aIndent);
- void DeleteTreeNode(DR_FrameTreeNode& aNode);
-
- bool mInited;
- bool mActive;
- int32_t mCount;
- int32_t mAssert;
- int32_t mIndent;
- bool mIndentUndisplayedFrames;
- bool mDisplayPixelErrors;
- nsTArray<DR_Rule*> mWildRules;
- nsTArray<DR_FrameTypeInfo> mFrameTypeTable;
- // reflow specific state
- nsTArray<DR_FrameTreeNode*> mFrameTreeLeaves;
-};
-
-static DR_State* DR_state; // the one and only DR_State
-
-struct DR_RulePart {
- explicit DR_RulePart(LayoutFrameType aFrameType)
- : mFrameType(aFrameType), mNext(0) {}
-
- void Destroy();
-
- LayoutFrameType mFrameType;
- DR_RulePart* mNext;
-};
-
-void DR_RulePart::Destroy() {
- if (mNext) {
- mNext->Destroy();
- }
- delete this;
-}
-
-struct DR_Rule {
- DR_Rule() : mLength(0), mTarget(nullptr), mDisplay(false) {
- MOZ_COUNT_CTOR(DR_Rule);
- }
- ~DR_Rule() {
- if (mTarget) mTarget->Destroy();
- MOZ_COUNT_DTOR(DR_Rule);
- }
- void AddPart(LayoutFrameType aFrameType);
-
- uint32_t mLength;
- DR_RulePart* mTarget;
- bool mDisplay;
-};
-
-void DR_Rule::AddPart(LayoutFrameType aFrameType) {
- DR_RulePart* newPart = new DR_RulePart(aFrameType);
- newPart->mNext = mTarget;
- mTarget = newPart;
- mLength++;
-}
-
-DR_FrameTypeInfo::~DR_FrameTypeInfo() {
- int32_t numElements;
- numElements = mRules.Length();
- for (int32_t i = numElements - 1; i >= 0; i--) {
- delete mRules.ElementAt(i);
- }
-}
-
-DR_FrameTypeInfo::DR_FrameTypeInfo(LayoutFrameType aFrameType,
- const char* aFrameNameAbbrev,
- const char* aFrameName) {
- mType = aFrameType;
- PL_strncpyz(mNameAbbrev, aFrameNameAbbrev, sizeof(mNameAbbrev));
- PL_strncpyz(mName, aFrameName, sizeof(mName));
-}
-
-struct DR_FrameTreeNode {
- DR_FrameTreeNode(nsIFrame* aFrame, DR_FrameTreeNode* aParent)
- : mFrame(aFrame), mParent(aParent), mDisplay(0), mIndent(0) {
- MOZ_COUNT_CTOR(DR_FrameTreeNode);
- }
-
- MOZ_COUNTED_DTOR(DR_FrameTreeNode)
-
- nsIFrame* mFrame;
- DR_FrameTreeNode* mParent;
- bool mDisplay;
- uint32_t mIndent;
-};
-
-// DR_State implementation
-
-DR_State::DR_State()
- : mInited(false),
- mActive(false),
- mCount(0),
- mAssert(-1),
- mIndent(0),
- mIndentUndisplayedFrames(false),
- mDisplayPixelErrors(false) {
- MOZ_COUNT_CTOR(DR_State);
-}
-
-void DR_State::Init() {
- char* env = PR_GetEnv("GECKO_DISPLAY_REFLOW_ASSERT");
- int32_t num;
- if (env) {
- if (GetNumber(env, num))
- mAssert = num;
- else
- printf("GECKO_DISPLAY_REFLOW_ASSERT - invalid value = %s", env);
- }
-
- env = PR_GetEnv("GECKO_DISPLAY_REFLOW_INDENT_START");
- if (env) {
- if (GetNumber(env, num))
- mIndent = num;
- else
- printf("GECKO_DISPLAY_REFLOW_INDENT_START - invalid value = %s", env);
- }
-
- env = PR_GetEnv("GECKO_DISPLAY_REFLOW_INDENT_UNDISPLAYED_FRAMES");
- if (env) {
- if (GetNumber(env, num))
- mIndentUndisplayedFrames = num;
- else
- printf(
- "GECKO_DISPLAY_REFLOW_INDENT_UNDISPLAYED_FRAMES - invalid value = %s",
- env);
- }
-
- env = PR_GetEnv("GECKO_DISPLAY_REFLOW_FLAG_PIXEL_ERRORS");
- if (env) {
- if (GetNumber(env, num))
- mDisplayPixelErrors = num;
- else
- printf("GECKO_DISPLAY_REFLOW_FLAG_PIXEL_ERRORS - invalid value = %s",
- env);
- }
-
- InitFrameTypeTable();
- ParseRulesFile();
- mInited = true;
-}
-
-DR_State::~DR_State() {
- MOZ_COUNT_DTOR(DR_State);
- int32_t numElements, i;
- numElements = mWildRules.Length();
- for (i = numElements - 1; i >= 0; i--) {
- delete mWildRules.ElementAt(i);
- }
- numElements = mFrameTreeLeaves.Length();
- for (i = numElements - 1; i >= 0; i--) {
- delete mFrameTreeLeaves.ElementAt(i);
- }
-}
-
-bool DR_State::GetNumber(char* aBuf, int32_t& aNumber) {
- if (sscanf(aBuf, "%d", &aNumber) > 0)
- return true;
- else
- return false;
-}
-
-bool DR_State::IsWhiteSpace(int c) {
- return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
-}
-
-bool DR_State::GetToken(FILE* aFile, char* aBuf, size_t aBufSize) {
- bool haveToken = false;
- aBuf[0] = 0;
- // get the 1st non whitespace char
- int c = -1;
- for (c = getc(aFile); (c > 0) && IsWhiteSpace(c); c = getc(aFile)) {
- }
-
- if (c > 0) {
- haveToken = true;
- aBuf[0] = c;
- // get everything up to the next whitespace char
- size_t cX;
- for (cX = 1; cX + 1 < aBufSize; cX++) {
- c = getc(aFile);
- if (c < 0) { // EOF
- ungetc(' ', aFile);
- break;
- } else {
- if (IsWhiteSpace(c)) {
- break;
- } else {
- aBuf[cX] = c;
- }
- }
- }
- aBuf[cX] = 0;
- }
- return haveToken;
-}
-
-DR_Rule* DR_State::ParseRule(FILE* aFile) {
- char buf[128];
- int32_t doDisplay;
- DR_Rule* rule = nullptr;
- while (GetToken(aFile, buf, sizeof(buf))) {
- if (GetNumber(buf, doDisplay)) {
- if (rule) {
- rule->mDisplay = !!doDisplay;
- break;
- } else {
- printf("unexpected token - %s \n", buf);
- }
- } else {
- if (!rule) {
- rule = new DR_Rule;
- }
- if (strcmp(buf, "*") == 0) {
- rule->AddPart(LayoutFrameType::None);
- } else {
- DR_FrameTypeInfo* info = GetFrameTypeInfo(buf);
- if (info) {
- rule->AddPart(info->mType);
- } else {
- printf("invalid frame type - %s \n", buf);
- }
- }
- }
- }
- return rule;
-}
-
-void DR_State::AddRule(nsTArray<DR_Rule*>& aRules, DR_Rule& aRule) {
- int32_t numRules = aRules.Length();
- for (int32_t ruleX = 0; ruleX < numRules; ruleX++) {
- DR_Rule* rule = aRules.ElementAt(ruleX);
- NS_ASSERTION(rule, "program error");
- if (aRule.mLength > rule->mLength) {
- aRules.InsertElementAt(ruleX, &aRule);
- return;
- }
- }
- aRules.AppendElement(&aRule);
-}
-
-static Maybe<bool> ShouldLogReflow(const char* processes) {
- switch (processes[0]) {
- case 'A':
- case 'a':
- return Some(true);
- case 'P':
- case 'p':
- return Some(XRE_IsParentProcess());
- case 'C':
- case 'c':
- return Some(XRE_IsContentProcess());
- default:
- return Nothing{};
- }
-}
-
-void DR_State::ParseRulesFile() {
- char* processes = PR_GetEnv("GECKO_DISPLAY_REFLOW_PROCESSES");
- if (processes) {
- Maybe<bool> enableLog = ShouldLogReflow(processes);
- if (enableLog.isNothing()) {
- MOZ_CRASH("GECKO_DISPLAY_REFLOW_PROCESSES: [a]ll [p]arent [c]ontent");
- } else if (enableLog.value()) {
- DR_Rule* rule = new DR_Rule;
- rule->AddPart(LayoutFrameType::None);
- rule->mDisplay = true;
- AddRule(mWildRules, *rule);
- mActive = true;
- }
- return;
- }
-
- char* path = PR_GetEnv("GECKO_DISPLAY_REFLOW_RULES_FILE");
- if (path) {
- FILE* inFile = fopen(path, "r");
- if (!inFile) {
- MOZ_CRASH(
- "Failed to open the specified rules file; Try `--setpref "
- "security.sandbox.content.level=2` if the sandbox is at cause");
- }
- for (DR_Rule* rule = ParseRule(inFile); rule; rule = ParseRule(inFile)) {
- if (rule->mTarget) {
- LayoutFrameType fType = rule->mTarget->mFrameType;
- if (fType != LayoutFrameType::None) {
- DR_FrameTypeInfo* info = GetFrameTypeInfo(fType);
- AddRule(info->mRules, *rule);
- } else {
- AddRule(mWildRules, *rule);
- }
- mActive = true;
- }
- }
-
- fclose(inFile);
- }
-}
-
-void DR_State::AddFrameTypeInfo(LayoutFrameType aFrameType,
- const char* aFrameNameAbbrev,
- const char* aFrameName) {
- mFrameTypeTable.EmplaceBack(aFrameType, aFrameNameAbbrev, aFrameName);
-}
-
-DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(LayoutFrameType aFrameType) {
- int32_t numEntries = mFrameTypeTable.Length();
- NS_ASSERTION(numEntries != 0, "empty FrameTypeTable");
- for (int32_t i = 0; i < numEntries; i++) {
- DR_FrameTypeInfo& info = mFrameTypeTable.ElementAt(i);
- if (info.mType == aFrameType) {
- return &info;
- }
- }
- return &mFrameTypeTable.ElementAt(numEntries -
- 1); // return unknown frame type
-}
-
-DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(char* aFrameName) {
- int32_t numEntries = mFrameTypeTable.Length();
- NS_ASSERTION(numEntries != 0, "empty FrameTypeTable");
- for (int32_t i = 0; i < numEntries; i++) {
- DR_FrameTypeInfo& info = mFrameTypeTable.ElementAt(i);
- if ((strcmp(aFrameName, info.mName) == 0) ||
- (strcmp(aFrameName, info.mNameAbbrev) == 0)) {
- return &info;
- }
- }
- return &mFrameTypeTable.ElementAt(numEntries -
- 1); // return unknown frame type
-}
-
-void DR_State::InitFrameTypeTable() {
- AddFrameTypeInfo(LayoutFrameType::Block, "block", "block");
- AddFrameTypeInfo(LayoutFrameType::Br, "br", "br");
- AddFrameTypeInfo(LayoutFrameType::ColorControl, "color", "colorControl");
- AddFrameTypeInfo(LayoutFrameType::GfxButtonControl, "button",
- "gfxButtonControl");
- AddFrameTypeInfo(LayoutFrameType::HTMLButtonControl, "HTMLbutton",
- "HTMLButtonControl");
- AddFrameTypeInfo(LayoutFrameType::HTMLCanvas, "HTMLCanvas", "HTMLCanvas");
- AddFrameTypeInfo(LayoutFrameType::SubDocument, "subdoc", "subDocument");
- AddFrameTypeInfo(LayoutFrameType::Image, "img", "image");
- AddFrameTypeInfo(LayoutFrameType::Inline, "inline", "inline");
- AddFrameTypeInfo(LayoutFrameType::Letter, "letter", "letter");
- AddFrameTypeInfo(LayoutFrameType::Line, "line", "line");
- AddFrameTypeInfo(LayoutFrameType::ListControl, "select", "select");
- AddFrameTypeInfo(LayoutFrameType::Page, "page", "page");
- AddFrameTypeInfo(LayoutFrameType::Placeholder, "place", "placeholder");
- AddFrameTypeInfo(LayoutFrameType::Canvas, "canvas", "canvas");
- AddFrameTypeInfo(LayoutFrameType::Scroll, "scroll", "scroll");
- AddFrameTypeInfo(LayoutFrameType::TableCell, "cell", "tableCell");
- AddFrameTypeInfo(LayoutFrameType::TableCol, "col", "tableCol");
- AddFrameTypeInfo(LayoutFrameType::TableColGroup, "colG", "tableColGroup");
- AddFrameTypeInfo(LayoutFrameType::Table, "tbl", "table");
- AddFrameTypeInfo(LayoutFrameType::TableWrapper, "tblW", "tableWrapper");
- AddFrameTypeInfo(LayoutFrameType::TableRowGroup, "rowG", "tableRowGroup");
- AddFrameTypeInfo(LayoutFrameType::TableRow, "row", "tableRow");
- AddFrameTypeInfo(LayoutFrameType::TextInput, "textCtl", "textInput");
- AddFrameTypeInfo(LayoutFrameType::Text, "text", "text");
- AddFrameTypeInfo(LayoutFrameType::Viewport, "VP", "viewport");
- AddFrameTypeInfo(LayoutFrameType::Slider, "Slider", "Slider");
- AddFrameTypeInfo(LayoutFrameType::None, "unknown", "unknown");
-}
-
-void DR_State::DisplayFrameTypeInfo(nsIFrame* aFrame, int32_t aIndent) {
- DR_FrameTypeInfo* frameTypeInfo = GetFrameTypeInfo(aFrame->Type());
- if (frameTypeInfo) {
- for (int32_t i = 0; i < aIndent; i++) {
- printf(" ");
- }
- if (!strcmp(frameTypeInfo->mNameAbbrev, "unknown")) {
- if (aFrame) {
- nsAutoString name;
- aFrame->GetFrameName(name);
- printf("%s %p ", NS_LossyConvertUTF16toASCII(name).get(),
- (void*)aFrame);
- } else {
- printf("%s %p ", frameTypeInfo->mNameAbbrev, (void*)aFrame);
- }
- } else {
- printf("%s %p ", frameTypeInfo->mNameAbbrev, (void*)aFrame);
- }
- }
-}
-
-bool DR_State::RuleMatches(DR_Rule& aRule, DR_FrameTreeNode& aNode) {
- NS_ASSERTION(aRule.mTarget, "program error");
-
- DR_RulePart* rulePart;
- DR_FrameTreeNode* parentNode;
- for (rulePart = aRule.mTarget->mNext, parentNode = aNode.mParent;
- rulePart && parentNode;
- rulePart = rulePart->mNext, parentNode = parentNode->mParent) {
- if (rulePart->mFrameType != LayoutFrameType::None) {
- if (parentNode->mFrame) {
- if (rulePart->mFrameType != parentNode->mFrame->Type()) {
- return false;
- }
- } else
- NS_ASSERTION(false, "program error");
- }
- // else wild card match
- }
- return true;
-}
-
-void DR_State::FindMatchingRule(DR_FrameTreeNode& aNode) {
- if (!aNode.mFrame) {
- NS_ASSERTION(false, "invalid DR_FrameTreeNode \n");
- return;
- }
-
- bool matchingRule = false;
-
- DR_FrameTypeInfo* info = GetFrameTypeInfo(aNode.mFrame->Type());
- NS_ASSERTION(info, "program error");
- int32_t numRules = info->mRules.Length();
- for (int32_t ruleX = 0; ruleX < numRules; ruleX++) {
- DR_Rule* rule = info->mRules.ElementAt(ruleX);
- if (rule && RuleMatches(*rule, aNode)) {
- aNode.mDisplay = rule->mDisplay;
- matchingRule = true;
- break;
- }
- }
- if (!matchingRule) {
- int32_t numWildRules = mWildRules.Length();
- for (int32_t ruleX = 0; ruleX < numWildRules; ruleX++) {
- DR_Rule* rule = mWildRules.ElementAt(ruleX);
- if (rule && RuleMatches(*rule, aNode)) {
- aNode.mDisplay = rule->mDisplay;
- break;
- }
- }
- }
-}
-
-DR_FrameTreeNode* DR_State::CreateTreeNode(nsIFrame* aFrame,
- const ReflowInput* aReflowInput) {
- // find the frame of the parent reflow input (usually just the parent of
- // aFrame)
- nsIFrame* parentFrame;
- if (aReflowInput) {
- const ReflowInput* parentRI = aReflowInput->mParentReflowInput;
- parentFrame = (parentRI) ? parentRI->mFrame : nullptr;
- } else {
- parentFrame = aFrame->GetParent();
- }
-
- // find the parent tree node leaf
- DR_FrameTreeNode* parentNode = nullptr;
-
- DR_FrameTreeNode* lastLeaf = nullptr;
- if (mFrameTreeLeaves.Length())
- lastLeaf = mFrameTreeLeaves.ElementAt(mFrameTreeLeaves.Length() - 1);
- if (lastLeaf) {
- for (parentNode = lastLeaf;
- parentNode && (parentNode->mFrame != parentFrame);
- parentNode = parentNode->mParent) {
- }
- }
- DR_FrameTreeNode* newNode = new DR_FrameTreeNode(aFrame, parentNode);
- FindMatchingRule(*newNode);
-
- newNode->mIndent = mIndent;
- if (newNode->mDisplay || mIndentUndisplayedFrames) {
- ++mIndent;
- }
-
- if (lastLeaf && (lastLeaf == parentNode)) {
- mFrameTreeLeaves.RemoveLastElement();
- }
- mFrameTreeLeaves.AppendElement(newNode);
- mCount++;
-
- return newNode;
-}
-
-void DR_State::PrettyUC(nscoord aSize, char* aBuf, int aBufSize) {
- if (NS_UNCONSTRAINEDSIZE == aSize) {
- strcpy(aBuf, "UC");
- } else {
- if ((nscoord)0xdeadbeefU == aSize) {
- strcpy(aBuf, "deadbeef");
- } else {
- snprintf(aBuf, aBufSize, "%d", aSize);
- }
- }
-}
-
-void DR_State::PrintMargin(const char* tag, const nsMargin* aMargin) {
- if (aMargin) {
- char t[16], r[16], b[16], l[16];
- PrettyUC(aMargin->top, t, 16);
- PrettyUC(aMargin->right, r, 16);
- PrettyUC(aMargin->bottom, b, 16);
- PrettyUC(aMargin->left, l, 16);
- printf(" %s=%s,%s,%s,%s", tag, t, r, b, l);
- } else {
- // use %p here for consistency with other null-pointer printouts
- printf(" %s=%p", tag, (void*)aMargin);
- }
-}
-
-void DR_State::DeleteTreeNode(DR_FrameTreeNode& aNode) {
- mFrameTreeLeaves.RemoveElement(&aNode);
- int32_t numLeaves = mFrameTreeLeaves.Length();
- if ((0 == numLeaves) ||
- (aNode.mParent != mFrameTreeLeaves.ElementAt(numLeaves - 1))) {
- mFrameTreeLeaves.AppendElement(aNode.mParent);
- }
-
- if (aNode.mDisplay || mIndentUndisplayedFrames) {
- --mIndent;
- }
- // delete the tree node
- delete &aNode;
-}
-
-static void CheckPixelError(nscoord aSize, int32_t aPixelToTwips) {
- if (NS_UNCONSTRAINEDSIZE != aSize) {
- if ((aSize % aPixelToTwips) > 0) {
- printf("VALUE %d is not a whole pixel \n", aSize);
- }
- }
-}
-
-static void DisplayReflowEnterPrint(nsPresContext* aPresContext,
- nsIFrame* aFrame,
- const ReflowInput& aReflowInput,
- DR_FrameTreeNode& aTreeNode,
- bool aChanged) {
- if (aTreeNode.mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, aTreeNode.mIndent);
-
- char width[16];
- char height[16];
-
- DR_state->PrettyUC(aReflowInput.AvailableWidth(), width, 16);
- DR_state->PrettyUC(aReflowInput.AvailableHeight(), height, 16);
- printf("Reflow a=%s,%s ", width, height);
-
- DR_state->PrettyUC(aReflowInput.ComputedWidth(), width, 16);
- DR_state->PrettyUC(aReflowInput.ComputedHeight(), height, 16);
- printf("c=%s,%s ", width, height);
-
- if (aFrame->HasAnyStateBits(NS_FRAME_IS_DIRTY)) printf("dirty ");
-
- if (aFrame->HasAnyStateBits(NS_FRAME_HAS_DIRTY_CHILDREN))
- printf("dirty-children ");
-
- if (aReflowInput.mFlags.mSpecialBSizeReflow) printf("special-bsize ");
-
- if (aReflowInput.IsHResize()) printf("h-resize ");
-
- if (aReflowInput.IsVResize()) printf("v-resize ");
-
- nsIFrame* inFlow = aFrame->GetPrevInFlow();
- if (inFlow) {
- printf("pif=%p ", (void*)inFlow);
- }
- inFlow = aFrame->GetNextInFlow();
- if (inFlow) {
- printf("nif=%p ", (void*)inFlow);
- }
- if (aChanged)
- printf("CHANGED \n");
- else
- printf("cnt=%d \n", DR_state->mCount);
- if (DR_state->mDisplayPixelErrors) {
- int32_t d2a = aPresContext->AppUnitsPerDevPixel();
- CheckPixelError(aReflowInput.AvailableWidth(), d2a);
- CheckPixelError(aReflowInput.AvailableHeight(), d2a);
- CheckPixelError(aReflowInput.ComputedWidth(), d2a);
- CheckPixelError(aReflowInput.ComputedHeight(), d2a);
- }
- }
-}
-
-void* nsIFrame::DisplayReflowEnter(nsPresContext* aPresContext,
- nsIFrame* aFrame,
- const ReflowInput& aReflowInput) {
- if (!DR_state->mInited) DR_state->Init();
- if (!DR_state->mActive) return nullptr;
-
- NS_ASSERTION(aFrame, "invalid call");
-
- DR_FrameTreeNode* treeNode = DR_state->CreateTreeNode(aFrame, &aReflowInput);
- if (treeNode) {
- DisplayReflowEnterPrint(aPresContext, aFrame, aReflowInput, *treeNode,
- false);
- }
- return treeNode;
-}
-
-void* nsIFrame::DisplayLayoutEnter(nsIFrame* aFrame) {
- if (!DR_state->mInited) DR_state->Init();
- if (!DR_state->mActive) return nullptr;
-
- NS_ASSERTION(aFrame, "invalid call");
-
- DR_FrameTreeNode* treeNode = DR_state->CreateTreeNode(aFrame, nullptr);
- if (treeNode && treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
- printf("XULLayout\n");
- }
- return treeNode;
-}
-
-void* nsIFrame::DisplayIntrinsicISizeEnter(nsIFrame* aFrame,
- const char* aType) {
- if (!DR_state->mInited) DR_state->Init();
- if (!DR_state->mActive) return nullptr;
-
- NS_ASSERTION(aFrame, "invalid call");
-
- DR_FrameTreeNode* treeNode = DR_state->CreateTreeNode(aFrame, nullptr);
- if (treeNode && treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
- printf("Get%sISize\n", aType);
- }
- return treeNode;
-}
-
-void* nsIFrame::DisplayIntrinsicSizeEnter(nsIFrame* aFrame, const char* aType) {
- if (!DR_state->mInited) DR_state->Init();
- if (!DR_state->mActive) return nullptr;
-
- NS_ASSERTION(aFrame, "invalid call");
-
- DR_FrameTreeNode* treeNode = DR_state->CreateTreeNode(aFrame, nullptr);
- if (treeNode && treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
- printf("Get%sSize\n", aType);
- }
- return treeNode;
-}
-
-void nsIFrame::DisplayReflowExit(nsPresContext* aPresContext, nsIFrame* aFrame,
- ReflowOutput& aMetrics,
- const nsReflowStatus& aStatus,
- void* aFrameTreeNode) {
- if (!DR_state->mActive) return;
-
- NS_ASSERTION(aFrame, "DisplayReflowExit - invalid call");
- if (!aFrameTreeNode) return;
-
- DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aFrameTreeNode;
- if (treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
-
- char width[16];
- char height[16];
- char x[16];
- char y[16];
- DR_state->PrettyUC(aMetrics.Width(), width, 16);
- DR_state->PrettyUC(aMetrics.Height(), height, 16);
- printf("Reflow d=%s,%s", width, height);
-
- if (!aStatus.IsEmpty()) {
- printf(" status=%s", ToString(aStatus).c_str());
- }
- if (aFrame->HasOverflowAreas()) {
- DR_state->PrettyUC(aMetrics.InkOverflow().x, x, 16);
- DR_state->PrettyUC(aMetrics.InkOverflow().y, y, 16);
- DR_state->PrettyUC(aMetrics.InkOverflow().width, width, 16);
- DR_state->PrettyUC(aMetrics.InkOverflow().height, height, 16);
- printf(" vis-o=(%s,%s) %s x %s", x, y, width, height);
-
- nsRect storedOverflow = aFrame->InkOverflowRect();
- DR_state->PrettyUC(storedOverflow.x, x, 16);
- DR_state->PrettyUC(storedOverflow.y, y, 16);
- DR_state->PrettyUC(storedOverflow.width, width, 16);
- DR_state->PrettyUC(storedOverflow.height, height, 16);
- printf(" vis-sto=(%s,%s) %s x %s", x, y, width, height);
-
- DR_state->PrettyUC(aMetrics.ScrollableOverflow().x, x, 16);
- DR_state->PrettyUC(aMetrics.ScrollableOverflow().y, y, 16);
- DR_state->PrettyUC(aMetrics.ScrollableOverflow().width, width, 16);
- DR_state->PrettyUC(aMetrics.ScrollableOverflow().height, height, 16);
- printf(" scr-o=(%s,%s) %s x %s", x, y, width, height);
-
- storedOverflow = aFrame->ScrollableOverflowRect();
- DR_state->PrettyUC(storedOverflow.x, x, 16);
- DR_state->PrettyUC(storedOverflow.y, y, 16);
- DR_state->PrettyUC(storedOverflow.width, width, 16);
- DR_state->PrettyUC(storedOverflow.height, height, 16);
- printf(" scr-sto=(%s,%s) %s x %s", x, y, width, height);
- }
- printf("\n");
- if (DR_state->mDisplayPixelErrors) {
- int32_t d2a = aPresContext->AppUnitsPerDevPixel();
- CheckPixelError(aMetrics.Width(), d2a);
- CheckPixelError(aMetrics.Height(), d2a);
- }
- }
- DR_state->DeleteTreeNode(*treeNode);
-}
-
-void nsIFrame::DisplayLayoutExit(nsIFrame* aFrame, void* aFrameTreeNode) {
- if (!DR_state->mActive) return;
-
- NS_ASSERTION(aFrame, "non-null frame required");
- if (!aFrameTreeNode) return;
-
- DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aFrameTreeNode;
- if (treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
- nsRect rect = aFrame->GetRect();
- printf("XULLayout=%d,%d,%d,%d\n", rect.x, rect.y, rect.width, rect.height);
- }
- DR_state->DeleteTreeNode(*treeNode);
-}
-
-void nsIFrame::DisplayIntrinsicISizeExit(nsIFrame* aFrame, const char* aType,
- nscoord aResult,
- void* aFrameTreeNode) {
- if (!DR_state->mActive) return;
-
- NS_ASSERTION(aFrame, "non-null frame required");
- if (!aFrameTreeNode) return;
-
- DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aFrameTreeNode;
- if (treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
- char iSize[16];
- DR_state->PrettyUC(aResult, iSize, 16);
- printf("Get%sISize=%s\n", aType, iSize);
- }
- DR_state->DeleteTreeNode(*treeNode);
-}
-
-void nsIFrame::DisplayIntrinsicSizeExit(nsIFrame* aFrame, const char* aType,
- nsSize aResult, void* aFrameTreeNode) {
- if (!DR_state->mActive) return;
-
- NS_ASSERTION(aFrame, "non-null frame required");
- if (!aFrameTreeNode) return;
-
- DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aFrameTreeNode;
- if (treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
-
- char width[16];
- char height[16];
- DR_state->PrettyUC(aResult.width, width, 16);
- DR_state->PrettyUC(aResult.height, height, 16);
- printf("Get%sSize=%s,%s\n", aType, width, height);
- }
- DR_state->DeleteTreeNode(*treeNode);
-}
-
-/* static */
-void nsIFrame::DisplayReflowStartup() { DR_state = new DR_State(); }
-
-/* static */
-void nsIFrame::DisplayReflowShutdown() {
- delete DR_state;
- DR_state = nullptr;
-}
-
-void DR_cookie::Change() const {
- DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)mValue;
- if (treeNode && treeNode->mDisplay) {
- DisplayReflowEnterPrint(mPresContext, mFrame, mReflowInput, *treeNode,
- true);
- }
-}
-
-/* static */
-void* ReflowInput::DisplayInitConstraintsEnter(nsIFrame* aFrame,
- ReflowInput* aState,
- nscoord aContainingBlockWidth,
- nscoord aContainingBlockHeight,
- const nsMargin* aBorder,
- const nsMargin* aPadding) {
- MOZ_ASSERT(aFrame, "non-null frame required");
- MOZ_ASSERT(aState, "non-null state required");
-
- if (!DR_state->mInited) DR_state->Init();
- if (!DR_state->mActive) return nullptr;
-
- DR_FrameTreeNode* treeNode = DR_state->CreateTreeNode(aFrame, aState);
- if (treeNode && treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
-
- printf("InitConstraints parent=%p", (void*)aState->mParentReflowInput);
-
- char width[16];
- char height[16];
-
- DR_state->PrettyUC(aContainingBlockWidth, width, 16);
- DR_state->PrettyUC(aContainingBlockHeight, height, 16);
- printf(" cb=%s,%s", width, height);
-
- DR_state->PrettyUC(aState->AvailableWidth(), width, 16);
- DR_state->PrettyUC(aState->AvailableHeight(), height, 16);
- printf(" as=%s,%s", width, height);
-
- DR_state->PrintMargin("b", aBorder);
- DR_state->PrintMargin("p", aPadding);
- putchar('\n');
- }
- return treeNode;
-}
-
-/* static */
-void ReflowInput::DisplayInitConstraintsExit(nsIFrame* aFrame,
- ReflowInput* aState,
- void* aValue) {
- MOZ_ASSERT(aFrame, "non-null frame required");
- MOZ_ASSERT(aState, "non-null state required");
-
- if (!DR_state->mActive) return;
- if (!aValue) return;
-
- DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aValue;
- if (treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
- char cmiw[16], cw[16], cmxw[16], cmih[16], ch[16], cmxh[16];
- DR_state->PrettyUC(aState->ComputedMinWidth(), cmiw, 16);
- DR_state->PrettyUC(aState->ComputedWidth(), cw, 16);
- DR_state->PrettyUC(aState->ComputedMaxWidth(), cmxw, 16);
- DR_state->PrettyUC(aState->ComputedMinHeight(), cmih, 16);
- DR_state->PrettyUC(aState->ComputedHeight(), ch, 16);
- DR_state->PrettyUC(aState->ComputedMaxHeight(), cmxh, 16);
- printf("InitConstraints= cw=(%s <= %s <= %s) ch=(%s <= %s <= %s)", cmiw, cw,
- cmxw, cmih, ch, cmxh);
- const nsMargin m = aState->ComputedPhysicalOffsets();
- DR_state->PrintMargin("co", &m);
- putchar('\n');
- }
- DR_state->DeleteTreeNode(*treeNode);
-}
-
-/* static */
-void* SizeComputationInput::DisplayInitOffsetsEnter(
- nsIFrame* aFrame, SizeComputationInput* aState, nscoord aPercentBasis,
- WritingMode aCBWritingMode, const nsMargin* aBorder,
- const nsMargin* aPadding) {
- MOZ_ASSERT(aFrame, "non-null frame required");
- MOZ_ASSERT(aState, "non-null state required");
-
- if (!DR_state->mInited) DR_state->Init();
- if (!DR_state->mActive) return nullptr;
-
- // aState is not necessarily a ReflowInput
- DR_FrameTreeNode* treeNode = DR_state->CreateTreeNode(aFrame, nullptr);
- if (treeNode && treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
-
- char pctBasisStr[16];
- DR_state->PrettyUC(aPercentBasis, pctBasisStr, 16);
- printf("InitOffsets pct_basis=%s", pctBasisStr);
-
- DR_state->PrintMargin("b", aBorder);
- DR_state->PrintMargin("p", aPadding);
- putchar('\n');
- }
- return treeNode;
-}
-
-/* static */
-void SizeComputationInput::DisplayInitOffsetsExit(nsIFrame* aFrame,
- SizeComputationInput* aState,
- void* aValue) {
- MOZ_ASSERT(aFrame, "non-null frame required");
- MOZ_ASSERT(aState, "non-null state required");
-
- if (!DR_state->mActive) return;
- if (!aValue) return;
-
- DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aValue;
- if (treeNode->mDisplay) {
- DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
- printf("InitOffsets=");
- const auto m = aState->ComputedPhysicalMargin();
- DR_state->PrintMargin("m", &m);
- const auto p = aState->ComputedPhysicalPadding();
- DR_state->PrintMargin("p", &p);
- const auto bp = aState->ComputedPhysicalBorderPadding();
- DR_state->PrintMargin("b+p", &bp);
- putchar('\n');
- }
- DR_state->DeleteTreeNode(*treeNode);
-}
-
-// End Display Reflow
-
// Validation of SideIsVertical.
# define CASE(side, result) \
static_assert(SideIsVertical(side) == result, "SideIsVertical is wrong")
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
index 16f3d17d64..6e55ebe1c7 100644
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -937,6 +937,8 @@ class nsIFrame : public nsQueryFrame {
already_AddRefed<ComputedStyle> ComputeHighlightSelectionStyle(
nsAtom* aHighlightName);
+ already_AddRefed<ComputedStyle> ComputeTargetTextStyle() const;
+
/**
* Accessor functions for geometric parent.
*/
@@ -1586,6 +1588,11 @@ class nsIFrame : public nsQueryFrame {
bool GetShapeBoxBorderRadii(nscoord aRadii[8]) const;
/**
+ * Returns one em unit, adjusted for font inflation if needed, in app units.
+ */
+ nscoord OneEmInAppUnits() const;
+
+ /**
* `GetNaturalBaselineBOffset`, but determines the baseline sharing group
* through `GetDefaultBaselineSharingGroup` (If not specified), assuming line
* layout context, and never fails, returning a synthesized baseline through
@@ -3932,6 +3939,9 @@ class nsIFrame : public nsQueryFrame {
public:
// given a frame five me the first/last leaf available
// XXX Robert O'Callahan wants to move these elsewhere
+ // FIXME: Only GetLastLeaf() never returns a leaf frame in native anonymous
+ // subtrees under aFrame. However, GetFirstLeaf() may return a leaf frame
+ // in a native anonymous subtree.
static void GetLastLeaf(nsIFrame** aFrame);
static void GetFirstLeaf(nsIFrame** aFrame);
@@ -5482,25 +5492,6 @@ class nsIFrame : public nsQueryFrame {
// NS_FRAME_IS_DIRTY bit set
static void VerifyDirtyBitSet(const nsFrameList& aFrameList);
- // Display Reflow Debugging
- static void* DisplayReflowEnter(nsPresContext* aPresContext, nsIFrame* aFrame,
- const ReflowInput& aReflowInput);
- static void* DisplayLayoutEnter(nsIFrame* aFrame);
- static void* DisplayIntrinsicISizeEnter(nsIFrame* aFrame, const char* aType);
- static void* DisplayIntrinsicSizeEnter(nsIFrame* aFrame, const char* aType);
- static void DisplayReflowExit(nsPresContext* aPresContext, nsIFrame* aFrame,
- ReflowOutput& aMetrics,
- const nsReflowStatus& aStatus,
- void* aFrameTreeNode);
- static void DisplayLayoutExit(nsIFrame* aFrame, void* aFrameTreeNode);
- static void DisplayIntrinsicISizeExit(nsIFrame* aFrame, const char* aType,
- nscoord aResult, void* aFrameTreeNode);
- static void DisplayIntrinsicSizeExit(nsIFrame* aFrame, const char* aType,
- nsSize aResult, void* aFrameTreeNode);
-
- static void DisplayReflowStartup();
- static void DisplayReflowShutdown();
-
static mozilla::LazyLogModule sFrameLogModule;
#endif
};
diff --git a/layout/generic/nsIFrameInlines.h b/layout/generic/nsIFrameInlines.h
index e187f0dfb0..f53ba607c0 100644
--- a/layout/generic/nsIFrameInlines.h
+++ b/layout/generic/nsIFrameInlines.h
@@ -36,7 +36,7 @@ bool nsIFrame::IsFlexOrGridItem() const {
bool nsIFrame::IsMasonry(mozilla::LogicalAxis aAxis) const {
MOZ_DIAGNOSTIC_ASSERT(IsGridContainerFrame());
- return HasAnyStateBits(aAxis == mozilla::eLogicalAxisBlock
+ return HasAnyStateBits(aAxis == mozilla::LogicalAxis::Block
? NS_STATE_GRID_IS_ROW_MASONRY
: NS_STATE_GRID_IS_COL_MASONRY);
}
diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp
index c1e69df6c9..91d8430b60 100644
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1476,8 +1476,6 @@ nscoord nsImageFrame::GetContinuationOffset() const {
nscoord nsImageFrame::GetMinISize(gfxContext* aRenderingContext) {
// XXX The caller doesn't account for constraints of the block-size,
// min-block-size, and max-block-size properties.
- DebugOnly<nscoord> result;
- DISPLAY_MIN_INLINE_SIZE(this, result);
EnsureIntrinsicSizeAndRatio();
const auto& iSize = GetWritingMode().IsVertical() ? mIntrinsicSize.height
: mIntrinsicSize.width;
@@ -1487,8 +1485,6 @@ nscoord nsImageFrame::GetMinISize(gfxContext* aRenderingContext) {
nscoord nsImageFrame::GetPrefISize(gfxContext* aRenderingContext) {
// XXX The caller doesn't account for constraints of the block-size,
// min-block-size, and max-block-size properties.
- DebugOnly<nscoord> result;
- DISPLAY_PREF_INLINE_SIZE(this, result);
EnsureIntrinsicSizeAndRatio();
const auto& iSize = GetWritingMode().IsVertical() ? mIntrinsicSize.height
: mIntrinsicSize.width;
@@ -1526,7 +1522,6 @@ void nsImageFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsImageFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
NS_FRAME_TRACE(
NS_FRAME_TRACE_CALLS,
diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp
index 7a99ecbe5d..b481c71827 100644
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -270,7 +270,6 @@ void nsInlineFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsInlineFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
if (!aReflowInput.mLineLayout) {
diff --git a/layout/generic/nsLeafFrame.cpp b/layout/generic/nsLeafFrame.cpp
index 2688da3d4b..6125f6b800 100644
--- a/layout/generic/nsLeafFrame.cpp
+++ b/layout/generic/nsLeafFrame.cpp
@@ -24,18 +24,12 @@ void nsLeafFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
/* virtual */
nscoord nsLeafFrame::GetMinISize(gfxContext* aRenderingContext) {
- nscoord result;
- DISPLAY_MIN_INLINE_SIZE(this, result);
- result = GetIntrinsicISize();
- return result;
+ return GetIntrinsicISize();
}
/* virtual */
nscoord nsLeafFrame::GetPrefISize(gfxContext* aRenderingContext) {
- nscoord result;
- DISPLAY_PREF_INLINE_SIZE(this, result);
- result = GetIntrinsicISize();
- return result;
+ return GetIntrinsicISize();
}
/* virtual */
diff --git a/layout/generic/nsLineBox.cpp b/layout/generic/nsLineBox.cpp
index 18051aa69a..53a6914030 100644
--- a/layout/generic/nsLineBox.cpp
+++ b/layout/generic/nsLineBox.cpp
@@ -217,7 +217,7 @@ void nsLineBox::List(FILE* out, const char* aPrefix,
IsPreviousMarginDirty() ? "prevmargindirty" : "prevmarginclean",
IsImpactedByFloat() ? "impacted" : "not-impacted",
IsLineWrapped() ? "wrapped" : "not-wrapped",
- HasForcedLineBreak() ? "forced-break" : "no-break",
+ HasForcedLineBreakAfter() ? "forced-break-after" : "no-break",
StyleClearToString(FloatClearTypeBefore()),
StyleClearToString(FloatClearTypeAfter()));
diff --git a/layout/generic/nsLineBox.h b/layout/generic/nsLineBox.h
index d46cf9604a..e35f36a481 100644
--- a/layout/generic/nsLineBox.h
+++ b/layout/generic/nsLineBox.h
@@ -238,42 +238,40 @@ class nsLineBox final : public nsLineLink {
}
}
- // mHasForcedLineBreak bit & mFloatClearType value
- // Break information is applied *before* the line if the line is a block,
- // or *after* the line if the line is an inline.
- bool HasForcedLineBreak() const { return mFlags.mHasForcedLineBreak; }
+ // mHasForcedLineBreakAfter bit & mFloatClearType value
void ClearForcedLineBreak() {
- mFlags.mHasForcedLineBreak = false;
+ mFlags.mHasForcedLineBreakAfter = false;
mFlags.mFloatClearType = mozilla::StyleClear::None;
}
- bool HasForcedLineBreakBefore() const {
- return IsBlock() && HasForcedLineBreak();
+ bool HasFloatClearTypeBefore() const {
+ return FloatClearTypeBefore() != mozilla::StyleClear::None;
}
- void SetForcedLineBreakBefore(mozilla::StyleClear aClearType) {
- MOZ_ASSERT(IsBlock(), "Only blocks have break-before");
+ void SetFloatClearTypeBefore(mozilla::StyleClear aClearType) {
+ MOZ_ASSERT(IsBlock(), "Only block lines have break-before status!");
MOZ_ASSERT(aClearType != mozilla::StyleClear::None,
"Only StyleClear:Left/Right/Both are allowed before a line");
- mFlags.mHasForcedLineBreak = true;
mFlags.mFloatClearType = aClearType;
}
mozilla::StyleClear FloatClearTypeBefore() const {
- return IsBlock() ? FloatClearType() : mozilla::StyleClear::None;
+ return IsBlock() ? mFlags.mFloatClearType : mozilla::StyleClear::None;
}
bool HasForcedLineBreakAfter() const {
- return IsInline() && HasForcedLineBreak();
+ MOZ_ASSERT(IsInline() || !mFlags.mHasForcedLineBreakAfter,
+ "A block line shouldn't set mHasForcedLineBreakAfter bit!");
+ return IsInline() && mFlags.mHasForcedLineBreakAfter;
}
void SetForcedLineBreakAfter(mozilla::StyleClear aClearType) {
- MOZ_ASSERT(IsInline(), "Only inlines have break-after");
- mFlags.mHasForcedLineBreak = true;
+ MOZ_ASSERT(IsInline(), "Only inline lines have break-after status!");
+ mFlags.mHasForcedLineBreakAfter = true;
mFlags.mFloatClearType = aClearType;
}
bool HasFloatClearTypeAfter() const {
- return IsInline() && FloatClearType() != mozilla::StyleClear::None;
+ return FloatClearTypeAfter() != mozilla::StyleClear::None;
}
mozilla::StyleClear FloatClearTypeAfter() const {
- return IsInline() ? FloatClearType() : mozilla::StyleClear::None;
+ return IsInline() ? mFlags.mFloatClearType : mozilla::StyleClear::None;
}
// mCarriedOutBEndMargin value
@@ -316,7 +314,7 @@ class nsLineBox final : public nsLineLink {
nsRect InkOverflowRect() const {
return GetOverflowArea(mozilla::OverflowType::Ink);
}
- nsRect ScrollableOverflowRect() {
+ nsRect ScrollableOverflowRect() const {
return GetOverflowArea(mozilla::OverflowType::Scrollable);
}
@@ -520,11 +518,15 @@ class nsLineBox final : public nsLineLink {
// Has this line moved to a different fragment of the block since
// the last time it was reflowed?
bool mMovedFragments : 1;
- // mHasForcedLineBreak indicates that this line has either a break-before or
- // a break-after.
- bool mHasForcedLineBreak : 1;
- // mFloatClearType indicates that there's a float clearance before or after
- // this line.
+ // mHasForcedLineBreakAfter indicates that this *inline* line has a
+ // break-after status due to a float clearance or ending with <br>. A block
+ // line shouldn't set this bit.
+ //
+ // Note: This bit is unrelated to CSS break-after property because it is all
+ // about line break-after for inline-level boxes.
+ bool mHasForcedLineBreakAfter : 1;
+ // mFloatClearType indicates that there's a float clearance before a block
+ // line, or after an inline line.
mozilla::StyleClear mFloatClearType;
};
@@ -570,8 +572,6 @@ class nsLineBox final : public nsLineLink {
FlagBits mFlags;
};
- mozilla::StyleClear FloatClearType() const { return mFlags.mFloatClearType; };
-
union {
ExtraData* mData;
ExtraBlockData* mBlockData;
diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp
index ab6924faa4..be6f64f1fe 100644
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -1713,10 +1713,10 @@ void nsLineLayout::AdjustLeadings(nsIFrame* spanFrame, PerSpanData* psd,
if (aStyleText->HasEffectiveTextEmphasis()) {
nscoord bsize = GetBSizeOfEmphasisMarks(spanFrame, aInflation);
LogicalSide side = aStyleText->TextEmphasisSide(mRootSpan->mWritingMode);
- if (side == eLogicalSideBStart) {
+ if (side == LogicalSide::BStart) {
requiredStartLeading += bsize;
} else {
- MOZ_ASSERT(side == eLogicalSideBEnd,
+ MOZ_ASSERT(side == LogicalSide::BEnd,
"emphasis marks must be in block axis");
requiredEndLeading += bsize;
}
@@ -2341,7 +2341,7 @@ void nsLineLayout::VerticalAlignFrames(PerSpanData* psd) {
delta = emphasisHeight;
}
LogicalSide side = mStyleText->TextEmphasisSide(lineWM);
- if (side == eLogicalSideBStart) {
+ if (side == LogicalSide::BStart) {
blockStart -= delta;
} else {
blockEnd += delta;
diff --git a/layout/generic/nsPageContentFrame.cpp b/layout/generic/nsPageContentFrame.cpp
index 11e634894d..1c82ca1523 100644
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -35,7 +35,6 @@ void nsPageContentFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsPageContentFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aReflowOutput, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
MOZ_ASSERT(mPD, "Need a pointer to nsSharedPageData before reflow starts");
diff --git a/layout/generic/nsPageFrame.cpp b/layout/generic/nsPageFrame.cpp
index fb9cfa2e81..de573962af 100644
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -9,6 +9,7 @@
#include "mozilla/AppUnits.h"
#include "mozilla/PresShell.h"
#include "mozilla/StaticPrefs_layout.h"
+#include "mozilla/StaticPrefs_print.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/intl/Segmenter.h"
#include "gfxContext.h"
@@ -213,7 +214,6 @@ void nsPageFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsPageFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aReflowOutput, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
MOZ_ASSERT(mPD, "Need a pointer to nsSharedPageData before reflow starts");
@@ -540,6 +540,69 @@ static std::tuple<uint32_t, uint32_t> GetRowAndColFromIdx(uint32_t aIdxOnSheet,
return {aIdxOnSheet / aNumCols, aIdxOnSheet % aNumCols};
}
+// The minimum ratio for which we will center the page on the sheet when using
+// auto-detect logic.
+// Note that this ratio is of the content's size to the sheet size scaled to be
+// in content space, and so the actual ratio will always be from 0.0 to 1.0,
+// with this marking the smallest ratio we consider a near-miss.
+// The ratio of A4 on Letter is 0.915034. A threshold of 0.9 will ensure that
+// A4 on Letter works, as well as other near-misses.
+//
+// The ratio is computed as so:
+// scale = min(1, sheetHeight / pageHeight, sheetWidth / pageWidth)
+//
+// Where pageSize is pageWidth or pageHeight, and sheetSize is sheetWidth or
+// sheetHeight, respectively:
+// scaledPageSize = pageSize * scale
+// ratio = scaledPageSize / sheetSize
+//
+// A4 (210mm x 297mm) on US Letter (215.9mm x 279.4mm) is derived as so:
+// scale = min(1, 215.9 / 210, 279.4 / 297) = 0.9407407407..
+//
+// Using the widths:
+// scaledPageSize = (210 * 0.940741) = 197.556
+// ratio = 197.556 / 215.9 = 0.915034
+//
+// See nsPageFrame::ComputeSinglePPSPageSizeScale for scale calculation, and
+// OffsetToCenterPage for ratio calculation.
+constexpr float kCenterPageRatioThreshold = 0.9f;
+
+// Numeric values for the pref "print.center_page_on_sheet"
+enum {
+ kPrintCenterPageOnSheetNever = 0,
+ kPrintCenterPageOnSheetAlways = 1,
+ kPrintCenterPageOnSheetAuto = 2
+};
+
+// Returns an offset to center the page on the sheet, with a given scale.
+// When no centering can/should happen, this will avoid extra calculations and
+// return 0.0f.
+// This takes into account the value of the pref "print.center_page_on_sheet".
+static float OffsetToCenterPage(nscoord aContentSize, nscoord aSheetSize,
+ float aScale, float aAppUnitsPerPixel) {
+ MOZ_ASSERT(aScale <= 1.0f && aScale > 0.0f,
+ "Scale must be in the range (0,1]");
+ const unsigned centerPagePref = StaticPrefs::print_center_page_on_sheet();
+ if (centerPagePref == kPrintCenterPageOnSheetNever) {
+ return 0.0f;
+ }
+
+ // Determine the ratio of scaled page to the sheet size.
+ const float sheetSize =
+ NSAppUnitsToFloatPixels(aSheetSize, aAppUnitsPerPixel);
+ const float scaledContentSize =
+ NSAppUnitsToFloatPixels(aContentSize, aAppUnitsPerPixel) * aScale;
+ const float ratio = scaledContentSize / sheetSize;
+
+ // If the ratio is within the threshold, or the pref indicates we should
+ // always center the page, return half the difference to form the offset.
+ if (centerPagePref == kPrintCenterPageOnSheetAlways ||
+ ratio >= kCenterPageRatioThreshold) {
+ return (sheetSize - scaledContentSize) * 0.5f;
+ }
+ return 0.0f;
+}
+
// Helper for BuildDisplayList:
static gfx::Matrix4x4 ComputePagesPerSheetAndPageSizeTransform(
const nsIFrame* aFrame, float aAppUnitsPerPixel) {
@@ -561,8 +624,8 @@ static gfx::Matrix4x4 ComputePagesPerSheetAndPageSizeTransform(
gfx::Matrix4x4 transform;
if (ppsInfo->mNumPages == 1) {
+ const nsSize sheetSize = sheetFrame->GetSizeForChildren();
if (rotation != 0.0) {
- const nsSize sheetSize = sheetFrame->GetSizeForChildren();
const bool sheetIsPortrait = sheetSize.width < sheetSize.height;
const bool rotatingClockwise = rotation > 0.0;
@@ -584,7 +647,21 @@ static gfx::Matrix4x4 ComputePagesPerSheetAndPageSizeTransform(
NSAppUnitsToFloatPixels(-y, aAppUnitsPerPixel), 0);
}
- float scale = pageFrame->ComputeSinglePPSPageSizeScale(contentPageSize);
+ // If the difference in horizontal size, after scaling, is relatively small
+ // then center the page on the sheet.
+ const float scale =
+ pageFrame->ComputeSinglePPSPageSizeScale(contentPageSize);
+ const float centeringOffset = OffsetToCenterPage(
+ contentPageSize.width, sheetSize.width, scale, aAppUnitsPerPixel);
+
+ // Only bother with the translation if it is at least one pixel.
+ // It's possible for a mismatch in the paper size reported by the print
+ // server and the paper size from Gecko to lead to small offsets, or
+ // even (in combination with floating point error) a very small negative
+ // offset. Do not apply an offset in those cases.
+ if (centeringOffset >= 1.0f) {
+ transform.PreTranslate(centeringOffset, 0, 0);
+ }
transform.PreScale(scale, scale, 1);
return transform;
}
@@ -937,7 +1014,6 @@ void nsPageBreakFrame::Reflow(nsPresContext* aPresContext,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) {
DO_GLOBAL_REFLOW_COUNT("nsPageBreakFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aReflowOutput, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
// Override reflow, since we don't want to deal with what our
diff --git a/layout/generic/nsPageSequenceFrame.cpp b/layout/generic/nsPageSequenceFrame.cpp
index a3348433cb..cd3c2cd6a5 100644
--- a/layout/generic/nsPageSequenceFrame.cpp
+++ b/layout/generic/nsPageSequenceFrame.cpp
@@ -266,7 +266,6 @@ void nsPageSequenceFrame::Reflow(nsPresContext* aPresContext,
MOZ_ASSERT(aPresContext->IsRootPaginatedDocument(),
"A Page Sequence is only for real pages");
DO_GLOBAL_REFLOW_COUNT("nsPageSequenceFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aReflowOutput, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
NS_FRAME_TRACE_REFLOW_IN("nsPageSequenceFrame::Reflow");
diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp
index f6b4d53193..aad2c816e5 100644
--- a/layout/generic/nsPlaceholderFrame.cpp
+++ b/layout/generic/nsPlaceholderFrame.cpp
@@ -124,7 +124,6 @@ void nsPlaceholderFrame::Reflow(nsPresContext* aPresContext,
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsPlaceholderFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
aDesiredSize.ClearSize();
}
diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp
index 6e29152bc9..50b08b6f5b 100644
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -275,7 +275,6 @@ void nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsRubyBaseContainerFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
if (!aReflowInput.mLineLayout) {
diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp
index d7da5bc321..d6119f44fb 100644
--- a/layout/generic/nsRubyFrame.cpp
+++ b/layout/generic/nsRubyFrame.cpp
@@ -94,7 +94,6 @@ void nsRubyFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsRubyFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
if (!aReflowInput.mLineLayout) {
@@ -345,11 +344,11 @@ void nsRubyFrame::ReflowSegment(nsPresContext* aPresContext,
: 0);
position = offsetRect.Origin(lineWM) + offset;
aReflowInput.mLineLayout->AdvanceICoord(size.ISize(lineWM));
- } else if (logicalSide == eLogicalSideBStart) {
+ } else if (logicalSide == LogicalSide::BStart) {
offsetRect.BStart(lineWM) -= size.BSize(lineWM);
offsetRect.BSize(lineWM) += size.BSize(lineWM);
position = offsetRect.Origin(lineWM);
- } else if (logicalSide == eLogicalSideBEnd) {
+ } else if (logicalSide == LogicalSide::BEnd) {
position = offsetRect.Origin(lineWM) +
LogicalPoint(lineWM, 0, offsetRect.BSize(lineWM));
offsetRect.BSize(lineWM) += size.BSize(lineWM);
diff --git a/layout/generic/nsRubyTextContainerFrame.cpp b/layout/generic/nsRubyTextContainerFrame.cpp
index 855d7c1825..8494b36a28 100644
--- a/layout/generic/nsRubyTextContainerFrame.cpp
+++ b/layout/generic/nsRubyTextContainerFrame.cpp
@@ -105,7 +105,6 @@ void nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsRubyTextContainerFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
// Although a ruby text container may have continuations, returning
diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp
index bfbd7763a9..69b4042033 100644
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -555,7 +555,6 @@ nsresult nsSubDocumentFrame::GetFrameName(nsAString& aResult) const {
/* virtual */
nscoord nsSubDocumentFrame::GetMinISize(gfxContext* aRenderingContext) {
nscoord result;
- DISPLAY_MIN_INLINE_SIZE(this, result);
nsCOMPtr<nsIObjectLoadingContent> iolc = do_QueryInterface(mContent);
auto olc = static_cast<nsObjectLoadingContent*>(iolc.get());
@@ -575,18 +574,13 @@ nscoord nsSubDocumentFrame::GetMinISize(gfxContext* aRenderingContext) {
/* virtual */
nscoord nsSubDocumentFrame::GetPrefISize(gfxContext* aRenderingContext) {
- nscoord result;
- DISPLAY_PREF_INLINE_SIZE(this, result);
-
// If the subdocument is an SVG document, then in theory we want to return
// the same thing that SVGOuterSVGFrame::GetPrefISize does. That method
// has some special handling of percentage values to avoid unhelpful zero
// sizing in the presence of orthogonal writing modes. We don't bother
// with that for SVG documents in <embed> and <object>, since that special
// handling doesn't look up across document boundaries anyway.
- result = GetIntrinsicISize();
-
- return result;
+ return GetIntrinsicISize();
}
/* virtual */
@@ -676,7 +670,6 @@ void nsSubDocumentFrame::Reflow(nsPresContext* aPresContext,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsSubDocumentFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
NS_FRAME_TRACE(
NS_FRAME_TRACE_CALLS,
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp
index 9afefc5c28..0ad527e842 100644
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -1929,8 +1929,8 @@ bool BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1,
// Map inline-end and inline-start to physical sides for checking presence
// of non-zero margin/border/padding.
- Side side1 = wm.PhysicalSide(eLogicalSideIEnd);
- Side side2 = wm.PhysicalSide(eLogicalSideIStart);
+ Side side1 = wm.PhysicalSide(LogicalSide::IEnd);
+ Side side2 = wm.PhysicalSide(LogicalSide::IStart);
// If the frames have an embedding level that is opposite to the writing
// mode, we need to swap which sides we're checking.
if (aFrame1->GetEmbeddingLevel().IsRTL() == wm.IsBidiLTR()) {
@@ -3611,6 +3611,20 @@ void nsTextFrame::PropertyProvider::GetSpacing(Range aRange,
!(mTextRun->GetFlags2() & nsTextFrameUtils::Flags::HasTab));
}
+static bool CanAddSpacingBefore(const gfxTextRun* aTextRun, uint32_t aOffset,
+ bool aNewlineIsSignificant) {
+ const auto* g = aTextRun->GetCharacterGlyphs();
+ MOZ_ASSERT(aOffset < aTextRun->GetLength());
+ if (aNewlineIsSignificant && g[aOffset].CharIsNewline()) {
+ return false;
+ }
+ if (!aOffset) {
+ return true;
+ }
+ return g[aOffset].IsClusterStart() && g[aOffset].IsLigatureGroupStart() &&
+ !g[aOffset - 1].CharIsFormattingControl() && !g[aOffset].CharIsTab();
+}
+
static bool CanAddSpacingAfter(const gfxTextRun* aTextRun, uint32_t aOffset,
bool aNewlineIsSignificant) {
const auto* g = aTextRun->GetCharacterGlyphs();
@@ -3683,14 +3697,45 @@ void nsTextFrame::PropertyProvider::GetSpacingInternal(Range aRange,
nsSkipCharsRunIterator run(
start, nsSkipCharsRunIterator::LENGTH_UNSKIPPED_ONLY, aRange.Length());
bool newlineIsSignificant = mTextStyle->NewlineIsSignificant(mFrame);
+ // Which letter-spacing model are we using?
+ // 0 - Gecko legacy model, spacing added to trailing side of letter
+ // 1 - WebKit/Blink-compatible, spacing added to right-hand side
+ // 2 - Symmetrical spacing, half added to each side
+ gfxFloat before, after;
+ switch (StaticPrefs::layout_css_letter_spacing_model()) {
+ default: // use Gecko legacy behavior if pref value is unknown
+ case 0:
+ before = 0.0;
+ after = mLetterSpacing;
+ break;
+ case 1:
+ if (mTextRun->IsRightToLeft()) {
+ before = mLetterSpacing;
+ after = 0.0;
+ } else {
+ before = 0.0;
+ after = mLetterSpacing;
+ }
+ break;
+ case 2:
+ before = mLetterSpacing / 2.0;
+ after = mLetterSpacing - before;
+ break;
+ }
while (run.NextRun()) {
uint32_t runOffsetInSubstring = run.GetSkippedOffset() - aRange.start;
gfxSkipCharsIterator iter = run.GetPos();
for (int32_t i = 0; i < run.GetRunLength(); ++i) {
- if (CanAddSpacingAfter(mTextRun, run.GetSkippedOffset() + i,
+ if (before != 0.0 &&
+ CanAddSpacingBefore(mTextRun, run.GetSkippedOffset() + i,
+ newlineIsSignificant)) {
+ aSpacing[runOffsetInSubstring + i].mBefore += before;
+ }
+ if (after != 0.0 &&
+ CanAddSpacingAfter(mTextRun, run.GetSkippedOffset() + i,
newlineIsSignificant)) {
// End of a cluster, not in a ligature: put letter-spacing after it
- aSpacing[runOffsetInSubstring + i].mAfter += mLetterSpacing;
+ aSpacing[runOffsetInSubstring + i].mAfter += after;
}
if (IsCSSWordSpacingSpace(mFrag, i + run.GetOriginalOffset(), mFrame,
mTextStyle)) {
@@ -5050,25 +5095,25 @@ nsRect nsTextFrame::UpdateTextEmphasis(WritingMode aWM,
: do_AddRef(aProvider.GetFontMetrics());
// When the writing mode is vertical-lr the line is inverted, and thus
// the ascent and descent are swapped.
- nscoord absOffset = (side == eLogicalSideBStart) != aWM.IsLineInverted()
+ nscoord absOffset = (side == LogicalSide::BStart) != aWM.IsLineInverted()
? baseFontMetrics->MaxAscent() + fm->MaxDescent()
: baseFontMetrics->MaxDescent() + fm->MaxAscent();
RubyBlockLeadings leadings;
if (nsRubyFrame* ruby = FindFurthestInlineRubyAncestor(this)) {
leadings = ruby->GetBlockLeadings();
}
- if (side == eLogicalSideBStart) {
+ if (side == LogicalSide::BStart) {
info->baselineOffset = -absOffset - leadings.mStart;
overflowRect.BStart(aWM) = -overflowRect.BSize(aWM) - leadings.mStart;
} else {
- MOZ_ASSERT(side == eLogicalSideBEnd);
+ MOZ_ASSERT(side == LogicalSide::BEnd);
info->baselineOffset = absOffset + leadings.mEnd;
overflowRect.BStart(aWM) = frameSize.BSize(aWM) + leadings.mEnd;
}
// If text combined, fix the gap between the text frame and its parent.
if (isTextCombined) {
nscoord gap = (baseFontMetrics->MaxHeight() - frameSize.BSize(aWM)) / 2;
- overflowRect.BStart(aWM) += gap * (side == eLogicalSideBStart ? -1 : 1);
+ overflowRect.BStart(aWM) += gap * (side == LogicalSide::BStart ? -1 : 1);
}
SetProperty(EmphasisMarkProperty(), info);
@@ -5676,6 +5721,10 @@ bool nsTextFrame::GetSelectionTextColors(SelectionType aSelectionType,
aHighlightName, aBackground);
return hasForeground || hasBackground;
}
+ case SelectionType::eTargetText: {
+ aTextPaintStyle.GetTargetTextColors(aForeground, aBackground);
+ return true;
+ }
case SelectionType::eURLSecondary:
aTextPaintStyle.GetURLSecondaryColor(aForeground);
*aBackground = NS_RGBA(0, 0, 0, 0);
@@ -9216,7 +9265,6 @@ void nsTextFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsTextFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
InvalidateSelectionState();
diff --git a/layout/generic/nsTextPaintStyle.cpp b/layout/generic/nsTextPaintStyle.cpp
index e97a059b07..f29fa753d0 100644
--- a/layout/generic/nsTextPaintStyle.cpp
+++ b/layout/generic/nsTextPaintStyle.cpp
@@ -213,6 +213,24 @@ void nsTextPaintStyle::GetHighlightColors(nscolor* aForeColor,
*aBackColor = NS_TRANSPARENT;
}
+void nsTextPaintStyle::GetTargetTextColors(nscolor* aForeColor,
+ nscolor* aBackColor) {
+ NS_ASSERTION(aForeColor, "aForeColor is null");
+ NS_ASSERTION(aBackColor, "aBackColor is null");
+ const RefPtr<const ComputedStyle> targetTextStyle =
+ mFrame->ComputeTargetTextStyle();
+ if (targetTextStyle) {
+ *aForeColor = targetTextStyle->GetVisitedDependentColor(
+ &nsStyleText::mWebkitTextFillColor);
+ *aBackColor = targetTextStyle->GetVisitedDependentColor(
+ &nsStyleBackground::mBackgroundColor);
+ return;
+ }
+ // XXX(:jjaschke): Before shipping this feature, a sensible set of colors must
+ // be set (Bug 1867940).
+ // in the meantime, use the colors of find selection.
+ GetHighlightColors(aForeColor, aBackColor);
+}
bool nsTextPaintStyle::GetCustomHighlightTextColor(nsAtom* aHighlightName,
nscolor* aForeColor) {
NS_ASSERTION(aForeColor, "aForeColor is null");
diff --git a/layout/generic/nsTextPaintStyle.h b/layout/generic/nsTextPaintStyle.h
index adf28fdad8..94cd3cf322 100644
--- a/layout/generic/nsTextPaintStyle.h
+++ b/layout/generic/nsTextPaintStyle.h
@@ -65,6 +65,7 @@ class MOZ_STACK_CLASS nsTextPaintStyle {
*/
bool GetSelectionColors(nscolor* aForeColor, nscolor* aBackColor);
void GetHighlightColors(nscolor* aForeColor, nscolor* aBackColor);
+ void GetTargetTextColors(nscolor* aForeColor, nscolor* aBackColor);
// Computes colors for custom highlights.
// Returns false if there are no rules associated with `aHighlightName`.
bool GetCustomHighlightTextColor(nsAtom* aHighlightName, nscolor* aForeColor);
diff --git a/layout/generic/nsTextRunTransformations.cpp b/layout/generic/nsTextRunTransformations.cpp
index d18a7ec293..de9fd31fda 100644
--- a/layout/generic/nsTextRunTransformations.cpp
+++ b/layout/generic/nsTextRunTransformations.cpp
@@ -80,6 +80,26 @@ bool nsTransformedTextRun::SetPotentialLineBreaks(Range aRange,
return changed;
}
+void nsTransformedTextRun::SetEmergencyWrapPositions() {
+ // This parallels part of what gfxShapedText::SetupClusterBoundaries() does
+ // for normal textruns.
+ bool prevWasHyphen = false;
+ for (uint32_t pos : IntegerRange(mString.Length())) {
+ const char16_t ch = mString[pos];
+ if (prevWasHyphen) {
+ if (nsContentUtils::IsAlphanumeric(ch)) {
+ mCharacterGlyphs[pos].SetCanBreakBefore(
+ CompressedGlyph::FLAG_BREAK_TYPE_EMERGENCY_WRAP);
+ }
+ prevWasHyphen = false;
+ }
+ if (nsContentUtils::IsHyphen(ch) && pos &&
+ nsContentUtils::IsAlphanumeric(mString[pos - 1])) {
+ prevWasHyphen = true;
+ }
+ }
+}
+
size_t nsTransformedTextRun::SizeOfExcludingThis(
mozilla::MallocSizeOf aMallocSizeOf) {
size_t total = gfxTextRun::SizeOfExcludingThis(aMallocSizeOf);
diff --git a/layout/generic/nsTextRunTransformations.h b/layout/generic/nsTextRunTransformations.h
index 915211c6af..6bcf26a8c0 100644
--- a/layout/generic/nsTextRunTransformations.h
+++ b/layout/generic/nsTextRunTransformations.h
@@ -202,7 +202,10 @@ class nsTransformedTextRun final : public gfxTextRun {
mOwnsFactory(aOwnsFactory),
mNeedsRebuild(true) {
mCharacterGlyphs = reinterpret_cast<CompressedGlyph*>(this + 1);
+ SetEmergencyWrapPositions();
}
+
+ void SetEmergencyWrapPositions();
};
/**
diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp
index d5bcc45969..e003058c3e 100644
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -226,7 +226,6 @@ void nsVideoFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsVideoFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
NS_FRAME_TRACE(
NS_FRAME_TRACE_CALLS,
@@ -375,14 +374,9 @@ nsIFrame::SizeComputationResult nsVideoFrame::ComputeSize(
}
nscoord nsVideoFrame::GetMinISize(gfxContext* aRenderingContext) {
- nscoord result;
- // Bind the result variable to a RAII-based debug object - the variable
- // therefore must match the function's return value.
- DISPLAY_MIN_INLINE_SIZE(this, result);
// This call handles size-containment
nsSize size = GetIntrinsicSize().ToSize().valueOr(nsSize());
- result = GetWritingMode().IsVertical() ? size.height : size.width;
- return result;
+ return GetWritingMode().IsVertical() ? size.height : size.width;
}
nscoord nsVideoFrame::GetPrefISize(gfxContext* aRenderingContext) {
diff --git a/layout/generic/test/mochitest.toml b/layout/generic/test/mochitest.toml
index 5c06c90eb7..dcaac3de7a 100644
--- a/layout/generic/test/mochitest.toml
+++ b/layout/generic/test/mochitest.toml
@@ -12,6 +12,7 @@ support-files = [
"file_SlowTallImage.sjs",
"bug1174521.html",
"!/gfx/layers/apz/test/mochitest/apz_test_utils.js",
+ "selection_cross_shadow_boundary_helper.js",
]
["test_bug240933.html"]
@@ -265,6 +266,42 @@ support-files = [
["test_selection_changes_with_middle_mouse_button.html"]
+["test_selection_cross_shadow_boundary_1_backward_click.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_1_backward_drag.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_1_forward_click.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_1_forward_drag.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_2_backward_click.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_2_backward_drag.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_2_forward_click.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_2_forward_drag.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_multi_ranges_forward_drag.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_multi_ranges_forward_click.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_multi_ranges_backward_drag.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
+["test_selection_cross_shadow_boundary_multi_ranges_backward_click.html"]
+skip-if = ["release_or_beta"] # requires Selection.getComposedRanges to be enabled (Nightly only)
+
["test_selection_doubleclick.html"]
["test_selection_expanding.html"]
diff --git a/layout/generic/test/selection_cross_shadow_boundary_helper.js b/layout/generic/test/selection_cross_shadow_boundary_helper.js
new file mode 100644
index 0000000000..b2a596a27f
--- /dev/null
+++ b/layout/generic/test/selection_cross_shadow_boundary_helper.js
@@ -0,0 +1,28 @@
+// Helper file for test_selection_cross_shadow_boundary_* related tests
+
+function drag(
+ fromTarget,
+ fromX,
+ fromY,
+ toTarget,
+ toX,
+ toY,
+ withAccelKey = false
+) {
+ synthesizeMouse(fromTarget, fromX, fromY, {
+ type: "mousemove",
+ accelKey: withAccelKey,
+ });
+ synthesizeMouse(fromTarget, fromX, fromY, {
+ type: "mousedown",
+ accelKey: withAccelKey,
+ });
+ synthesizeMouse(toTarget, toX, toY, {
+ type: "mousemove",
+ accelKey: withAccelKey,
+ });
+ synthesizeMouse(toTarget, toX, toY, {
+ type: "mouseup",
+ accelKey: withAccelKey,
+ });
+}
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_1_backward_click.html b/layout/generic/test/test_selection_cross_shadow_boundary_1_backward_click.html
new file mode 100644
index 0000000000..ee724b344c
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_1_backward_click.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+function run() {
+ document.getElementById("host").attachShadow({ mode: "open" }).innerHTML = "<span>InnerText</span>";
+
+ const inner = host.shadowRoot.firstChild;
+ const rect = inner.getBoundingClientRect();
+
+ // Click the bottom right of "InnerText"
+ synthesizeMouse(inner, rect.width, rect.height, { type: "mousedown"});
+ synthesizeMouse(inner, rect.width, rect.height, { type: "mouseup" });
+
+ // Click the top left of "OuterText"
+ synthesizeMouse(document.getElementById("outer"), 0, 0, { type: "mousedown" , shiftKey: true});
+ synthesizeMouse(document.getElementById("outer"), 0, 0, { type: "mouseup" , shiftKey: true});
+
+ // Above two clicks should select both "OuterText" and "InnerText"
+ const sel = document.getSelection().getComposedRanges(host.shadowRoot)[0];
+
+ // backward selection
+ is(sel.endContainer, inner.firstChild, "endContainer is the InnerText");
+ is(sel.endOffset, 9, "endOffset ends at the last character");
+ is(sel.startContainer, outer.firstChild, "startContainer is the OuterText");
+ is(sel.startOffset, 0, "startOffset starts at the first character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer">OuterText</span>
+ <div id="host"></div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_1_backward_drag.html b/layout/generic/test/test_selection_cross_shadow_boundary_1_backward_drag.html
new file mode 100644
index 0000000000..f1737eaefa
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_1_backward_drag.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+
+function run() {
+ document.getElementById("host").attachShadow({ mode: "open" }).innerHTML = "<span>InnerText</span>";
+
+ const inner = host.shadowRoot.firstChild;
+ const rect = inner.getBoundingClientRect();
+
+ // Drag from the bottom right of InnerText to the
+ // top left of OuterText.
+ drag(
+ inner,
+ rect.width,
+ rect.height,
+ document.getElementById("outer"),
+ 0,
+ 0);
+
+ // Above drag selects both "OuterText" and "InnerText"
+ const sel = document.getSelection().getComposedRanges(host.shadowRoot)[0];
+
+ // backward selection
+ is(sel.endContainer, inner.firstChild, "endContainer is the InnerText");
+ is(sel.endOffset, 9, "endOffset ends at the last character");
+ is(sel.startContainer, outer.firstChild, "startContainer is the OuterText");
+ is(sel.startOffset, 0, "startOffset starts at the first character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer">OuterText</span>
+ <div id="host"></div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_1_forward_click.html b/layout/generic/test/test_selection_cross_shadow_boundary_1_forward_click.html
new file mode 100644
index 0000000000..dcf4f9ad16
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_1_forward_click.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+function run() {
+ document.getElementById("host").attachShadow({ mode: "open" }).innerHTML = "<span>InnerText</span>";
+
+ // Click the top left of "OuterText"
+ synthesizeMouse(document.getElementById("outer"), 0, 0, { type: "mousedown" });
+ synthesizeMouse(document.getElementById("outer"), 0, 0, { type: "mouseup" });
+
+ // Click the bottom right of "InnerText"
+ const inner = host.shadowRoot.firstChild;
+ const rect = inner.getBoundingClientRect();
+ synthesizeMouse(inner, rect.width, rect.height, { type: "mousedown", shiftKey: true});
+ synthesizeMouse(inner, rect.width, rect.height, { type: "mouseup" , shiftKey: true});
+
+ // Above two clicks should select both "OuterText" and "InnerText"
+ const sel = document.getSelection().getComposedRanges(host.shadowRoot)[0];
+
+ // forward selection
+ is(sel.startContainer, outer.firstChild, "startContainer is the OuterText");
+ is(sel.startOffset, 0, "startOffset starts at the first character");
+ is(sel.endContainer, inner.firstChild, "endContainer is the InnerText");
+ is(sel.endOffset, 9, "endOffset ends at the last character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer">OuterText</span>
+ <div id="host"></div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_1_forward_drag.html b/layout/generic/test/test_selection_cross_shadow_boundary_1_forward_drag.html
new file mode 100644
index 0000000000..6a351ff16b
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_1_forward_drag.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+function run() {
+ document.getElementById("host").attachShadow({ mode: "open" }).innerHTML = "<span>InnerText</span>";
+
+ const inner = host.shadowRoot.firstChild;
+ const rect = inner.getBoundingClientRect();
+
+ // drag from the top left of OuterText
+ // to the bottom right of InnerText
+ drag(
+ document.getElementById("outer"),
+ 0,
+ 0,
+ inner,
+ rect.width,
+ rect.height);
+
+ // Above drag selects should select both "OuterText" and "InnerText"
+ const sel = document.getSelection().getComposedRanges(host.shadowRoot)[0];
+
+ // forward selection
+ is(sel.startContainer, outer.firstChild, "startContainer is the OuterText");
+ is(sel.startOffset, 0, "startOffset starts at the first character");
+ is(sel.endContainer, inner.firstChild, "endContainer is the InnerText");
+ is(sel.endOffset, 9, "endOffset ends at the last character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer">OuterText</span>
+ <div id="host"></div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_2_backward_click.html b/layout/generic/test/test_selection_cross_shadow_boundary_2_backward_click.html
new file mode 100644
index 0000000000..8df867a0a5
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_2_backward_click.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+
+function run() {
+ const root1 = document.getElementById("host1").attachShadow({ mode: "open" });
+ root1.innerHTML = "InnerText1";
+
+ const root2 = document.getElementById("host2").attachShadow({ mode: "open" });
+ root2.innerHTML = "<span>InnerText2</span>";
+
+
+
+ const inner2 = root2.firstChild;
+ const rect = inner2.getBoundingClientRect();
+
+ // Click the bottom right of "InnerText2"
+ synthesizeMouse(inner2, rect.width, rect.height, { type: "mousedown" });
+ synthesizeMouse(inner2, rect.width, rect.height, { type: "mouseup" });
+
+ // Click the top left of "OuterText1"
+ synthesizeMouse(document.getElementById("outer1"), 0, 0, { type: "mousedown", shiftKey: true});
+ synthesizeMouse(document.getElementById("outer1"), 0, 0, { type: "mouseup" , shiftKey: true});
+
+ // Above clicks selects should select
+ // "OuterText1", "OuterText2", "InnerText1" and "InnerText2".
+ const sel = document.getSelection().getComposedRanges(root2)[0];
+
+ // backward selection
+ is(sel.endContainer, inner2.firstChild, "endContainer is the InnerText2");
+ is(sel.endOffset, 10, "endOffset ends at the last character");
+ is(sel.startContainer, outer1.firstChild, "startContainer is the OuterText1");
+ is(sel.startOffset, 0, "startOffset starts at the first character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer1">OuterText1</span>
+ <div id="host1"></div>
+ <span id="outer2">OuterText2</span>
+ <div id="host2"></div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_2_backward_drag.html b/layout/generic/test/test_selection_cross_shadow_boundary_2_backward_drag.html
new file mode 100644
index 0000000000..f79512d35e
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_2_backward_drag.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+
+function run() {
+ const root1 = document.getElementById("host1").attachShadow({ mode: "open" });
+ root1.innerHTML = "InnerText1";
+
+ const root2 = document.getElementById("host2").attachShadow({ mode: "open" });
+ root2.innerHTML = "<span>InnerText2</span>";
+
+ const inner2 = root2.firstChild;
+ const rect = inner2.getBoundingClientRect();
+
+ const outer1 = document.getElementById("outer1");
+ // Drag from the bottom right of InnerText2 to
+ // the top left of OuterText1.
+ drag(
+ inner2,
+ rect.width,
+ rect.height,
+ outer1,
+ 0,
+ 0);
+
+ // Above drag should selects
+ // "OuterText1", "OuterText2", "InnerText1" and "InnerText2".
+ const sel = document.getSelection().getComposedRanges(root2)[0];
+
+ // backward selection
+ is(sel.endContainer, inner2.firstChild, "endContainer is the InnerText2");
+ is(sel.endOffset, 10, "endOffset ends at the last character");
+ is(sel.startContainer, outer1.firstChild, "startContainer is the OuterText1");
+ is(sel.startOffset, 0, "startOffset starts at the first character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer1">OuterText1</span>
+ <div id="host1"></div>
+ <span id="outer2">OuterText2</span>
+ <div id="host2"></div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_2_forward_click.html b/layout/generic/test/test_selection_cross_shadow_boundary_2_forward_click.html
new file mode 100644
index 0000000000..2ca2eaeda9
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_2_forward_click.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+
+function run() {
+ const root1 = document.getElementById("host1").attachShadow({ mode: "open" });
+ root1.innerHTML = "InnerText1";
+
+ const root2 = document.getElementById("host2").attachShadow({ mode: "open" });
+ root2.innerHTML = "<span>InnerText2</span>";
+
+ const outer1 = document.getElementById("outer1");
+ // Click the top left of "OuterText1"
+ synthesizeMouse(outer1, 0, 0, { type: "mousedown" });
+ synthesizeMouse(outer1, 0, 0, { type: "mouseup" });
+
+ const inner2 = root2.firstChild;
+ const rect = inner2.getBoundingClientRect();
+
+ // Click the bottom right of "InnerText2"
+ synthesizeMouse(inner2, rect.width, rect.height, { type: "mousedown", shiftKey: true});
+ synthesizeMouse(inner2, rect.width, rect.height, { type: "mouseup" , shiftKey: true});
+
+ // Above clicks should select
+ // "OuterText1", "OuterText2", "InnerText1" and "InnerText2".
+ const sel = document.getSelection().getComposedRanges(root2)[0];
+
+ // forward selection
+ is(sel.startContainer, outer1.firstChild, "startContainer is the OuterText1");
+ is(sel.startOffset, 0, "startOffset starts at the first character");
+ is(sel.endContainer, inner2.firstChild, "endContainer is the InnerText2");
+ is(sel.endOffset, 10, "endOffset ends at the last character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer1">OuterText1</span>
+ <div id="host1"></div>
+ <span id="outer2">OuterText2</span>
+ <div id="host2"></div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_2_forward_drag.html b/layout/generic/test/test_selection_cross_shadow_boundary_2_forward_drag.html
new file mode 100644
index 0000000000..b92108de95
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_2_forward_drag.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+
+function run() {
+ const root1 = document.getElementById("host1").attachShadow({ mode: "open" });
+ root1.innerHTML = "InnerText1";
+
+ const root2 = document.getElementById("host2").attachShadow({ mode: "open" });
+ root2.innerHTML = "<span>InnerText2</span>";
+
+ const inner2 = root2.firstChild;
+ const rect = inner2.getBoundingClientRect();
+
+ const outer1 = document.getElementById("outer1");
+ // Drag from the top lef of OuterText1 to the
+ // bottom right of InnerText2.
+ drag(
+ outer1,
+ 0,
+ 0,
+ inner2,
+ rect.width,
+ rect.height);
+
+ // Above drag should select
+ // "OuterText1", "OuterText2", "InnerText1" and "InnerText2".
+ const sel = document.getSelection().getComposedRanges(root2)[0];
+
+ // forward selection
+ is(sel.startContainer, outer1.firstChild, "startContainer is the OuterText1");
+ is(sel.startOffset, 0, "startOffset starts at the first character");
+ is(sel.endContainer, inner2.firstChild, "endContainer is the InnerText2");
+ is(sel.endOffset, 10, "endOffset ends at the last character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer1">OuterText1</span>
+ <div id="host1"></div>
+ <span id="outer2">OuterText2</span>
+ <div id="host2"></div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_click.html b/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_click.html
new file mode 100644
index 0000000000..a2a0d0e2be
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_click.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+function run() {
+ const inner1 = host1.shadowRoot.querySelector("span");
+ const rect1 = inner1.getBoundingClientRect();
+
+ // Click the bottom right of "InnerText1"
+ synthesizeMouse(inner1, rect1.width - 1, rect1.height - 1, { type: "mousedown" });
+ synthesizeMouse(inner1, rect1.width - 1, rect1.height - 1, { type: "mouseup" });
+
+ // Click the top left of "OuterText1"
+ synthesizeMouse(document.getElementById("outer1"), 0, 0, { type: "mousedown", shiftKey: true });
+ synthesizeMouse(document.getElementById("outer1"), 0, 0, { type: "mouseup", shiftKey: true });
+
+ const inner2 = host2.shadowRoot.querySelector("span");
+ const rect2 = inner2.getBoundingClientRect();
+
+ // Click the bottom right of "InnerText2" with accelKey
+ synthesizeMouse(inner2, rect2.width, rect2.height, { type: "mousedown", accelKey: true});
+ synthesizeMouse(inner2, rect2.width, rect2.height, { type: "mouseup" , accelKey: true});
+
+ // Click the top left of "OuterText2"
+ synthesizeMouse(document.getElementById("outer2"), 1, 1, { type: "mousedown", shiftKey: true});
+ synthesizeMouse(document.getElementById("outer2"), 1, 1, { type: "mouseup", shiftKey: true});
+
+ const ranges = document.getSelection().getComposedRanges(host1.shadowRoot, host2.shadowRoot);
+ is(ranges.length, 2, "Above two drag selection should produce two ranges");
+
+ is(ranges[0].startContainer, outer1.firstChild, "startContainer is the OuterText1");
+ is(ranges[0].startOffset, 0, "startOffset starts at the first character");
+ is(ranges[0].endContainer, inner1.firstChild, "endContainer is the InnerText1");
+ is(ranges[0].endOffset, 10, "endOffset ends at the last character");
+
+ is(ranges[1].startContainer, outer2.firstChild, "startContainer is the OuterText2");
+ is(ranges[1].startOffset, 0, "startOffset starts at the first character");
+ is(ranges[1].endContainer, inner2.firstChild, "endContainer is the InnerText2");
+ is(ranges[1].endOffset, 10, "endOffset ends at the last character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer1">OuterText1</span>
+ <div id="host1">
+ <template shadowrootmode="open">
+ <span>InnerText1</span>
+ </template>
+ </div>
+ <br>
+ <span id="outer2">OuterText2</span>
+ <div id="host2">
+ <template shadowrootmode="open">
+ <span>InnerText2</span>
+ </template>
+ </div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_drag.html b/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_drag.html
new file mode 100644
index 0000000000..317ee4f973
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_drag.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+function run() {
+ const inner1 = host1.shadowRoot.querySelector("span");
+ const rect1 = inner1.getBoundingClientRect();
+
+ // drag from the bottom right of InnerText1
+ // to the top left of OuterText1
+ drag(
+ inner1,
+ rect1.width - 1,
+ rect1.height - 1,
+ document.getElementById("outer1"),
+ 1,
+ 1);
+
+ const inner2 = host2.shadowRoot.querySelector("span");
+ const rect2 = inner2.getBoundingClientRect();
+ // drag from the bottom right of InnerText2
+ // to the top left of OuterText2
+ drag(
+ inner2,
+ rect2.width,
+ rect2.height,
+ document.getElementById("outer2"),
+ 1,
+ 1,
+ true /* accelKey */);
+
+ const ranges = document.getSelection().getComposedRanges(host1.shadowRoot, host2.shadowRoot);
+ is(ranges.length, 2, "Above two drag selection should produce two ranges");
+
+ is(ranges[0].startContainer, outer1.firstChild, "startContainer is the OuterText1");
+ is(ranges[0].startOffset, 0, "startOffset starts at the first character");
+ is(ranges[0].endContainer, inner1.firstChild, "endContainer is the InnerText1");
+ is(ranges[0].endOffset, 10, "endOffset ends at the last character");
+
+ is(ranges[1].startContainer, outer2.firstChild, "startContainer is the OuterText2");
+ is(ranges[1].startOffset, 0, "startOffset starts at the first character");
+ is(ranges[1].endContainer, inner2.firstChild, "endContainer is the InnerText2");
+ is(ranges[1].endOffset, 10, "endOffset ends at the last character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer1">OuterText1</span>
+ <div id="host1">
+ <template shadowrootmode="open">
+ <span>InnerText1</span>
+ </template>
+ </div>
+ <br>
+ <span id="outer2">OuterText2</span>
+ <div id="host2">
+ <template shadowrootmode="open">
+ <span>InnerText2</span>
+ </template>
+ </div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_click.html b/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_click.html
new file mode 100644
index 0000000000..931c01fca0
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_click.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+function run() {
+ // Click the top left of "OuterText1"
+ synthesizeMouse(document.getElementById("outer1"), 1, 1, { type: "mousedown" });
+ synthesizeMouse(document.getElementById("outer1"), 1, 1, { type: "mouseup" });
+
+ const inner1 = host1.shadowRoot.querySelector("span");
+ const rect1 = inner1.getBoundingClientRect();
+ // Click the bottom right of "InnerText1"
+ synthesizeMouse(inner1, rect1.width - 1, rect1.height - 1, { type: "mousedown", shiftKey: true});
+ synthesizeMouse(inner1, rect1.width - 1, rect1.height - 1, { type: "mouseup" , shiftKey: true});
+
+ // Click the top left of "OuterText2" with accelKey
+ synthesizeMouse(document.getElementById("outer2"), 1, 1, { type: "mousedown", accelKey: true});
+ synthesizeMouse(document.getElementById("outer2"), 1, 1, { type: "mouseup", accelKey: true});
+
+ const inner2 = host2.shadowRoot.querySelector("span");
+ const rect2 = inner2.getBoundingClientRect();
+ // Click the bottom right of "InnerText2"
+ synthesizeMouse(inner2, rect2.width, rect2.height, { type: "mousedown", shiftKey: true});
+ synthesizeMouse(inner2, rect2.width, rect2.height, { type: "mouseup" , shiftKey: true});
+
+ const ranges = document.getSelection().getComposedRanges(host1.shadowRoot, host2.shadowRoot);
+ is(ranges.length, 2, "Above two drag selection should produce two ranges");
+
+ is(ranges[0].startContainer, outer1.firstChild, "startContainer is the OuterText1");
+ is(ranges[0].startOffset, 0, "startOffset starts at the first character");
+ is(ranges[0].endContainer, inner1.firstChild, "endContainer is the InnerText1");
+ is(ranges[0].endOffset, 10, "endOffset ends at the last character");
+
+ is(ranges[1].startContainer, outer2.firstChild, "startContainer is the OuterText2");
+ is(ranges[1].startOffset, 0, "startOffset starts at the first character");
+ is(ranges[1].endContainer, inner2.firstChild, "endContainer is the InnerText2");
+ is(ranges[1].endOffset, 10, "endOffset ends at the last character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer1">OuterText1</span>
+ <div id="host1">
+ <template shadowrootmode="open">
+ <span>InnerText1</span>
+ </template>
+ </div>
+ <br>
+ <span id="outer2">OuterText2</span>
+ <div id="host2">
+ <template shadowrootmode="open">
+ <span>InnerText2</span>
+ </template>
+ </div>
+</body>
diff --git a/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_drag.html b/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_drag.html
new file mode 100644
index 0000000000..b45e588685
--- /dev/null
+++ b/layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_drag.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript" src="/tests/layout/generic/test/selection_cross_shadow_boundary_helper.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script>
+SimpleTest.waitForExplicitFinish();
+function run() {
+ const inner1 = host1.shadowRoot.querySelector("span");
+ const rect1 = inner1.getBoundingClientRect();
+
+ // drag from the top left of OuterText1
+ // to the bottom right of InnerText1
+ drag(
+ document.getElementById("outer1"),
+ 1,
+ 1,
+ inner1,
+ rect1.width - 1,
+ rect1.height - 1);
+
+ const inner2 = host2.shadowRoot.querySelector("span");
+ const rect2 = inner2.getBoundingClientRect();
+ // drag from the top left of OuterText2
+ // to the bottom right of InnerText2
+ drag(
+ document.getElementById("outer2"),
+ 1,
+ 1,
+ inner2,
+ rect2.width,
+ rect2.height,
+ true /* accelKey */);
+
+ const ranges = document.getSelection().getComposedRanges(host1.shadowRoot, host2.shadowRoot);
+ is(ranges.length, 2, "Above two drag selection should produce two ranges");
+
+ is(ranges[0].startContainer, outer1.firstChild, "startContainer is the OuterText1");
+ is(ranges[0].startOffset, 0, "startOffset starts at the first character");
+ is(ranges[0].endContainer, inner1.firstChild, "endContainer is the InnerText1");
+ is(ranges[0].endOffset, 10, "endOffset ends at the last character");
+
+ is(ranges[1].startContainer, outer2.firstChild, "startContainer is the OuterText2");
+ is(ranges[1].startOffset, 0, "startOffset starts at the first character");
+ is(ranges[1].endContainer, inner2.firstChild, "endContainer is the InnerText2");
+ is(ranges[1].endOffset, 10, "endOffset ends at the last character");
+
+ SimpleTest.finish();
+}
+</script>
+<body onload="SimpleTest.waitForFocus(run);">
+ <span id="outer1">OuterText1</span>
+ <div id="host1">
+ <template shadowrootmode="open">
+ <span>InnerText1</span>
+ </template>
+ </div>
+ <br>
+ <span id="outer2">OuterText2</span>
+ <div id="host2">
+ <template shadowrootmode="open">
+ <span>InnerText2</span>
+ </template>
+ </div>
+</body>