forked from mirrors/gecko-dev
Bug 1755565 - Implement contain: inline-size. r=emilio,dholbert
Differential Revision: https://phabricator.services.mozilla.com/D143501
This commit is contained in:
parent
c582dbf6d7
commit
ec93876623
34 changed files with 343 additions and 128 deletions
|
|
@ -5937,6 +5937,7 @@ exports.CSS_PROPERTIES = {
|
|||
"content",
|
||||
"inherit",
|
||||
"initial",
|
||||
"inline-size",
|
||||
"layout",
|
||||
"none",
|
||||
"paint",
|
||||
|
|
|
|||
|
|
@ -322,7 +322,8 @@ nscoord nsComboboxControlFrame::GetIntrinsicISize(gfxContext* aRenderingContext,
|
|||
IntrinsicISizeType aType) {
|
||||
nscoord displayISize = mDisplayFrame->IntrinsicISizeOffsets().padding;
|
||||
|
||||
if (!StyleDisplay()->IsContainSize() && !StyleContent()->mContent.IsNone()) {
|
||||
if (!StyleDisplay()->GetContainSizeAxes().mIContained &&
|
||||
!StyleContent()->mContent.IsNone()) {
|
||||
// Compute the width of each option's (potentially text-transformed) text,
|
||||
// and use the widest one as part of our intrinsic size.
|
||||
nscoord maxOptionSize = 0;
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ nscoord nsFieldSetFrame::GetIntrinsicISize(gfxContext* aRenderingContext,
|
|||
IntrinsicISizeType aType) {
|
||||
nscoord legendWidth = 0;
|
||||
nscoord contentWidth = 0;
|
||||
if (!StyleDisplay()->IsContainSize()) {
|
||||
if (!StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
// Both inner and legend are children, and if the fieldset is
|
||||
// size-contained they should not contribute to the intrinsic size.
|
||||
if (nsIFrame* legend = GetLegend()) {
|
||||
|
|
@ -743,9 +743,9 @@ void nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
|||
LogicalSize finalSize(
|
||||
wm, contentRect.ISize(wm) + border.IStartEnd(wm),
|
||||
mLegendSpace + border.BStartEnd(wm) + (inner ? inner->BSize(wm) : 0));
|
||||
if (aReflowInput.mStyleDisplay->IsContainSize()) {
|
||||
// If we're size-contained, then we must set finalSize to be what
|
||||
// it'd be if we had no children (i.e. if we had no legend and if
|
||||
if (aReflowInput.mStyleDisplay->GetContainSizeAxes().mBContained) {
|
||||
// If we're size-contained in block axis, then we must set finalSize to be
|
||||
// what it'd be if we had no children (i.e. if we had no legend and if
|
||||
// 'inner' were empty). Note: normally the fieldset's own padding
|
||||
// (which we still must honor) would be accounted for as part of
|
||||
// inner's size (see kidReflowInput.Init() call above). So: since
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ void nsHTMLButtonControlFrame::BuildDisplayList(
|
|||
nscoord nsHTMLButtonControlFrame::GetMinISize(gfxContext* aRenderingContext) {
|
||||
nscoord result;
|
||||
DISPLAY_MIN_INLINE_SIZE(this, result);
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
result = 0;
|
||||
} else {
|
||||
nsIFrame* kid = mFrames.FirstChild();
|
||||
|
|
@ -134,7 +134,7 @@ nscoord nsHTMLButtonControlFrame::GetMinISize(gfxContext* aRenderingContext) {
|
|||
nscoord nsHTMLButtonControlFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
||||
nscoord result;
|
||||
DISPLAY_PREF_INLINE_SIZE(this, result);
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
result = 0;
|
||||
} else {
|
||||
nsIFrame* kid = mFrames.FirstChild();
|
||||
|
|
@ -237,8 +237,9 @@ void nsHTMLButtonControlFrame::ReflowButtonContents(
|
|||
if (aButtonReflowInput.ComputedBSize() != NS_UNCONSTRAINEDSIZE) {
|
||||
// Button has a fixed block-size -- that's its content-box bSize.
|
||||
buttonContentBox.BSize(wm) = aButtonReflowInput.ComputedBSize();
|
||||
} else if (aButtonReflowInput.mStyleDisplay->IsContainSize()) {
|
||||
// Button is intrinsically sized and has size containment.
|
||||
} else if (aButtonReflowInput.mStyleDisplay->GetContainSizeAxes()
|
||||
.mBContained) {
|
||||
// Button is intrinsically sized and has size containment in block axis.
|
||||
// It should have a BSize that is either zero or the minimum
|
||||
// specified BSize.
|
||||
buttonContentBox.BSize(wm) = aButtonReflowInput.ComputedMinBSize();
|
||||
|
|
@ -258,7 +259,8 @@ void nsHTMLButtonControlFrame::ReflowButtonContents(
|
|||
}
|
||||
if (aButtonReflowInput.ComputedISize() != NS_UNCONSTRAINEDSIZE) {
|
||||
buttonContentBox.ISize(wm) = aButtonReflowInput.ComputedISize();
|
||||
} else if (aButtonReflowInput.mStyleDisplay->IsContainSize()) {
|
||||
} else if (aButtonReflowInput.mStyleDisplay->GetContainSizeAxes()
|
||||
.mIContained) {
|
||||
buttonContentBox.ISize(wm) = aButtonReflowInput.ComputedMinISize();
|
||||
} else {
|
||||
buttonContentBox.ISize(wm) = contentsDesiredSize.ISize(wm);
|
||||
|
|
|
|||
|
|
@ -220,10 +220,11 @@ nscoord nsListControlFrame::CalcBSizeOfARow() {
|
|||
// either of which may be visible or invisible, may use different
|
||||
// fonts, etc.
|
||||
nscoord rowBSize(0);
|
||||
if (StyleDisplay()->IsContainSize() ||
|
||||
if (StyleDisplay()->GetContainSizeAxes().mBContained ||
|
||||
!GetMaxRowBSize(GetOptionsContainer(), GetWritingMode(), &rowBSize)) {
|
||||
// We don't have any <option>s or <optgroup> labels with a frame.
|
||||
// (Or we're size-contained, which has the same outcome for our sizing.)
|
||||
// (Or we're size-contained in block axis, which has the same outcome for
|
||||
// our sizing.)
|
||||
float inflation = nsLayoutUtils::FontSizeInflationFor(this);
|
||||
rowBSize = CalcFallbackRowBSize(inflation);
|
||||
}
|
||||
|
|
@ -239,7 +240,7 @@ nscoord nsListControlFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
|||
// dropdown, and standalone listboxes are overflow:scroll so they need
|
||||
// it too.
|
||||
WritingMode wm = GetWritingMode();
|
||||
result = StyleDisplay()->IsContainSize()
|
||||
result = StyleDisplay()->GetContainSizeAxes().mIContained
|
||||
? 0
|
||||
: GetScrolledFrame()->GetPrefISize(aRenderingContext);
|
||||
LogicalMargin scrollbarSize(
|
||||
|
|
@ -257,7 +258,7 @@ nscoord nsListControlFrame::GetMinISize(gfxContext* aRenderingContext) {
|
|||
// dropdown, and standalone listboxes are overflow:scroll so they need
|
||||
// it too.
|
||||
WritingMode wm = GetWritingMode();
|
||||
result = StyleDisplay()->IsContainSize()
|
||||
result = StyleDisplay()->GetContainSizeAxes().mIContained
|
||||
? 0
|
||||
: GetScrolledFrame()->GetMinISize(aRenderingContext);
|
||||
LogicalMargin scrollbarSize(
|
||||
|
|
|
|||
|
|
@ -154,11 +154,11 @@ nscoord ColumnSetWrapperFrame::GetMinISize(gfxContext* aRenderingContext) {
|
|||
nscoord iSize = 0;
|
||||
DISPLAY_MIN_INLINE_SIZE(this, iSize);
|
||||
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
// If we're size-contained, we determine our minimum intrinsic size purely
|
||||
// from our column styling, as if we had no descendants. This should match
|
||||
// what happens in nsColumnSetFrame::GetMinISize in an actual no-descendants
|
||||
// scenario.
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
// If we're size-contained in inline axis, we determine our minimum
|
||||
// intrinsic size purely from our column styling, as if we had no
|
||||
// descendants. This should match what happens in
|
||||
// nsColumnSetFrame::GetMinISize in an actual no-descendants scenario.
|
||||
const nsStyleColumn* colStyle = StyleColumn();
|
||||
if (colStyle->mColumnWidth.IsLength()) {
|
||||
// As available inline size reduces to zero, our number of columns reduces
|
||||
|
|
@ -189,7 +189,7 @@ nscoord ColumnSetWrapperFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
|||
nscoord iSize = 0;
|
||||
DISPLAY_PREF_INLINE_SIZE(this, iSize);
|
||||
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
const nsStyleColumn* colStyle = StyleColumn();
|
||||
nscoord colISize;
|
||||
if (colStyle->mColumnWidth.IsLength()) {
|
||||
|
|
|
|||
|
|
@ -421,8 +421,8 @@ void ReflowInput::Init(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
if (mStyleDisplay->IsContainSize()) {
|
||||
// In the case that a box is size contained, we want to ensure
|
||||
if (mStyleDisplay->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 unsetting
|
||||
// AvailableBSize() to avoid fragmentaiton.
|
||||
AvailableBSize() = NS_UNCONSTRAINEDSIZE;
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@ nscoord nsBlockFrame::GetMinISize(gfxContext* aRenderingContext) {
|
|||
return mCachedMinISize;
|
||||
}
|
||||
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
mCachedMinISize = 0;
|
||||
return mCachedMinISize;
|
||||
}
|
||||
|
|
@ -873,7 +873,7 @@ nscoord nsBlockFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
|||
return mCachedPrefISize;
|
||||
}
|
||||
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
mCachedPrefISize = 0;
|
||||
return mCachedPrefISize;
|
||||
}
|
||||
|
|
@ -1947,11 +1947,11 @@ void nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
|
|||
// is replaced by the block size from aspect-ratio and inline size.
|
||||
aMetrics.mCarriedOutBEndMargin.Zero();
|
||||
} else if (!IsComboboxControlFrame() &&
|
||||
aReflowInput.mStyleDisplay->IsContainSize()) {
|
||||
// If we're size-containing and we don't have a specified size, then our
|
||||
// final size should actually be computed from only our border and padding,
|
||||
// as though we were empty.
|
||||
// Hence this case is a simplified version of the case below.
|
||||
aReflowInput.mStyleDisplay->GetContainSizeAxes().mBContained) {
|
||||
// If we're size-containing in block axis and we don't have a specified
|
||||
// block size, then our final size should actually be computed from only our
|
||||
// border and padding, as though we were empty. Hence this case is a
|
||||
// simplified version of the case below.
|
||||
//
|
||||
// NOTE: We exempt the nsComboboxControlFrame subclass from taking this
|
||||
// special case, because comboboxes implicitly honors the size-containment
|
||||
|
|
|
|||
|
|
@ -4313,9 +4313,9 @@ nscoord nsFlexContainerFrame::ComputeMainSize(
|
|||
return aTentativeContentBoxMainSize;
|
||||
}
|
||||
|
||||
// Column-oriented case, with size-containment:
|
||||
// Column-oriented case, with size-containment in block axis:
|
||||
// Behave as if we had no content and just use our MinBSize.
|
||||
if (aReflowInput.mStyleDisplay->IsContainSize()) {
|
||||
if (aReflowInput.mStyleDisplay->GetContainSizeAxes().mBContained) {
|
||||
return aReflowInput.ComputedMinBSize();
|
||||
}
|
||||
|
||||
|
|
@ -4360,9 +4360,9 @@ nscoord nsFlexContainerFrame::ComputeCrossSize(
|
|||
return computedBSize;
|
||||
}
|
||||
|
||||
// Row-oriented case, with size-containment:
|
||||
// Row-oriented case, with size-containment in block axis:
|
||||
// Behave as if we had no content and just use our MinBSize.
|
||||
if (aReflowInput.mStyleDisplay->IsContainSize()) {
|
||||
if (aReflowInput.mStyleDisplay->GetContainSizeAxes().mBContained) {
|
||||
*aIsDefinite = true;
|
||||
return aReflowInput.ComputedMinBSize();
|
||||
}
|
||||
|
|
@ -5770,7 +5770,7 @@ nscoord nsFlexContainerFrame::GetMinISize(gfxContext* aRenderingContext) {
|
|||
DISPLAY_MIN_INLINE_SIZE(this, mCachedMinISize);
|
||||
if (mCachedMinISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||
mCachedMinISize =
|
||||
StyleDisplay()->IsContainSize()
|
||||
StyleDisplay()->GetContainSizeAxes().mIContained
|
||||
? 0
|
||||
: IntrinsicISize(aRenderingContext, IntrinsicISizeType::MinISize);
|
||||
}
|
||||
|
|
@ -5783,7 +5783,7 @@ nscoord nsFlexContainerFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
|||
DISPLAY_PREF_INLINE_SIZE(this, mCachedPrefISize);
|
||||
if (mCachedPrefISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||
mCachedPrefISize =
|
||||
StyleDisplay()->IsContainSize()
|
||||
StyleDisplay()->GetContainSizeAxes().mIContained
|
||||
? 0
|
||||
: IntrinsicISize(aRenderingContext, IntrinsicISizeType::PrefISize);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -584,9 +584,9 @@ 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->IsContainSize()
|
||||
? nsSize(0, 0)
|
||||
: aKidMetrics->PhysicalSize();
|
||||
nsSize kidSize =
|
||||
aState.mReflowInput.mStyleDisplay->GetContainSizeAxes().ContainSize(
|
||||
aKidMetrics->PhysicalSize(), wm);
|
||||
const nsSize desiredInsideBorderSize = kidSize + scrollbarGutterSize;
|
||||
aState.mInsideBorderSize =
|
||||
ComputeInsideBorderSize(aState, desiredInsideBorderSize);
|
||||
|
|
@ -969,7 +969,8 @@ bool nsHTMLScrollFrame::InInitialReflow() const {
|
|||
|
||||
void nsHTMLScrollFrame::ReflowContents(ScrollReflowInput& aState,
|
||||
const ReflowOutput& aDesiredSize) {
|
||||
ReflowOutput kidDesiredSize(aDesiredSize.GetWritingMode());
|
||||
const WritingMode desiredWm = aDesiredSize.GetWritingMode();
|
||||
ReflowOutput kidDesiredSize(desiredWm);
|
||||
ReflowScrolledFrame(aState, GuessHScrollbarNeeded(aState),
|
||||
GuessVScrollbarNeeded(aState), &kidDesiredSize);
|
||||
|
||||
|
|
@ -996,9 +997,9 @@ void nsHTMLScrollFrame::ReflowContents(ScrollReflowInput& aState,
|
|||
aState.mReflowedContentsWithVScrollbar) &&
|
||||
aState.mVScrollbar != ShowScrollbar::Always &&
|
||||
aState.mHScrollbar != ShowScrollbar::Always) {
|
||||
nsSize kidSize = aState.mReflowInput.mStyleDisplay->IsContainSize()
|
||||
? nsSize(0, 0)
|
||||
: kidDesiredSize.PhysicalSize();
|
||||
nsSize kidSize =
|
||||
aState.mReflowInput.mStyleDisplay->GetContainSizeAxes().ContainSize(
|
||||
kidDesiredSize.PhysicalSize(), desiredWm);
|
||||
nsSize insideBorderSize = ComputeInsideBorderSize(aState, kidSize);
|
||||
nsRect scrolledRect = mHelper.GetUnsnappedScrolledRectInternal(
|
||||
kidDesiredSize.ScrollableOverflow(), insideBorderSize);
|
||||
|
|
@ -1160,7 +1161,7 @@ static bool IsMarqueeScrollbox(const nsIFrame& aScrollFrame) {
|
|||
/* virtual */
|
||||
nscoord nsHTMLScrollFrame::GetMinISize(gfxContext* aRenderingContext) {
|
||||
nscoord result = [&] {
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
return 0;
|
||||
}
|
||||
if (MOZ_UNLIKELY(IsMarqueeScrollbox(*this))) {
|
||||
|
|
@ -1176,7 +1177,7 @@ nscoord nsHTMLScrollFrame::GetMinISize(gfxContext* aRenderingContext) {
|
|||
/* virtual */
|
||||
nscoord nsHTMLScrollFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
||||
nscoord result =
|
||||
StyleDisplay()->IsContainSize()
|
||||
StyleDisplay()->GetContainSizeAxes().mIContained
|
||||
? 0
|
||||
: mHelper.mScrolledFrame->GetPrefISize(aRenderingContext);
|
||||
DISPLAY_PREF_INLINE_SIZE(this, result);
|
||||
|
|
|
|||
|
|
@ -8601,7 +8601,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
|
|||
// XXX Technically incorrect: We're ignoring our row sizes, when really
|
||||
// we should use them but *they* should be computed as if we had no
|
||||
// children. To be fixed in bug 1488878.
|
||||
if (!aReflowInput.mStyleDisplay->IsContainSize()) {
|
||||
if (!aReflowInput.mStyleDisplay->GetContainSizeAxes().mBContained) {
|
||||
if (IsMasonry(eLogicalAxisBlock)) {
|
||||
bSize = computedBSize;
|
||||
} else {
|
||||
|
|
@ -8625,7 +8625,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
|
|||
// XXX Technically incorrect: We're ignoring our row sizes, when really
|
||||
// we should use them but *they* should be computed as if we had no
|
||||
// children. To be fixed in bug 1488878.
|
||||
if (!aReflowInput.mStyleDisplay->IsContainSize()) {
|
||||
if (!aReflowInput.mStyleDisplay->GetContainSizeAxes().mBContained) {
|
||||
const uint32_t numRows = gridReflowInput.mRows.mSizes.Length();
|
||||
bSize = gridReflowInput.mRows.GridLineEdge(numRows,
|
||||
GridLineSide::AfterGridGap);
|
||||
|
|
@ -9352,7 +9352,7 @@ nscoord nsGridContainerFrame::GetMinISize(gfxContext* aRC) {
|
|||
|
||||
DISPLAY_MIN_INLINE_SIZE(this, mCachedMinISize);
|
||||
if (mCachedMinISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||
mCachedMinISize = StyleDisplay()->IsContainSize()
|
||||
mCachedMinISize = StyleDisplay()->GetContainSizeAxes().mIContained
|
||||
? 0
|
||||
: IntrinsicISize(aRC, IntrinsicISizeType::MinISize);
|
||||
}
|
||||
|
|
@ -9367,7 +9367,7 @@ nscoord nsGridContainerFrame::GetPrefISize(gfxContext* aRC) {
|
|||
|
||||
DISPLAY_PREF_INLINE_SIZE(this, mCachedPrefISize);
|
||||
if (mCachedPrefISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||
mCachedPrefISize = StyleDisplay()->IsContainSize()
|
||||
mCachedPrefISize = StyleDisplay()->GetContainSizeAxes().mIContained
|
||||
? 0
|
||||
: IntrinsicISize(aRC, IntrinsicISizeType::PrefISize);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ nscoord nsHTMLCanvasFrame::GetMinISize(gfxContext* aRenderingContext) {
|
|||
// min-height, and max-height properties.
|
||||
bool vertical = GetWritingMode().IsVertical();
|
||||
nscoord result;
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
result = 0;
|
||||
} else {
|
||||
result = nsPresContext::CSSPixelsToAppUnits(
|
||||
|
|
@ -419,7 +419,7 @@ nscoord nsHTMLCanvasFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
|||
// min-height, and max-height properties.
|
||||
bool vertical = GetWritingMode().IsVertical();
|
||||
nscoord result;
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
result = 0;
|
||||
} else {
|
||||
result = nsPresContext::CSSPixelsToAppUnits(
|
||||
|
|
@ -431,15 +431,17 @@ nscoord nsHTMLCanvasFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
|||
|
||||
/* virtual */
|
||||
IntrinsicSize nsHTMLCanvasFrame::GetIntrinsicSize() {
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
const auto containAxes = StyleDisplay()->GetContainSizeAxes();
|
||||
if (containAxes.IsBoth()) {
|
||||
return IntrinsicSize(0, 0);
|
||||
}
|
||||
return IntrinsicSizeFromCanvasSize(GetCanvasSize());
|
||||
return containAxes.ContainIntrinsicSize(
|
||||
IntrinsicSizeFromCanvasSize(GetCanvasSize()), GetWritingMode());
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
AspectRatio nsHTMLCanvasFrame::GetIntrinsicRatio() const {
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().IsAny()) {
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -749,7 +749,7 @@ void nsIFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
|||
AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
|
||||
}
|
||||
|
||||
if (disp->IsContainLayout() && disp->IsContainSize() &&
|
||||
if (disp->IsContainLayout() && disp->GetContainSizeAxes().IsBoth() &&
|
||||
// All frames that support contain:layout also support contain:size.
|
||||
IsFrameOfType(eSupportsContainLayoutAndPaint) && !IsTableWrapperFrame()) {
|
||||
// In general, frames that have contain:layout+size can be reflow roots.
|
||||
|
|
|
|||
|
|
@ -622,7 +622,8 @@ static IntrinsicSize ComputeIntrinsicSize(imgIContainer* aImage,
|
|||
nsImageFrame::Kind aKind,
|
||||
const nsImageFrame& aFrame) {
|
||||
const ComputedStyle& style = *aFrame.Style();
|
||||
if (style.StyleDisplay()->IsContainSize()) {
|
||||
const auto containAxes = style.StyleDisplay()->GetContainSizeAxes();
|
||||
if (containAxes.IsBoth()) {
|
||||
return IntrinsicSize(0, 0);
|
||||
}
|
||||
|
||||
|
|
@ -648,19 +649,23 @@ static IntrinsicSize ComputeIntrinsicSize(imgIContainer* aImage,
|
|||
ScaleIntrinsicSizeForDensity(intrinsicSize,
|
||||
aFrame.GetImageFromStyle()->GetResolution());
|
||||
}
|
||||
return intrinsicSize;
|
||||
return containAxes.ContainIntrinsicSize(intrinsicSize,
|
||||
aFrame.GetWritingMode());
|
||||
}
|
||||
|
||||
if (aKind == nsImageFrame::Kind::ListStyleImage) {
|
||||
// Note: images are handled above, this handles gradients etc.
|
||||
nscoord defaultLength = ListImageDefaultLength(aFrame);
|
||||
return IntrinsicSize(defaultLength, defaultLength);
|
||||
return containAxes.ContainIntrinsicSize(
|
||||
IntrinsicSize(defaultLength, defaultLength), aFrame.GetWritingMode());
|
||||
}
|
||||
|
||||
if (aFrame.ShouldShowBrokenImageIcon()) {
|
||||
nscoord edgeLengthToUse = nsPresContext::CSSPixelsToAppUnits(
|
||||
ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH)));
|
||||
return IntrinsicSize(edgeLengthToUse, edgeLengthToUse);
|
||||
return containAxes.ContainIntrinsicSize(
|
||||
IntrinsicSize(edgeLengthToUse, edgeLengthToUse),
|
||||
aFrame.GetWritingMode());
|
||||
}
|
||||
|
||||
if (aUseMappedRatio && style.StylePosition()->mAspectRatio.HasRatio()) {
|
||||
|
|
@ -700,7 +705,7 @@ static AspectRatio ComputeIntrinsicRatio(imgIContainer* aImage,
|
|||
bool aUseMappedRatio,
|
||||
const nsImageFrame& aFrame) {
|
||||
const ComputedStyle& style = *aFrame.Style();
|
||||
if (style.StyleDisplay()->IsContainSize()) {
|
||||
if (style.StyleDisplay()->GetContainSizeAxes().IsAny()) {
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
|
|
@ -1137,7 +1142,7 @@ bool nsImageFrame::IsForMarkerPseudo() const {
|
|||
}
|
||||
|
||||
void nsImageFrame::EnsureIntrinsicSizeAndRatio() {
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (StyleDisplay()->GetContainSizeAxes().IsBoth()) {
|
||||
// If we have 'contain:size', then our intrinsic size and ratio are 0,0
|
||||
// regardless of what our underlying image may think.
|
||||
mIntrinsicSize = IntrinsicSize(0, 0);
|
||||
|
|
|
|||
|
|
@ -618,7 +618,8 @@ nscoord nsSubDocumentFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
|||
|
||||
/* virtual */
|
||||
IntrinsicSize nsSubDocumentFrame::GetIntrinsicSize() {
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
const auto containAxes = StyleDisplay()->GetContainSizeAxes();
|
||||
if (containAxes.IsBoth()) {
|
||||
// Intrinsic size of 'contain:size' replaced elements is 0,0.
|
||||
return IntrinsicSize(0, 0);
|
||||
}
|
||||
|
|
@ -628,7 +629,7 @@ IntrinsicSize nsSubDocumentFrame::GetIntrinsicSize() {
|
|||
|
||||
if (auto size = olc->GetSubdocumentIntrinsicSize()) {
|
||||
// Use the intrinsic size from the child SVG document, if available.
|
||||
return *size;
|
||||
return containAxes.ContainIntrinsicSize(*size, GetWritingMode());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -641,7 +642,8 @@ IntrinsicSize nsSubDocumentFrame::GetIntrinsicSize() {
|
|||
}
|
||||
|
||||
// We must be an HTML <iframe>. Return fallback size.
|
||||
return IntrinsicSize(kFallbackIntrinsicSize);
|
||||
return containAxes.ContainIntrinsicSize(IntrinsicSize(kFallbackIntrinsicSize),
|
||||
GetWritingMode());
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
|
|
|||
|
|
@ -162,6 +162,9 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
|
|||
}
|
||||
|
||||
nscoord GetIntrinsicISize() {
|
||||
if (StyleDisplay()->GetContainSizeAxes().mIContained) {
|
||||
return 0;
|
||||
}
|
||||
auto size = GetIntrinsicSize();
|
||||
Maybe<nscoord> iSize =
|
||||
GetWritingMode().IsVertical() ? size.height : size.width;
|
||||
|
|
|
|||
|
|
@ -306,7 +306,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->IsContainSize()) {
|
||||
if (aReflowInput.mStyleDisplay->GetContainSizeAxes().mBContained) {
|
||||
contentBoxBSize = 0;
|
||||
} else {
|
||||
contentBoxBSize = myWM.IsOrthogonalTo(wm) ? kidDesiredSize.ISize(wm)
|
||||
|
|
@ -389,20 +389,25 @@ nsIFrame::SizeComputationResult nsVideoFrame::ComputeSize(
|
|||
|
||||
nscoord nsVideoFrame::GetMinISize(gfxContext* aRenderingContext) {
|
||||
nscoord result;
|
||||
// Bind the result variable to a RAII-based debug object - the variable
|
||||
// therefore must match the function's return value.
|
||||
DISPLAY_MIN_INLINE_SIZE(this, result);
|
||||
|
||||
nsSize size = kFallbackIntrinsicSize;
|
||||
nsSize size;
|
||||
const auto wm = GetWritingMode();
|
||||
if (HasVideoElement()) {
|
||||
// This call handles size-containment
|
||||
size = GetVideoIntrinsicSize();
|
||||
} else {
|
||||
const auto containAxes = StyleDisplay()->GetContainSizeAxes();
|
||||
// We expect last and only child of audio elements to be control if
|
||||
// "controls" attribute is present.
|
||||
if (StyleDisplay()->IsContainSize() || !mFrames.LastChild()) {
|
||||
if (containAxes.IsBoth() || !mFrames.LastChild()) {
|
||||
size = nsSize();
|
||||
} else {
|
||||
size = containAxes.ContainSize(kFallbackIntrinsicSize, wm);
|
||||
}
|
||||
}
|
||||
|
||||
result = GetWritingMode().IsVertical() ? size.height : size.width;
|
||||
result = wm.IsVertical() ? size.height : size.width;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -423,8 +428,8 @@ AspectRatio nsVideoFrame::GetIntrinsicRatio() const {
|
|||
return AspectRatio();
|
||||
}
|
||||
|
||||
// 'contain:size' replaced elements have no intrinsic ratio.
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
// 'contain:[inline-]size' replaced elements have no intrinsic ratio.
|
||||
if (StyleDisplay()->GetContainSizeAxes().IsAny()) {
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
|
|
@ -470,23 +475,25 @@ nsSize nsVideoFrame::GetVideoIntrinsicSize() const {
|
|||
return nsSize(0, 0);
|
||||
}
|
||||
|
||||
const auto containAxes = StyleDisplay()->GetContainSizeAxes();
|
||||
// 'contain:size' replaced elements have intrinsic size 0,0.
|
||||
if (StyleDisplay()->IsContainSize()) {
|
||||
if (containAxes.IsBoth()) {
|
||||
return nsSize(0, 0);
|
||||
}
|
||||
|
||||
HTMLVideoElement* element = static_cast<HTMLVideoElement*>(GetContent());
|
||||
if (Maybe<CSSIntSize> size = element->GetVideoSize()) {
|
||||
return CSSPixel::ToAppUnits(*size);
|
||||
return containAxes.ContainSize(CSSPixel::ToAppUnits(*size),
|
||||
GetWritingMode());
|
||||
}
|
||||
|
||||
if (ShouldDisplayPoster()) {
|
||||
if (Maybe<nsSize> imgSize = PosterImageSize()) {
|
||||
return *imgSize;
|
||||
return containAxes.ContainSize(*imgSize, GetWritingMode());
|
||||
}
|
||||
}
|
||||
|
||||
return kFallbackIntrinsicSize;
|
||||
return containAxes.ContainSize(kFallbackIntrinsicSize, GetWritingMode());
|
||||
}
|
||||
|
||||
IntrinsicSize nsVideoFrame::GetIntrinsicSize() {
|
||||
|
|
|
|||
|
|
@ -3525,3 +3525,40 @@ nscoord StyleCalcNode::Resolve(nscoord aBasis,
|
|||
CoordPercentageRounder aRounder) const {
|
||||
return ResolveInternal(aBasis, aRounder);
|
||||
}
|
||||
|
||||
nsSize ContainSizeAxes::ContainSize(const nsSize& aUncontainedSize,
|
||||
const WritingMode& aWM) const {
|
||||
if (!IsAny()) {
|
||||
return aUncontainedSize;
|
||||
}
|
||||
if (IsBoth()) {
|
||||
return nsSize();
|
||||
}
|
||||
// At this point, we know that precisely one of our dimensions is contained.
|
||||
const bool zeroWidth =
|
||||
(!aWM.IsVertical() && mIContained) || (aWM.IsVertical() && mBContained);
|
||||
if (zeroWidth) {
|
||||
return nsSize(0, aUncontainedSize.Height());
|
||||
}
|
||||
return nsSize(aUncontainedSize.Width(), 0);
|
||||
}
|
||||
|
||||
IntrinsicSize ContainSizeAxes::ContainIntrinsicSize(
|
||||
const IntrinsicSize& aUncontainedSize, const WritingMode& aWM) const {
|
||||
if (!IsAny()) {
|
||||
return aUncontainedSize;
|
||||
}
|
||||
if (IsBoth()) {
|
||||
return IntrinsicSize(0, 0);
|
||||
}
|
||||
// At this point, we know that precisely one of our dimensions is contained.
|
||||
const bool zeroWidth =
|
||||
(!aWM.IsVertical() && mIContained) || (aWM.IsVertical() && mBContained);
|
||||
IntrinsicSize result(aUncontainedSize);
|
||||
if (zeroWidth) {
|
||||
result.width = Some(0);
|
||||
} else {
|
||||
result.height = Some(0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef nsStyleStruct_h___
|
||||
#define nsStyleStruct_h___
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/ServoStyleConstsInlines.h"
|
||||
|
|
@ -39,6 +40,7 @@ struct nsStyleDisplay;
|
|||
struct nsStyleVisibility;
|
||||
namespace mozilla {
|
||||
class ComputedStyle;
|
||||
struct IntrinsicSize;
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
@ -66,6 +68,29 @@ inline Position Position::FromPercentage(float aPercent) {
|
|||
LengthPercentage::FromPercentage(aPercent)};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience struct for querying if a given box has size-containment in
|
||||
* either axis.
|
||||
*/
|
||||
struct ContainSizeAxes {
|
||||
ContainSizeAxes(bool aIContained, bool aBContained)
|
||||
: mIContained(aIContained), mBContained(aBContained) {}
|
||||
|
||||
bool IsBoth() const { return mIContained && mBContained; }
|
||||
bool IsAny() const { return mIContained || mBContained; }
|
||||
|
||||
/**
|
||||
* Return a contained size from an uncontained size.
|
||||
*/
|
||||
nsSize ContainSize(const nsSize& aUncontainedSize,
|
||||
const WritingMode& aWM) const;
|
||||
IntrinsicSize ContainIntrinsicSize(const IntrinsicSize& aUncontainedSize,
|
||||
const WritingMode& aWM) const;
|
||||
|
||||
const bool mIContained;
|
||||
const bool mBContained;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont {
|
||||
|
|
@ -1179,6 +1204,11 @@ struct StyleAnimation {
|
|||
} // namespace mozilla
|
||||
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
||||
private:
|
||||
using StyleContain = mozilla::StyleContain;
|
||||
using StyleContentVisibility = mozilla::StyleContentVisibility;
|
||||
|
||||
public:
|
||||
explicit nsStyleDisplay(const mozilla::dom::Document&);
|
||||
nsStyleDisplay(const nsStyleDisplay& aOther);
|
||||
~nsStyleDisplay();
|
||||
|
|
@ -1533,12 +1563,21 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
}
|
||||
|
||||
bool IsContainPaint() const {
|
||||
return (mContain & mozilla::StyleContain::PAINT ||
|
||||
!IsContentVisibilityVisible()) &&
|
||||
!IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell();
|
||||
const auto contain = EffectiveContainment();
|
||||
// Short circuit for no containment whatsoever
|
||||
if (!contain) {
|
||||
return false;
|
||||
}
|
||||
return (contain & StyleContain::PAINT) && !IsInternalRubyDisplayType() &&
|
||||
!IsInternalTableStyleExceptCell();
|
||||
}
|
||||
|
||||
bool IsContainLayout() const {
|
||||
const auto contain = EffectiveContainment();
|
||||
// Short circuit for no containment whatsoever
|
||||
if (!contain) {
|
||||
return false;
|
||||
}
|
||||
// Note: The spec for layout 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
|
||||
|
|
@ -1546,12 +1585,16 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
// responsible for checking if the box in question is
|
||||
// non-atomic and inline-level, and creating an
|
||||
// exemption as necessary.
|
||||
return (mContain & mozilla::StyleContain::LAYOUT ||
|
||||
!IsContentVisibilityVisible()) &&
|
||||
!IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell();
|
||||
return (contain & StyleContain::LAYOUT) && !IsInternalRubyDisplayType() &&
|
||||
!IsInternalTableStyleExceptCell();
|
||||
}
|
||||
|
||||
bool IsContainSize() const {
|
||||
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
|
||||
|
|
@ -1559,19 +1602,22 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
// responsible for checking if the box in question is
|
||||
// non-atomic and inline-level, and creating an
|
||||
// exemption as necessary.
|
||||
return (mContain & mozilla::StyleContain::SIZE ||
|
||||
mContentVisibility == mozilla::StyleContentVisibility::Hidden) &&
|
||||
!IsInternalRubyDisplayType() &&
|
||||
DisplayInside() != mozilla::StyleDisplayInside::Table &&
|
||||
!IsInnerTableStyle();
|
||||
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 IsContentVisibilityVisible() const {
|
||||
return mContentVisibility == mozilla::StyleContentVisibility::Visible;
|
||||
return mContentVisibility == StyleContentVisibility::Visible;
|
||||
}
|
||||
|
||||
bool IsContentVisibilityHidden() const {
|
||||
return mContentVisibility == mozilla::StyleContentVisibility::Hidden;
|
||||
return mContentVisibility == StyleContentVisibility::Hidden;
|
||||
}
|
||||
|
||||
/* Returns whether the element has the transform property or a related
|
||||
|
|
@ -1686,6 +1732,27 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
inline bool IsFixedPosContainingBlockForTransformSupportingFrames() const;
|
||||
|
||||
void GenerateCombinedIndividualTransform();
|
||||
|
||||
private:
|
||||
StyleContain EffectiveContainment() const {
|
||||
// content-visibility and container-type values implicitly enable some
|
||||
// containment flags.
|
||||
// FIXME(dshin, bug 1463600): Add in STYLE containment flag for `auto` &
|
||||
// `hidden` when implemented
|
||||
// FIXME(dshin, bug 1764640): Add in the effect of `container-type`
|
||||
switch (mContentVisibility) {
|
||||
case StyleContentVisibility::Visible:
|
||||
// Most likely case.
|
||||
return mContain;
|
||||
case StyleContentVisibility::Auto:
|
||||
return mContain | StyleContain::LAYOUT | StyleContain::PAINT;
|
||||
case StyleContentVisibility::Hidden:
|
||||
return mContain | StyleContain::LAYOUT | StyleContain::PAINT |
|
||||
StyleContain::INLINE_SIZE | StyleContain::BLOCK_SIZE;
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid content visibility.");
|
||||
return mContain;
|
||||
}
|
||||
};
|
||||
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable {
|
||||
|
|
|
|||
|
|
@ -90,9 +90,12 @@ SVGOuterSVGFrame::SVGOuterSVGFrame(ComputedStyle* aStyle,
|
|||
// they're not really "replaced", and there's no outer context to contain sizes
|
||||
// from leaking into). Hence, we check for a parent element before we bother
|
||||
// testing for 'contain:size'.
|
||||
static inline bool IsReplacedAndContainSize(const SVGOuterSVGFrame* aFrame) {
|
||||
return aFrame->GetContent()->GetParent() &&
|
||||
aFrame->StyleDisplay()->IsContainSize();
|
||||
static inline ContainSizeAxes ContainSizeAxesIfApplicable(
|
||||
const SVGOuterSVGFrame* aFrame) {
|
||||
if (!aFrame->GetContent()->GetParent()) {
|
||||
return ContainSizeAxes(false, false);
|
||||
}
|
||||
return aFrame->StyleDisplay()->GetContainSizeAxes();
|
||||
}
|
||||
|
||||
void SVGOuterSVGFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||
|
|
@ -171,7 +174,7 @@ nscoord SVGOuterSVGFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
|||
wm.IsVertical() ? svg->mLengthAttributes[SVGSVGElement::ATTR_HEIGHT]
|
||||
: svg->mLengthAttributes[SVGSVGElement::ATTR_WIDTH];
|
||||
|
||||
if (IsReplacedAndContainSize(this)) {
|
||||
if (ContainSizeAxesIfApplicable(this).mIContained) {
|
||||
result = nscoord(0);
|
||||
} else if (isize.IsPercentage()) {
|
||||
// It looks like our containing block's isize may depend on our isize. In
|
||||
|
|
@ -208,7 +211,8 @@ IntrinsicSize SVGOuterSVGFrame::GetIntrinsicSize() {
|
|||
// XXXjwatt Note that here we want to return the CSS width/height if they're
|
||||
// specified and we're embedded inside an nsIObjectLoadingContent.
|
||||
|
||||
if (IsReplacedAndContainSize(this)) {
|
||||
const auto containAxes = ContainSizeAxesIfApplicable(this);
|
||||
if (containAxes.IsBoth()) {
|
||||
// Intrinsic size of 'contain:size' replaced elements is 0,0.
|
||||
return IntrinsicSize(0, 0);
|
||||
}
|
||||
|
|
@ -233,12 +237,12 @@ IntrinsicSize SVGOuterSVGFrame::GetIntrinsicSize() {
|
|||
intrinsicSize.height.emplace(std::max(val, 0));
|
||||
}
|
||||
|
||||
return intrinsicSize;
|
||||
return containAxes.ContainIntrinsicSize(intrinsicSize, GetWritingMode());
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
AspectRatio SVGOuterSVGFrame::GetIntrinsicRatio() const {
|
||||
if (IsReplacedAndContainSize(this)) {
|
||||
if (ContainSizeAxesIfApplicable(this).IsAny()) {
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1267,22 +1267,26 @@ impl TouchAction {
|
|||
|
||||
bitflags! {
|
||||
#[derive(MallocSizeOf, Parse, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
|
||||
#[css(bitflags(single = "none,strict,content", mixed="size,layout,paint"))]
|
||||
#[css(bitflags(single = "none,strict,content", mixed="size,layout,paint,inline-size", overlapping_bits))]
|
||||
#[repr(C)]
|
||||
/// Constants for contain: https://drafts.csswg.org/css-contain/#contain-property
|
||||
pub struct Contain: u8 {
|
||||
/// `none` variant, just for convenience.
|
||||
const NONE = 0;
|
||||
/// 'size' variant, turns on size containment
|
||||
const SIZE = 1 << 0;
|
||||
/// `inline-size` variant, turns on single-axis inline size containment
|
||||
const INLINE_SIZE = 1 << 0;
|
||||
/// `block-size` variant, turns on single-axis block size containment, internal only
|
||||
const BLOCK_SIZE = 1 << 1;
|
||||
/// `layout` variant, turns on layout containment
|
||||
const LAYOUT = 1 << 1;
|
||||
const LAYOUT = 1 << 2;
|
||||
/// `paint` variant, turns on paint containment
|
||||
const PAINT = 1 << 2;
|
||||
const PAINT = 1 << 3;
|
||||
/// `strict` variant, turns on all types of containment
|
||||
const STRICT = 1 << 3 | Contain::LAYOUT.bits | Contain::PAINT.bits | Contain::SIZE.bits;
|
||||
/// 'content' variant, turns on layout and paint containment
|
||||
const CONTENT = 1 << 4 | Contain::LAYOUT.bits | Contain::PAINT.bits;
|
||||
const STRICT = 1 << 4 | Contain::LAYOUT.bits | Contain::PAINT.bits | Contain::SIZE.bits;
|
||||
/// `content` variant, turns on layout and paint containment
|
||||
const CONTENT = 1 << 5 | Contain::LAYOUT.bits | Contain::PAINT.bits;
|
||||
/// 'size' variant, turns on size containment
|
||||
const SIZE = 1 << 6 | Contain::INLINE_SIZE.bits | Contain::BLOCK_SIZE.bits;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
[contain-inline-size-bfc-floats-002.html]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[contain-inline-size-fieldset.html]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[contain-inline-size-flex.html]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[contain-inline-size-flexitem.html]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[contain-inline-size-grid.html]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[contain-inline-size-legend.html]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[contain-inline-size-multicol.html]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[contain-inline-size-regular-container.html]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[contain-inline-size-replaced.html]
|
||||
[.inline-contained 23]
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1764457
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[contain-inline-size-vertical-rl-.html]
|
||||
expected: FAIL
|
||||
|
|
@ -11,8 +11,5 @@
|
|||
[Property contain value 'size style layout paint']
|
||||
expected: FAIL
|
||||
|
||||
[Property contain value 'inline-size']
|
||||
expected: FAIL
|
||||
|
||||
[Property contain value 'inline-size layout style paint']
|
||||
expected: FAIL
|
||||
|
|
|
|||
|
|
@ -11,8 +11,5 @@
|
|||
[e.style['contain'\] = "layout paint style size" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['contain'\] = "inline-size" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['contain'\] = "layout inline-size" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: intrinsic size of inline-size-contained replaced elems</title>
|
||||
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
|
||||
<link rel="author" href="https://mozilla.org" title="Mozilla">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-size">
|
||||
<meta name=assert
|
||||
content="This test checks that various replaced elements with contain: inline-size have an intrinsic inline size of 0 regardless of their content.">
|
||||
<style>
|
||||
.inline-contained {
|
||||
contain: inline-size;
|
||||
width: auto;
|
||||
height: auto;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/check-layout-th.js"></script>
|
||||
|
||||
<body onload="checkLayout('.inline-contained')">
|
||||
<div>
|
||||
<!-- video element: -->
|
||||
<video class="inline-contained" data-expected-width="0" data-expected-height="150"></video>
|
||||
<video class="inline-contained" data-expected-width="0" data-expected-height="150" controls></video>
|
||||
<video class="inline-contained" data-expected-width="0" data-expected-height="100"
|
||||
poster="support/blue-100x100.png"></video>
|
||||
<video class="inline-contained" data-expected-width="0" data-expected-height="100" poster="support/blue-100x100.png"
|
||||
controls></video>
|
||||
<video class="inline-contained" data-expected-width="0" data-expected-height="240" src="support/white.webm"
|
||||
controls></video>
|
||||
<video class="inline-contained" data-expected-width="0" data-expected-height="240" src="support/white.webm"
|
||||
controls></video>
|
||||
<br>
|
||||
|
||||
<!-- audio element with controls, and a few other misc replaced elements: -->
|
||||
<audio class="inline-contained" data-expected-width="0" data-expected-height="40" controls></audio>
|
||||
<canvas class="inline-contained" data-expected-width="0" data-expected-height="150"></canvas>
|
||||
<svg class="inline-contained" data-expected-bounding-client-rect-width="0"
|
||||
data-expected-bounding-client-rect-height="150"></svg>
|
||||
<br>
|
||||
|
||||
<!-- Image elements: -->
|
||||
<img class="inline-contained" data-expected-width="0" data-expected-height="24" src="broken">
|
||||
<img class="inline-contained" data-expected-width="0" data-expected-height="100" src="support/blue-100x100.png">
|
||||
<picture>
|
||||
<source srcset="support/blue-100x100.png"><img class="inline-contained" data-expected-width="0"
|
||||
data-expected-height="100">
|
||||
</picture>
|
||||
<br>
|
||||
|
||||
<!-- Document-embedding elements (with a target resource that
|
||||
could provide an intrinsic ratio in some cases, in the absence of
|
||||
contain:inline-size): -->
|
||||
<embed class="inline-contained" data-expected-width="0" data-expected-height="100" src="support/blue-100x100.png">
|
||||
<object class="inline-contained" data-expected-width="0" data-expected-height="100"
|
||||
data="support/blue-100x100.png"></object>
|
||||
<iframe class="inline-contained" data-expected-width="0" data-expected-height="150"></iframe>
|
||||
<iframe class="inline-contained" data-expected-width="0" data-expected-height="150"
|
||||
src="support/blue-100x100.png"></iframe>
|
||||
<br>
|
||||
</div>
|
||||
<!-- Same, but in vertical mode -->
|
||||
<div style="writing-mode: vertical-rl;">
|
||||
<video class="inline-contained" data-expected-width="300" data-expected-height="0"></video>
|
||||
<video class="inline-contained" data-expected-width="300" data-expected-height="0" controls></video>
|
||||
<video class="inline-contained" data-expected-width="100" data-expected-height="0"
|
||||
poster="support/blue-100x100.png"></video>
|
||||
<video class="inline-contained" data-expected-width="100" data-expected-height="0" poster="support/blue-100x100.png"
|
||||
controls></video>
|
||||
<video class="inline-contained" data-expected-width="320" data-expected-height="0" src="support/white.webm"
|
||||
controls></video>
|
||||
<video class="inline-contained" data-expected-width="320" data-expected-height="0" src="support/white.webm"
|
||||
controls></video>
|
||||
|
||||
<audio class="inline-contained" data-expected-width="300" data-expected-height="0" controls></audio>
|
||||
<canvas class="inline-contained" data-expected-width="300" data-expected-height="0"></canvas>
|
||||
<svg class="inline-contained" data-expected-bounding-client-rect-width="300"
|
||||
data-expected-bounding-client-rect-height="0"></svg>
|
||||
<br>
|
||||
|
||||
<img class="inline-contained" data-expected-width="24" data-expected-height="0" src="broken">
|
||||
<img class="inline-contained" data-expected-width="100" data-expected-height="0" src="support/blue-100x100.png">
|
||||
<picture>
|
||||
<source srcset="support/blue-100x100.png"><img class="inline-contained" data-expected-width="100"
|
||||
data-expected-height="0">
|
||||
</picture>
|
||||
<br>
|
||||
|
||||
<embed class="inline-contained" data-expected-width="100" data-expected-height="0" src="support/blue-100x100.png">
|
||||
<object class="inline-contained" data-expected-width="100" data-expected-height="0"
|
||||
data="support/blue-100x100.png"></object>
|
||||
<iframe class="inline-contained" data-expected-width="300" data-expected-height="0"></iframe>
|
||||
<iframe class="inline-contained" data-expected-width="300" data-expected-height="0"
|
||||
src="support/blue-100x100.png"></iframe>
|
||||
<br>
|
||||
</div>
|
||||
</body>
|
||||
Loading…
Reference in a new issue