Issue #2765 - Part 1: Scrollbar width should be treated as a non-inherited property

Note: non-inherited properties are stored in "reset" style structs.

Previous implementation treats it as an inherited property, which
doesn't match the spec.

This also fixes the incorrect behavior when using the `unset` value
for this property by specifying SETVAL_UNSET_INITIAL in the mask.
This commit is contained in:
Francis Dominic Fajardo 2025-06-25 15:42:59 +08:00 • committed by roytam1
commit 8236eec152
7 changed files with 24 additions and 24 deletions

View file

@ -1058,7 +1058,7 @@ nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
// This is only needed for root element because scrollbars of non- // This is only needed for root element because scrollbars of non-
// root elements with "scrollbar-width: none" is already suppressed // root elements with "scrollbar-width: none" is already suppressed
// in ScrollFrameHelper::CreateAnonymousContent. // in ScrollFrameHelper::CreateAnonymousContent.
if (this->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::None) { if (this->StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::None) {
state.mVScrollbar = ShowScrollbar::Never; state.mVScrollbar = ShowScrollbar::Never;
state.mHScrollbar = ShowScrollbar::Never; state.mHScrollbar = ShowScrollbar::Never;
} }
@ -4415,7 +4415,7 @@ ScrollFrameHelper::CreateAnonymousContent(
canHaveHorizontal = true; canHaveHorizontal = true;
canHaveVertical = true; canHaveVertical = true;
} else { } else {
if (mOuter->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::None) { if (mOuter->StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::None) {
// If scrollbar-width is none, don't generate scrollbars. // If scrollbar-width is none, don't generate scrollbars.
canHaveHorizontal = false; canHaveHorizontal = false;
canHaveVertical = false; canHaveVertical = false;
@ -4448,7 +4448,7 @@ ScrollFrameHelper::CreateAnonymousContent(
kNameSpaceID_XUL, kNameSpaceID_XUL,
nsIDOMNode::ELEMENT_NODE); nsIDOMNode::ELEMENT_NODE);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
StyleScrollbarWidth scrollWidth = mOuter->StyleUserInterface()->mScrollbarWidth; StyleScrollbarWidth scrollWidth = mOuter->StyleUIReset()->mScrollbarWidth;
if (canHaveHorizontal) { if (canHaveHorizontal) {
RefPtr<NodeInfo> ni = nodeInfo; RefPtr<NodeInfo> ni = nodeInfo;

View file

@ -3723,7 +3723,7 @@ CSS_PROP_DISPLAY(
kScrollSnapTypeKTable, kScrollSnapTypeKTable,
CSS_PROP_NO_OFFSET, CSS_PROP_NO_OFFSET,
eStyleAnimType_Discrete) eStyleAnimType_Discrete)
CSS_PROP_USERINTERFACE( CSS_PROP_UIRESET(
scrollbar-width, scrollbar-width,
scrollbar_width, scrollbar_width,
ScrollbarWidth, ScrollbarWidth,

View file

@ -3302,7 +3302,7 @@ nsComputedDOMStyle::DoGetScrollbarWidth()
{ {
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetIdent( val->SetIdent(
nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mScrollbarWidth, nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mScrollbarWidth,
nsCSSProps::kScrollbarWidthKTable)); nsCSSProps::kScrollbarWidthKTable));
return val.forget(); return val.forget();
} }

View file

@ -5378,14 +5378,6 @@ nsRuleNode::ComputeUserInterfaceData(void* aStartStruct,
setComplexColor(aRuleData->ValueForCaretColor(), setComplexColor(aRuleData->ValueForCaretColor(),
&nsStyleUserInterface::mCaretColor); &nsStyleUserInterface::mCaretColor);
// scrollbar-width: auto, thin, none
SetValue(*aRuleData->ValueForScrollbarWidth(),
ui->mScrollbarWidth,
conditions,
SETVAL_ENUMERATED,
parentUI->mScrollbarWidth,
StyleScrollbarWidth::Auto);
COMPUTE_END_INHERITED(UserInterface, ui) COMPUTE_END_INHERITED(UserInterface, ui)
} }
@ -5434,6 +5426,14 @@ nsRuleNode::ComputeUIResetData(void* aStartStruct,
parentUI->mWindowShadow, parentUI->mWindowShadow,
NS_STYLE_WINDOW_SHADOW_DEFAULT); NS_STYLE_WINDOW_SHADOW_DEFAULT);
// scrollbar-width: auto, thin, none
SetValue(*aRuleData->ValueForScrollbarWidth(),
ui->mScrollbarWidth,
conditions,
SETVAL_ENUMERATED | SETVAL_UNSET_INITIAL,
parentUI->mScrollbarWidth,
StyleScrollbarWidth::Auto);
COMPUTE_END_RESET(UIReset, ui) COMPUTE_END_RESET(UIReset, ui)
} }

View file

@ -3924,7 +3924,6 @@ nsStyleUserInterface::nsStyleUserInterface(nsPresContext* aContext)
, mPointerEvents(NS_STYLE_POINTER_EVENTS_AUTO) , mPointerEvents(NS_STYLE_POINTER_EVENTS_AUTO)
, mCursor(NS_STYLE_CURSOR_AUTO) , mCursor(NS_STYLE_CURSOR_AUTO)
, mCaretColor(StyleComplexColor::Auto()) , mCaretColor(StyleComplexColor::Auto())
, mScrollbarWidth(StyleScrollbarWidth::Auto)
{ {
MOZ_COUNT_CTOR(nsStyleUserInterface); MOZ_COUNT_CTOR(nsStyleUserInterface);
} }
@ -3937,7 +3936,6 @@ nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface& aSource)
, mCursor(aSource.mCursor) , mCursor(aSource.mCursor)
, mCursorImages(aSource.mCursorImages) , mCursorImages(aSource.mCursorImages)
, mCaretColor(aSource.mCaretColor) , mCaretColor(aSource.mCaretColor)
, mScrollbarWidth(aSource.mScrollbarWidth)
{ {
MOZ_COUNT_CTOR(nsStyleUserInterface); MOZ_COUNT_CTOR(nsStyleUserInterface);
} }
@ -3990,13 +3988,6 @@ nsStyleUserInterface::CalcDifference(const nsStyleUserInterface& aNewData) const
hint |= nsChangeHint_RepaintFrame; 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; return hint;
} }
@ -4010,6 +4001,7 @@ nsStyleUIReset::nsStyleUIReset(nsPresContext* aContext)
, mIMEMode(NS_STYLE_IME_MODE_AUTO) , mIMEMode(NS_STYLE_IME_MODE_AUTO)
, mWindowDragging(StyleWindowDragging::Default) , mWindowDragging(StyleWindowDragging::Default)
, mWindowShadow(NS_STYLE_WINDOW_SHADOW_DEFAULT) , mWindowShadow(NS_STYLE_WINDOW_SHADOW_DEFAULT)
, mScrollbarWidth(StyleScrollbarWidth::Auto)
{ {
MOZ_COUNT_CTOR(nsStyleUIReset); MOZ_COUNT_CTOR(nsStyleUIReset);
} }
@ -4020,6 +4012,7 @@ nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource)
, mIMEMode(aSource.mIMEMode) , mIMEMode(aSource.mIMEMode)
, mWindowDragging(aSource.mWindowDragging) , mWindowDragging(aSource.mWindowDragging)
, mWindowShadow(aSource.mWindowShadow) , mWindowShadow(aSource.mWindowShadow)
, mScrollbarWidth(aSource.mScrollbarWidth)
{ {
MOZ_COUNT_CTOR(nsStyleUIReset); MOZ_COUNT_CTOR(nsStyleUIReset);
} }
@ -4050,6 +4043,13 @@ nsStyleUIReset::CalcDifference(const nsStyleUIReset& aNewData) const
return nsChangeHint_SchedulePaint; return nsChangeHint_SchedulePaint;
} }
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.
return nsChangeHint_ScrollbarChange;
}
return nsChangeHint(0); return nsChangeHint(0);
} }

View file

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

View file

@ -1572,7 +1572,7 @@ GetThemeDpiScaleFactor(nsIFrame* aFrame)
static bool static bool
IsScrollbarWidthThin(nsIFrame* aFrame) IsScrollbarWidthThin(nsIFrame* aFrame)
{ {
return aFrame->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::Thin; return aFrame->StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::Thin;
} }
NS_IMETHODIMP NS_IMETHODIMP