Skip to content

Commit e272ae2

Browse files
jenkins-botGerrit Code Review
authored andcommitted
Merge "Add CSS Transforms Module Level 2"
2 parents 1e945d9 + 7ecc5a0 commit e272ae2

File tree

4 files changed

+343
-20
lines changed

4 files changed

+343
-20
lines changed

HISTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Update Values and Units to Level 4 (WD 2024-03-12)
99
* Update Display Level 3 to CR 2023-03-30
1010
* Add support for Ruby Level 1 (WD 2022-12-31)
11+
* Add support for Transforms Level 2 (WD 2021-11-09)
1112

1213
## css-sanitizer 5.5.0 (2025-01-27)
1314
* Ensure <-token and identifiers are always separated as a security

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
* [Text Decorations Level 3, 2019-08-13](https://www.w3.org/TR/2019/CR-css-text-decor-3-20190813)
8888
* [Easing Level 1, 2019-04-30](https://www.w3.org/TR/2019/CR-css-easing-1-20190430/)
8989
* [Transforms Level 1, 2019-02-14](https://www.w3.org/TR/2019/CR-css-transforms-1-20190214)
90+
* [Transforms Level 2, 2021-11-09](https://www.w3.org/TR/2021/WD-css-transforms-2-20211109/)
9091
* [Transitions Level 1, 2018-10-11](https://www.w3.org/TR/2018/WD-css-transitions-1-20181011)
9192
* [UI 3 Level 3, 2018-06-21](https://www.w3.org/TR/2018/REC-css-ui-3-20180621)
9293
* [UI 4 Level 4, 2020-01-02](https://www.w3.org/TR/2020/WD-css-ui-4-20200102)

src/Sanitizer/StylePropertySanitizer.php

Lines changed: 128 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public function __construct( MatcherFactory $matcherFactory ) {
6767
$this->addKnownProperties( $this->cssTransitions( $matcherFactory ) );
6868
$this->addKnownProperties( $this->cssAnimations( $matcherFactory ) );
6969
$this->addKnownProperties( $this->cssFlexbox3( $matcherFactory ) );
70-
$this->addKnownProperties( $this->cssTransforms1( $matcherFactory ) );
70+
$this->addKnownProperties( $this->cssTransforms2( $matcherFactory ) );
7171
$this->addKnownProperties( $this->cssText3( $matcherFactory ) );
7272
$this->addKnownProperties( $this->cssTextDecor3( $matcherFactory ) );
7373
$this->addKnownProperties( $this->cssAlign3( $matcherFactory ) );
@@ -980,6 +980,70 @@ protected function cssFlexbox3( MatcherFactory $matcherFactory ) {
980980
return $props;
981981
}
982982

983+
/**
984+
* Get a matcher for any transform function for a given level of the
985+
* Transforms module.
986+
*
987+
* @see https://www.w3.org/TR/2019/CR-css-transforms-1-20190214/
988+
* @see https://www.w3.org/TR/2021/WD-css-transforms-2-20211109/
989+
*
990+
* @param MatcherFactory $matcherFactory
991+
* @param int $level
992+
* @return Alternative
993+
*/
994+
protected function transformFunc( MatcherFactory $matcherFactory, int $level ) {
995+
$a = $matcherFactory->angle();
996+
$az = new Alternative( [
997+
$matcherFactory->zero(),
998+
$a,
999+
] );
1000+
$n = $matcherFactory->number();
1001+
$l = $matcherFactory->length();
1002+
$lp = $matcherFactory->lengthPercentage();
1003+
$np = new Alternative( [ $n, $matcherFactory->percentage() ] );
1004+
1005+
$level1 = [
1006+
'matrix' => Quantifier::hash( $n, 6, 6 ),
1007+
'translate' => Quantifier::hash( $lp, 1, 2 ),
1008+
'translateX' => $lp,
1009+
'translateY' => $lp,
1010+
'scale' => Quantifier::hash( $n, 1, 2 ),
1011+
'scaleX' => $n,
1012+
'scaleY' => $n,
1013+
'rotate' => $az,
1014+
'skew' => Quantifier::hash( $az, 1, 2 ),
1015+
'skewX' => $az,
1016+
'skewY' => $az,
1017+
];
1018+
1019+
$level2 = [
1020+
'scale' => Quantifier::hash( $np, 1, 2 ),
1021+
'scaleX' => $np,
1022+
'scaleY' => $np,
1023+
'matrix3d' => Quantifier::hash( $n, 16, 16 ),
1024+
'translate3d' => new Juxtaposition( [ $lp, $lp, $l ], true ),
1025+
'translateZ' => $l,
1026+
'scale3d' => Quantifier::hash( $np, 3, 3 ),
1027+
'scaleZ' => $np,
1028+
'rotate3d' => new Juxtaposition( [ $n, $n, $n, $az ], true ),
1029+
'rotateX' => $az,
1030+
'rotateY' => $az,
1031+
'rotateZ' => $az,
1032+
'perspective' => new Alternative( [ $l, new KeywordMatcher( 'none' ) ] ),
1033+
];
1034+
1035+
if ( $level === 1 ) {
1036+
$funcs = $level1;
1037+
} else {
1038+
$funcs = $level2 + $level1;
1039+
}
1040+
$funcMatchers = [];
1041+
foreach ( $funcs as $name => $contents ) {
1042+
$funcMatchers[] = new FunctionMatcher( $name, $contents );
1043+
}
1044+
return new Alternative( $funcMatchers );
1045+
}
1046+
9831047
/**
9841048
* Properties for CSS Transforms Module Level 1
9851049
*
@@ -995,12 +1059,6 @@ protected function cssTransforms1( MatcherFactory $matcherFactory ) {
9951059
// @codeCoverageIgnoreEnd
9961060

9971061
$props = [];
998-
$a = $matcherFactory->angle();
999-
$az = new Alternative( [
1000-
$matcherFactory->zero(),
1001-
$a,
1002-
] );
1003-
$n = $matcherFactory->number();
10041062
$l = $matcherFactory->length();
10051063
$ol = Quantifier::optional( $l );
10061064
$lp = $matcherFactory->lengthPercentage();
@@ -1010,19 +1068,7 @@ protected function cssTransforms1( MatcherFactory $matcherFactory ) {
10101068

10111069
$props['transform'] = new Alternative( [
10121070
new KeywordMatcher( 'none' ),
1013-
Quantifier::plus( new Alternative( [
1014-
new FunctionMatcher( 'matrix', Quantifier::hash( $n, 6, 6 ) ),
1015-
new FunctionMatcher( 'translate', Quantifier::hash( $lp, 1, 2 ) ),
1016-
new FunctionMatcher( 'translateX', $lp ),
1017-
new FunctionMatcher( 'translateY', $lp ),
1018-
new FunctionMatcher( 'scale', Quantifier::hash( $n, 1, 2 ) ),
1019-
new FunctionMatcher( 'scaleX', $n ),
1020-
new FunctionMatcher( 'scaleY', $n ),
1021-
new FunctionMatcher( 'rotate', $az ),
1022-
new FunctionMatcher( 'skew', Quantifier::hash( $az, 1, 2 ) ),
1023-
new FunctionMatcher( 'skewX', $az ),
1024-
new FunctionMatcher( 'skewY', $az ),
1025-
] ) )
1071+
Quantifier::plus( $this->transformFunc( $matcherFactory, 1 ) )
10261072
] );
10271073

10281074
$props['transform-origin'] = new Alternative( [
@@ -1048,6 +1094,68 @@ protected function cssTransforms1( MatcherFactory $matcherFactory ) {
10481094
return $props;
10491095
}
10501096

1097+
/**
1098+
* Properties for CSS Transforms Module Levels 1 and 2
1099+
*
1100+
* @see https://www.w3.org/TR/2019/CR-css-transforms-1-20190214/
1101+
* @see https://www.w3.org/TR/2021/WD-css-transforms-2-20211109/
1102+
* @param MatcherFactory $matcherFactory Factory for Matchers
1103+
* @return Matcher[] Array mapping declaration names (lowercase) to Matchers for the values
1104+
*/
1105+
protected function cssTransforms2( MatcherFactory $matcherFactory ) {
1106+
if ( !isset( $this->cache[__METHOD__] ) ) {
1107+
$none = new KeywordMatcher( 'none' );
1108+
1109+
$this->cache[__METHOD__] = [
1110+
'transform' => new Alternative( [
1111+
new KeywordMatcher( 'none' ),
1112+
Quantifier::plus( $this->transformFunc( $matcherFactory, 2 ) )
1113+
] ),
1114+
'backface-visibility' => new KeywordMatcher( [ 'visible', 'hidden' ] ),
1115+
'perspective' => new Alternative( [
1116+
$none,
1117+
$matcherFactory->length()
1118+
] ),
1119+
'perspective-origin' => $matcherFactory->position(),
1120+
'rotate' => new Alternative( [
1121+
$none,
1122+
$matcherFactory->angle(),
1123+
UnorderedGroup::allOf( [
1124+
new Alternative( [
1125+
new KeywordMatcher( [ 'x', 'y', 'z' ] ),
1126+
Quantifier::count( $matcherFactory->number(), 3, 3 )
1127+
] ),
1128+
$matcherFactory->angle()
1129+
] )
1130+
] ),
1131+
'scale' => new Alternative( [
1132+
$none,
1133+
Quantifier::count(
1134+
new Alternative( [
1135+
$matcherFactory->number(),
1136+
$matcherFactory->percentage()
1137+
] ),
1138+
1, 3
1139+
)
1140+
] ),
1141+
'transform-style' => new KeywordMatcher( [ 'flat', 'preserve-3d' ] ),
1142+
'translate' => new Alternative( [
1143+
$none,
1144+
new Juxtaposition( [
1145+
$matcherFactory->lengthPercentage(),
1146+
Quantifier::optional(
1147+
new Juxtaposition( [
1148+
$matcherFactory->lengthPercentage(),
1149+
Quantifier::optional( $matcherFactory->length() )
1150+
] )
1151+
)
1152+
] )
1153+
] )
1154+
] + $this->cssTransforms1( $matcherFactory );
1155+
}
1156+
return $this->cache[__METHOD__];
1157+
}
1158+
10511159
/**
10521160
* Properties for CSS Text Module Level 3
10531161
* @see https://www.w3.org/TR/2019/WD-css-text-3-20191113/

0 commit comments

Comments
 (0)