зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1780475 - Obey contain-intrinsic-size in ContainSizeAxes. r=emilio
ContainSizeAxes::ContainSize and ContainSizeAxes::ContainIntrinsicSize were just using 0 for the axes with size containment, now they will take contain-intrinsic-width and contain-intrinsic-height into account. The WritingMode parameter is replaced with a nsIFrame from which the properties are retrieved. There are various places that aren't currently using these functions, so the effect of this patch is rather minimal, but some cases of the new test are now passing. Differential Revision: https://phabricator.services.mozilla.com/D152355
This commit is contained in:
Родитель
5706a29a88
Коммит
6ae79ec065
|
@ -586,7 +586,7 @@ bool nsHTMLScrollFrame::TryLayout(ScrollReflowInput& aState,
|
|||
// XXXldb Can we depend more on ComputeSize here?
|
||||
nsSize kidSize =
|
||||
aState.mReflowInput.mStyleDisplay->GetContainSizeAxes().ContainSize(
|
||||
aKidMetrics->PhysicalSize(), wm);
|
||||
aKidMetrics->PhysicalSize(), *aState.mReflowInput.mFrame);
|
||||
const nsSize desiredInsideBorderSize = kidSize + scrollbarGutterSize;
|
||||
aState.mInsideBorderSize =
|
||||
ComputeInsideBorderSize(aState, desiredInsideBorderSize);
|
||||
|
@ -999,7 +999,7 @@ void nsHTMLScrollFrame::ReflowContents(ScrollReflowInput& aState,
|
|||
aState.mHScrollbar != ShowScrollbar::Always) {
|
||||
nsSize kidSize =
|
||||
aState.mReflowInput.mStyleDisplay->GetContainSizeAxes().ContainSize(
|
||||
kidDesiredSize.PhysicalSize(), desiredWm);
|
||||
kidDesiredSize.PhysicalSize(), *aState.mReflowInput.mFrame);
|
||||
nsSize insideBorderSize = ComputeInsideBorderSize(aState, kidSize);
|
||||
nsRect scrolledRect = mHelper.GetUnsnappedScrolledRectInternal(
|
||||
kidDesiredSize.ScrollableOverflow(), insideBorderSize);
|
||||
|
|
|
@ -442,7 +442,7 @@ IntrinsicSize nsHTMLCanvasFrame::GetIntrinsicSize() {
|
|||
return IntrinsicSize(0, 0);
|
||||
}
|
||||
return containAxes.ContainIntrinsicSize(
|
||||
IntrinsicSizeFromCanvasSize(GetCanvasSize()), GetWritingMode());
|
||||
IntrinsicSizeFromCanvasSize(GetCanvasSize()), *this);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
|
|
@ -640,23 +640,21 @@ static IntrinsicSize ComputeIntrinsicSize(imgIContainer* aImage,
|
|||
ScaleIntrinsicSizeForDensity(intrinsicSize,
|
||||
aFrame.GetImageFromStyle()->GetResolution());
|
||||
}
|
||||
return containAxes.ContainIntrinsicSize(intrinsicSize,
|
||||
aFrame.GetWritingMode());
|
||||
return containAxes.ContainIntrinsicSize(intrinsicSize, aFrame);
|
||||
}
|
||||
|
||||
if (aKind == nsImageFrame::Kind::ListStyleImage) {
|
||||
// Note: images are handled above, this handles gradients etc.
|
||||
nscoord defaultLength = ListImageDefaultLength(aFrame);
|
||||
return containAxes.ContainIntrinsicSize(
|
||||
IntrinsicSize(defaultLength, defaultLength), aFrame.GetWritingMode());
|
||||
IntrinsicSize(defaultLength, defaultLength), aFrame);
|
||||
}
|
||||
|
||||
if (aFrame.ShouldShowBrokenImageIcon()) {
|
||||
nscoord edgeLengthToUse = nsPresContext::CSSPixelsToAppUnits(
|
||||
ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH)));
|
||||
return containAxes.ContainIntrinsicSize(
|
||||
IntrinsicSize(edgeLengthToUse, edgeLengthToUse),
|
||||
aFrame.GetWritingMode());
|
||||
IntrinsicSize(edgeLengthToUse, edgeLengthToUse), aFrame);
|
||||
}
|
||||
|
||||
if (aUseMappedRatio && style.StylePosition()->mAspectRatio.HasRatio()) {
|
||||
|
|
|
@ -626,7 +626,7 @@ IntrinsicSize nsSubDocumentFrame::GetIntrinsicSize() {
|
|||
|
||||
if (auto size = olc->GetSubdocumentIntrinsicSize()) {
|
||||
// Use the intrinsic size from the child SVG document, if available.
|
||||
return containAxes.ContainIntrinsicSize(*size, GetWritingMode());
|
||||
return containAxes.ContainIntrinsicSize(*size, *this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -640,7 +640,7 @@ IntrinsicSize nsSubDocumentFrame::GetIntrinsicSize() {
|
|||
|
||||
// We must be an HTML <iframe>. Return fallback size.
|
||||
return containAxes.ContainIntrinsicSize(IntrinsicSize(kFallbackIntrinsicSize),
|
||||
GetWritingMode());
|
||||
*this);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
|
|
@ -473,22 +473,21 @@ nsSize nsVideoFrame::GetVideoIntrinsicSize() const {
|
|||
return {};
|
||||
}
|
||||
|
||||
auto wm = GetWritingMode();
|
||||
if (!isVideo) {
|
||||
return containAxes.ContainSize(kFallbackIntrinsicSize, wm);
|
||||
return containAxes.ContainSize(kFallbackIntrinsicSize, *this);
|
||||
}
|
||||
|
||||
HTMLVideoElement* element = static_cast<HTMLVideoElement*>(GetContent());
|
||||
if (Maybe<CSSIntSize> size = element->GetVideoSize()) {
|
||||
return containAxes.ContainSize(CSSPixel::ToAppUnits(*size), wm);
|
||||
return containAxes.ContainSize(CSSPixel::ToAppUnits(*size), *this);
|
||||
}
|
||||
|
||||
if (ShouldDisplayPoster()) {
|
||||
if (Maybe<nsSize> imgSize = PosterImageSize()) {
|
||||
return containAxes.ContainSize(*imgSize, wm);
|
||||
return containAxes.ContainSize(*imgSize, *this);
|
||||
}
|
||||
}
|
||||
return containAxes.ContainSize(kFallbackIntrinsicSize, wm);
|
||||
return containAxes.ContainSize(kFallbackIntrinsicSize, *this);
|
||||
}
|
||||
|
||||
IntrinsicSize nsVideoFrame::GetIntrinsicSize() {
|
||||
|
|
|
@ -3565,39 +3565,57 @@ nscoord StyleCalcNode::Resolve(nscoord aBasis,
|
|||
return ResolveInternal(aBasis, aRounder);
|
||||
}
|
||||
|
||||
static nscoord Resolve(const StyleContainIntrinsicSize& aSize) {
|
||||
if (aSize.IsNone()) {
|
||||
return 0;
|
||||
}
|
||||
if (aSize.IsLength()) {
|
||||
return aSize.AsLength().ToAppUnits();
|
||||
}
|
||||
MOZ_ASSERT(aSize.IsAutoLength());
|
||||
// TODO: use last remembered size if possible.
|
||||
return aSize.AsAutoLength().ToAppUnits();
|
||||
}
|
||||
|
||||
nsSize ContainSizeAxes::ContainSize(const nsSize& aUncontainedSize,
|
||||
const WritingMode& aWM) const {
|
||||
const nsIFrame& aFrame) const {
|
||||
if (!IsAny()) {
|
||||
return aUncontainedSize;
|
||||
}
|
||||
const nsStylePosition* stylePos = aFrame.StylePosition();
|
||||
if (IsBoth()) {
|
||||
return nsSize();
|
||||
return nsSize(Resolve(stylePos->mContainIntrinsicWidth),
|
||||
Resolve(stylePos->mContainIntrinsicHeight));
|
||||
}
|
||||
// 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());
|
||||
const bool containsWidth =
|
||||
aFrame.GetWritingMode().IsVertical() ? mBContained : mIContained;
|
||||
if (containsWidth) {
|
||||
return nsSize(Resolve(stylePos->mContainIntrinsicWidth),
|
||||
aUncontainedSize.Height());
|
||||
}
|
||||
return nsSize(aUncontainedSize.Width(), 0);
|
||||
return nsSize(aUncontainedSize.Width(),
|
||||
Resolve(stylePos->mContainIntrinsicHeight));
|
||||
}
|
||||
|
||||
IntrinsicSize ContainSizeAxes::ContainIntrinsicSize(
|
||||
const IntrinsicSize& aUncontainedSize, const WritingMode& aWM) const {
|
||||
const IntrinsicSize& aUncontainedSize, const nsIFrame& aFrame) const {
|
||||
if (!IsAny()) {
|
||||
return aUncontainedSize;
|
||||
}
|
||||
const nsStylePosition* stylePos = aFrame.StylePosition();
|
||||
if (IsBoth()) {
|
||||
return IntrinsicSize(0, 0);
|
||||
return IntrinsicSize(Resolve(stylePos->mContainIntrinsicWidth),
|
||||
Resolve(stylePos->mContainIntrinsicHeight));
|
||||
}
|
||||
// At this point, we know that precisely one of our dimensions is contained.
|
||||
const bool zeroWidth =
|
||||
(!aWM.IsVertical() && mIContained) || (aWM.IsVertical() && mBContained);
|
||||
const bool containsWidth =
|
||||
aFrame.GetWritingMode().IsVertical() ? mBContained : mIContained;
|
||||
IntrinsicSize result(aUncontainedSize);
|
||||
if (zeroWidth) {
|
||||
result.width = Some(0);
|
||||
if (containsWidth) {
|
||||
result.width = Some(Resolve(stylePos->mContainIntrinsicWidth));
|
||||
} else {
|
||||
result.height = Some(0);
|
||||
result.height = Some(Resolve(stylePos->mContainIntrinsicHeight));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -87,9 +87,9 @@ struct ContainSizeAxes {
|
|||
* Return a contained size from an uncontained size.
|
||||
*/
|
||||
nsSize ContainSize(const nsSize& aUncontainedSize,
|
||||
const WritingMode& aWM) const;
|
||||
const nsIFrame& aFrame) const;
|
||||
IntrinsicSize ContainIntrinsicSize(const IntrinsicSize& aUncontainedSize,
|
||||
const WritingMode& aWM) const;
|
||||
const nsIFrame& aFrame) const;
|
||||
|
||||
const bool mIContained;
|
||||
const bool mBContained;
|
||||
|
|
|
@ -237,7 +237,7 @@ IntrinsicSize SVGOuterSVGFrame::GetIntrinsicSize() {
|
|||
intrinsicSize.height.emplace(std::max(val, 0));
|
||||
}
|
||||
|
||||
return containAxes.ContainIntrinsicSize(intrinsicSize, GetWritingMode());
|
||||
return containAxes.ContainIntrinsicSize(intrinsicSize, *this);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
[contain-intrinsic-size-028.html]
|
||||
[.test 3]
|
||||
expected: FAIL
|
||||
|
||||
[.test 4]
|
||||
expected: FAIL
|
||||
|
||||
[.test 6]
|
||||
expected: FAIL
|
||||
|
||||
[.test 8]
|
||||
expected: FAIL
|
||||
|
||||
[.test 9]
|
||||
expected: FAIL
|
||||
|
||||
[.test 10]
|
||||
expected: FAIL
|
||||
|
||||
[.test 13]
|
||||
expected: FAIL
|
||||
|
||||
[.test 15]
|
||||
expected: FAIL
|
||||
|
||||
[.test 17]
|
||||
expected: FAIL
|
||||
|
||||
[.test 18]
|
||||
expected: FAIL
|
||||
|
||||
[.test 21]
|
||||
expected: FAIL
|
||||
|
||||
[.test 23]
|
||||
expected: FAIL
|
|
@ -0,0 +1,99 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf8">
|
||||
<title>CSS contain-intrinsic-size: single axis size containment</title>
|
||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#containment-inline-size">
|
||||
<style>
|
||||
.test {
|
||||
contain: inline-size;
|
||||
display: inline-block;
|
||||
background: green;
|
||||
}
|
||||
.test::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
}
|
||||
.cis-none {
|
||||
contain-intrinsic-size: none none;
|
||||
}
|
||||
.cis-height {
|
||||
contain-intrinsic-size: none 50px;
|
||||
}
|
||||
.cis-width {
|
||||
contain-intrinsic-size: 100px none;
|
||||
}
|
||||
.cis-both {
|
||||
contain-intrinsic-size: 100px 50px;
|
||||
}
|
||||
.vertical {
|
||||
writing-mode: vertical-lr;
|
||||
}
|
||||
</style>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/check-layout-th.js"></script>
|
||||
|
||||
<body onload="checkLayout('.test')">
|
||||
<div id="log"></div>
|
||||
|
||||
<div class="test cis-none"
|
||||
data-expected-client-width="0" data-expected-client-height="20"></div>
|
||||
<div class="test cis-height"
|
||||
data-expected-client-width="0" data-expected-client-height="20"></div>
|
||||
<div class="test cis-width"
|
||||
data-expected-client-width="100" data-expected-client-height="20"></div>
|
||||
<div class="test cis-both"
|
||||
data-expected-client-width="100" data-expected-client-height="20"></div>
|
||||
|
||||
<div class="test cis-none vertical"
|
||||
data-expected-client-width="40" data-expected-client-height="0"></div>
|
||||
<div class="test cis-height vertical"
|
||||
data-expected-client-width="40" data-expected-client-height="50"></div>
|
||||
<div class="test cis-width vertical"
|
||||
data-expected-client-width="40" data-expected-client-height="0"></div>
|
||||
<div class="test cis-both vertical"
|
||||
data-expected-client-width="40" data-expected-client-height="50"></div>
|
||||
|
||||
<hr>
|
||||
|
||||
<img class="test cis-none" src="/css/support/60x60-green.png"
|
||||
data-expected-client-width="60" data-expected-client-height="60">
|
||||
<img class="test cis-height" src="/css/support/60x60-green.png"
|
||||
data-expected-client-width="60" data-expected-client-height="60">
|
||||
<img class="test cis-width" src="/css/support/60x60-green.png"
|
||||
data-expected-client-width="100" data-expected-client-height="60">
|
||||
<img class="test cis-both" src="/css/support/60x60-green.png"
|
||||
data-expected-client-width="100" data-expected-client-height="60">
|
||||
|
||||
<img class="test cis-none vertical" src="/css/support/60x60-green.png"
|
||||
data-expected-client-width="60" data-expected-client-height="60">
|
||||
<img class="test cis-height vertical" src="/css/support/60x60-green.png"
|
||||
data-expected-client-width="60" data-expected-client-height="50">
|
||||
<img class="test cis-width vertical" src="/css/support/60x60-green.png"
|
||||
data-expected-client-width="60" data-expected-client-height="60">
|
||||
<img class="test cis-both vertical" src="/css/support/60x60-green.png"
|
||||
data-expected-client-width="60" data-expected-client-height="50">
|
||||
|
||||
<hr>
|
||||
|
||||
<svg class="test cis-none"
|
||||
data-expected-client-width="300" data-expected-client-height="150"></svg>
|
||||
<svg class="test cis-height"
|
||||
data-expected-client-width="300" data-expected-client-height="150"></svg>
|
||||
<svg class="test cis-width"
|
||||
data-expected-client-width="100" data-expected-client-height="150"></svg>
|
||||
<svg class="test cis-both"
|
||||
data-expected-client-width="100" data-expected-client-height="150"></svg>
|
||||
|
||||
<svg class="test cis-none vertical"
|
||||
data-expected-client-width="300" data-expected-client-height="150"></svg>
|
||||
<svg class="test cis-height vertical"
|
||||
data-expected-client-width="300" data-expected-client-height="50"></svg>
|
||||
<svg class="test cis-width vertical"
|
||||
data-expected-client-width="300" data-expected-client-height="150"></svg>
|
||||
<svg class="test cis-both vertical"
|
||||
data-expected-client-width="300" data-expected-client-height="50"></svg>
|
||||
</body>
|
Загрузка…
Ссылка в новой задаче