@@ -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