mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 14:25:49 +00:00
Bug 1791760 - Move GetContainSizeAxes to nsIFrame r=emilio
This will allow this function to eventually return an appropriate value depending on whether or not content is skipped via `content-visibility: auto`. This change also starts looking directly at whether content-visibility is skipping content or not, which should make it compatible with a future `content-visibility: auto` implementation. Differential Revision: https://phabricator.services.mozilla.com/D157831
This commit is contained in:
parent
a26af613a4
commit
3b0ff9fae9
@ -565,7 +565,7 @@ static void LastRememberedSizeCallback(
|
||||
"Should have removed the last remembered block size.");
|
||||
MOZ_ASSERT(canRememberISize || !target->HasLastRememberedISize(),
|
||||
"Should have removed the last remembered inline size.");
|
||||
const auto containAxes = frame->StyleDisplay()->GetContainSizeAxes();
|
||||
const auto containAxes = frame->GetContainSizeAxes();
|
||||
bool canUpdateBSize = canRememberBSize && !containAxes.mBContained;
|
||||
bool canUpdateISize = canRememberISize && !containAxes.mIContained;
|
||||
MOZ_ASSERT(canUpdateBSize || canUpdateISize,
|
||||
|
@ -213,7 +213,7 @@ nscoord nsListControlFrame::CalcBSizeOfARow() {
|
||||
// either of which may be visible or invisible, may use different
|
||||
// fonts, etc.
|
||||
nscoord rowBSize(0);
|
||||
if (StyleDisplay()->GetContainSizeAxes().mBContained ||
|
||||
if (GetContainSizeAxes().mBContained ||
|
||||
!GetMaxRowBSize(GetOptionsContainer(), GetWritingMode(), &rowBSize)) {
|
||||
// We don't have any <option>s or <optgroup> labels with a frame.
|
||||
// (Or we're size-contained in block axis, which has the same outcome for
|
||||
|
@ -427,7 +427,7 @@ void ReflowInput::Init(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
if (mStyleDisplay->GetContainSizeAxes().mBContained) {
|
||||
if (mFrame->GetContainSizeAxes().mBContained) {
|
||||
// In the case that a box is size contained in block axis, we want to ensure
|
||||
// that it is also monolithic. We do this by setting AvailableBSize() to an
|
||||
// unconstrained size to avoid fragmentation.
|
||||
|
@ -584,9 +584,8 @@ bool nsHTMLScrollFrame::TryLayout(ScrollReflowInput& aState,
|
||||
|
||||
// First, compute our inside-border size and scrollport size
|
||||
// XXXldb Can we depend more on ComputeSize here?
|
||||
nsSize kidSize =
|
||||
aState.mReflowInput.mStyleDisplay->GetContainSizeAxes().ContainSize(
|
||||
aKidMetrics->PhysicalSize(), *aState.mReflowInput.mFrame);
|
||||
nsSize kidSize = GetContainSizeAxes().ContainSize(
|
||||
aKidMetrics->PhysicalSize(), *aState.mReflowInput.mFrame);
|
||||
const nsSize desiredInsideBorderSize = kidSize + scrollbarGutterSize;
|
||||
aState.mInsideBorderSize =
|
||||
ComputeInsideBorderSize(aState, desiredInsideBorderSize);
|
||||
@ -997,9 +996,8 @@ void nsHTMLScrollFrame::ReflowContents(ScrollReflowInput& aState,
|
||||
aState.mReflowedContentsWithVScrollbar) &&
|
||||
aState.mVScrollbar != ShowScrollbar::Always &&
|
||||
aState.mHScrollbar != ShowScrollbar::Always) {
|
||||
nsSize kidSize =
|
||||
aState.mReflowInput.mStyleDisplay->GetContainSizeAxes().ContainSize(
|
||||
kidDesiredSize.PhysicalSize(), *aState.mReflowInput.mFrame);
|
||||
nsSize kidSize = GetContainSizeAxes().ContainSize(
|
||||
kidDesiredSize.PhysicalSize(), *aState.mReflowInput.mFrame);
|
||||
nsSize insideBorderSize = ComputeInsideBorderSize(aState, kidSize);
|
||||
nsRect scrolledRect = mHelper.GetUnsnappedScrolledRectInternal(
|
||||
kidDesiredSize.ScrollableOverflow(), insideBorderSize);
|
||||
|
@ -437,7 +437,7 @@ nscoord nsHTMLCanvasFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
||||
|
||||
/* virtual */
|
||||
IntrinsicSize nsHTMLCanvasFrame::GetIntrinsicSize() {
|
||||
const auto containAxes = StyleDisplay()->GetContainSizeAxes();
|
||||
const auto containAxes = GetContainSizeAxes();
|
||||
IntrinsicSize size = containAxes.IsBoth()
|
||||
? IntrinsicSize(0, 0)
|
||||
: IntrinsicSizeFromCanvasSize(GetCanvasSize());
|
||||
@ -446,7 +446,7 @@ IntrinsicSize nsHTMLCanvasFrame::GetIntrinsicSize() {
|
||||
|
||||
/* virtual */
|
||||
AspectRatio nsHTMLCanvasFrame::GetIntrinsicRatio() const {
|
||||
if (StyleDisplay()->GetContainSizeAxes().IsAny()) {
|
||||
if (GetContainSizeAxes().IsAny()) {
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
|
@ -724,9 +724,7 @@ void nsIFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||
PresContext()->RegisterContainerQueryFrame(this);
|
||||
}
|
||||
|
||||
if (disp->IsContainLayout() && disp->GetContainSizeAxes().IsBoth() &&
|
||||
// All frames that support contain:layout also support contain:size.
|
||||
IsFrameOfType(eSupportsContainLayoutAndPaint) && !IsTableWrapperFrame()) {
|
||||
if (disp->IsContainLayout() && GetContainSizeAxes().IsBoth()) {
|
||||
// In general, frames that have contain:layout+size can be reflow roots.
|
||||
// (One exception: table-wrapper frames don't work well as reflow roots,
|
||||
// because their inner-table ReflowInput init path tries to reuse & deref
|
||||
@ -1445,7 +1443,7 @@ void nsIFrame::HandleLastRememberedSize() {
|
||||
element->RemoveLastRememberedISize();
|
||||
}
|
||||
if (canRememberBSize || canRememberISize) {
|
||||
const auto containAxes = StyleDisplay()->GetContainSizeAxes();
|
||||
const auto containAxes = GetContainSizeAxes();
|
||||
if ((canRememberBSize && !containAxes.mBContained) ||
|
||||
(canRememberISize && !containAxes.mIContained)) {
|
||||
bool isNonReplacedInline = IsFrameOfType(nsIFrame::eLineParticipant) &&
|
||||
@ -11354,6 +11352,33 @@ gfx::Matrix nsIFrame::ComputeWidgetTransform() {
|
||||
return result2d;
|
||||
}
|
||||
|
||||
ContainSizeAxes nsIFrame::GetContainSizeAxes() const {
|
||||
auto contain = StyleDisplay()->EffectiveContainment();
|
||||
// Short circuit for no containment whatsoever
|
||||
if (MOZ_LIKELY(!contain)) {
|
||||
return ContainSizeAxes(false, false);
|
||||
}
|
||||
|
||||
// Note: The spec for size containment says it should have no effect on
|
||||
// non-atomic, inline-level boxes.
|
||||
bool isNonReplacedInline = IsFrameOfType(nsIFrame::eLineParticipant) &&
|
||||
!IsFrameOfType(nsIFrame::eReplaced);
|
||||
if (isNonReplacedInline || StyleDisplay()->PrecludesSizeContainment()) {
|
||||
return ContainSizeAxes(false, false);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#content-visibility
|
||||
// If this content skips its content via content-visibility, it always has
|
||||
// size containment.
|
||||
if (MOZ_LIKELY(!(contain & StyleContain::SIZE)) &&
|
||||
MOZ_UNLIKELY(HidesContent())) {
|
||||
contain |= StyleContain::SIZE;
|
||||
}
|
||||
|
||||
return ContainSizeAxes(static_cast<bool>(contain & StyleContain::INLINE_SIZE),
|
||||
static_cast<bool>(contain & StyleContain::BLOCK_SIZE));
|
||||
}
|
||||
|
||||
void nsIFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoRestyleState& aRestyleState) {
|
||||
// As a special case, we check for {ib}-split block frames here, rather
|
||||
// than have an nsInlineFrame::AppendDirectlyOwnedAnonBoxes implementation
|
||||
|
@ -3988,14 +3988,14 @@ class nsIFrame : public nsQueryFrame {
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ContainSizeAxes GetContainSizeAxes() const;
|
||||
|
||||
Maybe<nscoord> ContainIntrinsicBSize(nscoord aNoneValue = 0) const {
|
||||
return StyleDisplay()->GetContainSizeAxes().ContainIntrinsicBSize(
|
||||
*this, aNoneValue);
|
||||
return GetContainSizeAxes().ContainIntrinsicBSize(*this, aNoneValue);
|
||||
}
|
||||
|
||||
Maybe<nscoord> ContainIntrinsicISize(nscoord aNoneValue = 0) const {
|
||||
return StyleDisplay()->GetContainSizeAxes().ContainIntrinsicISize(
|
||||
*this, aNoneValue);
|
||||
return GetContainSizeAxes().ContainIntrinsicISize(*this, aNoneValue);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -623,7 +623,7 @@ static IntrinsicSize ComputeIntrinsicSize(imgIContainer* aImage,
|
||||
bool aUseMappedRatio,
|
||||
nsImageFrame::Kind aKind,
|
||||
const nsImageFrame& aFrame) {
|
||||
const auto containAxes = aFrame.StyleDisplay()->GetContainSizeAxes();
|
||||
const auto containAxes = aFrame.GetContainSizeAxes();
|
||||
if (containAxes.IsBoth()) {
|
||||
return containAxes.ContainIntrinsicSize(IntrinsicSize(0, 0), aFrame);
|
||||
}
|
||||
@ -703,8 +703,7 @@ bool nsImageFrame::UpdateIntrinsicSize() {
|
||||
static AspectRatio ComputeIntrinsicRatio(imgIContainer* aImage,
|
||||
bool aUseMappedRatio,
|
||||
const nsImageFrame& aFrame) {
|
||||
const ComputedStyle& style = *aFrame.Style();
|
||||
if (style.StyleDisplay()->GetContainSizeAxes().IsAny()) {
|
||||
if (aFrame.GetContainSizeAxes().IsAny()) {
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
@ -714,7 +713,7 @@ static AspectRatio ComputeIntrinsicRatio(imgIContainer* aImage,
|
||||
}
|
||||
}
|
||||
if (aUseMappedRatio) {
|
||||
const StyleAspectRatio& ratio = style.StylePosition()->mAspectRatio;
|
||||
const StyleAspectRatio& ratio = aFrame.StylePosition()->mAspectRatio;
|
||||
if (ratio.auto_ && ratio.HasRatio()) {
|
||||
// Return the mapped intrinsic aspect ratio stored in
|
||||
// nsStylePosition::mAspectRatio.
|
||||
@ -1202,7 +1201,7 @@ bool nsImageFrame::IsForMarkerPseudo() const {
|
||||
}
|
||||
|
||||
void nsImageFrame::EnsureIntrinsicSizeAndRatio() {
|
||||
const auto containAxes = StyleDisplay()->GetContainSizeAxes();
|
||||
const auto containAxes = GetContainSizeAxes();
|
||||
if (containAxes.IsBoth()) {
|
||||
// If we have 'contain:size', then we have no intrinsic aspect ratio,
|
||||
// and the intrinsic size is determined by contain-intrinsic-size,
|
||||
|
@ -623,7 +623,7 @@ nscoord nsSubDocumentFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
||||
|
||||
/* virtual */
|
||||
IntrinsicSize nsSubDocumentFrame::GetIntrinsicSize() {
|
||||
const auto containAxes = StyleDisplay()->GetContainSizeAxes();
|
||||
const auto containAxes = GetContainSizeAxes();
|
||||
if (containAxes.IsBoth()) {
|
||||
// Intrinsic size of 'contain:size' replaced elements is determined by
|
||||
// contain-intrinsic-size.
|
||||
|
@ -311,7 +311,7 @@ void nsVideoFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
|
||||
// Resolve our own BSize based on the controls' size in the
|
||||
// same axis. Unless we're size-contained, in which case we
|
||||
// have to behave as if we have an intrinsic size of 0.
|
||||
if (aReflowInput.mStyleDisplay->GetContainSizeAxes().mBContained) {
|
||||
if (GetContainSizeAxes().mBContained) {
|
||||
contentBoxBSize = 0;
|
||||
} else {
|
||||
contentBoxBSize = myWM.IsOrthogonalTo(wm) ? kidDesiredSize.ISize(wm)
|
||||
@ -420,7 +420,7 @@ AspectRatio nsVideoFrame::GetIntrinsicRatio() const {
|
||||
}
|
||||
|
||||
// 'contain:[inline-]size' replaced elements have no intrinsic ratio.
|
||||
if (StyleDisplay()->GetContainSizeAxes().IsAny()) {
|
||||
if (GetContainSizeAxes().IsAny()) {
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
@ -470,7 +470,7 @@ bool nsVideoFrame::ShouldDisplayPoster() const {
|
||||
}
|
||||
|
||||
IntrinsicSize nsVideoFrame::GetIntrinsicSize() {
|
||||
const auto containAxes = StyleDisplay()->GetContainSizeAxes();
|
||||
const auto containAxes = GetContainSizeAxes();
|
||||
const auto isVideo = HasVideoElement();
|
||||
// Intrinsic size will be given by contain-intrinsic-size if the element is
|
||||
// size-contained. If both axes have containment, ContainIntrinsicSize() will
|
||||
|
@ -1543,27 +1543,10 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
||||
|
||||
bool IsContainAny() const { return !!EffectiveContainment(); }
|
||||
|
||||
mozilla::ContainSizeAxes GetContainSizeAxes() const {
|
||||
const auto contain = EffectiveContainment();
|
||||
// Short circuit for no containment whatsoever
|
||||
if (!contain) {
|
||||
return mozilla::ContainSizeAxes(false, false);
|
||||
}
|
||||
// Note: The spec for size containment says it should
|
||||
// have no effect on non-atomic, inline-level boxes. We
|
||||
// don't check for these here because we don't know
|
||||
// what type of element is involved. Callers are
|
||||
// responsible for checking if the box in question is
|
||||
// non-atomic and inline-level, and creating an
|
||||
// exemption as necessary.
|
||||
if (IsInternalRubyDisplayType() ||
|
||||
DisplayInside() == mozilla::StyleDisplayInside::Table ||
|
||||
IsInnerTableStyle()) {
|
||||
return mozilla::ContainSizeAxes(false, false);
|
||||
}
|
||||
return mozilla::ContainSizeAxes(
|
||||
static_cast<bool>(contain & StyleContain::INLINE_SIZE),
|
||||
static_cast<bool>(contain & StyleContain::BLOCK_SIZE));
|
||||
bool PrecludesSizeContainment() const {
|
||||
return IsInternalRubyDisplayType() ||
|
||||
DisplayInside() == mozilla::StyleDisplayInside::Table ||
|
||||
IsInnerTableStyle();
|
||||
}
|
||||
|
||||
bool IsContentVisibilityVisible() const {
|
||||
@ -1685,7 +1668,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
||||
IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() const;
|
||||
inline bool IsFixedPosContainingBlockForTransformSupportingFrames() const;
|
||||
|
||||
private:
|
||||
StyleContain EffectiveContainment() const {
|
||||
auto contain = mContain;
|
||||
// content-visibility and container-type implicitly enable some containment
|
||||
@ -1699,6 +1681,9 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
||||
case StyleContentVisibility::Visible:
|
||||
break;
|
||||
case StyleContentVisibility::Auto:
|
||||
// `content-visibility:auto` also applies size containment when content
|
||||
// is not relevant (and therefore skipped). This is checked in
|
||||
// nsIFrame::GetContainSizeAxes.
|
||||
contain |=
|
||||
StyleContain::LAYOUT | StyleContain::PAINT | StyleContain::STYLE;
|
||||
break;
|
||||
|
@ -95,7 +95,7 @@ static inline ContainSizeAxes ContainSizeAxesIfApplicable(
|
||||
if (!aFrame->GetContent()->GetParent()) {
|
||||
return ContainSizeAxes(false, false);
|
||||
}
|
||||
return aFrame->StyleDisplay()->GetContainSizeAxes();
|
||||
return aFrame->GetContainSizeAxes();
|
||||
}
|
||||
|
||||
void SVGOuterSVGFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||
|
Loading…
x
Reference in New Issue
Block a user