Skip to content

Commit c6bf84c

Browse files
siddharthvpjenkins-bot
authored andcommitted
Add support for CSS Scroll Snap Module Level 1
Bug: T271598 Change-Id: Ie1309145730bfc5b1ec46f76ed11fe75e1111c4d
1 parent 023aaeb commit c6bf84c

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

HISTORY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Release History
22

3+
## css-sanitizer (unreleased)
4+
* Add support for CSS Scroll Snap Module Level 1
5+
36
## css-sanitizer 6.0.0 (2025-07-23)
47

58
New modules:

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ The sanitizer recognizes the following CSS modules:
8787
* [Position Level 3, 2025-03-11](https://www.w3.org/TR/2025/WD-css-position-3-20250311/)
8888
* [Pseudo-Elements Level 4, 2022-12-30](https://www.w3.org/TR/2022/WD-css-pseudo-4-20221230/)
8989
* [Ruby Level 1, 2022-12-31](https://www.w3.org/TR/2022/WD-css-ruby-1-20221231/)
90+
* [Scroll Snap Module Level 1](https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/)
9091
* [Shapes Level 1, 2022-11-15](https://www.w3.org/TR/2022/CRD-css-shapes-1-20221115/)
9192
* [Sizing Level 3, 2021-12-17](https://www.w3.org/TR/2021/WD-css-sizing-3-20211217/)
9293
* [Sizing Level 4, 2025-02-24](https://drafts.csswg.org/css-sizing-4/)

src/Sanitizer/StylePropertySanitizer.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public function __construct( MatcherFactory $matcherFactory ) {
8080
$this->addKnownProperties( $this->cssLogical1( $matcherFactory ) );
8181
$this->addKnownProperties( $this->cssRuby1( $matcherFactory ) );
8282
$this->addKnownProperties( $this->cssLists3( $matcherFactory ) );
83+
$this->addKnownProperties( $this->cssScrollSnap1( $matcherFactory ) );
8384
}
8485

8586
/**
@@ -2196,4 +2197,73 @@ protected function cssLists3( MatcherFactory $matcherFactory ) {
21962197
$this->cache[__METHOD__] = $props;
21972198
return $props;
21982199
}
2200+
2201+
/**
2202+
* Properties for CSS Scroll Snap Module Level 1
2203+
* @see https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/
2204+
* @param MatcherFactory $matcherFactory
2205+
* @return Matcher[] Array mapping declaration names (lowercase) to Matchers for the values
2206+
*/
2207+
protected function cssScrollSnap1( MatcherFactory $matcherFactory ) {
2208+
// @codeCoverageIgnoreStart
2209+
if ( isset( $this->cache[__METHOD__] ) ) {
2210+
return $this->cache[__METHOD__];
2211+
}
2212+
// @codeCoverageIgnoreEnd
2213+
2214+
$props = [];
2215+
$none = new KeywordMatcher( 'none' );
2216+
$auto = new KeywordMatcher( 'auto' );
2217+
$length = $matcherFactory->length();
2218+
$lp = $matcherFactory->lengthPercentage();
2219+
2220+
// https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/#scroll-snap-type
2221+
$props['scroll-snap-type'] = new Alternative( [
2222+
$none,
2223+
new Juxtaposition( [
2224+
new KeywordMatcher( [ 'x', 'y', 'block', 'inline', 'both' ] ),
2225+
Quantifier::optional( new KeywordMatcher( [ 'mandatory', 'proximity' ] ) ),
2226+
] ),
2227+
] );
2228+
2229+
// https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/#scroll-padding
2230+
$props['scroll-padding'] = Quantifier::count( new Alternative( [ $auto, $lp ] ), 1, 4 );
2231+
2232+
$props['scroll-padding-top'] = new Alternative( [ $auto, $lp ] );
2233+
$props['scroll-padding-right'] = new Alternative( [ $auto, $lp ] );
2234+
$props['scroll-padding-bottom'] = new Alternative( [ $auto, $lp ] );
2235+
$props['scroll-padding-left'] = new Alternative( [ $auto, $lp ] );
2236+
2237+
$props['scroll-padding-inline'] = Quantifier::count( new Alternative( [ $auto, $lp ] ), 1, 2 );
2238+
$props['scroll-padding-inline-start'] = new Alternative( [ $auto, $lp ] );
2239+
$props['scroll-padding-inline-end'] = new Alternative( [ $auto, $lp ] );
2240+
$props['scroll-padding-block'] = Quantifier::count( new Alternative( [ $auto, $lp ] ), 1, 2 );
2241+
$props['scroll-padding-block-start'] = new Alternative( [ $auto, $lp ] );
2242+
$props['scroll-padding-block-end'] = new Alternative( [ $auto, $lp ] );
2243+
2244+
// https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/#scroll-margin
2245+
$props['scroll-margin'] = Quantifier::count( $length, 1, 4 );
2246+
2247+
$props['scroll-margin-top'] = $length;
2248+
$props['scroll-margin-right'] = $length;
2249+
$props['scroll-margin-bottom'] = $length;
2250+
$props['scroll-margin-left'] = $length;
2251+
2252+
$props['scroll-margin-inline'] = Quantifier::count( $length, 1, 2 );
2253+
$props['scroll-margin-inline-start'] = $length;
2254+
$props['scroll-margin-inline-end'] = $length;
2255+
$props['scroll-margin-block'] = Quantifier::count( $length, 1, 2 );
2256+
$props['scroll-margin-block-start'] = $length;
2257+
$props['scroll-margin-block-end'] = $length;
2258+
2259+
// https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/#scroll-snap-align
2260+
$props['scroll-snap-align'] = Quantifier::count( new KeywordMatcher( [ 'none', 'start', 'end', 'center' ] ),
2261+
1, 2 );
2262+
2263+
// https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/#scroll-snap-stop
2264+
$props['scroll-snap-stop'] = new KeywordMatcher( [ 'normal', 'always' ] );
2265+
2266+
$this->cache[__METHOD__] = $props;
2267+
return $props;
2268+
}
21992269
}

tests/Sanitizer/StylePropertySanitizerTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,38 @@ public static function provideDeclarations() {
10911091
[ 'list-style: disc radial-gradient(circle, #006, #00a 90%, #0000af 100%,white 100%) inside' ],
10921092
[ 'list-style: linear-gradient( white, blue ) inside square' ],
10931093
[ 'list-style: foo' ],
1094+
1095+
// cssScrollSnap1
1096+
[ 'scroll-snap-type: none' ],
1097+
[ 'scroll-snap-type: x' ],
1098+
[ 'scroll-snap-type: y' ],
1099+
[ 'scroll-snap-type: block' ],
1100+
[ 'scroll-snap-type: inline' ],
1101+
[ 'scroll-snap-type: both' ],
1102+
[ 'scroll-snap-type: x mandatory' ],
1103+
[ 'scroll-snap-type: y mandatory' ],
1104+
[ 'scroll-snap-type: both mandatory' ],
1105+
[ 'scroll-snap-stop: normal' ],
1106+
[ 'scroll-snap-stop: always' ],
1107+
[ 'scroll-snap-align: start end' ],
1108+
[ 'scroll-snap-align: end center' ],
1109+
[ 'scroll-snap-align: center start' ],
1110+
[ 'scroll-padding: 10px' ],
1111+
[ 'scroll-padding: 1em 0.5em 1em 1em' ],
1112+
[ 'scroll-padding: 10%' ],
1113+
[ 'scroll-padding: none', 'bad-value-for-property' ],
1114+
[ 'scroll-padding-top: 20', 'bad-value-for-property' ],
1115+
[ 'scroll-padding-block: 10px' ],
1116+
[ 'scroll-padding-block: 1em 0.5em' ],
1117+
[ 'scroll-padding-block: 10%' ],
1118+
[ 'scroll-padding-block: auto' ],
1119+
[ 'scroll-padding-block-end: auto' ],
1120+
[ 'scroll-margin: 10px' ],
1121+
[ 'scroll-margin: auto', 'bad-value-for-property' ],
1122+
[ 'scroll-margin-top: auto', 'bad-value-for-property' ],
1123+
[ 'scroll-margin: 1em 0.5em 1em 1em' ],
1124+
[ 'scroll-margin-block-end: 10px' ],
1125+
[ 'scroll-margin-block-end: 1em' ],
10941126
];
10951127
}
10961128
}

0 commit comments

Comments
 (0)