summaryrefslogtreecommitdiffstats
path: root/layout/generic
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:29 +0000
commit59203c63bb777a3bacec32fb8830fba33540e809 (patch)
tree58298e711c0ff0575818c30485b44a2f21bf28a0 /layout/generic
parentAdding upstream version 126.0.1. (diff)
downloadfirefox-59203c63bb777a3bacec32fb8830fba33540e809.tar.xz
firefox-59203c63bb777a3bacec32fb8830fba33540e809.zip
Adding upstream version 127.0.upstream/127.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/generic')
-rw-r--r--layout/generic/CSSAlignUtils.cpp2
-rw-r--r--layout/generic/ReflowInput.cpp80
-rw-r--r--layout/generic/ReflowInput.h9
-rw-r--r--layout/generic/ScrollAnchorContainer.cpp12
-rw-r--r--layout/generic/StickyScrollContainer.cpp6
-rw-r--r--layout/generic/WritingModes.h227
-rw-r--r--layout/generic/crashtests/crashtests.list6
-rw-r--r--layout/generic/nsAbsoluteContainingBlock.cpp6
-rw-r--r--layout/generic/nsBlockFrame.cpp5
-rw-r--r--layout/generic/nsCanvasFrame.cpp14
-rw-r--r--layout/generic/nsColumnSetFrame.cpp6
-rw-r--r--layout/generic/nsContainerFrame.cpp2
-rw-r--r--layout/generic/nsContainerFrameInlines.h4
-rw-r--r--layout/generic/nsFirstLetterFrame.cpp10
-rw-r--r--layout/generic/nsFlexContainerFrame.cpp216
-rw-r--r--layout/generic/nsFlexContainerFrame.h3
-rw-r--r--layout/generic/nsFloatManager.cpp6
-rw-r--r--layout/generic/nsFrameSelection.cpp5
-rw-r--r--layout/generic/nsGfxScrollFrame.cpp24
-rw-r--r--layout/generic/nsGridContainerFrame.cpp25
-rw-r--r--layout/generic/nsGridContainerFrame.h59
-rw-r--r--layout/generic/nsIFrame.cpp87
-rw-r--r--layout/generic/nsIFrame.h26
-rw-r--r--layout/generic/nsImageFrame.cpp16
-rw-r--r--layout/generic/nsInlineFrame.cpp10
-rw-r--r--layout/generic/nsLineLayout.cpp2
-rw-r--r--layout/generic/nsRubyFrame.cpp18
-rw-r--r--layout/generic/nsSplittableFrame.cpp8
-rw-r--r--layout/generic/nsSubDocumentFrame.cpp54
29 files changed, 567 insertions, 381 deletions
diff --git a/layout/generic/CSSAlignUtils.cpp b/layout/generic/CSSAlignUtils.cpp
index 7dd8999563..090cba3a2a 100644
--- a/layout/generic/CSSAlignUtils.cpp
+++ b/layout/generic/CSSAlignUtils.cpp
@@ -56,7 +56,7 @@ nscoord CSSAlignUtils::AlignJustifySelf(const StyleAlignFlags& aAlignment,
WritingMode wm = aRI.GetWritingMode();
const LogicalMargin margin = aRI.ComputedLogicalMargin(wm);
const auto startSide = MakeLogicalSide(
- aAxis, MOZ_LIKELY(isSameSide) ? eLogicalEdgeStart : eLogicalEdgeEnd);
+ aAxis, MOZ_LIKELY(isSameSide) ? LogicalEdge::Start : LogicalEdge::End);
const nscoord marginStart = margin.Side(startSide, wm);
const auto endSide = GetOppositeSide(startSide);
const nscoord marginEnd = margin.Side(endSide, wm);
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
index c642c77b2c..bdfd39aff1 100644
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -953,21 +953,10 @@ void ReflowInput::ApplyRelativePositioning(nsIFrame* aFrame,
const nsStyleDisplay* display = aFrame->StyleDisplay();
if (StylePositionProperty::Relative == display->mPosition) {
*aPosition += nsPoint(aComputedOffsets.left, aComputedOffsets.top);
- } else if (StylePositionProperty::Sticky == display->mPosition &&
- !aFrame->GetNextContinuation() && !aFrame->GetPrevContinuation() &&
- !aFrame->HasAnyStateBits(NS_FRAME_PART_OF_IBSPLIT)) {
- // Sticky positioning for elements with multiple frames needs to be
- // computed all at once. We can't safely do that here because we might be
- // partway through (re)positioning the frames, so leave it until the scroll
- // container reflows and calls StickyScrollContainer::UpdatePositions.
- // For single-frame sticky positioned elements, though, go ahead and apply
- // it now to avoid unnecessary overflow updates later.
- StickyScrollContainer* ssc =
- StickyScrollContainer::GetStickyScrollContainerForFrame(aFrame);
- if (ssc) {
- *aPosition = ssc->ComputePosition(aFrame);
- }
}
+ // For sticky positioned elements, we'll leave them until the scroll container
+ // reflows and calls StickyScrollContainer::UpdatePositions() to update their
+ // positions.
}
// static
@@ -1123,9 +1112,9 @@ void ReflowInput::CalculateBorderPaddingMargin(
nscoord* aOutsideBoxSizing) const {
WritingMode wm = GetWritingMode();
mozilla::Side startSide =
- wm.PhysicalSide(MakeLogicalSide(aAxis, eLogicalEdgeStart));
+ wm.PhysicalSide(MakeLogicalSide(aAxis, LogicalEdge::Start));
mozilla::Side endSide =
- wm.PhysicalSide(MakeLogicalSide(aAxis, eLogicalEdgeEnd));
+ wm.PhysicalSide(MakeLogicalSide(aAxis, LogicalEdge::End));
nsMargin styleBorder = mStyleBorder->GetComputedBorder();
nscoord borderStartEnd =
@@ -1228,9 +1217,9 @@ static bool AxisPolarityFlipped(LogicalAxis aThisAxis, WritingMode aThisWm,
aThisWm.PhysicalAxis(aThisAxis) == aOtherWm.PhysicalAxis(otherAxis),
"Physical axes must match!");
Side thisStartSide =
- aThisWm.PhysicalSide(MakeLogicalSide(aThisAxis, eLogicalEdgeStart));
+ aThisWm.PhysicalSide(MakeLogicalSide(aThisAxis, LogicalEdge::Start));
Side otherStartSide =
- aOtherWm.PhysicalSide(MakeLogicalSide(otherAxis, eLogicalEdgeStart));
+ aOtherWm.PhysicalSide(MakeLogicalSide(otherAxis, LogicalEdge::Start));
return thisStartSide != otherStartSide;
}
@@ -2549,9 +2538,9 @@ void SizeComputationInput::InitOffsets(WritingMode aCBWM, nscoord aPercentBasis,
NS_ASSERTION(val != nscoord(0), "zero in this property is useless");
LogicalSide side;
if (val > 0) {
- side = MakeLogicalSide(aAxis, eLogicalEdgeStart);
+ side = MakeLogicalSide(aAxis, LogicalEdge::Start);
} else {
- side = MakeLogicalSide(aAxis, eLogicalEdgeEnd);
+ side = MakeLogicalSide(aAxis, LogicalEdge::End);
val = -val;
}
mComputedPadding.Side(side, wm) += val;
@@ -2742,27 +2731,28 @@ void ReflowInput::CalculateBlockSideMargins() {
// zeros, we should compensate this by creating extra (external) leading.
// This is necessary because without this compensation, normal line height might
// look too tight.
-constexpr float kNormalLineHeightFactor = 1.2f;
static nscoord GetNormalLineHeight(nsFontMetrics* aFontMetrics) {
MOZ_ASSERT(aFontMetrics, "no font metrics");
nscoord externalLeading = aFontMetrics->ExternalLeading();
nscoord internalLeading = aFontMetrics->InternalLeading();
nscoord emHeight = aFontMetrics->EmHeight();
if (!internalLeading && !externalLeading) {
- return NSToCoordRound(emHeight * kNormalLineHeightFactor);
+ return NSToCoordRound(static_cast<float>(emHeight) *
+ ReflowInput::kNormalLineHeightFactor);
}
return emHeight + internalLeading + externalLeading;
}
static inline nscoord ComputeLineHeight(const StyleLineHeight& aLh,
- const nsStyleFont& aRelativeToFont,
+ const nsFont& aFont, nsAtom* aLanguage,
+ bool aExplicitLanguage,
nsPresContext* aPresContext,
bool aIsVertical, nscoord aBlockBSize,
float aFontSizeInflation) {
if (aLh.IsLength()) {
nscoord result = aLh.AsLength().ToAppUnits();
if (aFontSizeInflation != 1.0f) {
- result = NSToCoordRound(result * aFontSizeInflation);
+ result = NSToCoordRound(static_cast<float>(result) * aFontSizeInflation);
}
return result;
}
@@ -2771,8 +2761,7 @@ static inline nscoord ComputeLineHeight(const StyleLineHeight& aLh,
// For factor units the computed value of the line-height property
// is found by multiplying the factor by the font's computed size
// (adjusted for min-size prefs and text zoom).
- return aRelativeToFont.mFont.size
- .ScaledBy(aLh.AsNumber() * aFontSizeInflation)
+ return aFont.size.ScaledBy(aLh.AsNumber() * aFontSizeInflation)
.ToAppUnits();
}
@@ -2781,17 +2770,25 @@ static inline nscoord ComputeLineHeight(const StyleLineHeight& aLh,
return aBlockBSize;
}
- auto size = aRelativeToFont.mFont.size;
+ auto size = aFont.size;
size.ScaleBy(aFontSizeInflation);
if (aPresContext) {
- RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetMetricsFor(
- aPresContext, aIsVertical, &aRelativeToFont, size,
- /* aUseUserFontSet = */ true);
+ nsFont font = aFont;
+ font.size = size;
+ nsFontMetrics::Params params;
+ params.language = aLanguage;
+ params.explicitLanguage = aExplicitLanguage;
+ params.orientation =
+ aIsVertical ? nsFontMetrics::eVertical : nsFontMetrics::eHorizontal;
+ params.userFontSet = aPresContext->GetUserFontSet();
+ params.textPerf = aPresContext->GetTextPerfMetrics();
+ params.featureValueLookup = aPresContext->GetFontFeatureValuesLookup();
+ RefPtr<nsFontMetrics> fm = aPresContext->GetMetricsFor(font, params);
return GetNormalLineHeight(fm);
}
// If we don't have a pres context, use a 1.2em fallback.
- size.ScaleBy(kNormalLineHeightFactor);
+ size.ScaleBy(ReflowInput::kNormalLineHeightFactor);
return size.ToAppUnits();
}
@@ -2839,8 +2836,9 @@ nscoord ReflowInput::CalcLineHeight(
nsPresContext* aPresContext, bool aIsVertical, const nsIContent* aContent,
nscoord aBlockBSize, float aFontSizeInflation) {
nscoord lineHeight =
- ComputeLineHeight(aLh, aRelativeToFont, aPresContext, aIsVertical,
- aBlockBSize, aFontSizeInflation);
+ ComputeLineHeight(aLh, aRelativeToFont.mFont, aRelativeToFont.mLanguage,
+ aRelativeToFont.mExplicitLanguage, aPresContext,
+ aIsVertical, aBlockBSize, aFontSizeInflation);
NS_ASSERTION(lineHeight >= 0, "ComputeLineHeight screwed up");
@@ -2850,8 +2848,9 @@ nscoord ReflowInput::CalcLineHeight(
// have a line-height smaller than 'normal'.
if (!aLh.IsNormal()) {
nscoord normal = ComputeLineHeight(
- StyleLineHeight::Normal(), aRelativeToFont, aPresContext, aIsVertical,
- aBlockBSize, aFontSizeInflation);
+ StyleLineHeight::Normal(), aRelativeToFont.mFont,
+ aRelativeToFont.mLanguage, aRelativeToFont.mExplicitLanguage,
+ aPresContext, aIsVertical, aBlockBSize, aFontSizeInflation);
if (lineHeight < normal) {
lineHeight = normal;
}
@@ -2861,6 +2860,17 @@ nscoord ReflowInput::CalcLineHeight(
return lineHeight;
}
+nscoord ReflowInput::CalcLineHeightForCanvas(const StyleLineHeight& aLh,
+ const nsFont& aRelativeToFont,
+ nsAtom* aLanguage,
+ bool aExplicitLanguage,
+ nsPresContext* aPresContext,
+ mozilla::WritingMode aWM) {
+ return ComputeLineHeight(aLh, aRelativeToFont, aLanguage, aExplicitLanguage,
+ aPresContext, aWM.IsVertical() && !aWM.IsSideways(),
+ NS_UNCONSTRAINEDSIZE, 1.0f);
+}
+
bool SizeComputationInput::ComputeMargin(WritingMode aCBWM,
nscoord aPercentBasis,
LayoutFrameType aFrameType) {
diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h
index ba49edcaf6..7bf7c4fc73 100644
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -741,6 +741,15 @@ struct ReflowInput : public SizeComputationInput {
const nsIContent* aContent, nscoord aBlockBSize,
float aFontSizeInflation);
+ static nscoord CalcLineHeightForCanvas(const StyleLineHeight& aLh,
+ const nsFont& aRelativeToFont,
+ nsAtom* aLanguage,
+ bool aExplicitLanguage,
+ nsPresContext* aPresContext,
+ mozilla::WritingMode aWM);
+
+ static constexpr float kNormalLineHeightFactor = 1.2f;
+
mozilla::LogicalSize ComputeContainingBlockRectangle(
nsPresContext* aPresContext, const ReflowInput* aContainingBlockRI) const;
diff --git a/layout/generic/ScrollAnchorContainer.cpp b/layout/generic/ScrollAnchorContainer.cpp
index 93336480f7..9bf17ec3d5 100644
--- a/layout/generic/ScrollAnchorContainer.cpp
+++ b/layout/generic/ScrollAnchorContainer.cpp
@@ -178,15 +178,15 @@ static nsRect FindScrollAnchoringBoundingRect(const nsIFrame* aScrollFrame,
// axis of the scroll frame
WritingMode writingMode = aScrollFrame->GetWritingMode();
switch (writingMode.GetBlockDir()) {
- case WritingMode::eBlockTB: {
+ case WritingMode::BlockDir::TB: {
overflowRect.SetBoxY(borderRect.Y(), overflowRect.YMost());
break;
}
- case WritingMode::eBlockLR: {
+ case WritingMode::BlockDir::LR: {
overflowRect.SetBoxX(borderRect.X(), overflowRect.XMost());
break;
}
- case WritingMode::eBlockRL: {
+ case WritingMode::BlockDir::RL: {
overflowRect.SetBoxX(overflowRect.X(), borderRect.XMost());
break;
}
@@ -522,15 +522,15 @@ void ScrollAnchorContainer::ApplyAdjustments() {
nsPoint physicalAdjustment;
switch (writingMode.GetBlockDir()) {
- case WritingMode::eBlockTB: {
+ case WritingMode::BlockDir::TB: {
physicalAdjustment.y = logicalAdjustment;
break;
}
- case WritingMode::eBlockLR: {
+ case WritingMode::BlockDir::LR: {
physicalAdjustment.x = logicalAdjustment;
break;
}
- case WritingMode::eBlockRL: {
+ case WritingMode::BlockDir::RL: {
physicalAdjustment.x = -logicalAdjustment;
break;
}
diff --git a/layout/generic/StickyScrollContainer.cpp b/layout/generic/StickyScrollContainer.cpp
index 416bbbf4c4..e16c3af585 100644
--- a/layout/generic/StickyScrollContainer.cpp
+++ b/layout/generic/StickyScrollContainer.cpp
@@ -200,11 +200,13 @@ void StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame,
nsLayoutUtils::TransformRect(cbFrame, aFrame->GetParent(), *aContain);
} else {
*aContain = nsLayoutUtils::GetAllInFlowRectsUnion(
- cbFrame, aFrame->GetParent(), nsLayoutUtils::RECTS_USE_CONTENT_BOX);
+ cbFrame, aFrame->GetParent(),
+ nsLayoutUtils::GetAllInFlowRectsFlag::UseContentBox);
}
nsRect marginRect = nsLayoutUtils::GetAllInFlowRectsUnion(
- aFrame, aFrame->GetParent(), nsLayoutUtils::RECTS_USE_MARGIN_BOX);
+ aFrame, aFrame->GetParent(),
+ nsLayoutUtils::GetAllInFlowRectsFlag::UseMarginBoxWithAutoResolvedAsZero);
// Deflate aContain by the difference between the union of aFrame's
// continuations' margin boxes and the union of their border boxes, so that
diff --git a/layout/generic/WritingModes.h b/layout/generic/WritingModes.h
index 0fcf47f1d0..4f6e9eaec1 100644
--- a/layout/generic/WritingModes.h
+++ b/layout/generic/WritingModes.h
@@ -11,10 +11,8 @@
#include "mozilla/intl/BidiEmbeddingLevel.h"
#include "mozilla/ComputedStyle.h"
-#include "mozilla/EnumeratedRange.h"
-
+#include "mozilla/EnumSet.h"
#include "nsRect.h"
-#include "nsBidiUtils.h"
#include "nsStyleStruct.h"
// It is the caller's responsibility to operate on logical-coordinate objects
@@ -50,7 +48,7 @@ enum class LogicalAxis : uint8_t {
Block,
Inline,
};
-enum LogicalEdge { eLogicalEdgeStart = 0x0, eLogicalEdgeEnd = 0x1 };
+enum class LogicalEdge : uint8_t { Start, End };
enum class LogicalSide : uint8_t {
BStart,
@@ -59,11 +57,6 @@ enum class LogicalSide : uint8_t {
IEnd,
};
-constexpr auto AllLogicalSides() {
- return mozilla::MakeInclusiveEnumeratedRange(LogicalSide::BStart,
- LogicalSide::IEnd);
-}
-
enum class LogicalCorner : uint8_t {
BStartIStart,
BStartIEnd,
@@ -72,7 +65,7 @@ enum class LogicalCorner : uint8_t {
};
// Physical axis constants.
-enum PhysicalAxis { eAxisVertical = 0x0, eAxisHorizontal = 0x1 };
+enum class PhysicalAxis : uint8_t { Vertical, Horizontal };
// Represents zero or more physical axes.
enum class PhysicalAxes : uint8_t {
@@ -104,38 +97,30 @@ inline LogicalAxis GetAxis(LogicalSide aSide) {
}
inline LogicalEdge GetEdge(LogicalSide aSide) {
- return IsEnd(aSide) ? eLogicalEdgeEnd : eLogicalEdgeStart;
+ return IsEnd(aSide) ? LogicalEdge::End : LogicalEdge::Start;
}
inline LogicalEdge GetOppositeEdge(LogicalEdge aEdge) {
- // This relies on the only two LogicalEdge enum values being 0 and 1.
- return LogicalEdge(1 - aEdge);
+ return aEdge == LogicalEdge::Start ? LogicalEdge::End : LogicalEdge::Start;
}
inline LogicalSide MakeLogicalSide(LogicalAxis aAxis, LogicalEdge aEdge) {
- return LogicalSide((uint8_t(aAxis) << 1) | aEdge);
+ if (aAxis == LogicalAxis::Inline) {
+ return aEdge == LogicalEdge::Start ? LogicalSide::IStart
+ : LogicalSide::IEnd;
+ }
+ return aEdge == LogicalEdge::Start ? LogicalSide::BStart : LogicalSide::BEnd;
}
inline LogicalSide GetOppositeSide(LogicalSide aSide) {
return MakeLogicalSide(GetAxis(aSide), GetOppositeEdge(GetEdge(aSide)));
}
-enum LogicalSideBits {
- eLogicalSideBitsNone = 0,
- 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 = 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)
+enum class LineRelativeDir : uint8_t {
+ Over = static_cast<uint8_t>(LogicalSide::BStart),
+ Under = static_cast<uint8_t>(LogicalSide::BEnd),
+ Left = static_cast<uint8_t>(LogicalSide::IStart),
+ Right = static_cast<uint8_t>(LogicalSide::IEnd)
};
/**
@@ -155,54 +140,41 @@ class WritingMode {
/**
* Absolute inline flow direction
*/
- enum InlineDir {
- eInlineLTR = 0x00, // text flows horizontally left to right
- eInlineRTL = 0x02, // text flows horizontally right to left
- eInlineTTB = 0x01, // text flows vertically top to bottom
- eInlineBTT = 0x03, // text flows vertically bottom to top
+ enum class InlineDir : uint8_t {
+ LTR, // text flows horizontally left to right
+ RTL, // text flows horizontally right to left
+ TTB, // text flows vertically top to bottom
+ BTT, // text flows vertically bottom to top
};
/**
* Absolute block flow direction
*/
- enum BlockDir {
- eBlockTB = 0x00, // horizontal lines stack top to bottom
- eBlockRL = 0x01, // vertical lines stack right to left
- eBlockLR = 0x05, // vertical lines stack left to right
- };
-
- /**
- * Line-relative (bidi-relative) inline flow direction
- */
- enum BidiDir {
- eBidiLTR = 0x00, // inline flow matches bidi LTR text
- eBidiRTL = 0x10, // inline flow matches bidi RTL text
+ enum class BlockDir : uint8_t {
+ TB, // horizontal lines stack top to bottom
+ RL, // vertical lines stack right to left
+ LR, // vertical lines stack left to right
};
/**
- * Unknown writing mode (should never actually be stored or used anywhere).
- */
- enum { eUnknownWritingMode = 0xff };
-
- /**
* Return the absolute inline flow direction as an InlineDir
*/
InlineDir GetInlineDir() const {
- return InlineDir(mWritingMode._0 & eInlineMask);
+ if (IsVertical()) {
+ return IsInlineReversed() ? InlineDir::BTT : InlineDir::TTB;
+ }
+ return IsInlineReversed() ? InlineDir::RTL : InlineDir::LTR;
}
/**
* Return the absolute block flow direction as a BlockDir
*/
BlockDir GetBlockDir() const {
- return BlockDir(mWritingMode._0 & eBlockMask);
- }
-
- /**
- * Return the line-relative inline flow direction as a BidiDir
- */
- BidiDir GetBidiDir() const {
- return BidiDir((mWritingMode & StyleWritingMode::RTL)._0);
+ if (IsVertical()) {
+ return mWritingMode & StyleWritingMode::VERTICAL_LR ? BlockDir::LR
+ : BlockDir::RL;
+ }
+ return BlockDir::TB;
}
/**
@@ -216,14 +188,14 @@ class WritingMode {
}
/**
- * Return true if bidi direction is LTR. (Convenience method)
+ * Return true if bidi direction is LTR.
*/
- bool IsBidiLTR() const { return eBidiLTR == GetBidiDir(); }
+ bool IsBidiLTR() const { return !IsBidiRTL(); }
/**
- * Return true if bidi direction is RTL. (Convenience method)
+ * Return true if bidi direction is RTL.
*/
- bool IsBidiRTL() const { return eBidiRTL == GetBidiDir(); }
+ bool IsBidiRTL() const { return !!(mWritingMode & StyleWritingMode::RTL); }
/**
* True if it is vertical and vertical-lr, or is horizontal and bidi LTR.
@@ -242,12 +214,12 @@ class WritingMode {
/**
* True if vertical-mode block direction is LR (convenience method).
*/
- bool IsVerticalLR() const { return eBlockLR == GetBlockDir(); }
+ bool IsVerticalLR() const { return GetBlockDir() == BlockDir::LR; }
/**
* True if vertical-mode block direction is RL (convenience method).
*/
- bool IsVerticalRL() const { return eBlockRL == GetBlockDir(); }
+ bool IsVerticalRL() const { return GetBlockDir() == BlockDir::RL; }
/**
* True if vertical writing mode, i.e. when
@@ -339,8 +311,9 @@ class WritingMode {
uint8_t(StyleWritingModeProperty::VerticalRl) == 1 &&
uint8_t(StyleWritingModeProperty::VerticalLr) == 3 &&
uint8_t(LogicalAxis::Block) == 0 &&
- uint8_t(LogicalAxis::Inline) == 1 && eAxisVertical == 0 &&
- eAxisHorizontal == 1,
+ uint8_t(LogicalAxis::Inline) == 1 &&
+ uint8_t(PhysicalAxis::Vertical) == 0 &&
+ uint8_t(PhysicalAxis::Horizontal) == 1,
"unexpected writing-mode, logical axis or physical axis "
"constant values");
return mozilla::PhysicalAxis((aWritingModeValue ^ uint8_t(aAxis)) & 0x1);
@@ -376,7 +349,7 @@ class WritingMode {
// What's left of the writing-mode should be in the range 0-3:
NS_ASSERTION(aWritingModeValue < 4, "invalid aWritingModeValue value");
- return kLogicalBlockSides[aWritingModeValue][aEdge];
+ return kLogicalBlockSides[aWritingModeValue][static_cast<uint8_t>(aEdge)];
}
mozilla::Side PhysicalSideForInlineAxis(LogicalEdge aEdge) const {
@@ -413,13 +386,13 @@ class WritingMode {
// StyleWritingMode::INLINE_REVERSED, StyleWritingMode::VERTICAL_LR and
// StyleWritingMode::LINE_INVERTED bits. Use these four bits to index into
// kLogicalInlineSides.
- MOZ_ASSERT(StyleWritingMode::VERTICAL._0 == 0x01 &&
- StyleWritingMode::INLINE_REVERSED._0 == 0x02 &&
- StyleWritingMode::VERTICAL_LR._0 == 0x04 &&
- StyleWritingMode::LINE_INVERTED._0 == 0x08,
- "unexpected mask values");
- int index = mWritingMode._0 & 0x0F;
- return kLogicalInlineSides[index][aEdge];
+ static_assert(StyleWritingMode::VERTICAL._0 == 0x01 &&
+ StyleWritingMode::INLINE_REVERSED._0 == 0x02 &&
+ StyleWritingMode::VERTICAL_LR._0 == 0x04 &&
+ StyleWritingMode::LINE_INVERTED._0 == 0x08,
+ "Unexpected values for StyleWritingMode constants!");
+ uint8_t index = mWritingMode._0 & 0x0F;
+ return kLogicalInlineSides[index][static_cast<uint8_t>(aEdge)];
}
/**
@@ -428,9 +401,9 @@ class WritingMode {
*/
mozilla::Side PhysicalSide(LogicalSide aSide) const {
if (IsBlock(aSide)) {
- MOZ_ASSERT(StyleWritingMode::VERTICAL._0 == 0x01 &&
- StyleWritingMode::VERTICAL_LR._0 == 0x04,
- "unexpected mask values");
+ static_assert(StyleWritingMode::VERTICAL._0 == 0x01 &&
+ StyleWritingMode::VERTICAL_LR._0 == 0x04,
+ "Unexpected values for StyleWritingMode constants!");
const uint8_t wm =
((mWritingMode & StyleWritingMode::VERTICAL_LR)._0 >> 1) |
(mWritingMode & StyleWritingMode::VERTICAL)._0;
@@ -490,12 +463,12 @@ class WritingMode {
};
// clang-format on
- MOZ_ASSERT(StyleWritingMode::VERTICAL._0 == 0x01 &&
- StyleWritingMode::INLINE_REVERSED._0 == 0x02 &&
- StyleWritingMode::VERTICAL_LR._0 == 0x04 &&
- StyleWritingMode::LINE_INVERTED._0 == 0x08,
- "unexpected mask values");
- int index = mWritingMode._0 & 0x0F;
+ static_assert(StyleWritingMode::VERTICAL._0 == 0x01 &&
+ StyleWritingMode::INLINE_REVERSED._0 == 0x02 &&
+ StyleWritingMode::VERTICAL_LR._0 == 0x04 &&
+ StyleWritingMode::LINE_INVERTED._0 == 0x08,
+ "Unexpected values for StyleWritingMode constants!");
+ uint8_t index = mWritingMode._0 & 0x0F;
return kPhysicalToLogicalSides[index][aSide];
}
@@ -580,7 +553,7 @@ class WritingMode {
bool ParallelAxisStartsOnSameSide(LogicalAxis aLogicalAxis,
const WritingMode& aOther) const {
mozilla::Side myStartSide =
- this->PhysicalSide(MakeLogicalSide(aLogicalAxis, eLogicalEdgeStart));
+ this->PhysicalSide(MakeLogicalSide(aLogicalAxis, LogicalEdge::Start));
// Figure out which of aOther's axes is parallel to |this| WritingMode's
// aLogicalAxis, and get its physical start side as well.
@@ -588,7 +561,7 @@ class WritingMode {
? GetOrthogonalAxis(aLogicalAxis)
: aLogicalAxis;
mozilla::Side otherWMStartSide =
- aOther.PhysicalSide(MakeLogicalSide(otherWMAxis, eLogicalEdgeStart));
+ aOther.PhysicalSide(MakeLogicalSide(otherWMAxis, LogicalEdge::Start));
NS_ASSERTION(myStartSide % 2 == otherWMStartSide % 2,
"Should end up with sides in the same physical axis");
@@ -611,10 +584,15 @@ class WritingMode {
friend struct widget::IMENotification;
/**
+ * Unknown writing mode (should never actually be stored or used anywhere).
+ */
+ static constexpr uint8_t kUnknownWritingMode = 0xff;
+
+ /**
* Return a WritingMode representing an unknown value.
*/
static inline WritingMode Unknown() {
- return WritingMode(eUnknownWritingMode);
+ return WritingMode(kUnknownWritingMode);
}
/**
@@ -624,12 +602,6 @@ class WritingMode {
explicit WritingMode(uint8_t aValue) : mWritingMode{aValue} {}
StyleWritingMode mWritingMode;
-
- enum Masks {
- // Masks for output enums
- eInlineMask = 0x03, // VERTICAL | INLINE_REVERSED
- eBlockMask = 0x05, // VERTICAL | VERTICAL_LR
- };
};
inline std::ostream& operator<<(std::ostream& aStream, const WritingMode& aWM) {
@@ -818,7 +790,7 @@ class LogicalPoint {
LogicalPoint operator+(const LogicalPoint& aOther) const {
CHECK_WRITING_MODE(aOther.GetWritingMode());
// In non-debug builds, LogicalPoint does not store the WritingMode,
- // so the first parameter here (which will always be eUnknownWritingMode)
+ // so the first parameter here (which will always be WritingMode::Unknown())
// is ignored.
return LogicalPoint(GetWritingMode(), mPoint.x + aOther.mPoint.x,
mPoint.y + aOther.mPoint.y);
@@ -834,7 +806,7 @@ class LogicalPoint {
LogicalPoint operator-(const LogicalPoint& aOther) const {
CHECK_WRITING_MODE(aOther.GetWritingMode());
// In non-debug builds, LogicalPoint does not store the WritingMode,
- // so the first parameter here (which will always be eUnknownWritingMode)
+ // so the first parameter here (which will always be WritingMode::Unknown())
// is ignored.
return LogicalPoint(GetWritingMode(), mPoint.x - aOther.mPoint.x,
mPoint.y - aOther.mPoint.y);
@@ -857,7 +829,7 @@ class LogicalPoint {
/**
* NOTE that in non-DEBUG builds, GetWritingMode() always returns
- * eUnknownWritingMode, as the current mode is not stored in the logical-
+ * WritingMode::Unknown(), as the current mode is not stored in the logical-
* geometry classes. Therefore, this method is private; it is used ONLY
* by the DEBUG-mode checking macros in this class and its friends;
* other code is not allowed to ask a logical point for its writing mode,
@@ -1107,48 +1079,51 @@ class LogicalSize {
* LogicalSides represents a set of logical sides.
*/
struct LogicalSides final {
+ static constexpr EnumSet<LogicalSide> BBoth{LogicalSide::BStart,
+ LogicalSide::BEnd};
+ static constexpr EnumSet<LogicalSide> IBoth{LogicalSide::IStart,
+ LogicalSide::IEnd};
+ static constexpr EnumSet<LogicalSide> All{
+ LogicalSide::BStart, LogicalSide::BEnd, LogicalSide::IStart,
+ LogicalSide::IEnd};
+
explicit LogicalSides(WritingMode aWritingMode)
+#ifdef DEBUG
+ : mWritingMode(aWritingMode)
+#endif
+ {
+ }
+ LogicalSides(WritingMode aWritingMode, LogicalSides aSides)
:
#ifdef DEBUG
mWritingMode(aWritingMode),
#endif
- mBits(0) {
+ mSides(aSides.mSides) {
}
- LogicalSides(WritingMode aWritingMode, LogicalSideBits aSideBits)
+ LogicalSides(WritingMode aWritingMode, EnumSet<LogicalSide> aSides)
:
#ifdef DEBUG
mWritingMode(aWritingMode),
#endif
- mBits(aSideBits) {
- MOZ_ASSERT((aSideBits & ~eLogicalSideBitsAll) == 0, "illegal side bits");
- }
- bool IsEmpty() const { return mBits == 0; }
- bool BStart() const { return mBits & eLogicalSideBitsBStart; }
- bool BEnd() const { return mBits & eLogicalSideBitsBEnd; }
- bool IStart() const { return mBits & eLogicalSideBitsIStart; }
- bool IEnd() const { return mBits & eLogicalSideBitsIEnd; }
- bool Contains(LogicalSideBits aSideBits) const {
- MOZ_ASSERT((aSideBits & ~eLogicalSideBitsAll) == 0, "illegal side bits");
- return (mBits & aSideBits) == aSideBits;
- }
- LogicalSides operator|(LogicalSides aOther) const {
- CHECK_WRITING_MODE(aOther.GetWritingMode());
- return *this | LogicalSideBits(aOther.mBits);
- }
- LogicalSides operator|(LogicalSideBits aSideBits) const {
- return LogicalSides(GetWritingMode(), LogicalSideBits(mBits | aSideBits));
- }
- LogicalSides& operator|=(LogicalSides aOther) {
- CHECK_WRITING_MODE(aOther.GetWritingMode());
- return *this |= LogicalSideBits(aOther.mBits);
+ mSides(aSides) {
+ }
+ bool IsEmpty() const { return mSides.isEmpty(); }
+ bool BStart() const { return mSides.contains(LogicalSide::BStart); }
+ bool BEnd() const { return mSides.contains(LogicalSide::BEnd); }
+ bool IStart() const { return mSides.contains(LogicalSide::IStart); }
+ bool IEnd() const { return mSides.contains(LogicalSide::IEnd); }
+ bool Contains(LogicalSide aSide) const { return mSides.contains(aSide); }
+ LogicalSides& operator+=(LogicalSides aOther) {
+ mSides += aOther.mSides;
+ return *this;
}
- LogicalSides& operator|=(LogicalSideBits aSideBits) {
- mBits |= aSideBits;
+ LogicalSides& operator+=(LogicalSide aOther) {
+ mSides += aOther;
return *this;
}
bool operator==(LogicalSides aOther) const {
CHECK_WRITING_MODE(aOther.GetWritingMode());
- return mBits == aOther.mBits;
+ return mSides == aOther.mSides;
}
bool operator!=(LogicalSides aOther) const {
CHECK_WRITING_MODE(aOther.GetWritingMode());
@@ -1165,7 +1140,7 @@ struct LogicalSides final {
#ifdef DEBUG
WritingMode mWritingMode;
#endif
- uint8_t mBits;
+ EnumSet<LogicalSide> mSides;
};
/**
diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list
index 2aea090a6f..9044b12f8d 100644
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -394,7 +394,7 @@ load 571618-1.svg
asserts(0-1) load 571975-1.html # bug 574889
load 571995.xhtml
load 574958.xhtml
-asserts(0-6) load 578977.html # bug 757305
+asserts(0-8) load 578977.html # bug 757305
load 580504-1.xhtml
load 582793-1.html
load 585598-1.xhtml
@@ -622,8 +622,8 @@ load flex-nested-abspos-1.html
pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) asserts(0-100) load font-inflation-762332.html # bug 762332
asserts-if(Android||cocoaWidget,0-2) load outline-on-frameset.xhtml # bug 762332, bug 1594135
load summary-position-out-of-flow.html
-pref(widget.windows.window_occlusion_tracking.enabled,false) load text-overflow-bug666751-1.html # Bug 1819154
-pref(widget.windows.window_occlusion_tracking.enabled,false) load text-overflow-bug666751-2.html # Bug 1819154
+load text-overflow-bug666751-1.html
+load text-overflow-bug666751-2.html
load text-overflow-bug670564.xhtml
load text-overflow-bug671796.xhtml
load text-overflow-bug713610.html
diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp
index 4f561688bf..5afd9f33f2 100644
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -372,8 +372,8 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
// and be positioned relative to the containing block right edge.
// 'left' length and 'right' auto is the only combination we can be
// sure of.
- if ((wm.GetInlineDir() == WritingMode::eInlineRTL ||
- wm.GetBlockDir() == WritingMode::eBlockRL) &&
+ if ((wm.GetInlineDir() == WritingMode::InlineDir::RTL ||
+ wm.GetBlockDir() == WritingMode::BlockDir::RL) &&
!pos->mOffset.Get(eSideRight).IsAuto()) {
return true;
}
@@ -383,7 +383,7 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
return true;
}
// See comment above for width changes.
- if (wm.GetInlineDir() == WritingMode::eInlineBTT &&
+ if (wm.GetInlineDir() == WritingMode::InlineDir::BTT &&
!pos->mOffset.Get(eSideBottom).IsAuto()) {
return true;
}
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index 4582c29e0b..4b314bfcaf 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1186,7 +1186,8 @@ static bool IsLineClampRoot(const nsBlockFrame* aFrame) {
return false;
}
- if (StaticPrefs::layout_css_webkit_line_clamp_block_enabled()) {
+ if (StaticPrefs::layout_css_webkit_line_clamp_block_enabled() ||
+ aFrame->PresContext()->Document()->ChromeRulesEnabled()) {
return true;
}
@@ -7979,7 +7980,7 @@ bool nsBlockFrame::MarkerIsEmpty() const {
const nsStyleList* list = marker->StyleList();
return marker->StyleContent()->mContent.IsNone() ||
(list->mCounterStyle.IsNone() && list->mListStyleImage.IsNone() &&
- marker->StyleContent()->ContentCount() == 0);
+ marker->StyleContent()->NonAltContentItems().IsEmpty());
}
void nsBlockFrame::ReflowOutsideMarker(nsIFrame* aMarkerFrame,
diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp
index b4b108905f..36b579ed60 100644
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -546,6 +546,8 @@ void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
layers.mImageCount > 0 &&
layers.mLayers[0].mAttachment == StyleImageLayerAttachment::Fixed;
+ nsDisplayList list(aBuilder);
+
if (!hasFixedBottomLayer || needBlendContainer) {
// Put a scrolled background color item in place, at the bottom of the
// list. The color of this item will be filled in during
@@ -557,20 +559,18 @@ void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// interleaving the two with a scrolled background color.
// PresShell::AddCanvasBackgroundColorItem makes sure there always is a
// non-scrolled background color item at the bottom.
- aLists.BorderBackground()->AppendNewToTop<nsDisplayCanvasBackgroundColor>(
- aBuilder, this);
+ list.AppendNewToTop<nsDisplayCanvasBackgroundColor>(aBuilder, this);
}
- aLists.BorderBackground()->AppendToTop(&layerItems);
+ list.AppendToTop(&layerItems);
if (needBlendContainer) {
const ActiveScrolledRoot* containerASR = contASRTracker.GetContainerASR();
DisplayListClipState::AutoSaveRestore blendContainerClip(aBuilder);
- aLists.BorderBackground()->AppendToTop(
- nsDisplayBlendContainer::CreateForBackgroundBlendMode(
- aBuilder, this, nullptr, aLists.BorderBackground(),
- containerASR));
+ list.AppendToTop(nsDisplayBlendContainer::CreateForBackgroundBlendMode(
+ aBuilder, this, nullptr, &list, containerASR));
}
+ aLists.BorderBackground()->AppendToTop(&list);
}
for (nsIFrame* kid : PrincipalChildList()) {
diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp
index a9d3e28138..d78a5cb992 100644
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -570,17 +570,17 @@ nsColumnSetFrame::ColumnBalanceData nsColumnSetFrame::ReflowColumns(
// this is a calculation that affects layout.
if (!reflowChild && shrinkingBSize) {
switch (wm.GetBlockDir()) {
- case WritingMode::eBlockTB:
+ case WritingMode::BlockDir::TB:
if (child->ScrollableOverflowRect().YMost() > aConfig.mColBSize) {
reflowChild = true;
}
break;
- case WritingMode::eBlockLR:
+ case WritingMode::BlockDir::LR:
if (child->ScrollableOverflowRect().XMost() > aConfig.mColBSize) {
reflowChild = true;
}
break;
- case WritingMode::eBlockRL:
+ case WritingMode::BlockDir::RL:
// XXX not sure how to handle this, so for now just don't attempt
// the optimization
reflowChild = true;
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
index 2c9e707830..3cebfae2e7 100644
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -780,7 +780,7 @@ void nsContainerFrame::SyncFrameViewAfterReflow(nsPresContext* aPresContext,
if (!(aFlags & ReflowChildFlags::NoSizeView)) {
nsViewManager* vm = aView->GetViewManager();
- vm->ResizeView(aView, aInkOverflowArea, true);
+ vm->ResizeView(aView, aInkOverflowArea);
}
}
diff --git a/layout/generic/nsContainerFrameInlines.h b/layout/generic/nsContainerFrameInlines.h
index f6c85d791e..bc544fa6f8 100644
--- a/layout/generic/nsContainerFrameInlines.h
+++ b/layout/generic/nsContainerFrameInlines.h
@@ -21,8 +21,8 @@ void nsContainerFrame::DoInlineIntrinsicISize(ISizeData* aData,
if (GetPrevInFlow()) return; // Already added.
WritingMode wm = GetWritingMode();
- Side startSide = wm.PhysicalSideForInlineAxis(eLogicalEdgeStart);
- Side endSide = wm.PhysicalSideForInlineAxis(eLogicalEdgeEnd);
+ Side startSide = wm.PhysicalSideForInlineAxis(LogicalEdge::Start);
+ Side endSide = wm.PhysicalSideForInlineAxis(LogicalEdge::End);
const nsStylePadding* stylePadding = StylePadding();
const nsStyleBorder* styleBorder = StyleBorder();
diff --git a/layout/generic/nsFirstLetterFrame.cpp b/layout/generic/nsFirstLetterFrame.cpp
index 28d1b08a30..c08950121a 100644
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -447,12 +447,12 @@ Maybe<nscoord> nsFirstLetterFrame::GetNaturalBaselineBOffset(
LogicalSides nsFirstLetterFrame::GetLogicalSkipSides() const {
if (GetPrevContinuation()) {
- // We shouldn't get calls to GetSkipSides for later continuations since
- // they have separate ComputedStyles with initial values for all the
- // properties that could trigger a call to GetSkipSides. Then again,
- // it's not really an error to call GetSkipSides on any frame, so
+ // We shouldn't get calls to GetLogicalSkipSides for later continuations
+ // since they have separate ComputedStyles with initial values for all the
+ // properties that could trigger a call to GetLogicalSkipSides. Then again,
+ // it's not really an error to call GetLogicalSkipSides on any frame, so
// that's why we handle it properly.
- return LogicalSides(mWritingMode, eLogicalSideBitsAll);
+ return LogicalSides(mWritingMode, LogicalSides::All);
}
return LogicalSides(mWritingMode); // first continuation displays all sides
}
diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp
index 66f1e79609..4604106a4a 100644
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -312,7 +312,7 @@ class MOZ_STACK_CLASS nsFlexContainerFrame::FlexboxAxisTracker {
return StyleAlignFlags::START;
}
- MOZ_ASSERT(wm.PhysicalAxis(MainAxis()) == eAxisHorizontal,
+ MOZ_ASSERT(wm.PhysicalAxis(MainAxis()) == PhysicalAxis::Horizontal,
"Vertical column-oriented flex container's main axis should "
"be parallel to physical left <-> right axis!");
// Map 'left' or 'right' to 'start' or 'end', depending on its block flow
@@ -2021,7 +2021,7 @@ const CachedBAxisMeasurement& nsFlexContainerFrame::MeasureBSizeForFlexItem(
// CachedFlexItemData is stored in item's writing mode, so we pass
// aChildReflowInput into ReflowOutput's constructor.
ReflowOutput childReflowOutput(aChildReflowInput);
- nsReflowStatus childReflowStatus;
+ nsReflowStatus childStatus;
const ReflowChildFlags flags = ReflowChildFlags::NoMoveFrame;
const WritingMode outerWM = GetWritingMode();
@@ -2032,12 +2032,12 @@ const CachedBAxisMeasurement& nsFlexContainerFrame::MeasureBSizeForFlexItem(
// unimportant.
ReflowChild(aItem.Frame(), PresContext(), childReflowOutput,
aChildReflowInput, outerWM, dummyPosition, dummyContainerSize,
- flags, childReflowStatus);
+ flags, childStatus);
aItem.SetHadMeasuringReflow();
// We always use unconstrained available block-size to measure flex items,
// which means they should always complete.
- MOZ_ASSERT(childReflowStatus.IsComplete(),
+ MOZ_ASSERT(childStatus.IsComplete(),
"We gave flex item unconstrained available block-size, so it "
"should be complete");
@@ -2227,7 +2227,7 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput, float aFlexGrow,
// (We'll resolve them later; until then, we want to treat them as 0-sized.)
#ifdef DEBUG
{
- for (const auto side : AllLogicalSides()) {
+ for (const auto side : LogicalSides::All) {
if (styleMargin->mMargin.Get(mCBWM, side).IsAuto()) {
MOZ_ASSERT(GetMarginComponentForSide(side) == 0,
"Someone else tried to resolve our auto margin");
@@ -2257,7 +2257,7 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput, float aFlexGrow,
// (Note: this is *not* the "flex-start" side; rather, it's the *logical*
// i.e. WM-relative block-start or inline-start side.)
mozilla::Side containerStartSideInCrossAxis = mCBWM.PhysicalSide(
- MakeLogicalSide(aAxisTracker.CrossAxis(), eLogicalEdgeStart));
+ MakeLogicalSide(aAxisTracker.CrossAxis(), LogicalEdge::Start));
// We already know these two Sides (the item's block-start and the
// container's 'logical start' side for its cross axis) are in the same
@@ -2354,7 +2354,7 @@ nscoord FlexItem::BaselineOffsetFromOuterCrossEdge(
// column-oriented flex container. We need to synthesize the item's baseline
// from its border-box edge.
const bool isMainAxisHorizontal =
- mCBWM.PhysicalAxis(MainAxis()) == mozilla::eAxisHorizontal;
+ mCBWM.PhysicalAxis(MainAxis()) == PhysicalAxis::Horizontal;
// When the main axis is horizontal, the synthesized baseline is the bottom
// edge of the item's border-box. Otherwise, when the main axis is vertical,
@@ -2448,7 +2448,7 @@ void FlexItem::ResolveFlexBaseSizeFromAspectRatio(
uint32_t FlexItem::NumAutoMarginsInAxis(LogicalAxis aAxis) const {
uint32_t numAutoMargins = 0;
const auto& styleMargin = mFrame->StyleMargin()->mMargin;
- for (const auto edge : {eLogicalEdgeStart, eLogicalEdgeEnd}) {
+ for (const auto edge : {LogicalEdge::Start, LogicalEdge::End}) {
const auto side = MakeLogicalSide(aAxis, edge);
if (styleMargin.Get(mCBWM, side).IsAuto()) {
numAutoMargins++;
@@ -2708,12 +2708,12 @@ class MOZ_STACK_CLASS PositionTracker {
inline LogicalSide StartSide() {
return MakeLogicalSide(
- mAxis, mIsAxisReversed ? eLogicalEdgeEnd : eLogicalEdgeStart);
+ mAxis, mIsAxisReversed ? LogicalEdge::End : LogicalEdge::Start);
}
inline LogicalSide EndSide() {
return MakeLogicalSide(
- mAxis, mIsAxisReversed ? eLogicalEdgeStart : eLogicalEdgeEnd);
+ mAxis, mIsAxisReversed ? LogicalEdge::Start : LogicalEdge::End);
}
// Advances our position across the start edge of the given margin, in the
@@ -4111,12 +4111,13 @@ FlexboxAxisTracker::FlexboxAxisTracker(
LogicalSide FlexboxAxisTracker::MainAxisStartSide() const {
return MakeLogicalSide(
- MainAxis(), IsMainAxisReversed() ? eLogicalEdgeEnd : eLogicalEdgeStart);
+ MainAxis(), IsMainAxisReversed() ? LogicalEdge::End : LogicalEdge::Start);
}
LogicalSide FlexboxAxisTracker::CrossAxisStartSide() const {
- return MakeLogicalSide(
- CrossAxis(), IsCrossAxisReversed() ? eLogicalEdgeEnd : eLogicalEdgeStart);
+ return MakeLogicalSide(CrossAxis(), IsCrossAxisReversed()
+ ? LogicalEdge::End
+ : LogicalEdge::Start);
}
void nsFlexContainerFrame::GenerateFlexLines(
@@ -4885,8 +4886,14 @@ void nsFlexContainerFrame::UnionInFlowChildOverflow(
bool anyScrolledContentItem = false;
// Union of normal-positioned margin boxes for all the items.
nsRect itemMarginBoxes;
- // Union of relative-positioned margin boxes for the relpos items only.
- nsRect relPosItemMarginBoxes;
+ // Overflow areas containing the union of relative-positioned and
+ // stick-positioned margin boxes of relpos items.
+ //
+ // Note for sticky-positioned margin boxes, we only union it with the ink
+ // overflow to avoid circular dependencies with the scroll container. (The
+ // scroll position and the scroll container's size impact the sticky position,
+ // so we don't want the sticky position to impact them.)
+ OverflowAreas relPosItemMarginBoxes;
const bool useMozBoxCollapseBehavior =
StyleVisibility()->UseLegacyCollapseBehavior();
for (nsIFrame* f : mFrames) {
@@ -4905,8 +4912,13 @@ void nsFlexContainerFrame::UnionInFlowChildOverflow(
const nsRect marginRect = f->GetMarginRectRelativeToSelf();
itemMarginBoxes =
itemMarginBoxes.Union(marginRect + f->GetNormalPosition());
- relPosItemMarginBoxes =
- relPosItemMarginBoxes.Union(marginRect + f->GetPosition());
+ if (f->IsRelativelyPositioned()) {
+ relPosItemMarginBoxes.UnionAllWith(marginRect + f->GetPosition());
+ } else {
+ MOZ_ASSERT(f->IsStickyPositioned());
+ relPosItemMarginBoxes.UnionWith(
+ OverflowAreas(marginRect + f->GetPosition(), nsRect()));
+ }
} else {
itemMarginBoxes = itemMarginBoxes.Union(f->GetMarginRect());
}
@@ -4915,7 +4927,7 @@ void nsFlexContainerFrame::UnionInFlowChildOverflow(
if (anyScrolledContentItem) {
itemMarginBoxes.Inflate(GetUsedPadding());
aOverflowAreas.UnionAllWith(itemMarginBoxes);
- aOverflowAreas.UnionAllWith(relPosItemMarginBoxes);
+ aOverflowAreas.UnionWith(relPosItemMarginBoxes);
}
}
@@ -5515,14 +5527,19 @@ std::tuple<nscoord, nsReflowStatus> nsFlexContainerFrame::ReflowChildren(
const bool isSingleLine =
StyleFlexWrap::Nowrap == aReflowInput.mStylePosition->mFlexWrap;
-
- // FINAL REFLOW: Give each child frame another chance to reflow, now that
- // we know its final size and position.
const FlexLine& startmostLine = StartmostLine(aFlr.mLines, aAxisTracker);
+ const FlexLine& endmostLine = EndmostLine(aFlr.mLines, aAxisTracker);
const FlexItem* startmostItem =
startmostLine.IsEmpty() ? nullptr
: &startmostLine.StartmostItem(aAxisTracker);
+ const FlexItem* endmostItem =
+ endmostLine.IsEmpty() ? nullptr : &endmostLine.EndmostItem(aAxisTracker);
+
+ bool endmostItemOrLineHasBreakAfter = false;
+ // If true, push all remaining flex items to the container's next-in-flow.
+ bool shouldPushRemainingItems = false;
+ // FINAL REFLOW: Give each child frame another chance to reflow.
const size_t numLines = aFlr.mLines.Length();
for (size_t lineIdx = 0; lineIdx < numLines; ++lineIdx) {
// Iterate flex lines from the startmost to endmost (relative to flex
@@ -5533,6 +5550,11 @@ std::tuple<nscoord, nsReflowStatus> nsFlexContainerFrame::ReflowChildren(
MOZ_ASSERT(lineIdx != 0 || &line == &startmostLine,
"Logic for finding startmost line should be consistent!");
+ // These two variables can be set when we are a row-oriented flex container
+ // during fragmentation.
+ bool lineHasBreakBefore = false;
+ bool lineHasBreakAfter = false;
+
const size_t numItems = line.Items().Length();
for (size_t itemIdx = 0; itemIdx < numItems; ++itemIdx) {
// Iterate flex items from the startmost to endmost (relative to flex
@@ -5631,15 +5653,22 @@ std::tuple<nscoord, nsReflowStatus> nsFlexContainerFrame::ReflowChildren(
// (i.e. its frame rect), instead of the container's content-box:
framePos += containerContentBoxOrigin;
- // Check if we actually need to reflow the item -- if the item's position
- // is below the available space's block-end, push it to our next-in-flow;
- // if it does need a reflow, and we already reflowed it with the right
- // content-box size.
- const bool childBPosExceedAvailableSpaceBEnd =
- availableBSizeForItem != NS_UNCONSTRAINEDSIZE &&
- availableBSizeForItem <= 0;
+ // Check if we can skip reflowing the item because it will be pushed to
+ // our next-in-flow -- i.e. if there was a forced break before it, or its
+ // position is beyond the available space's block-end.
bool itemInPushedItems = false;
- if (childBPosExceedAvailableSpaceBEnd) {
+ if (shouldPushRemainingItems) {
+ FLEX_ITEM_LOG(
+ item.Frame(),
+ "[frag] Item needed to be pushed to container's next-in-flow due "
+ "to a forced break before it");
+ pushedItems.Insert(item.Frame());
+ itemInPushedItems = true;
+ } else if (availableBSizeForItem != NS_UNCONSTRAINEDSIZE &&
+ availableBSizeForItem <= 0) {
+ // The item's position is beyond the available space, so we have to push
+ // it.
+ //
// Note: Even if all of our items are beyond the available space & get
// pushed here, we'll be guaranteed to place at least one of them (and
// make progress) in one of the flex container's *next* fragment. It's
@@ -5662,17 +5691,50 @@ std::tuple<nscoord, nsReflowStatus> nsFlexContainerFrame::ReflowChildren(
availableBSizeForItem)
.ConvertTo(itemWM, flexWM);
- const nsReflowStatus childReflowStatus =
+ const bool isAdjacentWithBStart =
+ framePos.B(flexWM) == containerContentBoxOrigin.B(flexWM);
+ const nsReflowStatus childStatus =
ReflowFlexItem(aAxisTracker, aReflowInput, item, framePos,
- availableSize, aContainerSize);
+ isAdjacentWithBStart, availableSize, aContainerSize);
+
+ if (aReflowInput.IsInFragmentedContext()) {
+ const bool itemHasBreakBefore =
+ item.Frame()->ShouldBreakBefore(aReflowInput.mBreakType) ||
+ childStatus.IsInlineBreakBefore();
+ if (itemHasBreakBefore) {
+ if (aAxisTracker.IsRowOriented()) {
+ lineHasBreakBefore = true;
+ } else if (isSingleLine) {
+ if (&item == startmostItem) {
+ if (!GetPrevInFlow() && !aReflowInput.mFlags.mIsTopOfPage) {
+ // If we are first-in-flow and not at top-of-page, early
+ // return here to propagate forced break-before from the
+ // startmost item to the flex container.
+ nsReflowStatus childrenStatus;
+ childrenStatus.SetInlineLineBreakBeforeAndReset();
+ return {0, childrenStatus};
+ }
+ } else {
+ shouldPushRemainingItems = true;
+ }
+ } else {
+ // Bug 1806717: We haven't implemented fragmentation for
+ // multi-line column-oriented flex container, so we just ignore
+ // forced breaks for now.
+ }
+ }
+ }
const bool shouldPushItem = [&]() {
+ if (shouldPushRemainingItems) {
+ return true;
+ }
if (availableBSizeForItem == NS_UNCONSTRAINEDSIZE) {
// If the available block-size is unconstrained, then we're not
// fragmenting and we don't want to push the item.
return false;
}
- if (framePos.B(flexWM) == containerContentBoxOrigin.B(flexWM)) {
+ if (isAdjacentWithBStart) {
// The flex item is adjacent with block-start of the container's
// content-box. Don't push it, or we'll trap in an infinite loop.
return false;
@@ -5691,15 +5753,38 @@ std::tuple<nscoord, nsReflowStatus> nsFlexContainerFrame::ReflowChildren(
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");
+ "because it encounters a forced break before it, or its "
+ "block-size is larger than the available space");
pushedItems.Insert(item.Frame());
itemInPushedItems = true;
- } else if (childReflowStatus.IsIncomplete()) {
+ } else if (childStatus.IsIncomplete()) {
incompleteItems.Insert(item.Frame());
- } else if (childReflowStatus.IsOverflowIncomplete()) {
+ } else if (childStatus.IsOverflowIncomplete()) {
overflowIncompleteItems.Insert(item.Frame());
}
+
+ if (aReflowInput.IsInFragmentedContext()) {
+ const bool itemHasBreakAfter =
+ item.Frame()->ShouldBreakAfter(aReflowInput.mBreakType) ||
+ childStatus.IsInlineBreakAfter();
+ if (itemHasBreakAfter) {
+ if (aAxisTracker.IsRowOriented()) {
+ lineHasBreakAfter = true;
+ } else if (isSingleLine) {
+ shouldPushRemainingItems = true;
+ if (&item == endmostItem) {
+ endmostItemOrLineHasBreakAfter = true;
+ }
+ } else {
+ // Bug 1806717: We haven't implemented fragmentation for
+ // multi-line column-oriented flex container, so we just ignore
+ // forced breaks for now.
+ }
+ }
+ }
} else {
+ // We already reflowed the item with the right content-box size, so we
+ // can simply move it into place.
MoveFlexItemToFinalPosition(item, framePos, aContainerSize);
}
@@ -5787,6 +5872,37 @@ std::tuple<nscoord, nsReflowStatus> nsFlexContainerFrame::ReflowChildren(
}
}
+ if (aReflowInput.IsInFragmentedContext() && aAxisTracker.IsRowOriented()) {
+ // Propagate forced break values from the flex items to its flex line.
+ if (lineHasBreakBefore) {
+ if (&line == &startmostLine) {
+ if (!GetPrevInFlow() && !aReflowInput.mFlags.mIsTopOfPage) {
+ // If we are first-in-flow and not at top-of-page, early return here
+ // to propagate forced break-before from the startmost line to the
+ // flex container.
+ nsReflowStatus childrenStatus;
+ childrenStatus.SetInlineLineBreakBeforeAndReset();
+ return {0, childrenStatus};
+ }
+ } else {
+ // Current non-startmost line has forced break-before, so push all the
+ // items in this line.
+ for (const FlexItem& item : line.Items()) {
+ pushedItems.Insert(item.Frame());
+ incompleteItems.Remove(item.Frame());
+ overflowIncompleteItems.Remove(item.Frame());
+ }
+ shouldPushRemainingItems = true;
+ }
+ }
+ if (lineHasBreakAfter) {
+ shouldPushRemainingItems = true;
+ if (&line == &endmostLine) {
+ endmostItemOrLineHasBreakAfter = true;
+ }
+ }
+ }
+
// Now we've finished processing all the items in the startmost line.
// Determine the amount by which the startmost line's block-end edge has
// shifted, so we can apply the same shift for the remaining lines.
@@ -5808,6 +5924,8 @@ std::tuple<nscoord, nsReflowStatus> nsFlexContainerFrame::ReflowChildren(
childrenStatus.SetIncomplete();
} else if (!overflowIncompleteItems.IsEmpty()) {
childrenStatus.SetOverflowIncomplete();
+ } else if (endmostItemOrLineHasBreakAfter) {
+ childrenStatus.SetInlineLineBreakAfter();
}
PushIncompleteChildren(pushedItems, incompleteItems, overflowIncompleteItems);
@@ -5952,6 +6070,14 @@ void nsFlexContainerFrame::PopulateReflowOutput(
return;
}
+ // Propagate forced break values from flex items or flex lines.
+ if (aChildrenStatus.IsInlineBreakBefore()) {
+ aStatus.SetInlineLineBreakBeforeAndReset();
+ }
+ if (aChildrenStatus.IsInlineBreakAfter()) {
+ aStatus.SetInlineLineBreakAfter();
+ }
+
// If we haven't established a baseline for the container yet, i.e. if we
// don't have any flex item in the startmost flex line that participates in
// baseline alignment, then use the startmost flex item to derive the
@@ -6067,7 +6193,8 @@ void nsFlexContainerFrame::MoveFlexItemToFinalPosition(
nsReflowStatus nsFlexContainerFrame::ReflowFlexItem(
const FlexboxAxisTracker& aAxisTracker, const ReflowInput& aReflowInput,
const FlexItem& aItem, const LogicalPoint& aFramePos,
- const LogicalSize& aAvailableSize, const nsSize& aContainerSize) {
+ const bool aIsAdjacentWithBStart, const LogicalSize& aAvailableSize,
+ const nsSize& aContainerSize) {
FLEX_ITEM_LOG(aItem.Frame(), "Doing final reflow");
// Returns true if we should use 'auto' in block axis's StyleSizeOverrides to
@@ -6206,6 +6333,13 @@ nsReflowStatus nsFlexContainerFrame::ReflowFlexItem(
aItem.Frame()->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
}
+ if (!aIsAdjacentWithBStart) {
+ // mIsTopOfPage bit in childReflowInput is carried over from aReflowInput.
+ // However, if this item's position is not adjacent with the flex
+ // container's content-box block-start edge, we should clear it.
+ childReflowInput.mFlags.mIsTopOfPage = false;
+ }
+
// NOTE: Be very careful about doing anything else with childReflowInput
// after this point, because some of its methods (e.g. SetComputedWidth)
// internally call InitResizeFlags and stomp on mVResize & mHResize.
@@ -6216,11 +6350,11 @@ nsReflowStatus nsFlexContainerFrame::ReflowFlexItem(
// CachedFlexItemData is stored in item's writing mode, so we pass
// aChildReflowInput into ReflowOutput's constructor.
ReflowOutput childReflowOutput(childReflowInput);
- nsReflowStatus childReflowStatus;
+ nsReflowStatus childStatus;
WritingMode outerWM = aReflowInput.GetWritingMode();
ReflowChild(aItem.Frame(), PresContext(), childReflowOutput, childReflowInput,
outerWM, aFramePos, aContainerSize, ReflowChildFlags::Default,
- childReflowStatus);
+ childStatus);
// XXXdholbert Perhaps we should call CheckForInterrupt here; see bug 1495532.
@@ -6240,7 +6374,7 @@ nsReflowStatus nsFlexContainerFrame::ReflowFlexItem(
aItem.Frame()->SetProperty(CachedFlexItemData::Prop(), cached);
}
- return childReflowStatus;
+ return childStatus;
}
void nsFlexContainerFrame::ReflowPlaceholders(
@@ -6260,10 +6394,10 @@ void nsFlexContainerFrame::ReflowPlaceholders(
// No need to set the -webkit-line-clamp related flags when reflowing
// a placeholder.
ReflowOutput childReflowOutput(outerWM);
- nsReflowStatus childReflowStatus;
+ nsReflowStatus childStatus;
ReflowChild(placeholder, PresContext(), childReflowOutput, childReflowInput,
outerWM, aContentBoxOrigin, aContainerSize,
- ReflowChildFlags::Default, childReflowStatus);
+ ReflowChildFlags::Default, childStatus);
FinishReflowChild(placeholder, PresContext(), childReflowOutput,
&childReflowInput, outerWM, aContentBoxOrigin,
diff --git a/layout/generic/nsFlexContainerFrame.h b/layout/generic/nsFlexContainerFrame.h
index 14f91ae064..2771098255 100644
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -604,6 +604,8 @@ class nsFlexContainerFrame final : public nsContainerFrame,
* @param aItem The flex item to be reflowed.
* @param aFramePos The position where the flex item's frame should
* be placed. (pre-relative positioning)
+ * @param aIsAdjacentWithBStart True if aFramePos is adjacent with the flex
+ * container's content-box block-start edge.
* @param aAvailableSize The available size to reflow the child frame (in the
* child frame's writing-mode).
* @param aContainerSize The flex container's size (required by some methods
@@ -614,6 +616,7 @@ class nsFlexContainerFrame final : public nsContainerFrame,
const ReflowInput& aReflowInput,
const FlexItem& aItem,
const mozilla::LogicalPoint& aFramePos,
+ const bool aIsAdjacentWithBStart,
const mozilla::LogicalSize& aAvailableSize,
const nsSize& aContainerSize);
diff --git a/layout/generic/nsFloatManager.cpp b/layout/generic/nsFloatManager.cpp
index e1866b35c1..88a8b20b4c 100644
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -2834,8 +2834,8 @@ nsFloatManager::ShapeInfo::ConvertToFloatLogical(const nscoord aRadii[8],
// Get the physical side for line-left and line-right since border radii
// are on the physical axis.
- Side lineLeftSide =
- aWM.PhysicalSide(aWM.LogicalSideForLineRelativeDir(eLineRelativeDirLeft));
+ Side lineLeftSide = aWM.PhysicalSide(
+ aWM.LogicalSideForLineRelativeDir(LineRelativeDir::Left));
logicalRadii[eCornerTopLeftX] =
aRadii[SideToHalfCorner(lineLeftSide, true, false)];
logicalRadii[eCornerTopLeftY] =
@@ -2846,7 +2846,7 @@ nsFloatManager::ShapeInfo::ConvertToFloatLogical(const nscoord aRadii[8],
aRadii[SideToHalfCorner(lineLeftSide, false, true)];
Side lineRightSide = aWM.PhysicalSide(
- aWM.LogicalSideForLineRelativeDir(eLineRelativeDirRight));
+ aWM.LogicalSideForLineRelativeDir(LineRelativeDir::Right));
logicalRadii[eCornerTopRightX] =
aRadii[SideToHalfCorner(lineRightSide, false, false)];
logicalRadii[eCornerTopRightY] =
diff --git a/layout/generic/nsFrameSelection.cpp b/layout/generic/nsFrameSelection.cpp
index ca4e3d647e..94cf368480 100644
--- a/layout/generic/nsFrameSelection.cpp
+++ b/layout/generic/nsFrameSelection.cpp
@@ -1441,11 +1441,6 @@ nsresult nsFrameSelection::TakeFocus(nsIContent& aNewFocus,
}
}
- // Don't notify selection listeners if batching is on:
- if (IsBatching()) {
- return NS_OK;
- }
-
// Be aware, the Selection instance may be destroyed after this call.
return NotifySelectionListeners(SelectionType::eNormal);
}
diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp
index 2b0c53efe1..97e6b614dc 100644
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -964,7 +964,7 @@ void nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowInput& aState,
nsRect childScrollableOverflow = childOverflow.ScrollableOverflow();
const LogicalMargin inlinePadding =
- padding.ApplySkipSides(LogicalSides(wm, eLogicalSideBitsBBoth));
+ padding.ApplySkipSides(LogicalSides(wm, LogicalSides::BBoth));
childScrollableOverflow.Inflate(inlinePadding.GetPhysicalMargin(wm));
nsRect& so = aMetrics->ScrollableOverflow();
@@ -5211,15 +5211,19 @@ nsSize nsHTMLScrollFrame::GetPageScrollAmount() const {
}
nsSize lineScrollAmount = GetLineScrollAmount();
-
- // The page increment is the size of the page, minus the smaller of
- // 10% of the size or 2 lines.
- return nsSize(effectiveScrollPortSize.width -
- std::min(effectiveScrollPortSize.width / 10,
- 2 * lineScrollAmount.width),
- effectiveScrollPortSize.height -
- std::min(effectiveScrollPortSize.height / 10,
- 2 * lineScrollAmount.height));
+ const int32_t maxOverlapPercent = std::clamp(
+ StaticPrefs::toolkit_scrollbox_pagescroll_maxOverlapPercent(), 0, 80);
+ const int32_t maxOverlapLines =
+ std::max(StaticPrefs::toolkit_scrollbox_pagescroll_maxOverlapLines(), 0);
+
+ // The page increment is the size of the page, minus some overlap.
+ return nsSize(
+ effectiveScrollPortSize.width -
+ std::min(effectiveScrollPortSize.width * maxOverlapPercent / 100,
+ maxOverlapLines * lineScrollAmount.width),
+ effectiveScrollPortSize.height -
+ std::min(effectiveScrollPortSize.height * maxOverlapPercent / 100,
+ maxOverlapLines * lineScrollAmount.height));
}
/**
diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp
index bb6e2150ce..48c70cd479 100644
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -4317,7 +4317,7 @@ int32_t nsGridContainerFrame::Grid::ResolveLine(
bool useStart = IsNameWithStartSuffix(aLine.LineName(), &index);
if (useStart || IsNameWithEndSuffix(aLine.LineName(), &index)) {
auto side = MakeLogicalSide(
- GetAxis(aSide), useStart ? eLogicalEdgeStart : eLogicalEdgeEnd);
+ GetAxis(aSide), useStart ? LogicalEdge::Start : LogicalEdge::End);
RefPtr<nsAtom> name = NS_Atomize(nsDependentSubstring(
nsDependentAtomString(aLine.LineName()), 0, index));
aNameMap.FindNamedAreas(name, side, implicitLines);
@@ -4377,7 +4377,7 @@ nsGridContainerFrame::Grid::ResolveLineRangeHelper(
uint32_t from = aEnd.line_num < 0 ? aExplicitGridEnd + 1 : 0;
auto end = ResolveLine(aEnd, aEnd.line_num, from, aNameMap,
- MakeLogicalSide(aAxis, eLogicalEdgeEnd),
+ MakeLogicalSide(aAxis, LogicalEdge::End),
aExplicitGridEnd, aStyle);
int32_t span = aStart.line_num == 0 ? 1 : aStart.line_num;
if (end <= 1) {
@@ -4387,7 +4387,7 @@ nsGridContainerFrame::Grid::ResolveLineRangeHelper(
return LinePair(start, end);
}
auto start = ResolveLine(aStart, -span, end, aNameMap,
- MakeLogicalSide(aAxis, eLogicalEdgeStart),
+ MakeLogicalSide(aAxis, LogicalEdge::Start),
aExplicitGridEnd, aStyle);
return LinePair(start, end);
}
@@ -4411,7 +4411,7 @@ nsGridContainerFrame::Grid::ResolveLineRangeHelper(
} else {
uint32_t from = aStart.line_num < 0 ? aExplicitGridEnd + 1 : 0;
start = ResolveLine(aStart, aStart.line_num, from, aNameMap,
- MakeLogicalSide(aAxis, eLogicalEdgeStart),
+ MakeLogicalSide(aAxis, LogicalEdge::Start),
aExplicitGridEnd, aStyle);
if (aEnd.IsAuto()) {
// A "definite line / auto" should resolve the auto to 'span 1'.
@@ -4441,7 +4441,7 @@ nsGridContainerFrame::Grid::ResolveLineRangeHelper(
from = aEnd.line_num < 0 ? aExplicitGridEnd + 1 : 0;
}
auto end = ResolveLine(aEnd, nth, from, aNameMap,
- MakeLogicalSide(aAxis, eLogicalEdgeEnd),
+ MakeLogicalSide(aAxis, LogicalEdge::End),
aExplicitGridEnd, aStyle);
if (start == int32_t(kAutoLine)) {
// auto / definite line
@@ -4527,7 +4527,7 @@ nsGridContainerFrame::Grid::ResolveAbsPosLineRange(
}
uint32_t from = aEnd.line_num < 0 ? aExplicitGridEnd + 1 : 0;
int32_t end = ResolveLine(aEnd, aEnd.line_num, from, aNameMap,
- MakeLogicalSide(aAxis, eLogicalEdgeEnd),
+ MakeLogicalSide(aAxis, LogicalEdge::End),
aExplicitGridEnd, aStyle);
if (aEnd.is_span) {
++end;
@@ -4540,7 +4540,7 @@ nsGridContainerFrame::Grid::ResolveAbsPosLineRange(
if (aEnd.IsAuto()) {
uint32_t from = aStart.line_num < 0 ? aExplicitGridEnd + 1 : 0;
int32_t start = ResolveLine(aStart, aStart.line_num, from, aNameMap,
- MakeLogicalSide(aAxis, eLogicalEdgeStart),
+ MakeLogicalSide(aAxis, LogicalEdge::Start),
aExplicitGridEnd, aStyle);
if (aStart.is_span) {
start = std::max(aGridEnd - start, aGridStart);
@@ -5761,7 +5761,7 @@ static nscoord MinSize(const GridItemInfo& aGridItem,
PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis));
const nsStylePosition* stylePos = child->StylePosition();
StyleSize sizeStyle =
- axis == eAxisHorizontal ? stylePos->mWidth : stylePos->mHeight;
+ axis == PhysicalAxis::Horizontal ? stylePos->mWidth : stylePos->mHeight;
auto ourInlineAxis =
child->GetWritingMode().PhysicalAxis(LogicalAxis::Inline);
@@ -5800,8 +5800,9 @@ static nscoord MinSize(const GridItemInfo& aGridItem,
nsLayoutUtils::MinSizeContributionForAxis(
axis, aRC, child, IntrinsicISizeType::MinISize,
*aCache->mPercentageBasis);
- const StyleSize& style =
- axis == eAxisHorizontal ? stylePos->mMinWidth : stylePos->mMinHeight;
+ const StyleSize& style = axis == PhysicalAxis::Horizontal
+ ? stylePos->mMinWidth
+ : stylePos->mMinHeight;
// 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
@@ -6017,7 +6018,7 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselines(
// against the physical block start side of the child to determine its
// baseline sharing group.
auto containerBlockStartSide =
- containerWM.PhysicalSide(MakeLogicalSide(mAxis, eLogicalEdgeStart));
+ containerWM.PhysicalSide(MakeLogicalSide(mAxis, LogicalEdge::Start));
for (GridItemInfo& gridItem : aGridItems) {
if (gridItem.IsSubgrid(mAxis)) {
@@ -6124,7 +6125,7 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselines(
{
auto childAxis = isOrthogonal ? GetOrthogonalAxis(mAxis) : mAxis;
auto childBlockStartSide = childWM.PhysicalSide(
- MakeLogicalSide(childAxis, eLogicalEdgeStart));
+ MakeLogicalSide(childAxis, LogicalEdge::Start));
bool isFirstBaseline = (state & ItemState::eFirstBaseline) != 0;
const bool containerAndChildHasEqualBaselineSide =
containerBlockStartSide == childBlockStartSide;
diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h
index cb3eef68c3..1fa7bbe487 100644
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -566,12 +566,8 @@ class nsGridContainerFrame final : public nsContainerFrame,
if (aFrame->IsSubtreeDirty()) {
return false;
}
-
- if (!CanCacheMeasurement(aFrame, aCBSize)) {
- return false;
- }
-
- return mKey == Key(aFrame, aCBSize);
+ const mozilla::Maybe<Key> maybeKey = Key::TryHash(aFrame, aCBSize);
+ return maybeKey.isSome() && mKey == *maybeKey;
}
static bool CanCacheMeasurement(const nsIFrame* aFrame,
@@ -583,55 +579,54 @@ class nsGridContainerFrame final : public nsContainerFrame,
void Update(const nsIFrame* aFrame, const LogicalSize& aCBSize,
const nscoord aBSize) {
- MOZ_ASSERT(CanCacheMeasurement(aFrame, aCBSize));
- mKey.mHashKey = Key::GenerateHash(aFrame, aCBSize);
+ mKey.UpdateHash(aFrame, aCBSize);
mBSize = aBSize;
}
private:
- struct Key {
+ class Key {
// mHashKey is generated by combining these 2 variables together
// 1. The containing block size in the item's inline axis used
// for measuring reflow
// 2. The item's baseline padding property
uint32_t mHashKey;
+ explicit Key(uint32_t aHashKey) : mHashKey(aHashKey) {}
+
+ public:
Key() = default;
Key(const nsIFrame* aFrame, const LogicalSize& aCBSize) {
- MOZ_ASSERT(CanHash(aFrame, aCBSize));
- mHashKey = GenerateHash(aFrame, aCBSize);
+ UpdateHash(aFrame, aCBSize);
}
void UpdateHash(const nsIFrame* aFrame, const LogicalSize& aCBSize) {
- MOZ_ASSERT(CanHash(aFrame, aCBSize));
- mHashKey = GenerateHash(aFrame, aCBSize);
+ const mozilla::Maybe<Key> maybeKey = TryHash(aFrame, aCBSize);
+ MOZ_ASSERT(maybeKey.isSome());
+ mHashKey = maybeKey->mHashKey;
}
- static uint32_t GenerateHash(const nsIFrame* aFrame,
- const LogicalSize& aCBSize) {
- MOZ_ASSERT(CanHash(aFrame, aCBSize));
-
- nscoord gridAreaISize = aCBSize.ISize(aFrame->GetWritingMode());
- nscoord bBaselinePaddingProperty =
+ static mozilla::Maybe<Key> TryHash(const nsIFrame* aFrame,
+ const LogicalSize& aCBSize) {
+ const nscoord gridAreaISize = aCBSize.ISize(aFrame->GetWritingMode());
+ const nscoord bBaselinePaddingProperty =
abs(aFrame->GetProperty(nsIFrame::BBaselinePadProperty()));
- uint_fast8_t bitsNeededForISize = mozilla::FloorLog2(gridAreaISize) + 1;
-
- return (gridAreaISize << (32 - bitsNeededForISize)) |
- bBaselinePaddingProperty;
+ const uint_fast8_t bitsNeededForISize =
+ mozilla::FloorLog2(gridAreaISize) + 1;
+
+ const uint_fast8_t bitsNeededForBBaselinePadding =
+ mozilla::FloorLog2(bBaselinePaddingProperty) + 1;
+ if (bitsNeededForISize + bitsNeededForBBaselinePadding > 32) {
+ return mozilla::Nothing();
+ }
+ const uint32_t hashKey = (gridAreaISize << (32 - bitsNeededForISize)) |
+ bBaselinePaddingProperty;
+ return mozilla::Some(Key(hashKey));
}
static bool CanHash(const nsIFrame* aFrame, const LogicalSize& aCBSize) {
- uint_fast8_t bitsNeededForISize =
- mozilla::FloorLog2(aCBSize.ISize(aFrame->GetWritingMode())) + 1;
-
- uint_fast8_t bitsNeededForBBaselinePadding =
- mozilla::FloorLog2(
- abs(aFrame->GetProperty(nsIFrame::BBaselinePadProperty()))) +
- 1;
-
- return bitsNeededForISize + bitsNeededForBBaselinePadding <= 32;
+ return TryHash(aFrame, aCBSize).isSome();
}
bool operator==(const Key& aOther) const {
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
index 27f09b84f6..28c328c9e2 100644
--- a/layout/generic/nsIFrame.cpp
+++ b/layout/generic/nsIFrame.cpp
@@ -19,6 +19,7 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/DisplayPortUtils.h"
#include "mozilla/EventForwards.h"
+#include "mozilla/FocusModel.h"
#include "mozilla/dom/CSSAnimation.h"
#include "mozilla/dom/CSSTransition.h"
#include "mozilla/dom/ContentVisibilityAutoStateChangeEvent.h"
@@ -4928,12 +4929,14 @@ bool nsIFrame::MovingCaretToEventPointAllowedIfSecondaryButtonEvent(
: aContentAtEventPoint.GetClosestNativeAnonymousSubtreeRoot());
if (Selection* selection =
aFrameSelection.GetSelection(SelectionType::eNormal)) {
- const bool selectionIsCollapsed = selection->IsCollapsed();
- // If right click in a selection range, we should not collapse selection.
- if (!selectionIsCollapsed &&
- nsContentUtils::IsPointInSelection(
- *selection, aContentAtEventPoint,
- static_cast<uint32_t>(aOffsetAtEventPoint))) {
+ const bool selectionIsCollapsed =
+ selection->AreNormalAndCrossShadowBoundaryRangesCollapsed();
+ // If right click in a selection range, we should not collapse
+ // selection.
+ if (!selectionIsCollapsed && nsContentUtils::IsPointInSelection(
+ *selection, aContentAtEventPoint,
+ static_cast<uint32_t>(aOffsetAtEventPoint),
+ true /* aAllowCrossShadowBoundary */)) {
return false;
}
const bool wantToPreventMoveCaret =
@@ -7889,7 +7892,7 @@ nsRect nsIFrame::GetNormalRect() const {
nsRect nsIFrame::GetBoundingClientRect() {
return nsLayoutUtils::GetAllInFlowRectsUnion(
this, nsLayoutUtils::GetContainingBlockForClientRect(this),
- nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
+ nsLayoutUtils::GetAllInFlowRectsFlag::AccountForTransforms);
}
nsPoint nsIFrame::GetPositionIgnoringScrolling() const {
@@ -7950,8 +7953,19 @@ OverflowAreas nsIFrame::GetActualAndNormalOverflowAreasRelativeToParent()
}
const OverflowAreas overflows = GetOverflowAreas();
- OverflowAreas actualAndNormalOverflows = overflows + GetPosition();
- actualAndNormalOverflows.UnionWith(overflows + GetNormalPosition());
+ OverflowAreas actualAndNormalOverflows = overflows + GetNormalPosition();
+ if (IsRelativelyPositioned()) {
+ actualAndNormalOverflows.UnionWith(overflows + GetPosition());
+ } else {
+ // For sticky positioned elements, we only use the normal position for the
+ // scrollable overflow. This avoids circular dependencies between sticky
+ // positioned elements and their scroll container. (The scroll position and
+ // the scroll container's size impact the sticky position, so we don't want
+ // the sticky position to impact them.)
+ MOZ_ASSERT(IsStickyPositioned());
+ actualAndNormalOverflows.UnionWith(
+ OverflowAreas(overflows.InkOverflow() + GetPosition(), nsRect()));
+ }
return actualAndNormalOverflows;
}
@@ -8008,7 +8022,7 @@ bool nsIFrame::UpdateOverflow() {
if (nsView* view = GetView()) {
// Make sure the frame's view is properly sized.
nsViewManager* vm = view->GetViewManager();
- vm->ResizeView(view, overflowAreas.InkOverflow(), true);
+ vm->ResizeView(view, overflowAreas.InkOverflow());
}
return true;
@@ -10795,7 +10809,7 @@ bool nsIFrame::IsFocusableDueToScrollFrame() {
return true;
}
-Focusable nsIFrame::IsFocusable(bool aWithMouse, bool aCheckVisibility) {
+Focusable nsIFrame::IsFocusable(IsFocusableFlags aFlags) {
// cannot focus content in print preview mode. Only the root can be focused,
// but that's handled elsewhere.
if (PresContext()->Type() == nsPresContext::eContext_PrintPreview) {
@@ -10806,7 +10820,8 @@ Focusable nsIFrame::IsFocusable(bool aWithMouse, bool aCheckVisibility) {
return {};
}
- if (aCheckVisibility && !IsVisibleConsideringAncestors()) {
+ if (!(aFlags & IsFocusableFlags::IgnoreVisibility) &&
+ !IsVisibleConsideringAncestors()) {
return {};
}
@@ -10826,14 +10841,14 @@ Focusable nsIFrame::IsFocusable(bool aWithMouse, bool aCheckVisibility) {
// As a legacy special-case, -moz-user-focus controls focusability and
// tabability of XUL elements in some circumstances (which default to
// -moz-user-focus: ignore).
- auto focusability = xul->GetXULFocusability(aWithMouse);
+ auto focusability = xul->GetXULFocusability(aFlags);
focusable.mFocusable =
focusability.mForcedFocusable.valueOr(uf == StyleUserFocus::Normal);
if (focusable) {
focusable.mTabIndex = focusability.mForcedTabIndexIfFocusable.valueOr(0);
}
} else {
- focusable = mContent->IsFocusableWithoutStyle(aWithMouse);
+ focusable = mContent->IsFocusableWithoutStyle(aFlags);
}
if (focusable) {
@@ -10841,7 +10856,8 @@ Focusable nsIFrame::IsFocusable(bool aWithMouse, bool aCheckVisibility) {
}
// If we're focusing with the mouse we never focus scroll areas.
- if (!aWithMouse && IsFocusableDueToScrollFrame()) {
+ if (!(aFlags & IsFocusableFlags::WithMouse) &&
+ IsFocusableDueToScrollFrame()) {
return {true, 0};
}
@@ -11627,6 +11643,47 @@ bool nsIFrame::HasUnreflowedContainerQueryAncestor() const {
return false;
}
+bool nsIFrame::ShouldBreakBefore(
+ const ReflowInput::BreakType aBreakType) const {
+ const auto* display = StyleDisplay();
+ return ShouldBreakBetween(display, display->mBreakBefore, aBreakType);
+}
+
+bool nsIFrame::ShouldBreakAfter(const ReflowInput::BreakType aBreakType) const {
+ const auto* display = StyleDisplay();
+ return ShouldBreakBetween(display, display->mBreakAfter, aBreakType);
+}
+
+bool nsIFrame::ShouldBreakBetween(
+ const nsStyleDisplay* aDisplay, const StyleBreakBetween aBreakBetween,
+ const ReflowInput::BreakType aBreakType) const {
+ const bool shouldBreakBetween = [&] {
+ switch (aBreakBetween) {
+ case StyleBreakBetween::Always:
+ return true;
+ case StyleBreakBetween::Auto:
+ case StyleBreakBetween::Avoid:
+ return false;
+ case StyleBreakBetween::Page:
+ case StyleBreakBetween::Left:
+ case StyleBreakBetween::Right:
+ return aBreakType == ReflowInput::BreakType::Page;
+ }
+ MOZ_ASSERT_UNREACHABLE("Unknown break-between value!");
+ return false;
+ }();
+
+ if (!shouldBreakBetween) {
+ return false;
+ }
+ if (IsAbsolutelyPositioned(aDisplay)) {
+ // 'break-before' and 'break-after' properties does not apply to
+ // absolutely-positioned boxes.
+ return false;
+ }
+ return true;
+}
+
#ifdef DEBUG
static void GetTagName(nsIFrame* aFrame, nsIContent* aContent, int aResultSize,
char* aResult) {
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
index 6e55ebe1c7..801e80c7e0 100644
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -127,6 +127,7 @@ struct CharacterDataChangeInfo;
namespace mozilla {
enum class CaretAssociationHint;
+enum class IsFocusableFlags : uint8_t;
enum class PeekOffsetOption : uint16_t;
enum class PseudoStyleType : uint8_t;
enum class TableSelectionMode : uint32_t;
@@ -1386,7 +1387,25 @@ class nsIFrame : public nsQueryFrame {
bool HasUnreflowedContainerQueryAncestor() const;
+ // Return True if this frame has a forced break value before it.
+ //
+ // Note: this method only checks 'break-before' property on *this* frame, and
+ // it doesn't handle forced break value propagation from its first child.
+ // Callers should handle the propagation in reflow.
+ bool ShouldBreakBefore(const ReflowInput::BreakType aBreakType) const;
+
+ // Return True if this frame has a forced break value after it.
+ //
+ // Note: this method only checks 'break-after' property on *this* frame, and
+ // it doesn't handle forced break value propagation from its last child.
+ // Callers should handle the propagation in reflow.
+ bool ShouldBreakAfter(const ReflowInput::BreakType aBreakType) const;
+
private:
+ bool ShouldBreakBetween(const nsStyleDisplay* aDisplay,
+ const mozilla::StyleBreakBetween aBreakBetween,
+ const ReflowInput::BreakType aBreakType) const;
+
// The value that the CSS page-name "auto" keyword resolves to for children
// of this frame.
//
@@ -4369,13 +4388,10 @@ class nsIFrame : public nsQueryFrame {
* Also, depending on the pref accessibility.tabfocus some widgets may be
* focusable but removed from the tab order. This is the default on
* Mac OS X, where fewer items are focusable.
- * @param [in, optional] aWithMouse, is this focus query for mouse clicking
- * @param [in, optional] aCheckVisibility, whether to treat an invisible
- * frame as not focusable
* @return whether the frame is focusable via mouse, kbd or script.
*/
- [[nodiscard]] Focusable IsFocusable(bool aWithMouse = false,
- bool aCheckVisibility = true);
+ [[nodiscard]] Focusable IsFocusable(
+ mozilla::IsFocusableFlags = mozilla::IsFocusableFlags(0));
protected:
// Helper for IsFocusable.
diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp
index 91d8430b60..c330f1ce6b 100644
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -645,8 +645,9 @@ const StyleImage* nsImageFrame::GetImageFromStyle() const {
nonAnonymousParent->GetContent());
styleContent = nonAnonymousParent->StyleContent();
}
- MOZ_RELEASE_ASSERT(contentIndex < styleContent->ContentCount());
- auto& contentItem = styleContent->ContentAt(contentIndex);
+ auto items = styleContent->NonAltContentItems();
+ MOZ_RELEASE_ASSERT(contentIndex < items.Length());
+ const auto& contentItem = items[contentIndex];
MOZ_RELEASE_ASSERT(contentItem.IsImage());
return &contentItem.AsImage();
}
@@ -1055,11 +1056,8 @@ bool nsImageFrame::ShouldCreateImageFrameForContentProperty(
if (aElement.IsRootOfNativeAnonymousSubtree()) {
return false;
}
- const auto& content = aStyle.StyleContent()->mContent;
- if (!content.IsItems()) {
- return false;
- }
- Span<const StyleContentItem> items = content.AsItems().AsSpan();
+ Span<const StyleContentItem> items =
+ aStyle.StyleContent()->NonAltContentItems();
return items.Length() == 1 && items[0].IsImage();
}
@@ -2857,10 +2855,10 @@ LogicalSides nsImageFrame::GetLogicalSkipSides() const {
return skip;
}
if (GetPrevInFlow()) {
- skip |= eLogicalSideBitsBStart;
+ skip += LogicalSide::BStart;
}
if (GetNextInFlow()) {
- skip |= eLogicalSideBitsBEnd;
+ skip += LogicalSide::BEnd;
}
return skip;
}
diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp
index b481c71827..44fce51931 100644
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -797,7 +797,7 @@ LogicalSides nsInlineFrame::GetLogicalSkipSides() const {
(prev && (prev->mRect.height || prev->mRect.width))) {
// Prev continuation is not empty therefore we don't render our start
// border edge.
- skip |= eLogicalSideBitsIStart;
+ skip += LogicalSide::IStart;
} else {
// If the prev continuation is empty, then go ahead and let our start
// edge border render.
@@ -809,7 +809,7 @@ LogicalSides nsInlineFrame::GetLogicalSkipSides() const {
(next && (next->mRect.height || next->mRect.width))) {
// Next continuation is not empty therefore we don't render our end
// border edge.
- skip |= eLogicalSideBitsIEnd;
+ skip += LogicalSide::IEnd;
} else {
// If the next continuation is empty, then go ahead and let our end
// edge border render.
@@ -822,15 +822,15 @@ LogicalSides nsInlineFrame::GetLogicalSkipSides() const {
// a split should skip the "start" side. But figuring out which part of
// the split we are involves getting our first continuation, which might be
// expensive. So don't bother if we already have the relevant bits set.
- if (skip != LogicalSides(mWritingMode, eLogicalSideBitsIBoth)) {
+ if (skip != LogicalSides(mWritingMode, LogicalSides::IBoth)) {
// We're missing one of the skip bits, so check whether we need to set it.
// Only get the first continuation once, as an optimization.
nsIFrame* firstContinuation = FirstContinuation();
if (firstContinuation->FrameIsNonLastInIBSplit()) {
- skip |= eLogicalSideBitsIEnd;
+ skip += LogicalSide::IEnd;
}
if (firstContinuation->FrameIsNonFirstInIBSplit()) {
- skip |= eLogicalSideBitsIStart;
+ skip += LogicalSide::IStart;
}
}
}
diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp
index be6f64f1fe..a452568f57 100644
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -396,8 +396,10 @@ nsLineLayout::PerSpanData* nsLineLayout::NewPerSpanData() {
psd->mFrame = nullptr;
psd->mFirstFrame = nullptr;
psd->mLastFrame = nullptr;
+ psd->mReflowInput = nullptr;
psd->mContainsFloat = false;
psd->mHasNonemptyContent = false;
+ psd->mBaseline = nullptr;
#ifdef DEBUG
outerLineLayout->mSpansAllocated++;
diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp
index d6119f44fb..fc74ce8184 100644
--- a/layout/generic/nsRubyFrame.cpp
+++ b/layout/generic/nsRubyFrame.cpp
@@ -300,25 +300,25 @@ void nsRubyFrame::ReflowSegment(nsPresContext* aPresContext,
Maybe<LineRelativeDir> lineSide;
switch (textContainer->StyleText()->mRubyPosition) {
case StyleRubyPosition::Over:
- lineSide.emplace(eLineRelativeDirOver);
+ lineSide.emplace(LineRelativeDir::Over);
break;
case StyleRubyPosition::Under:
- lineSide.emplace(eLineRelativeDirUnder);
+ lineSide.emplace(LineRelativeDir::Under);
break;
case StyleRubyPosition::AlternateOver:
if (lastLineSide.isSome() &&
- lastLineSide.value() == eLineRelativeDirOver) {
- lineSide.emplace(eLineRelativeDirUnder);
+ lastLineSide.value() == LineRelativeDir::Over) {
+ lineSide.emplace(LineRelativeDir::Under);
} else {
- lineSide.emplace(eLineRelativeDirOver);
+ lineSide.emplace(LineRelativeDir::Over);
}
break;
case StyleRubyPosition::AlternateUnder:
if (lastLineSide.isSome() &&
- lastLineSide.value() == eLineRelativeDirUnder) {
- lineSide.emplace(eLineRelativeDirOver);
+ lastLineSide.value() == LineRelativeDir::Under) {
+ lineSide.emplace(LineRelativeDir::Over);
} else {
- lineSide.emplace(eLineRelativeDirUnder);
+ lineSide.emplace(LineRelativeDir::Under);
}
break;
default:
@@ -333,7 +333,7 @@ void nsRubyFrame::ReflowSegment(nsPresContext* aPresContext,
lineWM.LogicalSideForLineRelativeDir(lineSide.value());
if (StaticPrefs::layout_css_ruby_intercharacter_enabled() &&
rtcWM.IsVerticalRL() &&
- lineWM.GetInlineDir() == WritingMode::eInlineLTR) {
+ lineWM.GetInlineDir() == WritingMode::InlineDir::LTR) {
// Inter-character ruby annotations are only supported for vertical-rl
// in ltr horizontal writing. Fall back to non-inter-character behavior
// otherwise.
diff --git a/layout/generic/nsSplittableFrame.cpp b/layout/generic/nsSplittableFrame.cpp
index 4054e45f8c..abc3b5bf6e 100644
--- a/layout/generic/nsSplittableFrame.cpp
+++ b/layout/generic/nsSplittableFrame.cpp
@@ -316,7 +316,7 @@ LogicalSides nsSplittableFrame::GetBlockLevelLogicalSkipSides(
bool aAfterReflow) const {
LogicalSides skip(mWritingMode);
if (MOZ_UNLIKELY(IsTrueOverflowContainer())) {
- skip |= eLogicalSideBitsBBoth;
+ skip += LogicalSides(mWritingMode, LogicalSides::BBoth);
return skip;
}
@@ -326,19 +326,19 @@ LogicalSides nsSplittableFrame::GetBlockLevelLogicalSkipSides(
}
if (GetPrevContinuation()) {
- skip |= eLogicalSideBitsBStart;
+ skip += LogicalSide::BStart;
}
// Always skip block-end side if we have a *later* sibling across column-span
// split.
if (HasColumnSpanSiblings()) {
- skip |= eLogicalSideBitsBEnd;
+ skip += LogicalSide::BEnd;
}
if (aAfterReflow) {
nsIFrame* nif = GetNextContinuation();
if (nif && !nif->IsTrueOverflowContainer()) {
- skip |= eLogicalSideBitsBEnd;
+ skip += LogicalSide::BEnd;
}
}
diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp
index 69b4042033..731d31a16f 100644
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -322,30 +322,29 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
return;
}
- nsFrameLoader* frameLoader = FrameLoader();
- bool isRemoteFrame = frameLoader && frameLoader->IsRemoteFrame();
-
- // If we are pointer-events:none then we don't need to HitTest background
const bool pointerEventsNone =
Style()->PointerEvents() == StylePointerEvents::None;
- if (!aBuilder->IsForEventDelivery() || !pointerEventsNone) {
- nsDisplayListCollection decorations(aBuilder);
- DisplayBorderBackgroundOutline(aBuilder, decorations);
- if (isRemoteFrame) {
- // Wrap background colors of <iframe>s with remote subdocuments in their
- // own layer so we generate a ColorLayer. This is helpful for optimizing
- // compositing; we can skip compositing the ColorLayer when the
- // remote content is opaque.
- WrapBackgroundColorInOwnLayer(aBuilder, this,
- decorations.BorderBackground());
- }
- decorations.MoveTo(aLists);
- }
-
if (aBuilder->IsForEventDelivery() && pointerEventsNone) {
+ // If we are pointer-events:none then we don't need to HitTest background or
+ // anything else.
return;
}
+ nsFrameLoader* frameLoader = FrameLoader();
+ const bool isRemoteFrame = frameLoader && frameLoader->IsRemoteFrame();
+
+ nsDisplayListCollection decorations(aBuilder);
+ DisplayBorderBackgroundOutline(aBuilder, decorations);
+ if (isRemoteFrame) {
+ // Wrap background colors of <iframe>s with remote subdocuments in their
+ // own layer so we generate a ColorLayer. This is helpful for optimizing
+ // compositing; we can skip compositing the ColorLayer when the
+ // remote content is opaque.
+ WrapBackgroundColorInOwnLayer(aBuilder, this,
+ decorations.BorderBackground());
+ }
+ decorations.MoveTo(aLists);
+
if (HidesContent()) {
return;
}
@@ -554,22 +553,7 @@ nsresult nsSubDocumentFrame::GetFrameName(nsAString& aResult) const {
/* virtual */
nscoord nsSubDocumentFrame::GetMinISize(gfxContext* aRenderingContext) {
- nscoord result;
-
- nsCOMPtr<nsIObjectLoadingContent> iolc = do_QueryInterface(mContent);
- auto olc = static_cast<nsObjectLoadingContent*>(iolc.get());
-
- if (olc && olc->GetSubdocumentIntrinsicSize()) {
- // The subdocument is an SVG document, so technically we should call
- // SVGOuterSVGFrame::GetMinISize() on its root frame. That method always
- // returns 0, though, so we can just do that & don't need to bother with
- // the cross-doc communication.
- result = 0;
- } else {
- result = GetIntrinsicISize();
- }
-
- return result;
+ return GetIntrinsicISize();
}
/* virtual */
@@ -706,7 +690,7 @@ void nsSubDocumentFrame::Reflow(nsPresContext* aPresContext,
nsViewManager* vm = mInnerView->GetViewManager();
vm->MoveViewTo(mInnerView, destRect.x, destRect.y);
- vm->ResizeView(mInnerView, nsRect(nsPoint(0, 0), destRect.Size()), true);
+ vm->ResizeView(mInnerView, nsRect(nsPoint(0, 0), destRect.Size()));
}
aDesiredSize.SetOverflowAreasToDesiredBounds();