зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1741774 - Support scrollbar-gutter in the style system. r=emilio
This patch adds `scrollbar-gutter` property in CSS Overflow level 3 [1] to the style system. `devtools/shared/css/generated/properties-db.js` is generated by `./mach devtools-css-db`. [1] https://drafts.csswg.org/css-overflow-3/#scrollbar-gutter-property Differential Revision: https://phabricator.services.mozilla.com/D131460
This commit is contained in:
Родитель
ca1b688007
Коммит
5d4998ecf4
|
@ -140,6 +140,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
|||
"scroll-snap-align",
|
||||
"scroll-snap-type",
|
||||
"shape-rendering",
|
||||
"scrollbar-gutter",
|
||||
"scrollbar-width",
|
||||
"stroke-linecap",
|
||||
"stroke-linejoin",
|
||||
|
|
|
@ -2866,6 +2866,7 @@ exports.CSS_PROPERTIES = {
|
|||
"shape-outside",
|
||||
"touch-action",
|
||||
"-webkit-line-clamp",
|
||||
"scrollbar-gutter",
|
||||
"column-width",
|
||||
"column-count",
|
||||
"column-fill",
|
||||
|
@ -11007,6 +11008,10 @@ exports.PREFERENCES = [
|
|||
"overflow-anchor",
|
||||
"layout.css.scroll-anchoring.enabled"
|
||||
],
|
||||
[
|
||||
"scrollbar-gutter",
|
||||
"layout.css.scrollbar-gutter.enabled"
|
||||
],
|
||||
[
|
||||
"touch-action",
|
||||
"layout.css.touch_action.enabled"
|
||||
|
|
|
@ -586,6 +586,7 @@ cbindgen-types = [
|
|||
{ gecko = "StylePageSize", servo = "crate::values::computed::page::PageSize" },
|
||||
{ gecko = "StyleDProperty", servo = "crate::values::specified::svg::DProperty" },
|
||||
{ gecko = "StyleImageRendering", servo = "crate::values::computed::ImageRendering" },
|
||||
{ gecko = "StyleScrollbarGutter", servo = "crate::values::computed::ScrollbarGutter" },
|
||||
]
|
||||
|
||||
mapped-generic-types = [
|
||||
|
|
|
@ -2198,6 +2198,7 @@ nsStyleDisplay::nsStyleDisplay(const Document& aDocument)
|
|||
mOverflowY(StyleOverflow::Visible),
|
||||
mOverflowClipBoxBlock(StyleOverflowClipBox::PaddingBox),
|
||||
mOverflowClipBoxInline(StyleOverflowClipBox::PaddingBox),
|
||||
mScrollbarGutter(StyleScrollbarGutter::AUTO),
|
||||
mResize(StyleResize::None),
|
||||
mOrient(StyleOrient::Inline),
|
||||
mIsolation(StyleIsolation::Auto),
|
||||
|
@ -2269,6 +2270,7 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
|
|||
mOverflowY(aSource.mOverflowY),
|
||||
mOverflowClipBoxBlock(aSource.mOverflowClipBoxBlock),
|
||||
mOverflowClipBoxInline(aSource.mOverflowClipBoxInline),
|
||||
mScrollbarGutter(aSource.mScrollbarGutter),
|
||||
mResize(aSource.mResize),
|
||||
mOrient(aSource.mOrient),
|
||||
mIsolation(aSource.mIsolation),
|
||||
|
@ -2462,6 +2464,17 @@ nsChangeHint nsStyleDisplay::CalcDifference(
|
|||
}
|
||||
}
|
||||
|
||||
if (mScrollbarGutter != aNewData.mScrollbarGutter) {
|
||||
if (IsScrollableOverflow()) {
|
||||
// Changing scrollbar-gutter affects available inline-size of a inner
|
||||
// scrolled frame, so we need a reflow for scrollbar change.
|
||||
hint |= nsChangeHint_ReflowHintsForScrollbarChange;
|
||||
} else {
|
||||
// scrollbar-gutter only applies to the scroll containers.
|
||||
hint |= nsChangeHint_NeutralChange;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: When mScrollBehavior or mScrollSnapType are changed,
|
||||
* nsChangeHint_NeutralChange is not sufficient to enter
|
||||
* nsCSSFrameConstructor::PropagateScrollToViewport. By using the same hint as
|
||||
|
|
|
@ -1229,6 +1229,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
mozilla::StyleOverflow mOverflowY;
|
||||
mozilla::StyleOverflowClipBox mOverflowClipBoxBlock;
|
||||
mozilla::StyleOverflowClipBox mOverflowClipBoxInline;
|
||||
mozilla::StyleScrollbarGutter mScrollbarGutter;
|
||||
mozilla::StyleResize mResize;
|
||||
mozilla::StyleOrient mOrient;
|
||||
mozilla::StyleIsolation mIsolation;
|
||||
|
|
|
@ -19,6 +19,7 @@ prefs =
|
|||
layout.css.fit-content-function.enabled=true
|
||||
layout.css.d-property.enabled=true
|
||||
layout.css.scroll-linked-animations=true
|
||||
layout.css.scrollbar-gutter.enabled=true
|
||||
support-files =
|
||||
animation_utils.js
|
||||
bug1729861.js
|
||||
|
|
|
@ -13454,6 +13454,30 @@ if (IsCSSPropertyPrefEnabled("layout.css.scroll-linked-animations.enabled")) {
|
|||
};
|
||||
}
|
||||
|
||||
if (IsCSSPropertyPrefEnabled("layout.css.scrollbar-gutter.enabled")) {
|
||||
gCSSProperties["scrollbar-gutter"] = {
|
||||
domProp: "scrollbarGutter",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: ["auto"],
|
||||
other_values: ["stable", "stable both-edges", "both-edges stable"],
|
||||
invalid_values: [
|
||||
"auto stable",
|
||||
"auto both-edges",
|
||||
"both-edges",
|
||||
"stable mirror",
|
||||
// The following values are from scrollbar-gutter extension in CSS
|
||||
// Overflow 4 https://drafts.csswg.org/css-overflow-4/#sbg-ext.
|
||||
"always",
|
||||
"always both-edges",
|
||||
"always force",
|
||||
"always both-edges force",
|
||||
"stable both-edges force",
|
||||
"match-parent",
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
// Copy aliased properties' fields from their alias targets. Keep this logic
|
||||
// at the bottom of this file to ensure all the aliased properties are
|
||||
// processed.
|
||||
|
|
|
@ -7771,6 +7771,13 @@
|
|||
mirror: always
|
||||
rust: true
|
||||
|
||||
# Whether the `scrollbar-gutter` CSS property is enabled.
|
||||
- name: layout.css.scrollbar-gutter.enabled
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
rust: true
|
||||
|
||||
# Whether frame visibility tracking is enabled globally.
|
||||
- name: layout.framevisibility.enabled
|
||||
type: bool
|
||||
|
|
|
@ -505,6 +505,7 @@ class Longhand(Property):
|
|||
"RubyPosition",
|
||||
"SVGOpacity",
|
||||
"SVGPaintOrder",
|
||||
"ScrollbarGutter",
|
||||
"ScrollSnapAlign",
|
||||
"ScrollSnapAxis",
|
||||
"ScrollSnapStrictness",
|
||||
|
|
|
@ -703,3 +703,13 @@ ${helpers.predefined_type(
|
|||
animation_value_type="Integer",
|
||||
spec="https://drafts.csswg.org/css-overflow-3/#line-clamp",
|
||||
)}
|
||||
|
||||
${helpers.predefined_type(
|
||||
"scrollbar-gutter",
|
||||
"ScrollbarGutter",
|
||||
"computed::ScrollbarGutter::AUTO",
|
||||
engines="gecko",
|
||||
gecko_pref="layout.css.scrollbar-gutter.enabled",
|
||||
animation_value_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-overflow-3/#scrollbar-gutter-property",
|
||||
)}
|
||||
|
|
|
@ -15,7 +15,7 @@ pub use crate::values::specified::box_::{
|
|||
AnimationName, AnimationTimeline, Appearance, BreakBetween, BreakWithin,
|
||||
Clear as SpecifiedClear, Contain, Display, Float as SpecifiedFloat, Overflow, OverflowAnchor,
|
||||
OverflowClipBox, OverscrollBehavior, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStrictness,
|
||||
ScrollSnapType, TouchAction, TransitionProperty, WillChange,
|
||||
ScrollSnapType, ScrollbarGutter, TouchAction, TransitionProperty, WillChange,
|
||||
};
|
||||
|
||||
/// A computed value for the `vertical-align` property.
|
||||
|
|
|
@ -45,7 +45,7 @@ pub use self::border::{BorderImageSlice, BorderImageWidth};
|
|||
pub use self::box_::{AnimationIterationCount, AnimationName, AnimationTimeline, Contain};
|
||||
pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, Float};
|
||||
pub use self::box_::{Display, Overflow, OverflowAnchor, TransitionProperty};
|
||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
|
||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollbarGutter};
|
||||
pub use self::box_::{ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStrictness, ScrollSnapType};
|
||||
pub use self::box_::{TouchAction, VerticalAlign, WillChange};
|
||||
pub use self::color::{Color, ColorOrAuto, ColorPropertyValue, ColorScheme};
|
||||
|
|
|
@ -2079,3 +2079,73 @@ impl Overflow {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||
#[value_info(other_values = "auto,stable,both-edges")]
|
||||
#[repr(C)]
|
||||
/// Values for scrollbar-gutter:
|
||||
/// <https://drafts.csswg.org/css-overflow-3/#scrollbar-gutter-property>
|
||||
pub struct ScrollbarGutter: u8 {
|
||||
/// `auto` variant. Just for convenience if there is no flag set.
|
||||
const AUTO = 0;
|
||||
/// `stable` variant.
|
||||
const STABLE = 1 << 0;
|
||||
/// `both-edges` variant.
|
||||
const BOTH_EDGES = 1 << 1;
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for ScrollbarGutter {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
if self.is_empty() {
|
||||
return dest.write_str("auto");
|
||||
}
|
||||
|
||||
debug_assert!(
|
||||
self.contains(ScrollbarGutter::STABLE),
|
||||
"We failed to parse the syntax!"
|
||||
);
|
||||
dest.write_str("stable")?;
|
||||
if self.contains(ScrollbarGutter::BOTH_EDGES) {
|
||||
dest.write_str(" both-edges")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for ScrollbarGutter {
|
||||
/// auto | stable && both-edges?
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<ScrollbarGutter, ParseError<'i>> {
|
||||
if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() {
|
||||
return Ok(ScrollbarGutter::AUTO);
|
||||
}
|
||||
|
||||
let mut result = ScrollbarGutter::empty();
|
||||
while let Ok(ident) = input.try_parse(|i| i.expect_ident_cloned()) {
|
||||
let flag = match_ignore_ascii_case! { &ident,
|
||||
"stable" => Some(ScrollbarGutter::STABLE),
|
||||
"both-edges" => Some(ScrollbarGutter::BOTH_EDGES),
|
||||
_ => None
|
||||
};
|
||||
|
||||
match flag {
|
||||
Some(flag) if !result.contains(flag) => result.insert(flag),
|
||||
_ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||
}
|
||||
}
|
||||
|
||||
if result.contains(ScrollbarGutter::STABLE) {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing, BorderStyle
|
|||
pub use self::box_::{AnimationIterationCount, AnimationName, AnimationTimeline, Contain, Display};
|
||||
pub use self::box_::{Appearance, BreakBetween, BreakWithin};
|
||||
pub use self::box_::{Clear, Float, Overflow, OverflowAnchor};
|
||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
|
||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollbarGutter};
|
||||
pub use self::box_::{ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStrictness, ScrollSnapType};
|
||||
pub use self::box_::{TouchAction, TransitionProperty, VerticalAlign, WillChange};
|
||||
pub use self::color::{Color, ColorOrAuto, ColorPropertyValue, ColorScheme};
|
||||
|
|
|
@ -234,6 +234,7 @@ include = [
|
|||
"PageSize",
|
||||
"DProperty",
|
||||
"ImageRendering",
|
||||
"ScrollbarGutter",
|
||||
]
|
||||
item_types = ["enums", "structs", "unions", "typedefs", "functions", "constants"]
|
||||
renaming_overrides_prefixing = true
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
leak-threshold: [default:51200]
|
||||
prefs: [layout.css.scrollbar-gutter.enabled:true]
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
[scrollbar-gutter-valid.html]
|
||||
[e.style['scrollbar-gutter'\] = "auto" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['scrollbar-gutter'\] = "stable" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['scrollbar-gutter'\] = "stable both-edges" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['scrollbar-gutter'\] = "both-edges stable" should set the property value]
|
||||
expected: FAIL
|
Загрузка…
Ссылка в новой задаче