From a591467fd5a971a91bc1727b1e847bbbb398c35e Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 4 Mar 2024 14:30:23 +0000 Subject: [PATCH] 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 --- layout/generic/nsGfxScrollFrame.cpp | 46 +++++++----- layout/generic/nsGfxScrollFrame.h | 6 ++ layout/generic/nsGridContainerFrame.cpp | 6 +- .../subgrid/scrollbar-gutter-002.html.ini | 3 + .../subgrid/scrollbar-gutter-001-ref.html | 68 +++++++++++++++++ .../subgrid/scrollbar-gutter-001.html | 68 +++++++++++++++++ .../subgrid/scrollbar-gutter-002.html | 73 +++++++++++++++++++ 7 files changed, 249 insertions(+), 21 deletions(-) create mode 100644 testing/web-platform/meta/css/css-grid/subgrid/scrollbar-gutter-002.html.ini create mode 100644 testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-001-ref.html create mode 100644 testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-001.html create mode 100644 testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-002.html diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 22bf02c47c0e..361847b7530d 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -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( diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 63f375dfce9e..ce2a75a3df6d 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -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. // diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index c7ab0bd0e256..93685444cbb4 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -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); } diff --git a/testing/web-platform/meta/css/css-grid/subgrid/scrollbar-gutter-002.html.ini b/testing/web-platform/meta/css/css-grid/subgrid/scrollbar-gutter-002.html.ini new file mode 100644 index 000000000000..c4299e897642 --- /dev/null +++ b/testing/web-platform/meta/css/css-grid/subgrid/scrollbar-gutter-002.html.ini @@ -0,0 +1,3 @@ +[scrollbar-gutter-002.html] + fuzzy: + if os == "mac": maxDifference=6-6;totalPixels=240-240 diff --git a/testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-001-ref.html b/testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-001-ref.html new file mode 100644 index 000000000000..0d00d380b66f --- /dev/null +++ b/testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-001-ref.html @@ -0,0 +1,68 @@ + + +CSS Grid Reference: Subgrids with 'overflow' and/or 'scrollbar-gutter' + + + + + +

All the following subgrid scroll container shouldn't have any scrollbars.

+ +

Testcase 1: subgrid with 'overflow: scroll'

+
+
+
+
+
+
+
+
+
+
+ +

Testcase 2: subgrid with 'overflow: auto' and 'scrollbar-gutter: stable'

+
+
+
+
+
+
+
+
+
+
+ +

Testcase 3: subgrid with 'overflow: hidden' and 'scrollbar-gutter: stable'

+
+
+
+
+
+
+
+
+
+
diff --git a/testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-001.html b/testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-001.html new file mode 100644 index 000000000000..664e4bc70eb5 --- /dev/null +++ b/testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-001.html @@ -0,0 +1,68 @@ + + +CSS Grid Test: Subgrids with 'overflow' and/or 'scrollbar-gutter' + + + + + + + + +

All the following subgrid scroll container shouldn't have any scrollbars.

+ +

Testcase 1: subgrid with 'overflow: scroll'

+
+
+
+
+
+
+
+
+
+
+ +

Testcase 2: subgrid with 'overflow: auto' and 'scrollbar-gutter: stable'

+
+
+
+
+
+
+
+
+
+
+ +

Testcase 3: subgrid with 'overflow: hidden' and 'scrollbar-gutter: stable'

+
+
+
+
+
+
+
+
+
+
diff --git a/testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-002.html b/testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-002.html new file mode 100644 index 000000000000..724bf06104c8 --- /dev/null +++ b/testing/web-platform/tests/css/css-grid/subgrid/scrollbar-gutter-002.html @@ -0,0 +1,73 @@ + + +CSS Grid Test: Fieldset subgrids with 'overflow' and/or 'scrollbar-gutter' + + + + + + + + +

All the following subgrid scroll container shouldn't have any scrollbars.

+ +

Testcase 1: subgrid with 'overflow: scroll'

+
+
+
+
+
+
+
+
+
+
+ +

Testcase 2: subgrid with 'overflow: auto' and 'scrollbar-gutter: stable'

+
+
+
+
+
+
+
+
+
+
+ +

Testcase 3: subgrid with 'overflow: hidden' and 'scrollbar-gutter: stable'

+
+
+
+
+
+
+
+
+
+