Bug 1879770 Part 2 - Add a helper to query intrinsic scrollbar-gutter size for subgrid. r=emilio

See https://bugzilla.mozilla.org/show_bug.cgi?id=1879770#c2 for an analysis.

Differential Revision: https://phabricator.services.mozilla.com/D201893
This commit is contained in:
Ting-Yu Lin 2024-03-04 14:30:23 +00:00
Родитель c5790fed3f
Коммит a591467fd5
7 изменённых файлов: 249 добавлений и 21 удалений

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

@ -1173,9 +1173,15 @@ void nsHTMLScrollFrame::PlaceScrollArea(ScrollReflowInput& aState,
}
nscoord nsHTMLScrollFrame::IntrinsicScrollbarGutterSizeAtInlineEdges() const {
const bool isVerticalWM = GetWritingMode().IsVertical();
const auto wm = GetWritingMode();
const LogicalMargin gutter(wm, IntrinsicScrollbarGutterSize());
return gutter.IStartEnd(wm);
}
nsMargin nsHTMLScrollFrame::IntrinsicScrollbarGutterSize() const {
if (PresContext()->UseOverlayScrollbars()) {
return 0;
// Overlay scrollbars do not consume space per spec.
return {};
}
const auto* styleForScrollbar = nsLayoutUtils::StyleForScrollbar(this);
@ -1183,28 +1189,30 @@ nscoord nsHTMLScrollFrame::IntrinsicScrollbarGutterSizeAtInlineEdges() const {
styleForScrollbar->StyleUIReset()->ScrollbarWidth();
if (styleScrollbarWidth == StyleScrollbarWidth::None) {
// Scrollbar shouldn't appear at all with "scrollbar-width: none".
return 0;
return {};
}
const auto& styleScrollbarGutter =
styleForScrollbar->StyleDisplay()->mScrollbarGutter;
ScrollStyles ss = GetScrollStyles();
const StyleOverflow& inlineEndStyleOverflow =
isVerticalWM ? ss.mHorizontal : ss.mVertical;
// Return the scrollbar-gutter size only if we have "overflow:scroll" or
// non-auto "scrollbar-gutter", so early-return here if the conditions aren't
// satisfied.
if (inlineEndStyleOverflow != StyleOverflow::Scroll &&
styleScrollbarGutter == StyleScrollbarGutter::AUTO) {
return 0;
nsMargin gutter =
ComputeStableScrollbarGutter(styleScrollbarWidth, styleScrollbarGutter);
if (gutter.LeftRight() == 0 || gutter.TopBottom() == 0) {
// If there is no stable scrollbar-gutter at vertical or horizontal
// dimension, check if a scrollbar is always shown at that dimension.
ScrollStyles scrollStyles = GetScrollStyles();
const nscoord scrollbarSize =
GetNonOverlayScrollbarSize(PresContext(), styleScrollbarWidth);
if (gutter.LeftRight() == 0 &&
scrollStyles.mVertical == StyleOverflow::Scroll) {
(IsScrollbarOnRight() ? gutter.right : gutter.left) = scrollbarSize;
}
if (gutter.TopBottom() == 0 &&
scrollStyles.mHorizontal == StyleOverflow::Scroll) {
// The horizontal scrollbar is always at the bottom side.
gutter.bottom = scrollbarSize;
}
}
const nscoord scrollbarSize =
GetNonOverlayScrollbarSize(PresContext(), styleScrollbarWidth);
const auto bothEdges =
bool(styleScrollbarGutter & StyleScrollbarGutter::BOTH_EDGES);
return bothEdges ? scrollbarSize * 2 : scrollbarSize;
return gutter;
}
nsMargin nsHTMLScrollFrame::ComputeStableScrollbarGutter(

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

@ -112,6 +112,12 @@ class nsHTMLScrollFrame : public nsContainerFrame,
// scrollbar that scrolls in the block axis).
nscoord IntrinsicScrollbarGutterSizeAtInlineEdges() const;
// Return the size of space created by scrollbar-gutter or actual scrollbars,
// assuming that the content is *not* overflowing the container. In other
// words, this space is created by stable scrollbar-gutter or by scrollbars
// due to "overflow: scroll".
nsMargin IntrinsicScrollbarGutterSize() const;
// Compute stable scrollbar-gutter from scrollbar-width and scrollbar-gutter
// properties.
//

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

@ -28,6 +28,7 @@
#include "nsCSSFrameConstructor.h"
#include "nsDisplayList.h"
#include "nsFieldSetFrame.h"
#include "nsGfxScrollFrame.h"
#include "nsHashKeys.h"
#include "nsIFrameInlines.h" // for nsIFrame::GetLogicalNormalPosition (don't remove)
#include "nsLayoutUtils.h"
@ -3685,7 +3686,8 @@ static Subgrid* SubgridComputeMarginBorderPadding(
sz.ComputedLogicalMargin(cbWM) + sz.ComputedLogicalBorderPadding(cbWM);
if (aGridItem.mFrame != subgridFrame) {
nsIScrollableFrame* scrollFrame = aGridItem.mFrame->GetScrollTargetFrame();
nsHTMLScrollFrame* scrollFrame =
do_QueryFrame(aGridItem.mFrame->GetScrollTargetFrame());
if (scrollFrame) {
MOZ_ASSERT(
sz.ComputedLogicalMargin(cbWM) == LogicalMargin(cbWM) &&
@ -3699,7 +3701,7 @@ static Subgrid* SubgridComputeMarginBorderPadding(
szScrollFrame.ComputedLogicalMargin(cbWM) +
szScrollFrame.ComputedLogicalBorder(cbWM);
nsMargin ssz = scrollFrame->GetActualScrollbarSizes();
nsMargin ssz = scrollFrame->IntrinsicScrollbarGutterSize();
subgrid->mMarginBorderPadding += LogicalMargin(cbWM, ssz);
}

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

@ -0,0 +1,3 @@
[scrollbar-gutter-002.html]
fuzzy:
if os == "mac": maxDifference=6-6;totalPixels=240-240

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

@ -0,0 +1,68 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>CSS Grid Reference: Subgrids with 'overflow' and/or 'scrollbar-gutter'</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<style>
:root {
overflow: scroll; /* Required to reproduce the bug on Firefox */
}
.grid {
display: inline-block;
inline-size: 75px;
border: 5px solid blue;
vertical-align: top;
}
.subgrid {
block-size: 75px;
}
.item {
inline-size: 50px;
block-size: 50px;
background: green;
}
fieldset {
margin: 0;
padding: 0;
border: 0;
}
</style>
<p>All the following subgrid scroll container shouldn't have any scrollbars.</p>
<p>Testcase 1: subgrid with 'overflow: scroll'</p>
<div class="grid">
<div class="subgrid" style="overflow: scroll;">
<div class="item"></div>
</div>
</div>
<div class="grid" style="writing-mode: vertical-rl;">
<div class="subgrid" style="overflow: scroll;">
<div class="item"></div>
</div>
</div>
<p>Testcase 2: subgrid with 'overflow: auto' and 'scrollbar-gutter: stable'</p>
<div class="grid">
<div class="subgrid" style="overflow: auto; scrollbar-gutter: stable;">
<div class="item"></div>
</div>
</div>
<div class="grid" style="writing-mode: vertical-rl;">
<div class="subgrid" style="overflow: auto; scrollbar-gutter: stable;">
<div class="item"></div>
</div>
</div>
<p>Testcase 3: subgrid with 'overflow: hidden' and 'scrollbar-gutter: stable'</p>
<div class="grid">
<div class="subgrid" style="overflow: hidden; scrollbar-gutter: stable;">
<div class="item"></div>
</div>
</div>
<div class="grid" style="writing-mode: vertical-rl;">
<div class="subgrid" style="overflow: hidden; scrollbar-gutter: stable;">
<div class="item"></div>
</div>
</div>

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

@ -0,0 +1,68 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>CSS Grid Test: Subgrids with 'overflow' and/or 'scrollbar-gutter'</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879770">
<link rel="help" href="https://drafts.csswg.org/css-grid-2/#subgrid-item-contribution">
<link rel="match" href="scrollbar-gutter-001-ref.html">
<style>
:root {
overflow: scroll; /* Required to reproduce the bug on Firefox */
}
.grid {
inline-size: 75px;
display: inline-grid;
border: 5px solid blue;
vertical-align: top;
}
.subgrid {
block-size: 75px;
display: grid;
grid: auto / subgrid;
}
.item {
inline-size: 50px;
block-size: 50px;
background: green;
}
</style>
<p>All the following subgrid scroll container shouldn't have any scrollbars.</p>
<p>Testcase 1: subgrid with 'overflow: scroll'</p>
<div class="grid">
<div class="subgrid" style="overflow: scroll;">
<div class="item"></div>
</div>
</div>
<div class="grid" style="writing-mode: vertical-rl;">
<div class="subgrid" style="overflow: scroll;">
<div class="item"></div>
</div>
</div>
<p>Testcase 2: subgrid with 'overflow: auto' and 'scrollbar-gutter: stable'</p>
<div class="grid">
<div class="subgrid" style="overflow: auto; scrollbar-gutter: stable;">
<div class="item"></div>
</div>
</div>
<div class="grid" style="writing-mode: vertical-rl;">
<div class="subgrid" style="overflow: auto; scrollbar-gutter: stable;">
<div class="item"></div>
</div>
</div>
<p>Testcase 3: subgrid with 'overflow: hidden' and 'scrollbar-gutter: stable'</p>
<div class="grid">
<div class="subgrid" style="overflow: hidden; scrollbar-gutter: stable;">
<div class="item"></div>
</div>
</div>
<div class="grid" style="writing-mode: vertical-rl;">
<div class="subgrid" style="overflow: hidden; scrollbar-gutter: stable;">
<div class="item"></div>
</div>
</div>

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

@ -0,0 +1,73 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>CSS Grid Test: Fieldset subgrids with 'overflow' and/or 'scrollbar-gutter'</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879770">
<link rel="help" href="https://drafts.csswg.org/css-grid-2/#subgrid-item-contribution">
<link rel="match" href="scrollbar-gutter-001-ref.html">
<style>
:root {
overflow: scroll; /* Required to reproduce the bug on Firefox */
}
.grid {
inline-size: 75px;
display: inline-grid;
border: 5px solid blue;
vertical-align: top;
}
.subgrid {
block-size: 75px;
display: grid;
grid: auto / subgrid;
}
.item {
inline-size: 50px;
block-size: 50px;
background: green;
}
fieldset {
margin: 0;
padding: 0;
border: 0;
}
</style>
<p>All the following subgrid scroll container shouldn't have any scrollbars.</p>
<p>Testcase 1: subgrid with 'overflow: scroll'</p>
<div class="grid">
<fieldset class="subgrid" style="overflow: scroll;">
<div class="item"></div>
</fieldset>
</div>
<div class="grid" style="writing-mode: vertical-rl;">
<fieldset class="subgrid" style="overflow: scroll;">
<div class="item"></div>
</fieldset>
</div>
<p>Testcase 2: subgrid with 'overflow: auto' and 'scrollbar-gutter: stable'</p>
<div class="grid">
<fieldset class="subgrid" style="overflow: auto; scrollbar-gutter: stable;">
<div class="item"></div>
</fieldset>
</div>
<div class="grid" style="writing-mode: vertical-rl;">
<fieldset class="subgrid" style="overflow: auto; scrollbar-gutter: stable;">
<div class="item"></div>
</fieldset>
</div>
<p>Testcase 3: subgrid with 'overflow: hidden' and 'scrollbar-gutter: stable'</p>
<div class="grid">
<fieldset class="subgrid" style="overflow: hidden; scrollbar-gutter: stable;">
<div class="item"></div>
</fieldset>
</div>
<div class="grid" style="writing-mode: vertical-rl;">
<fieldset class="subgrid" style="overflow: hidden; scrollbar-gutter: stable;">
<div class="item"></div>
</fieldset>
</div>