Implement CSS scrollbar-width.

This commit is contained in:
Fedor 2021-02-07 17:32:52 +02:00
parent c179b55f7d
commit 5ea204f926
44 changed files with 392 additions and 207 deletions

View File

@ -67,7 +67,7 @@
* Change scrollbar styles from hidden to auto. That makes us to create an
* accessible for scroll area.
*/
function changeScrollbarStyles(aContainerID, aScrollAreaID)
function changeScrollStyles(aContainerID, aScrollAreaID)
{
this.container = getAccessible(aContainerID);
this.scrollAreaNode = getNode(aScrollAreaID);
@ -77,7 +77,7 @@
new invokerChecker(EVENT_REORDER, this.container)
];
this.invoke = function changeScrollbarStyles_invoke()
this.invoke = function changeScrollStyles_invoke()
{
var accTree =
{ SECTION: [] };
@ -86,7 +86,7 @@
this.scrollAreaNode.style.overflow = "auto";
}
this.finalCheck = function changeScrollbarStyles_finalCheck()
this.finalCheck = function changeScrollStyles_finalCheck()
{
var accTree =
{ SECTION: [ // container
@ -95,7 +95,7 @@
testAccessibleTree(this.container, accTree);
}
this.getID = function changeScrollbarStyles_getID()
this.getID = function changeScrollStyles_getID()
{
return "change scrollbar styles " + prettyName(aScrollAreaID);
}
@ -114,7 +114,7 @@
gQueue = new eventQueue();
gQueue.push(new changeScrollRange("container", "scrollarea"));
gQueue.push(new changeScrollbarStyles("container2", "scrollarea2"));
gQueue.push(new changeScrollStyles("container2", "scrollarea2"));
gQueue.invoke(); // Will call SimpleTest.finish();
}

View File

@ -3038,6 +3038,7 @@ exports.CSS_PROPERTIES = {
"scroll-snap-points-y",
"scroll-snap-type-x",
"scroll-snap-type-y",
"scrollbar-width",
"shape-outside",
"shape-rendering",
"-moz-stack-sizing",

View File

@ -1089,7 +1089,7 @@ KeyframeEffectReadOnly::CanThrottleTransformChanges(nsIFrame& aFrame) const
return true;
}
ScrollbarStyles ss = scrollable->GetScrollbarStyles();
ScrollStyles ss = scrollable->GetScrollStyles();
if (ss.mVertical == NS_STYLE_OVERFLOW_HIDDEN &&
ss.mHorizontal == NS_STYLE_OVERFLOW_HIDDEN &&
scrollable->GetLogicalScrollPosition() == nsPoint(0, 0)) {

View File

@ -745,7 +745,7 @@ Element::Scroll(const CSSIntPoint& aScroll, const ScrollOptions& aOptions)
if (aOptions.mBehavior == ScrollBehavior::Smooth) {
scrollMode = nsIScrollableFrame::SMOOTH_MSD;
} else if (aOptions.mBehavior == ScrollBehavior::Auto) {
ScrollbarStyles styles = sf->GetScrollbarStyles();
ScrollStyles styles = sf->GetScrollStyles();
if (styles.mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_SMOOTH) {
scrollMode = nsIScrollableFrame::SMOOTH_MSD;
}
@ -834,7 +834,7 @@ Element::SetScrollTop(int32_t aScrollTop)
nsIScrollableFrame* sf = GetScrollFrame();
if (sf) {
nsIScrollableFrame::ScrollMode scrollMode = nsIScrollableFrame::INSTANT;
if (sf->GetScrollbarStyles().mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_SMOOTH) {
if (sf->GetScrollStyles().mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_SMOOTH) {
scrollMode = nsIScrollableFrame::SMOOTH_MSD;
}
sf->ScrollToCSSPixels(CSSIntPoint(sf->GetScrollPositionCSSPixels().x,
@ -856,7 +856,7 @@ Element::SetScrollLeft(int32_t aScrollLeft)
nsIScrollableFrame* sf = GetScrollFrame();
if (sf) {
nsIScrollableFrame::ScrollMode scrollMode = nsIScrollableFrame::INSTANT;
if (sf->GetScrollbarStyles().mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_SMOOTH) {
if (sf->GetScrollStyles().mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_SMOOTH) {
scrollMode = nsIScrollableFrame::SMOOTH_MSD;
}
@ -1069,7 +1069,7 @@ ShadowRoot*
Element::GetShadowRootByMode() const
{
/**
* 1. Let shadow be context objects shadow root.
* 1. Let shadow be context object???s shadow root.
* 2. If shadow is null or its mode is "closed", then return null.
*/
ShadowRoot* shadowRoot = GetShadowRoot();
@ -1088,7 +1088,7 @@ already_AddRefed<ShadowRoot>
Element::AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError)
{
/**
* 1. If context objects namespace is not the HTML namespace,
* 1. If context object???s namespace is not the HTML namespace,
* then throw a "NotSupportedError" DOMException.
*/
if (!IsHTMLElement()) {
@ -1097,7 +1097,7 @@ Element::AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError)
}
/**
* 2. If context objects local name is not
* 2. If context object???s local name is not
* a valid custom element name, "article", "aside", "blockquote",
* "body", "div", "footer", "h1", "h2", "h3", "h4", "h5", "h6",
* "header", "main" "nav", "p", "section", or "span",
@ -1181,8 +1181,8 @@ Element::AttachShadowInternal(bool aClosed, ErrorResult& aError)
/**
* 4. Let shadow be a new shadow root whose node document is
* context objects node document, host is context object,
* and mode is inits mode.
* context object???s node document, host is context object,
* and mode is init???s mode.
*/
RefPtr<ShadowRoot> shadowRoot =
new ShadowRoot(this, aClosed, nodeInfo.forget(), protoBinding);
@ -1190,7 +1190,7 @@ Element::AttachShadowInternal(bool aClosed, ErrorResult& aError)
shadowRoot->SetIsComposedDocParticipant(IsInComposedDoc());
/**
* 5. Set context objects shadow root to shadow.
* 5. Set context object???s shadow root to shadow.
*/
SetShadowRoot(shadowRoot);
@ -1890,7 +1890,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
nsPresContext* presContext = presShell->GetPresContext();
if (presContext) {
MOZ_ASSERT(this !=
presContext->GetViewportScrollbarStylesOverrideNode(),
presContext->GetViewportScrollStylesOverrideNode(),
"Leaving behind a raw pointer to this node (as having "
"propagated scrollbar styles) - that's dangerous...");
}

View File

@ -10562,7 +10562,7 @@ UpdateViewportScrollbarOverrideForFullscreen(nsIDocument* aDoc)
{
if (nsIPresShell* presShell = aDoc->GetShell()) {
if (nsPresContext* presContext = presShell->GetPresContext()) {
presContext->UpdateViewportScrollbarStylesOverride();
presContext->UpdateViewportScrollStylesOverride();
}
}
}

View File

@ -8266,7 +8266,7 @@ nsGlobalWindow::ScrollTo(const CSSIntPoint& aScroll,
scroll.y = maxpx;
}
bool smoothScroll = sf->GetScrollbarStyles().IsSmoothScroll(aOptions.mBehavior);
bool smoothScroll = sf->GetScrollStyles().IsSmoothScroll(aOptions.mBehavior);
sf->ScrollToCSSPixels(scroll, smoothScroll
? nsIScrollableFrame::SMOOTH_MSD
@ -8322,7 +8322,7 @@ nsGlobalWindow::ScrollByLines(int32_t numLines,
// It seems like it would make more sense for ScrollByLines to use
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
// Perhaps Web content does too.
bool smoothScroll = sf->GetScrollbarStyles().IsSmoothScroll(aOptions.mBehavior);
bool smoothScroll = sf->GetScrollStyles().IsSmoothScroll(aOptions.mBehavior);
sf->ScrollBy(nsIntPoint(0, numLines), nsIScrollableFrame::LINES,
smoothScroll
@ -8343,7 +8343,7 @@ nsGlobalWindow::ScrollByPages(int32_t numPages,
// It seems like it would make more sense for ScrollByPages to use
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
// Perhaps Web content does too.
bool smoothScroll = sf->GetScrollbarStyles().IsSmoothScroll(aOptions.mBehavior);
bool smoothScroll = sf->GetScrollStyles().IsSmoothScroll(aOptions.mBehavior);
sf->ScrollBy(nsIntPoint(0, numPages), nsIScrollableFrame::PAGES,
smoothScroll

View File

@ -2516,7 +2516,7 @@ EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
return frameToScroll;
}
ScrollbarStyles ss = scrollableFrame->GetScrollbarStyles();
ScrollStyles ss = scrollableFrame->GetScrollStyles();
bool hiddenForV = (NS_STYLE_OVERFLOW_HIDDEN == ss.mVertical);
bool hiddenForH = (NS_STYLE_OVERFLOW_HIDDEN == ss.mHorizontal);
if ((hiddenForV && hiddenForH) ||
@ -2609,7 +2609,7 @@ EventStateManager::DoScrollText(nsIScrollableFrame* aScrollableFrame,
ComputeScrollAmountForDefaultAction(aEvent, scrollAmountInDevPixels);
// Don't scroll around the axis whose overflow style is hidden.
ScrollbarStyles overflowStyle = aScrollableFrame->GetScrollbarStyles();
ScrollStyles overflowStyle = aScrollableFrame->GetScrollStyles();
if (overflowStyle.mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
actualDevPixelScrollAmount.x = 0;
}

View File

@ -92,10 +92,10 @@ ScrollFrameTo(nsIScrollableFrame* aFrame, const FrameMetrics& aMetrics, bool& aS
// (by design). Note also that when we run into this case, even if both axes
// have overflow:hidden, we want to set aSuccessOut to true, so that the displayport
// follows the async scroll position rather than the gecko scroll position.
if (aFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
if (aFrame->GetScrollStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
targetScrollPosition.y = geckoScrollPosition.y;
}
if (aFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
if (aFrame->GetScrollStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
targetScrollPosition.x = geckoScrollPosition.x;
}

View File

@ -171,7 +171,7 @@ RestyleManagerBase::ChangeHintToString(nsChangeHint aHint)
"NeutralChange", "InvalidateRenderingObservers",
"ReflowChangesSizeOrPosition", "UpdateComputedBSize",
"UpdateUsesOpacity", "UpdateBackgroundPosition",
"AddOrRemoveTransform", "CSSOverflowChange",
"AddOrRemoveTransform", "ScrollbarChange",
};
static_assert(nsChangeHint_AllHints == (1 << ArrayLength(names)) - 1,
"Name list doesn't match change hints.");
@ -1111,11 +1111,11 @@ if (!mDestroyedFrames) {
nsPresContext* presContext = PresContext();
nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor();
// Handle nsChangeHint_CSSOverflowChange, by either updating the
// Handle nsChangeHint_ScrollbarChange, by either updating the
// scrollbars on the viewport, or upgrading the change hint to frame-reconstruct.
for (nsStyleChangeData& data : aChangeList) {
if (data.mHint & nsChangeHint_CSSOverflowChange) {
data.mHint &= ~nsChangeHint_CSSOverflowChange;
if (data.mHint & nsChangeHint_ScrollbarChange) {
data.mHint &= ~nsChangeHint_ScrollbarChange;
bool doReconstruct = true; // assume the worst
// Only bother with this if we're html/body, since:
@ -1137,9 +1137,9 @@ if (!mDestroyedFrames) {
// to reconstruct - we can just reflow, because no scrollframe is being
// added/removed.
nsIContent* prevOverrideNode =
presContext->GetViewportScrollbarStylesOverrideNode();
presContext->GetViewportScrollStylesOverrideNode();
nsIContent* newOverrideNode =
presContext->UpdateViewportScrollbarStylesOverride();
presContext->UpdateViewportScrollStylesOverride();
if (data.mContent == prevOverrideNode ||
data.mContent == newOverrideNode) {

View File

@ -3,12 +3,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ScrollbarStyles.h"
#include "ScrollStyles.h"
#include "nsStyleStruct.h" // for nsStyleDisplay and nsStyleBackground::Position
namespace mozilla {
ScrollbarStyles::ScrollbarStyles(uint8_t aH, uint8_t aV,
ScrollStyles::ScrollStyles(uint8_t aH, uint8_t aV,
const nsStyleDisplay* aDisplay)
: mHorizontal(aH), mVertical(aV),
mScrollBehavior(aDisplay->mScrollBehavior),
@ -19,7 +19,7 @@ namespace mozilla {
mScrollSnapDestinationX(aDisplay->mScrollSnapDestination.mXPosition),
mScrollSnapDestinationY(aDisplay->mScrollSnapDestination.mYPosition) {}
ScrollbarStyles::ScrollbarStyles(const nsStyleDisplay* aDisplay)
ScrollStyles::ScrollStyles(const nsStyleDisplay* aDisplay)
: mHorizontal(aDisplay->mOverflowX), mVertical(aDisplay->mOverflowY),
mScrollBehavior(aDisplay->mScrollBehavior),
mScrollSnapTypeX(aDisplay->mScrollSnapTypeX),

View File

@ -3,8 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ScrollbarStyles_h
#define ScrollbarStyles_h
#ifndef ScrollStyles_h
#define ScrollStyles_h
#include <stdint.h>
#include "nsStyleConsts.h" // for NS_STYLE_SCROLL_SNAP_*
@ -16,7 +16,7 @@ struct nsStyleDisplay;
namespace mozilla {
struct ScrollbarStyles
struct ScrollStyles
{
// Always one of NS_STYLE_OVERFLOW_SCROLL, NS_STYLE_OVERFLOW_HIDDEN,
// or NS_STYLE_OVERFLOW_AUTO.
@ -34,7 +34,7 @@ struct ScrollbarStyles
nsStyleCoord::CalcValue mScrollSnapDestinationX;
nsStyleCoord::CalcValue mScrollSnapDestinationY;
ScrollbarStyles(uint8_t aH, uint8_t aV)
ScrollStyles(uint8_t aH, uint8_t aV)
: mHorizontal(aH), mVertical(aV),
mScrollBehavior(NS_STYLE_SCROLL_BEHAVIOR_AUTO),
mScrollSnapTypeX(NS_STYLE_SCROLL_SNAP_TYPE_NONE),
@ -50,10 +50,10 @@ struct ScrollbarStyles
mScrollSnapDestinationY.mHasPercent = false;
}
explicit ScrollbarStyles(const nsStyleDisplay* aDisplay);
ScrollbarStyles(uint8_t aH, uint8_t aV, const nsStyleDisplay* aDisplay);
ScrollbarStyles() {}
bool operator==(const ScrollbarStyles& aStyles) const {
explicit ScrollStyles(const nsStyleDisplay* aDisplay);
ScrollStyles(uint8_t aH, uint8_t aV, const nsStyleDisplay* aDisplay);
ScrollStyles() {}
bool operator==(const ScrollStyles& aStyles) const {
return aStyles.mHorizontal == mHorizontal && aStyles.mVertical == mVertical &&
aStyles.mScrollBehavior == mScrollBehavior &&
aStyles.mScrollSnapTypeX == mScrollSnapTypeX &&
@ -63,7 +63,7 @@ struct ScrollbarStyles
aStyles.mScrollSnapDestinationX == mScrollSnapDestinationX &&
aStyles.mScrollSnapDestinationY == mScrollSnapDestinationY;
}
bool operator!=(const ScrollbarStyles& aStyles) const {
bool operator!=(const ScrollStyles& aStyles) const {
return !(*this == aStyles);
}
bool IsHiddenInBothDirections() const {

View File

@ -95,7 +95,7 @@ EXPORTS += [
'nsRefreshDriver.h',
'nsStyleChangeList.h',
'nsStyleSheetService.h',
'ScrollbarStyles.h',
'ScrollStyles.h',
'StackArena.h',
'Units.h',
'UnitTransforms.h',
@ -162,7 +162,7 @@ SOURCES += [
'RestyleManager.cpp',
'RestyleManagerBase.cpp',
'RestyleTracker.cpp',
'ScrollbarStyles.cpp',
'ScrollStyles.cpp',
'ServoRestyleManager.cpp',
'StackArena.cpp',
'StaticPresData.cpp',

View File

@ -2406,12 +2406,12 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
GetRootFrame()->SetStyleContextWithoutNotification(sc);
}
// Make sure to call UpdateViewportScrollbarStylesOverride before
// Make sure to call UpdateViewportScrollStylesOverride before
// SetUpDocElementContainingBlock, since it sets up our scrollbar state
// properly.
DebugOnly<nsIContent*> propagatedScrollFrom;
if (nsPresContext* presContext = mPresShell->GetPresContext()) {
propagatedScrollFrom = presContext->UpdateViewportScrollbarStylesOverride();
propagatedScrollFrom = presContext->UpdateViewportScrollStylesOverride();
}
SetUpDocElementContainingBlock(aDocElement);
@ -4666,7 +4666,7 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
if (aElement->IsHTMLElement(nsGkAtoms::body)) {
if (nsPresContext* presContext = mPresShell->GetPresContext()) {
propagatedScrollToViewport =
presContext->UpdateViewportScrollbarStylesOverride() == aElement;
presContext->UpdateViewportScrollStylesOverride() == aElement;
}
}
@ -4702,7 +4702,7 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
// scrollframe so that it paginates correctly, but we don't want to set
// the bit on the block that tells it to clip at paint time.
if (mPresShell->GetPresContext()->
ElementWouldPropagateScrollbarStyles(aElement)) {
ElementWouldPropagateScrollStyles(aElement)) {
suppressScrollFrame = false;
}
}
@ -8139,7 +8139,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
// source is a fullscreen element, and we have code elsewhere to update
// scrollbars after fullscreen elements are removed -- specifically, it's
// part of the fullscreen cleanup code called by Element::UnbindFromTree.)
presContext->UpdateViewportScrollbarStylesOverride();
presContext->UpdateViewportScrollStylesOverride();
}
// XXXldb Do we need to re-resolve style to handle the CSS2 + combinator and

View File

@ -22,7 +22,7 @@
#include "nsCounterManager.h"
#include "nsIAnonymousContentCreator.h"
#include "nsFrameManager.h"
#include "ScrollbarStyles.h"
#include "ScrollStyles.h"
struct nsFrameItems;
class nsStyleContext;

View File

@ -225,7 +225,7 @@ enum nsChangeHint {
* scrollframe, this is instead equivalent to nsChangeHint_AllReflowHints
* (because the viewport always has an associated scrollframe).
*/
nsChangeHint_CSSOverflowChange = 1 << 28,
nsChangeHint_ScrollbarChange = 1 << 28,
// IMPORTANT NOTE: When adding new hints, consider whether you need
// to add them to NS_HintsNotHandledForDescendantsIn() below. Please
@ -316,7 +316,7 @@ inline nsChangeHint operator^=(nsChangeHint& aLeft, nsChangeHint aRight)
nsChangeHint_UpdatePostTransformOverflow | \
nsChangeHint_UpdateParentOverflow | \
nsChangeHint_ChildrenOnlyTransform | \
nsChangeHint_CSSOverflowChange | \
nsChangeHint_ScrollbarChange | \
nsChangeHint_RecomputePosition | \
nsChangeHint_UpdateContainingBlock | \
nsChangeHint_AddOrRemoveTransform | \

View File

@ -2028,7 +2028,7 @@ nsLayoutUtils::GetNearestScrollableFrameForDirection(nsIFrame* aFrame,
for (nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
nsIScrollableFrame* scrollableFrame = do_QueryFrame(f);
if (scrollableFrame) {
ScrollbarStyles ss = scrollableFrame->GetScrollbarStyles();
ScrollStyles ss = scrollableFrame->GetScrollStyles();
uint32_t directions = scrollableFrame->GetPerceivedScrollingDirections();
if (aDirection == eVertical ?
(ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN &&
@ -2055,7 +2055,7 @@ nsLayoutUtils::GetNearestScrollableFrame(nsIFrame* aFrame, uint32_t aFlags)
return scrollableFrame;
}
} else {
ScrollbarStyles ss = scrollableFrame->GetScrollbarStyles();
ScrollStyles ss = scrollableFrame->GetScrollStyles();
if ((aFlags & SCROLLABLE_INCLUDE_HIDDEN) ||
ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN ||
ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
@ -8260,11 +8260,11 @@ nsLayoutUtils::CalculateScrollableRectForFrame(nsIScrollableFrame* aScrollableFr
contentBounds = aScrollableFrame->GetScrollRange();
nsPoint scrollPosition = aScrollableFrame->GetScrollPosition();
if (aScrollableFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
if (aScrollableFrame->GetScrollStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
contentBounds.y = scrollPosition.y;
contentBounds.height = 0;
}
if (aScrollableFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
if (aScrollableFrame->GetScrollStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
contentBounds.x = scrollPosition.x;
contentBounds.width = 0;
}

View File

@ -1346,7 +1346,7 @@ nsPresContext::ScreenSizeInchesForFontInflation(bool* aChanged)
}
static bool
CheckOverflow(const nsStyleDisplay* aDisplay, ScrollbarStyles* aStyles)
CheckOverflow(const nsStyleDisplay* aDisplay, ScrollStyles* aStyles)
{
if (aDisplay->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE &&
aDisplay->mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_AUTO &&
@ -1362,17 +1362,17 @@ CheckOverflow(const nsStyleDisplay* aDisplay, ScrollbarStyles* aStyles)
}
if (aDisplay->mOverflowX == NS_STYLE_OVERFLOW_CLIP) {
*aStyles = ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN,
*aStyles = ScrollStyles(NS_STYLE_OVERFLOW_HIDDEN,
NS_STYLE_OVERFLOW_HIDDEN, aDisplay);
} else {
*aStyles = ScrollbarStyles(aDisplay);
*aStyles = ScrollStyles(aDisplay);
}
return true;
}
static nsIContent*
GetPropagatedScrollbarStylesForViewport(nsPresContext* aPresContext,
ScrollbarStyles *aStyles)
GetPropagatedScrollStylesForViewport(nsPresContext* aPresContext,
ScrollStyles *aStyles)
{
nsIDocument* document = aPresContext->Document();
Element* docElement = document->GetRootElement();
@ -1424,16 +1424,16 @@ GetPropagatedScrollbarStylesForViewport(nsPresContext* aPresContext,
}
nsIContent*
nsPresContext::UpdateViewportScrollbarStylesOverride()
nsPresContext::UpdateViewportScrollStylesOverride()
{
// Start off with our default styles, and then update them as needed.
mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_AUTO,
mViewportStyleScrollbar = ScrollStyles(NS_STYLE_OVERFLOW_AUTO,
NS_STYLE_OVERFLOW_AUTO);
mViewportScrollbarOverrideNode = nullptr;
// Don't propagate the scrollbar state in printing or print preview.
if (!IsPaginated()) {
mViewportScrollbarOverrideNode =
GetPropagatedScrollbarStylesForViewport(this, &mViewportStyleScrollbar);
GetPropagatedScrollStylesForViewport(this, &mViewportStyleScrollbar);
}
nsIDocument* document = Document();
@ -1445,7 +1445,7 @@ nsPresContext::UpdateViewportScrollbarStylesOverride()
// affected across fullscreen change.
if (fullscreenElement != document->GetRootElement() &&
fullscreenElement != mViewportScrollbarOverrideNode) {
mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN,
mViewportStyleScrollbar = ScrollStyles(NS_STYLE_OVERFLOW_HIDDEN,
NS_STYLE_OVERFLOW_HIDDEN);
}
}
@ -1454,7 +1454,7 @@ nsPresContext::UpdateViewportScrollbarStylesOverride()
}
bool
nsPresContext::ElementWouldPropagateScrollbarStyles(Element* aElement)
nsPresContext::ElementWouldPropagateScrollStyles(Element* aElement)
{
MOZ_ASSERT(IsPaginated(), "Should only be called on paginated contexts");
if (aElement->GetParent() && !aElement->IsHTMLElement(nsGkAtoms::body)) {
@ -1462,13 +1462,13 @@ nsPresContext::ElementWouldPropagateScrollbarStyles(Element* aElement)
return false;
}
// Go ahead and just call GetPropagatedScrollbarStylesForViewport, but update
// a dummy ScrollbarStyles we don't care about. It'll do a bit of extra work,
// Go ahead and just call GetPropagatedScrollStylesForViewport, but update
// a dummy ScrollStyles we don't care about. It'll do a bit of extra work,
// but saves us having to have more complicated code or more code duplication;
// in practice we will make this call quite rarely, because we checked for all
// the common cases above.
ScrollbarStyles dummy(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO);
return GetPropagatedScrollbarStylesForViewport(this, &dummy) == aElement;
ScrollStyles dummy(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO);
return GetPropagatedScrollStylesForViewport(this, &dummy) == aElement;
}
void

View File

@ -35,7 +35,7 @@
#include "mozilla/AppUnits.h"
#include "prclist.h"
#include "nsThreadUtils.h"
#include "ScrollbarStyles.h"
#include "ScrollStyles.h"
#include "nsIMessageManager.h"
#include "mozilla/RestyleLogging.h"
#include "Units.h"
@ -140,7 +140,7 @@ class nsPresContext : public nsIObserver,
public mozilla::SupportsWeakPtr<nsPresContext> {
public:
typedef mozilla::LangGroupFontPrefs LangGroupFontPrefs;
typedef mozilla::ScrollbarStyles ScrollbarStyles;
typedef mozilla::ScrollStyles ScrollStyles;
typedef mozilla::StaticPresData StaticPresData;
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -716,19 +716,19 @@ public:
* @return if scroll was propagated from some content node, the content node
* it was propagated from.
*/
nsIContent* UpdateViewportScrollbarStylesOverride();
nsIContent* UpdateViewportScrollStylesOverride();
/**
* Returns the cached result from the last call to
* UpdateViewportScrollbarStylesOverride() -- i.e. return the node
* UpdateViewportScrollStylesOverride() -- i.e. return the node
* whose scrollbar styles we have propagated to the viewport (or nullptr if
* there is no such node).
*/
nsIContent* GetViewportScrollbarStylesOverrideNode() const {
nsIContent* GetViewportScrollStylesOverrideNode() const {
return mViewportScrollbarOverrideNode;
}
const ScrollbarStyles& GetViewportScrollbarStylesOverride() const
const ScrollStyles& GetViewportScrollStylesOverride() const
{
return mViewportStyleScrollbar;
}
@ -737,7 +737,7 @@ public:
* Check whether the given element would propagate its scrollbar styles to the
* viewport in non-paginated mode. Must only be called if IsPaginated().
*/
bool ElementWouldPropagateScrollbarStyles(mozilla::dom::Element* aElement);
bool ElementWouldPropagateScrollStyles(mozilla::dom::Element* aElement);
/**
* Set and get methods for controlling the background drawing
@ -1312,13 +1312,13 @@ protected:
// This is a non-owning pointer. May be null. If non-null, it's guaranteed
// to be pointing to a node that's still alive, because we'll reset it in
// UpdateViewportScrollbarStylesOverride() as part of the cleanup code
// UpdateViewportScrollStylesOverride() as part of the cleanup code
// when this node is removed from the document. (For <body> and the root node,
// this call happens in nsCSSFrameConstructor::ContentRemoved(). For
// fullscreen elements, it happens in the fullscreen-specific cleanup
// invoked by Element::UnbindFromTree().)
nsIContent* MOZ_NON_OWNING_REF mViewportScrollbarOverrideNode;
ScrollbarStyles mViewportStyleScrollbar;
ScrollStyles mViewportStyleScrollbar;
uint8_t mFocusRingWidth;

View File

@ -3335,7 +3335,7 @@ static void ScrollToShowRect(nsIScrollableFrame* aFrameAsScrollable,
aHorizontal.mWhenToScroll == nsIPresShell::SCROLL_IF_NOT_VISIBLE) {
lineSize = aFrameAsScrollable->GetLineScrollAmount();
}
ScrollbarStyles ss = aFrameAsScrollable->GetScrollbarStyles();
ScrollStyles ss = aFrameAsScrollable->GetScrollStyles();
nsRect allowedRange(scrollPt, nsSize(0, 0));
bool needToScroll = false;
uint32_t directions = aFrameAsScrollable->GetPerceivedScrollingDirections();
@ -3392,7 +3392,7 @@ static void ScrollToShowRect(nsIScrollableFrame* aFrameAsScrollable,
// a current smooth scroll operation.
if (needToScroll) {
nsIScrollableFrame::ScrollMode scrollMode = nsIScrollableFrame::INSTANT;
bool autoBehaviorIsSmooth = (aFrameAsScrollable->GetScrollbarStyles().mScrollBehavior
bool autoBehaviorIsSmooth = (aFrameAsScrollable->GetScrollStyles().mScrollBehavior
== NS_STYLE_SCROLL_BEHAVIOR_SMOOTH);
bool smoothScroll = (aFlags & nsIPresShell::SCROLL_SMOOTH) ||
((aFlags & nsIPresShell::SCROLL_SMOOTH_AUTO) && autoBehaviorIsSmooth);

View File

@ -614,17 +614,17 @@ nsListControlFrame::ReflowAsDropdown(nsPresContext* aPresContext,
nsHTMLScrollFrame::Reflow(aPresContext, aDesiredSize, state, aStatus);
}
ScrollbarStyles
nsListControlFrame::GetScrollbarStyles() const
ScrollStyles
nsListControlFrame::GetScrollStyles() const
{
// We can't express this in the style system yet; when we can, this can go away
// and GetScrollbarStyles can be devirtualized
// and GetScrollStyles can be devirtualized
int32_t style = IsInDropDownMode() ? NS_STYLE_OVERFLOW_AUTO
: NS_STYLE_OVERFLOW_SCROLL;
if (GetWritingMode().IsVertical()) {
return ScrollbarStyles(style, NS_STYLE_OVERFLOW_HIDDEN);
return ScrollStyles(style, NS_STYLE_OVERFLOW_HIDDEN);
} else {
return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, style);
return ScrollStyles(NS_STYLE_OVERFLOW_HIDDEN, style);
}
}

View File

@ -106,7 +106,7 @@ public:
virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) override;
virtual void SetFocus(bool aOn = true, bool aRepaint = false) override;
virtual mozilla::ScrollbarStyles GetScrollbarStyles() const override;
virtual mozilla::ScrollStyles GetScrollStyles() const override;
virtual bool ShouldPropagateComputedBSizeToScrolledContent() const override;
// for accessibility purposes

View File

@ -305,8 +305,8 @@ TextOverflow::TextOverflow(nsDisplayListBuilder* aBuilder,
mCanHaveInlineAxisScrollbar = false;
if (mScrollableFrame) {
auto scrollbarStyle = mBlockWM.IsVertical() ?
mScrollableFrame->GetScrollbarStyles().mVertical :
mScrollableFrame->GetScrollbarStyles().mHorizontal;
mScrollableFrame->GetScrollStyles().mVertical :
mScrollableFrame->GetScrollStyles().mHorizontal;
mCanHaveInlineAxisScrollbar = scrollbarStyle != NS_STYLE_OVERFLOW_HIDDEN;
if (!mAdjustForPixelSnapping) {
// Scrolling to the end position can leave some text still overflowing due

View File

@ -9178,7 +9178,7 @@ nsIFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse)
// will be enough to make them keyboard scrollable.
nsIScrollableFrame *scrollFrame = do_QueryFrame(this);
if (scrollFrame &&
!scrollFrame->GetScrollbarStyles().IsHiddenInBothDirections() &&
!scrollFrame->GetScrollStyles().IsHiddenInBothDirections() &&
!scrollFrame->GetScrollRange().IsEqualEdges(nsRect(0, 0, 0, 0))) {
// Scroll bars will be used for overflow
isFocusable = true;

View File

@ -211,10 +211,32 @@ nsHTMLScrollFrame::GetType() const
namespace mozilla {
enum class ShowScrollbar : uint8_t
{
Auto,
Always,
Never,
};
static ShowScrollbar
ShouldShowScrollbar(uint8_t aOverflow)
{
switch (aOverflow) {
case NS_STYLE_OVERFLOW_SCROLL:
return ShowScrollbar::Always;
case NS_STYLE_OVERFLOW_HIDDEN:
return ShowScrollbar::Never;
default:
case NS_STYLE_OVERFLOW_AUTO:
return ShowScrollbar::Auto;
}
}
struct MOZ_STACK_CLASS ScrollReflowInput {
const ReflowInput& mReflowInput;
nsBoxLayoutState mBoxState;
ScrollbarStyles mStyles;
ShowScrollbar mHScrollbar;
ShowScrollbar mVScrollbar;
nsMargin mComputedBorder;
// === Filled in by ReflowScrolledFrame ===
@ -235,12 +257,15 @@ struct MOZ_STACK_CLASS ScrollReflowInput {
bool mShowVScrollbar;
ScrollReflowInput(nsIScrollableFrame* aFrame,
const ReflowInput& aState) :
mReflowInput(aState),
const ReflowInput& aState)
: mReflowInput(aState)
// mBoxState is just used for scrollbars so we don't need to
// worry about the reflow depth here
mBoxState(aState.mFrame->PresContext(), aState.mRenderingContext, 0),
mStyles(aFrame->GetScrollbarStyles()) {
, mBoxState(aState.mFrame->PresContext(), aState.mRenderingContext, 0)
{
ScrollStyles styles = aFrame->GetScrollStyles();
mHScrollbar = ShouldShowScrollbar(styles.mHorizontal);
mVScrollbar = ShouldShowScrollbar(styles.mVertical);
}
};
@ -328,8 +353,8 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowInput* aState,
bool aAssumeHScroll, bool aAssumeVScroll,
bool aForce)
{
if ((aState->mStyles.mVertical == NS_STYLE_OVERFLOW_HIDDEN && aAssumeVScroll) ||
(aState->mStyles.mHorizontal == NS_STYLE_OVERFLOW_HIDDEN && aAssumeHScroll)) {
if ((aState->mVScrollbar == ShowScrollbar::Never && aAssumeVScroll) ||
(aState->mHScrollbar == ShowScrollbar::Never && aAssumeHScroll)) {
NS_ASSERTION(!aForce, "Shouldn't be forcing a hidden scrollbar to show!");
return false;
}
@ -399,9 +424,9 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowInput* aState,
nscoord oneDevPixel = aState->mBoxState.PresContext()->DevPixelsToAppUnits(1);
// If the style is HIDDEN then we already know that aAssumeHScroll is false
if (aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
if (aState->mHScrollbar != ShowScrollbar::Never) {
bool wantHScrollbar =
aState->mStyles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL ||
aState->mHScrollbar == ShowScrollbar::Always ||
scrolledRect.XMost() >= visualScrollPortSize.width + oneDevPixel ||
scrolledRect.x <= -oneDevPixel;
if (scrollPortSize.width < hScrollbarMinSize.width)
@ -411,9 +436,9 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowInput* aState,
}
// If the style is HIDDEN then we already know that aAssumeVScroll is false
if (aState->mStyles.mVertical != NS_STYLE_OVERFLOW_HIDDEN) {
if (aState->mVScrollbar != ShowScrollbar::Never) {
bool wantVScrollbar =
aState->mStyles.mVertical == NS_STYLE_OVERFLOW_SCROLL ||
aState->mVScrollbar == ShowScrollbar::Always ||
scrolledRect.YMost() >= visualScrollPortSize.height + oneDevPixel ||
scrolledRect.y <= -oneDevPixel;
if (scrollPortSize.height < vScrollbarMinSize.height)
@ -597,19 +622,20 @@ nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowInput* aState,
bool
nsHTMLScrollFrame::GuessHScrollbarNeeded(const ScrollReflowInput& aState)
{
if (aState.mStyles.mHorizontal != NS_STYLE_OVERFLOW_AUTO)
// no guessing required
return aState.mStyles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL;
if (aState.mHScrollbar != ShowScrollbar::Auto) {
// No guessing required
return aState.mHScrollbar == ShowScrollbar::Always;
}
return mHelper.mHasHorizontalScrollbar;
}
bool
nsHTMLScrollFrame::GuessVScrollbarNeeded(const ScrollReflowInput& aState)
{
if (aState.mStyles.mVertical != NS_STYLE_OVERFLOW_AUTO)
// no guessing required
return aState.mStyles.mVertical == NS_STYLE_OVERFLOW_SCROLL;
if (aState.mVScrollbar != ShowScrollbar::Auto) {
// No guessing required
return aState.mVScrollbar == ShowScrollbar::Always;
}
// If we've had at least one non-initial reflow, then just assume
// the state of the vertical scrollbar will be what we determined
@ -684,8 +710,8 @@ nsHTMLScrollFrame::ReflowContents(ScrollReflowInput* aState,
// XXX Is this check really sufficient to catch all the incremental cases
// where the ideal case doesn't have a scrollbar?
if ((aState->mReflowedContentsWithHScrollbar || aState->mReflowedContentsWithVScrollbar) &&
aState->mStyles.mVertical != NS_STYLE_OVERFLOW_SCROLL &&
aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_SCROLL) {
aState->mVScrollbar != ShowScrollbar::Always &&
aState->mHScrollbar != ShowScrollbar::Always) {
nsSize insideBorderSize =
ComputeInsideBorderSize(aState,
nsSize(kidDesiredSize.Width(), kidDesiredSize.Height()));
@ -725,8 +751,8 @@ nsHTMLScrollFrame::ReflowContents(ScrollReflowInput* aState,
// enable and force the layout to stick even if it's inconsistent.
// This just happens sometimes.
TryLayout(aState, &kidDesiredSize,
aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN,
aState->mStyles.mVertical != NS_STYLE_OVERFLOW_HIDDEN,
aState->mHScrollbar != ShowScrollbar::Never,
aState->mVScrollbar != ShowScrollbar::Never,
true);
}
@ -782,7 +808,7 @@ nsHTMLScrollFrame::PlaceScrollArea(ScrollReflowInput& aState,
nscoord
nsHTMLScrollFrame::GetIntrinsicVScrollbarWidth(nsRenderingContext *aRenderingContext)
{
ScrollbarStyles ss = GetScrollbarStyles();
ScrollStyles ss = GetScrollStyles();
if (ss.mVertical != NS_STYLE_OVERFLOW_SCROLL || !mHelper.mVScrollbarBox)
return 0;
@ -982,10 +1008,10 @@ nsHTMLScrollFrame::AdjustForPerspective(nsRect& aScrollableOverflow)
}
void
nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus)
nsReflowStatus& aStatus)
{
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsHTMLScrollFrame");
@ -996,10 +1022,12 @@ nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
ScrollReflowInput state(this, aReflowInput);
// sanity check: ensure that if we have no scrollbar, we treat it
// as hidden.
if (!mHelper.mVScrollbarBox || mHelper.mNeverHasVerticalScrollbar)
state.mStyles.mVertical = NS_STYLE_OVERFLOW_HIDDEN;
if (!mHelper.mHScrollbarBox || mHelper.mNeverHasHorizontalScrollbar)
state.mStyles.mHorizontal = NS_STYLE_OVERFLOW_HIDDEN;
if (!mHelper.mVScrollbarBox || mHelper.mNeverHasVerticalScrollbar) {
state.mVScrollbar = ShowScrollbar::Never;
}
if (!mHelper.mHScrollbarBox || mHelper.mNeverHasHorizontalScrollbar) {
state.mHScrollbar = ShowScrollbar::Never;
}
//------------ Handle Incremental Reflow -----------------
bool reflowHScrollbar = true;
@ -1026,6 +1054,15 @@ nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
reflowScrollCorner = showResizer == mHelper.mCollapsedResizer;
mHelper.mCollapsedResizer = !showResizer;
}
// Hide the scrollbar when the scrollbar-width is set to none.
// This is only needed for root element because scrollbars of non-
// root elements with "scrollbar-width: none" is already suppressed
// in ScrollFrameHelper::CreateAnonymousContent.
if (this->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::None) {
state.mVScrollbar = ShowScrollbar::Never;
state.mHScrollbar = ShowScrollbar::Never;
}
}
nsRect oldScrollAreaBounds = mHelper.mScrollPort;
@ -1133,7 +1170,7 @@ nsHTMLScrollFrame::AccessibleType()
// Create an accessible regardless of focusable state because the state can be
// changed during frame life cycle without any notifications to accessibility.
if (mContent->IsRootOfNativeAnonymousSubtree() ||
GetScrollbarStyles().IsHiddenInBothDirections()) {
GetScrollStyles().IsHiddenInBothDirections()) {
return a11y::eNoType;
}
@ -1307,7 +1344,7 @@ ScrollFrameHelper::WantAsyncScroll() const
return true;
}
ScrollbarStyles styles = GetScrollbarStylesFromFrame();
ScrollStyles styles = GetScrollStylesFromFrame();
nscoord oneDevPixel = GetScrolledFrame()->PresContext()->AppUnitsPerDevPixel();
nsRect scrollRange = GetScrollRange();
bool isVScrollable = (scrollRange.height >= oneDevPixel) &&
@ -1562,7 +1599,7 @@ nsXULScrollFrame::GetXULPrefSize(nsBoxLayoutState& aState)
nsSize pref = mHelper.mScrolledFrame->GetXULPrefSize(aState);
ScrollbarStyles styles = GetScrollbarStyles();
ScrollStyles styles = GetScrollStyles();
// scrolled frames don't have their own margins
@ -1595,7 +1632,7 @@ nsXULScrollFrame::GetXULMinSize(nsBoxLayoutState& aState)
nsSize min = mHelper.mScrolledFrame->GetXULMinSizeForScrollArea(aState);
ScrollbarStyles styles = GetScrollbarStyles();
ScrollStyles styles = GetScrollStyles();
if (mHelper.mVScrollbarBox &&
styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) {
@ -2481,7 +2518,7 @@ bool ScrollFrameHelper::IsAlwaysActive() const
// If we're overflow:hidden, then start as inactive until
// we get scrolled manually.
ScrollbarStyles styles = GetScrollbarStylesFromFrame();
ScrollStyles styles = GetScrollStylesFromFrame();
return (styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN &&
styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN);
}
@ -3812,21 +3849,21 @@ static void HandleScrollPref(nsIScrollable *aScrollable, int32_t aOrientation,
}
}
ScrollbarStyles
ScrollFrameHelper::GetScrollbarStylesFromFrame() const
ScrollStyles
ScrollFrameHelper::GetScrollStylesFromFrame() const
{
nsPresContext* presContext = mOuter->PresContext();
if (!presContext->IsDynamic() &&
!(mIsRoot && presContext->HasPaginatedScrolling())) {
return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_HIDDEN);
return ScrollStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_HIDDEN);
}
if (!mIsRoot) {
const nsStyleDisplay* disp = mOuter->StyleDisplay();
return ScrollbarStyles(disp);
return ScrollStyles(disp);
}
ScrollbarStyles result = presContext->GetViewportScrollbarStylesOverride();
ScrollStyles result = presContext->GetViewportScrollStylesOverride();
nsCOMPtr<nsISupports> container = presContext->GetContainerWeak();
nsCOMPtr<nsIScrollable> scrollable = do_QueryInterface(container);
if (scrollable) {
@ -3995,7 +4032,7 @@ ScrollFrameHelper::ScrollBy(nsIntPoint aDelta,
nsPoint newPos = mDestination + nsPoint(aDelta.x*deltaMultiplier.width, aDelta.y*deltaMultiplier.height);
if (aSnap == nsIScrollableFrame::ENABLE_SNAP) {
ScrollbarStyles styles = GetScrollbarStylesFromFrame();
ScrollStyles styles = GetScrollStylesFromFrame();
if (styles.mScrollSnapTypeY != NS_STYLE_SCROLL_SNAP_TYPE_NONE ||
styles.mScrollSnapTypeX != NS_STYLE_SCROLL_SNAP_TYPE_NONE) {
nscoord appUnitsPerDevPixel = mOuter->PresContext()->AppUnitsPerDevPixel();
@ -4395,24 +4432,30 @@ ScrollFrameHelper::CreateAnonymousContent(
nsIScrollableFrame *scrollable = do_QueryFrame(mOuter);
// If we're the scrollframe for the root, then we want to construct
// our scrollbar frames no matter what. That way later dynamic
// changes to propagated overflow styles will show or hide
// scrollbars on the viewport without requiring frame reconstruction
// of the viewport (good!).
bool canHaveHorizontal;
bool canHaveVertical;
if (!mIsRoot) {
ScrollbarStyles styles = scrollable->GetScrollbarStyles();
canHaveHorizontal = styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN;
canHaveVertical = styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN;
if (mIsRoot) {
// If we're the scrollframe for the root, then we want to construct
// our scrollbar frames no matter what. That way, later dynamic
// changes to propagated overflow styles will show or hide
// scrollbars on the viewport without requiring frame reconstruction
// of the viewport (which is a Good Thing(tm)!).
canHaveHorizontal = true;
canHaveVertical = true;
} else {
if (mOuter->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::None) {
// If scrollbar-width is none, don't generate scrollbars.
canHaveHorizontal = false;
canHaveVertical = false;
} else {
ScrollStyles styles = scrollable->GetScrollStyles();
canHaveHorizontal = styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN;
canHaveVertical = styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN;
}
if (!canHaveHorizontal && !canHaveVertical && !isResizable) {
// Nothing to do.
return NS_OK;
}
} else {
canHaveHorizontal = true;
canHaveVertical = true;
}
// The anonymous <div> used by <inputs> never gets scrollbars.
@ -5085,7 +5128,7 @@ nsXULScrollFrame::XULLayout(nsBoxLayoutState& aState)
(if we're the viewport and we added or removed a scrollbar).
**************/
ScrollbarStyles styles = GetScrollbarStyles();
ScrollStyles styles = GetScrollStyles();
// Look at our style do we always have vertical or horizontal scrollbars?
if (styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL)
@ -5390,7 +5433,7 @@ bool
ScrollFrameHelper::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas)
{
nsIScrollableFrame* sf = do_QueryFrame(mOuter);
ScrollbarStyles ss = sf->GetScrollbarStyles();
ScrollStyles ss = sf->GetScrollStyles();
// Reflow when the change in overflow leads to one of our scrollbars
// changing or might require repositioning the scrolled content due to
@ -6112,7 +6155,7 @@ ComputeScrollSnapInfo(const ScrollFrameHelper& aScrollFrame)
{
ScrollSnapInfo result;
ScrollbarStyles styles = aScrollFrame.GetScrollbarStylesFromFrame();
ScrollStyles styles = aScrollFrame.GetScrollStylesFromFrame();
if (styles.mScrollSnapTypeY == NS_STYLE_SCROLL_SNAP_TYPE_NONE &&
styles.mScrollSnapTypeX == NS_STYLE_SCROLL_SNAP_TYPE_NONE) {

View File

@ -55,7 +55,7 @@ public:
ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot);
~ScrollFrameHelper();
mozilla::ScrollbarStyles GetScrollbarStylesFromFrame() const;
mozilla::ScrollStyles GetScrollStylesFromFrame() const;
// If a child frame was added or removed on the scrollframe,
// reload our child frame list.
@ -775,8 +775,8 @@ public:
virtual nsIFrame* GetScrolledFrame() const override {
return mHelper.GetScrolledFrame();
}
virtual mozilla::ScrollbarStyles GetScrollbarStyles() const override {
return mHelper.GetScrollbarStylesFromFrame();
virtual mozilla::ScrollStyles GetScrollStyles() const override {
return mHelper.GetScrollStylesFromFrame();
}
virtual uint32_t GetScrollbarVisibility() const override {
return mHelper.GetScrollbarVisibility();
@ -1199,8 +1199,8 @@ public:
virtual nsIFrame* GetScrolledFrame() const override {
return mHelper.GetScrolledFrame();
}
virtual mozilla::ScrollbarStyles GetScrollbarStyles() const override {
return mHelper.GetScrollbarStylesFromFrame();
virtual mozilla::ScrollStyles GetScrollStyles() const override {
return mHelper.GetScrollStylesFromFrame();
}
virtual uint32_t GetScrollbarVisibility() const override {
return mHelper.GetScrollbarVisibility();

View File

@ -12,7 +12,7 @@
#include "nsCoord.h"
#include "DisplayItemClip.h"
#include "ScrollbarStyles.h"
#include "ScrollStyles.h"
#include "mozilla/Maybe.h"
#include "mozilla/gfx/Point.h"
#include "nsIScrollbarMediator.h"
@ -63,7 +63,7 @@ public:
* or NS_STYLE_OVERFLOW_AUTO) governing the horizontal and vertical
* scrollbars for this frame.
*/
virtual mozilla::ScrollbarStyles GetScrollbarStyles() const = 0;
virtual mozilla::ScrollStyles GetScrollStyles() const = 0;
enum { HORIZONTAL = 0x01, VERTICAL = 0x02 };
/**

View File

@ -509,6 +509,7 @@ CSS_KEY(scrollbar, scrollbar)
CSS_KEY(scrollbar-small, scrollbar_small)
CSS_KEY(scrollbar-horizontal, scrollbar_horizontal)
CSS_KEY(scrollbar-vertical, scrollbar_vertical)
CSS_KEY(scrollbar-width, scrollbar_width)
CSS_KEY(se-resize, se_resize)
CSS_KEY(select-after, select_after)
CSS_KEY(select-all, select_all)

View File

@ -3709,6 +3709,16 @@ CSS_PROP_DISPLAY(
kScrollSnapTypeKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Discrete)
CSS_PROP_USERINTERFACE(
scrollbar-width,
scrollbar_width,
ScrollbarWidth,
CSS_PROPERTY_PARSE_VALUE,
"layout.css.scrollbar-width.enabled",
VARIANT_HK,
kScrollbarWidthKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Discrete)
CSS_PROP_DISPLAY(
shape-outside,
shape_outside,

View File

@ -2009,6 +2009,12 @@ const KTableEntry nsCSSProps::kScrollSnapTypeKTable[] = {
{ eCSSKeyword_UNKNOWN, -1 }
};
const KTableEntry nsCSSProps::kScrollbarWidthKTable[] = {
{ eCSSKeyword_auto, StyleScrollbarWidth::Auto },
{ eCSSKeyword_thin, StyleScrollbarWidth::Thin },
{ eCSSKeyword_none, StyleScrollbarWidth::None }
};
const KTableEntry nsCSSProps::kStackSizingKTable[] = {
{ eCSSKeyword_ignore, NS_STYLE_STACK_SIZING_IGNORE },
{ eCSSKeyword_stretch_to_fit, NS_STYLE_STACK_SIZING_STRETCH_TO_FIT },

View File

@ -856,6 +856,7 @@ public:
static const KTableEntry kRubyPositionKTable[];
static const KTableEntry kScrollBehaviorKTable[];
static const KTableEntry kScrollSnapTypeKTable[];
static const KTableEntry kScrollbarWidthKTable[];
static const KTableEntry kSpeakKTable[];
static const KTableEntry kSpeakHeaderKTable[];
static const KTableEntry kSpeakNumeralKTable[];

View File

@ -3305,6 +3305,16 @@ nsComputedDOMStyle::DoGetScrollSnapTypeY()
return val.forget();
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetScrollbarWidth()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mScrollbarWidth,
nsCSSProps::kScrollbarWidthKTable));
return val.forget();
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::GetScrollSnapPoints(const nsStyleCoord& aCoord)
{

View File

@ -492,6 +492,7 @@ private:
already_AddRefed<CSSValue> DoGetCursor();
already_AddRefed<CSSValue> DoGetForceBrokenImageIcon();
already_AddRefed<CSSValue> DoGetIMEMode();
already_AddRefed<CSSValue> DoGetScrollbarWidth();
already_AddRefed<CSSValue> DoGetUserFocus();
already_AddRefed<CSSValue> DoGetUserInput();
already_AddRefed<CSSValue> DoGetUserModify();

View File

@ -226,6 +226,7 @@ COMPUTED_STYLE_PROP(scroll_snap_points_x, ScrollSnapPointsX)
COMPUTED_STYLE_PROP(scroll_snap_points_y, ScrollSnapPointsY)
COMPUTED_STYLE_PROP(scroll_snap_type_x, ScrollSnapTypeX)
COMPUTED_STYLE_PROP(scroll_snap_type_y, ScrollSnapTypeY)
COMPUTED_STYLE_PROP(scrollbar_width, ScrollbarWidth)
COMPUTED_STYLE_PROP(shape_outside, ShapeOutside)
//// COMPUTED_STYLE_PROP(size, Size)
COMPUTED_STYLE_PROP(tab_size, TabSize)

View File

@ -424,7 +424,7 @@ static nsSize CalcViewportUnitsScale(nsPresContext* aPresContext)
nsIScrollableFrame* scrollFrame =
aPresContext->PresShell()->GetRootScrollFrameAsScrollable();
if (scrollFrame) {
ScrollbarStyles styles(scrollFrame->GetScrollbarStyles());
ScrollStyles styles(scrollFrame->GetScrollStyles());
if (styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL ||
styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) {
@ -1394,6 +1394,7 @@ struct SetEnumValueHelper
DEFINE_ENUM_CLASS_SETTER(StyleFillRule, Nonzero, Evenodd)
DEFINE_ENUM_CLASS_SETTER(StyleFloat, None, InlineEnd)
DEFINE_ENUM_CLASS_SETTER(StyleFloatEdge, ContentBox, MarginBox)
DEFINE_ENUM_CLASS_SETTER(StyleScrollbarWidth, Auto, None)
DEFINE_ENUM_CLASS_SETTER(StyleTextJustify, None, InterCharacter)
DEFINE_ENUM_CLASS_SETTER(StyleUserFocus, None, SelectMenu)
DEFINE_ENUM_CLASS_SETTER(StyleUserSelect, None, MozText)
@ -5235,6 +5236,14 @@ nsRuleNode::ComputeUserInterfaceData(void* aStartStruct,
// caret-color: auto, color, inherit
setComplexColor(aRuleData->ValueForCaretColor(),
&nsStyleUserInterface::mCaretColor);
// scrollbar-width: auto, thin, none
SetValue(*aRuleData->ValueForScrollbarWidth(),
ui->mScrollbarWidth,
conditions,
SETVAL_ENUMERATED,
parentUI->mScrollbarWidth,
StyleScrollbarWidth::Auto);
COMPUTE_END_INHERITED(UserInterface, ui)
}

View File

@ -187,6 +187,13 @@ enum class StyleFloatEdge : uint8_t {
MarginBox,
};
// scrollbar-width
enum class StyleScrollbarWidth : uint8_t {
Auto,
Thin,
None,
};
// shape-box for shape-outside
enum class StyleShapeOutsideShapeBox : uint8_t {
NoBox,

View File

@ -3264,7 +3264,7 @@ nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const
if (mOverflowX != aNewData.mOverflowX
|| mOverflowY != aNewData.mOverflowY) {
hint |= nsChangeHint_CSSOverflowChange;
hint |= nsChangeHint_ScrollbarChange;
}
/* Note: When mScrollBehavior, mScrollSnapTypeX, mScrollSnapTypeY,
@ -4024,6 +4024,7 @@ nsStyleUserInterface::nsStyleUserInterface(StyleStructContext aContext)
, mPointerEvents(NS_STYLE_POINTER_EVENTS_AUTO)
, mCursor(NS_STYLE_CURSOR_AUTO)
, mCaretColor(StyleComplexColor::Auto())
, mScrollbarWidth(StyleScrollbarWidth::Auto)
{
MOZ_COUNT_CTOR(nsStyleUserInterface);
}
@ -4036,6 +4037,7 @@ nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface& aSource)
, mCursor(aSource.mCursor)
, mCursorImages(aSource.mCursorImages)
, mCaretColor(aSource.mCaretColor)
, mScrollbarWidth(aSource.mScrollbarWidth)
{
MOZ_COUNT_CTOR(nsStyleUserInterface);
}
@ -4087,6 +4089,13 @@ nsStyleUserInterface::CalcDifference(const nsStyleUserInterface& aNewData) const
if (mCaretColor != aNewData.mCaretColor) {
hint |= nsChangeHint_RepaintFrame;
}
if (mScrollbarWidth != aNewData.mScrollbarWidth) {
// For scrollbar-width change, we need some special handling similar
// to overflow properties. Specifically, we may need to reconstruct
// the scrollbar or force reflow of the viewport scrollbar.
hint |= nsChangeHint_ScrollbarChange;
}
return hint;
}

View File

@ -3417,6 +3417,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUserInterface
uint8_t mCursor; // [inherited] See nsStyleConsts.h
nsTArray<nsCursorImage> mCursorImages; // [inherited] images and coords
mozilla::StyleComplexColor mCaretColor; // [inherited]
mozilla::StyleScrollbarWidth mScrollbarWidth;
inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
};

View File

@ -7944,6 +7944,18 @@ for (var prop in gCSSProperties) {
}
}
if (IsCSSPropertyPrefEnabled("layout.css.scrollbar-width.enabled")) {
gCSSProperties["scrollbar-width"] = {
domProp: "scrollbarWidth",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "auto" ],
other_values: [ "none", "thin" ],
invalid_values: [ "1px" ]
};
}
if (false) {
// TODO These properties are chrome-only, and are not exposed via CSSOM.
// We may still want to find a way to test them. See bug 1206999.

View File

@ -296,7 +296,7 @@ nsListBoxBodyFrame::GetXULMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState
result.height = 0;
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(this);
if (scrollFrame &&
scrollFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_AUTO) {
scrollFrame->GetScrollStyles().mVertical == NS_STYLE_OVERFLOW_AUTO) {
nsMargin scrollbars =
scrollFrame->GetDesiredScrollbarSizes(&aBoxLayoutState);
result.width += scrollbars.left + scrollbars.right;
@ -316,7 +316,7 @@ nsListBoxBodyFrame::GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState)
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(this);
if (scrollFrame &&
scrollFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_AUTO) {
scrollFrame->GetScrollStyles().mVertical == NS_STYLE_OVERFLOW_AUTO) {
nsMargin scrollbars = scrollFrame->GetDesiredScrollbarSizes(&aBoxLayoutState);
pref.width += scrollbars.left + scrollbars.right;
}

View File

@ -2483,6 +2483,9 @@ pref("layout.css.isolation.enabled", true);
// Is support for CSS Filters enabled?
pref("layout.css.filters.enabled", true);
// Is support for scrollbar-width property enabled?
pref("layout.css.scrollbar-width.enabled", false);
// Set the threshold distance in CSS pixels below which scrolling will snap to
// an edge, when scroll snapping is set to "proximity".
pref("layout.css.scroll-snap.proximity-threshold", 200);

View File

@ -72,8 +72,6 @@ thumb[orient="horizontal"] {
scrollbarbutton {
background: -moz-Dialog no-repeat 50% 50%;
min-width: 16px;
min-height: 16px;
}
scrollbarbutton:hover:active, scrollbarbutton[active="true"] {

View File

@ -2279,6 +2279,12 @@ IsHiDPIContext(nsPresContext* aContext)
2 * aContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
}
static bool
IsScrollbarWidthThin(nsIFrame* aFrame)
{
return aFrame->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::Thin;
}
NS_IMETHODIMP
nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame,
@ -3392,9 +3398,10 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext,
// Find our parent scrollbar frame in order to find out whether we're in
// a small or a large scrollbar.
nsIFrame *scrollbarFrame = GetParentScrollbarFrame(aFrame);
if (!scrollbarFrame)
if (!scrollbarFrame) {
return NS_ERROR_FAILURE;
}
bool isSmall = (scrollbarFrame->StyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL);
bool isHorizontal = (aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL);
int32_t& minSize = isHorizontal ? aResult->width : aResult->height;
@ -3419,6 +3426,9 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext,
else {
aResult->SizeTo(16, 16);
}
if (IsScrollbarWidthThin(aFrame)) {
aResult->SizeTo(8, 8);
}
break;
}
@ -3435,6 +3445,9 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext,
kThemeMetricScrollBarWidth;
SInt32 scrollbarWidth = 0;
::GetThemeMetric(themeMetric, &scrollbarWidth);
if (IsScrollbarWidthThin(aFrame)) {
scrollbarWidth /= 2;
}
aResult->SizeTo(scrollbarWidth, scrollbarWidth);
break;
}
@ -3467,22 +3480,26 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext,
case NS_THEME_SCROLLBARBUTTON_LEFT:
case NS_THEME_SCROLLBARBUTTON_RIGHT:
{
nsIFrame *scrollbarFrame = GetParentScrollbarFrame(aFrame);
if (!scrollbarFrame) return NS_ERROR_FAILURE;
if (!IsScrollbarWidthThin(aFrame)) {
// Get scrollbar button metrics from the system, except in the case of
// thin scrollbars, where we leave them at 0 (collapse)
// Since there is no NS_THEME_SCROLLBARBUTTON_UP_SMALL we need to ask the parent what appearance style it has.
int32_t themeMetric = (scrollbarFrame->StyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL) ?
kThemeMetricSmallScrollBarWidth :
kThemeMetricScrollBarWidth;
SInt32 scrollbarWidth = 0;
::GetThemeMetric(themeMetric, &scrollbarWidth);
nsIFrame *scrollbarFrame = GetParentScrollbarFrame(aFrame);
if (!scrollbarFrame) return NS_ERROR_FAILURE;
// It seems that for both sizes of scrollbar, the buttons are one pixel "longer".
if (aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT || aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT)
aResult->SizeTo(scrollbarWidth+1, scrollbarWidth);
else
aResult->SizeTo(scrollbarWidth, scrollbarWidth+1);
// Since there is no NS_THEME_SCROLLBARBUTTON_UP_SMALL we need to ask the parent what appearance style it has.
int32_t themeMetric = (scrollbarFrame->StyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL) ?
kThemeMetricSmallScrollBarWidth :
kThemeMetricScrollBarWidth;
SInt32 scrollbarWidth = 0;
::GetThemeMetric(themeMetric, &scrollbarWidth);
// It seems that for both sizes of scrollbar, the buttons are one pixel "longer".
if (aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT || aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT)
aResult->SizeTo(scrollbarWidth+1, scrollbarWidth);
else
aResult->SizeTo(scrollbarWidth, scrollbarWidth+1);
}
*aIsOverridable = false;
break;
}

View File

@ -1098,6 +1098,12 @@ nsNativeThemeGTK::GetExtraSizeForWidget(nsIFrame* aFrame, uint8_t aWidgetType,
return true;
}
static bool
IsScrollbarWidthThin(nsIFrame* aFrame)
{
return aFrame->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::Thin;
}
NS_IMETHODIMP
nsNativeThemeGTK::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame,
@ -1419,32 +1425,39 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
case NS_THEME_SCROLLBARBUTTON_UP:
case NS_THEME_SCROLLBARBUTTON_DOWN:
{
if (gtk_check_version(3,20,0) == nullptr) {
moz_gtk_get_widget_min_size(MOZ_GTK_SCROLLBAR_BUTTON,
&(aResult->width), &(aResult->height));
} else {
MozGtkScrollbarMetrics metrics;
moz_gtk_get_scrollbar_metrics(&metrics);
if (!IsScrollbarWidthThin(aFrame)) {
// Get scrollbar button metrics from the system, except in the case of
// thin scrollbars, where we leave them at 0 (collapse)
if (gtk_check_version(3,20,0) == nullptr) {
moz_gtk_get_widget_min_size(MOZ_GTK_SCROLLBAR_BUTTON,
&(aResult->width), &(aResult->height));
} else {
MozGtkScrollbarMetrics metrics;
moz_gtk_get_scrollbar_metrics(&metrics);
aResult->width = metrics.slider_width;
aResult->height = metrics.stepper_size;
aResult->width = metrics.slider_width;
aResult->height = metrics.stepper_size;
}
}
*aIsOverridable = false;
}
break;
case NS_THEME_SCROLLBARBUTTON_LEFT:
case NS_THEME_SCROLLBARBUTTON_RIGHT:
{
if (gtk_check_version(3,20,0) == nullptr) {
moz_gtk_get_widget_min_size(MOZ_GTK_SCROLLBAR_BUTTON,
&(aResult->width), &(aResult->height));
} else {
MozGtkScrollbarMetrics metrics;
moz_gtk_get_scrollbar_metrics(&metrics);
if (!IsScrollbarWidthThin(aFrame)) {
// Get scrollbar button metrics from the system, except in the case of
// thin scrollbars, where we leave them at 0 (collapse)
if (gtk_check_version(3,20,0) == nullptr) {
moz_gtk_get_widget_min_size(MOZ_GTK_SCROLLBAR_BUTTON,
&(aResult->width), &(aResult->height));
} else {
MozGtkScrollbarMetrics metrics;
moz_gtk_get_scrollbar_metrics(&metrics);
aResult->width = metrics.stepper_size;
aResult->height = metrics.slider_width;
aResult->width = metrics.stepper_size;
aResult->height = metrics.slider_width;
}
}
*aIsOverridable = false;
}
@ -1514,6 +1527,24 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
}
break;
case NS_THEME_SCROLLBARTHUMB_VERTICAL:
{
if (gtk_check_version(3,20,0) == nullptr) {
moz_gtk_get_widget_min_size(NativeThemeToGtkTheme(aWidgetType, aFrame),
&(aResult->width), &(aResult->height));
} else {
MozGtkScrollbarMetrics metrics;
moz_gtk_get_scrollbar_metrics(&metrics);
aResult->width = metrics.slider_width;
aResult->height = metrics.min_slider_size;
}
if (IsScrollbarWidthThin(aFrame)) {
// If thin scrollbars, divide the thickness by 3
aResult->width /= 3;
}
*aIsOverridable = false;
}
break;
case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
{
if (gtk_check_version(3,20,0) == nullptr) {
@ -1523,13 +1554,12 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
MozGtkScrollbarMetrics metrics;
moz_gtk_get_scrollbar_metrics(&metrics);
if (aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL) {
aResult->width = metrics.slider_width;
aResult->height = metrics.min_slider_size;
} else {
aResult->height = metrics.slider_width;
aResult->width = metrics.min_slider_size;
}
aResult->height = metrics.slider_width;
aResult->width = metrics.min_slider_size;
}
if (IsScrollbarWidthThin(aFrame)) {
// If thin scrollbars, divide the thickness by 3
aResult->height /= 3;
}
*aIsOverridable = false;
}

View File

@ -1569,6 +1569,12 @@ GetThemeDpiScaleFactor(nsIFrame* aFrame)
return 1.0;
}
static bool
IsScrollbarWidthThin(nsIFrame* aFrame)
{
return aFrame->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::Thin;
}
NS_IMETHODIMP
nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame,
@ -2999,14 +3005,21 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIFrame* aFrame,
break;
case NS_THEME_SCROLLBARBUTTON_UP:
case NS_THEME_SCROLLBARBUTTON_DOWN:
(*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
(*aResult).height = ::GetSystemMetrics(SM_CYVSCROLL);
// Get scrollbar button metrics from the system, except in the case of
// thin scrollbars, where we leave them at 0 (collapsing them to invisible)
if (!IsScrollbarWidthThin(aFrame)) {
(*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
(*aResult).height = ::GetSystemMetrics(SM_CYVSCROLL);
}
*aIsOverridable = false;
break;
case NS_THEME_SCROLLBARBUTTON_LEFT:
case NS_THEME_SCROLLBARBUTTON_RIGHT:
(*aResult).width = ::GetSystemMetrics(SM_CXHSCROLL);
(*aResult).height = ::GetSystemMetrics(SM_CYHSCROLL);
// See comment above.
if (!IsScrollbarWidthThin(aFrame)) {
(*aResult).width = ::GetSystemMetrics(SM_CXHSCROLL);
(*aResult).height = ::GetSystemMetrics(SM_CYHSCROLL);
}
*aIsOverridable = false;
break;
case NS_THEME_SCROLLBAR_VERTICAL:
@ -3082,8 +3095,14 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIFrame* aFrame,
(*aResult).height = ::GetSystemMetrics(SM_CYVTHUMB);
// Without theming, divide the thumb size by two in order to look more
// native
if (!GetTheme(aWidgetType))
(*aResult).height >>= 1;
if (!GetTheme(aWidgetType)) {
(*aResult).height /= 2;
}
// If scrollbar-width is thin, divide the thickness by three to make
// it more compact.
if (IsScrollbarWidthThin(aFrame)) {
(*aResult).width /= 3;
}
*aIsOverridable = false;
break;
case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
@ -3091,8 +3110,14 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIFrame* aFrame,
(*aResult).height = ::GetSystemMetrics(SM_CYHSCROLL);
// Without theming, divide the thumb size by two in order to look more
// native
if (!GetTheme(aWidgetType))
(*aResult).width >>= 1;
if (!GetTheme(aWidgetType)) {
(*aResult).width /= 2;
}
// If scrollbar-width is thin, divide the thickness by three to make
// it more compact.
if (IsScrollbarWidthThin(aFrame)) {
(*aResult).height /= 3;
}
*aIsOverridable = false;
break;
case NS_THEME_SCROLLBAR_HORIZONTAL: