Bug 1871412 - Fix scroll container checks for automatic minimum size and grid stretching checks. r=dholbert

The spec says scroll container, so overflow: visible and clip shouldn't
be different.

Note that the spec here is pending some edits from
https://github.com/w3c/csswg-drafts/issues/7714 tho.

Differential Revision: https://phabricator.services.mozilla.com/D197052
This commit is contained in:
Emilio Cobos Álvarez 2023-12-26 20:49:16 +00:00
Родитель 39cfcbf9ab
Коммит 64f95e649a
11 изменённых файлов: 206 добавлений и 28 удалений

Просмотреть файл

@ -5184,7 +5184,12 @@ nscoord nsLayoutUtils::MinSizeContributionForAxis(
nscoord minSize;
nscoord* fixedMinSize = nullptr;
if (size.IsAuto()) {
if (aFrame->StyleDisplay()->mOverflowX == StyleOverflow::Visible) {
if (aFrame->StyleDisplay()->IsScrollableOverflow()) {
// min-[width|height]:auto with scrollable overflow computes to
// zero.
minSize = 0;
fixedMinSize = &minSize;
} else {
size = aAxis == eAxisHorizontal ? stylePos->mWidth : stylePos->mHeight;
// This is same as above: keywords should behaves as property's initial
// values in block axis.
@ -5202,10 +5207,6 @@ nscoord nsLayoutUtils::MinSizeContributionForAxis(
fixedMinSize = &minSize;
}
// fall through - the caller will have to deal with "transferred size"
} else {
// min-[width|height]:auto with overflow != visible computes to zero.
minSize = 0;
fixedMinSize = &minSize;
}
} else if (GetAbsoluteCoord(size, minSize)) {
fixedMinSize = &minSize;

Просмотреть файл

@ -2306,6 +2306,9 @@ bool FlexItem::IsMinSizeAutoResolutionNeeded() const {
// (b) the item is *not* a scroll container. (A scroll container's automatic
// minimum size is zero.)
// https://drafts.csswg.org/css-flexbox-1/#min-size-auto
//
// Note that the scroll container case is redefined to be looking at the
// computed value instead, see https://github.com/w3c/csswg-drafts/issues/7714
const auto& mainMinSize =
Frame()->StylePosition()->MinSize(MainAxis(), ContainingBlockWM());

Просмотреть файл

@ -743,8 +743,7 @@ struct nsGridContainerFrame::GridItemInfo {
(isInlineAxis ==
aContainerWM.IsOrthogonalTo(mFrame->GetWritingMode()) &&
minSize.BehavesLikeInitialValueOnBlockAxis());
return isAuto &&
mFrame->StyleDisplay()->mOverflowX == StyleOverflow::Visible;
return isAuto && !mFrame->StyleDisplay()->IsScrollableOverflow();
}
#ifdef DEBUG
@ -5598,7 +5597,7 @@ static nscoord MinSize(const GridItemInfo& aGridItem,
style.IsAuto() ||
(!inInlineAxis && style.BehavesLikeInitialValueOnBlockAxis());
if ((inInlineAxis && nsIFrame::ToExtremumLength(style)) ||
(isAuto && child->StyleDisplay()->mOverflowX == StyleOverflow::Visible)) {
(isAuto && !child->StyleDisplay()->IsScrollableOverflow())) {
// Now calculate the "content size" part and return whichever is smaller.
MOZ_ASSERT(isAuto || sz == NS_UNCONSTRAINEDSIZE);
sz = std::min(sz, ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis,

Просмотреть файл

@ -7956,10 +7956,12 @@ bool nsIFrame::ComputeCustomOverflow(OverflowAreas& aOverflowAreas) {
}
bool nsIFrame::DoesClipChildrenInBothAxes() const {
nsIScrollableFrame* sf = do_QueryFrame(this);
if (IsScrollContainer()) {
return true;
}
const nsStyleDisplay* display = StyleDisplay();
return sf || (display->mOverflowX == StyleOverflow::Clip &&
display->mOverflowY == StyleOverflow::Clip);
return display->mOverflowX == StyleOverflow::Clip &&
display->mOverflowY == StyleOverflow::Clip;
}
/* virtual */
@ -11404,6 +11406,10 @@ static bool HasNoVisibleDescendants(const nsIFrame* aFrame) {
return true;
}
nsIScrollableFrame* nsIFrame::GetAsScrollContainer() const {
return do_QueryFrame(this);
}
void nsIFrame::UpdateVisibleDescendantsState() {
if (StyleVisibility()->IsVisible()) {
// Notify invisible ancestors that a visible descendant exists now.

Просмотреть файл

@ -4590,6 +4590,14 @@ class nsIFrame : public nsQueryFrame {
return HasAnyStateBits(NS_FRAME_IS_SVG_TEXT);
}
// https://drafts.csswg.org/css-overflow-3/#scroll-container
bool IsScrollContainer() const {
const bool result = IsScrollFrame() || IsListControlFrame();
MOZ_ASSERT(result == !!GetAsScrollContainer());
return result;
}
nsIScrollableFrame* GetAsScrollContainer() const;
/**
* Returns true if the frame is an SVG Rendering Observer container.
*/

Просмотреть файл

@ -119,7 +119,6 @@ fuzzy-if(winWidget,0-1,0-10) == grid-max-sizing-flex-003.html grid-max-sizing-fl
== grid-item-overflow-stretch-002.html grid-item-overflow-stretch-002-ref.html
== grid-item-overflow-stretch-003.html grid-item-overflow-stretch-003-ref.html
== grid-item-overflow-stretch-004.html grid-item-overflow-stretch-004-ref.html
== grid-item-overflow-stretch-005.html grid-item-overflow-stretch-005-ref.html
== grid-item-overflow-stretch-006.html grid-item-overflow-stretch-006-ref.html
== grid-item-canvas-001.html grid-item-canvas-001-ref.html
== grid-item-button-001.html grid-item-button-001-ref.html

Просмотреть файл

@ -915,6 +915,7 @@ gfxRect SVGUtils::GetBBox(nsIFrame* aFrame, uint32_t aFlags,
y = fillBBox.y;
width = fillBBox.width;
height = fillBBox.height;
// XXX Should probably check for overflow: clip too.
bool hasClip = aFrame->StyleDisplay()->IsScrollableOverflow();
if (hasClip) {
clipRect = SVGUtils::GetClipRectForFrame(aFrame, x, y, width, height);

Просмотреть файл

@ -0,0 +1,78 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>CSS Grid Reference: stretching overflow!=visible items</title>
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
<style>
body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
.grid {
display: inline-grid;
width: 100px;
height: 50px;
grid: 7px auto 3px / 7px auto 3px;
grid-gap: 5px;
border:1px solid;
}
.grid > * {
grid-area: 2/2;
border:1px solid;
appearance: none;
min-width:0;
min-height:0;
box-sizing: border-box;
}
.m { margin: 17px 3px 5px 7px; }
x { display:block; width:110px; height:5px; background:grey; }
.h .grid x { width:5px; height:110px; }
br { clear:both; }
</style>
</head>
<body>
<div class="grid"><button class="oa"></button></div>
<div class="grid"><button class="os"></button></div>
<div class="grid"><button class="oh"></button></div>
<div class="grid"><button class="ov"></button></div>
<div class="grid"><button class="oc"></button></div>
<br>
<div class="grid"><button class="m oa"></button></div>
<div class="grid"><button class="m os"></button></div>
<div class="grid"><button class="m oh"></button></div>
<div class="grid"><button class="m ov"></button></div>
<div class="grid"><button class="m oc"></button></div>
<br>
<div class="h">
<div class="grid"><button class="oa"></button></div>
<div class="grid"><button class="os"></button></div>
<div class="grid"><button class="oh"></button></div>
<div class="grid"><button class="ov"></button></div>
<div class="grid"><button class="oc"></button></div>
<br>
<div class="grid"><button class="m oa"></button></div>
<div class="grid"><button class="m os"></button></div>
<div class="grid"><button class="m oh"></button></div>
<div class="grid"><button class="m ov"></button></div>
<div class="grid"><button class="m oc"></button></div>
<br>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,82 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>CSS Grid Test: stretching overflow!=visible items: stretching rules for scroll containers</title>
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
<link rel="help" href="https://drafts.csswg.org/css-grid/#min-size-auto">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7714">
<link rel="match" href="stretch-grid-item-button-overflow-ref.html">
<style>
body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
.grid {
display: inline-grid;
width: 100px;
height: 50px;
grid: 7px auto 3px / 7px auto 3px;
grid-gap: 5px;
border:1px solid;
}
.grid > * {
grid-area: 2/2;
border:1px solid;
appearance: none;
}
.oa { overflow: auto; }
.os { overflow: scroll; }
.oh { overflow: hidden; }
.oc { overflow: clip; }
.m { margin: 17px 3px 5px 7px; }
x { display:block; width:110px; height:5px; background:grey; }
.h .grid x { width:5px; height:110px; }
br { clear:both; }
</style>
</head>
<body>
<div class="grid"><button class="oa"></button></div>
<div class="grid"><button class="os"></button></div>
<div class="grid"><button class="oh"></button></div>
<div class="grid"><button class="oc"></button></div>
<div class="grid"><button class=" "></button></div>
<br>
<div class="grid"><button class="m oa"></button></div>
<div class="grid"><button class="m os"></button></div>
<div class="grid"><button class="m oh"></button></div>
<div class="grid"><button class="m oc"></button></div>
<div class="grid"><button class="m "></button></div>
<br>
<div class="h">
<div class="grid"><button class="oa"></button></div>
<div class="grid"><button class="os"></button></div>
<div class="grid"><button class="oh"></button></div>
<div class="grid"><button class="oc"></button></div>
<div class="grid"><button class=" "></button></div>
<br>
<div class="grid"><button class="m oa"></button></div>
<div class="grid"><button class="m os"></button></div>
<div class="grid"><button class="m oh"></button></div>
<div class="grid"><button class="m oc"></button></div>
<div class="grid"><button class="m "></button></div>
<br>
</div>
</body>
</html>

Просмотреть файл

@ -22,22 +22,14 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
.grid > * {
grid-area: 2/2;
border:1px solid;
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
min-width:0;
min-height:0;
box-sizing: border-box;
}
.oa, .os, .oh, .ov { width:80px; height:30px; }
.m.oa, .m.os, .m.oh, .m.ov { width:70px; height:8px; }
.oa { overflow: auto; }
.os { overflow: scroll; }
.oh { overflow: hidden; }
.ov { justify-self: start; }
.m.ov { align-self: start; }
.m { margin: 17px 3px 5px 7px; }
input { justify-self: start; }
.m { align-self: start; margin: 17px 3px 5px 7px; }
x { display:block; width:110px; height:5px; background:grey; }
.h .grid x { width:5px; height:110px; }
@ -51,6 +43,7 @@ br { clear:both; }
<div class="grid"><input class="os"></div>
<div class="grid"><input class="oh"></div>
<div class="grid"><input class="ov"></div>
<div class="grid"><input class="oc"></div>
<br>
@ -58,6 +51,7 @@ br { clear:both; }
<div class="grid"><input class="m os"></div>
<div class="grid"><input class="m oh"></div>
<div class="grid"><input class="m ov"></div>
<div class="grid"><input class="m oc"></div>
<br>
@ -67,6 +61,7 @@ br { clear:both; }
<div class="grid"><input class="os"></div>
<div class="grid"><input class="oh"></div>
<div class="grid"><input class="ov"></div>
<div class="grid"><input class="oc"></div>
<br>
@ -74,6 +69,7 @@ br { clear:both; }
<div class="grid"><input class="m os"></div>
<div class="grid"><input class="m oh"></div>
<div class="grid"><input class="m ov"></div>
<div class="grid"><input class="m oc"></div>
<br>

Просмотреть файл

@ -5,9 +5,11 @@
-->
<html><head>
<meta charset="utf-8">
<title>CSS Grid Test: stretching overflow!=visible items</title>
<title>CSS Grid Test: stretching overflow!=visible items: stretching rules for scroll containers don't apply to input</title>
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
<link rel="match" href="grid-item-overflow-stretch-005-ref.html">
<link rel="match" href="stretch-grid-item-text-input-overflow-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-grid/#min-size-auto">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7714">
<style type="text/css">
body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
@ -23,14 +25,13 @@ body,html { color:black; background:white; font:16px/1 monospace; padding:0; mar
.grid > * {
grid-area: 2/2;
border:1px solid;
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
}
.oa { overflow: auto; }
.os { overflow: scroll; }
.oh { overflow: hidden; }
.oc { overflow: clip; }
.m { margin: 17px 3px 5px 7px; }
x { display:block; width:110px; height:5px; background:grey; }
@ -44,6 +45,7 @@ br { clear:both; }
<div class="grid"><input class="oa"></div>
<div class="grid"><input class="os"></div>
<div class="grid"><input class="oh"></div>
<div class="grid"><input class="oc"></div>
<div class="grid"><input class=" "></div>
<br>
@ -51,6 +53,7 @@ br { clear:both; }
<div class="grid"><input class="m oa"></div>
<div class="grid"><input class="m os"></div>
<div class="grid"><input class="m oh"></div>
<div class="grid"><input class="m oc"></div>
<div class="grid"><input class="m "></div>
<br>
@ -60,6 +63,7 @@ br { clear:both; }
<div class="grid"><input class="oa"></div>
<div class="grid"><input class="os"></div>
<div class="grid"><input class="oh"></div>
<div class="grid"><input class="oc"></div>
<div class="grid"><input class=" "></div>
<br>
@ -67,6 +71,7 @@ br { clear:both; }
<div class="grid"><input class="m oa"></div>
<div class="grid"><input class="m os"></div>
<div class="grid"><input class="m oh"></div>
<div class="grid"><input class="m oc"></div>
<div class="grid"><input class="m "></div>
<br>