@@ -30,104 +30,124 @@ public function __construct(array $aColor, $iLineNo = 0)
30
30
*/
31
31
public static function parse (ParserState $ oParserState , bool $ bIgnoreCase = false ): CSSFunction
32
32
{
33
- $ aColor = [];
34
- if ($ oParserState ->comes ('# ' )) {
35
- $ oParserState ->consume ('# ' );
36
- $ sValue = $ oParserState ->parseIdentifier (false );
37
- if ($ oParserState ->strlen ($ sValue ) === 3 ) {
38
- $ sValue = $ sValue [0 ] . $ sValue [0 ] . $ sValue [1 ] . $ sValue [1 ] . $ sValue [2 ] . $ sValue [2 ];
39
- } elseif ($ oParserState ->strlen ($ sValue ) === 4 ) {
40
- $ sValue = $ sValue [0 ] . $ sValue [0 ] . $ sValue [1 ] . $ sValue [1 ] . $ sValue [2 ] . $ sValue [2 ] . $ sValue [3 ]
41
- . $ sValue [3 ];
42
- }
33
+ return
34
+ $ oParserState ->comes ('# ' )
35
+ ? self ::parseHexColor ($ oParserState )
36
+ : self ::parseColorFunction ($ oParserState );
37
+ }
43
38
44
- if ($ oParserState ->strlen ($ sValue ) === 8 ) {
45
- $ aColor = [
46
- 'r ' => new Size (\intval ($ sValue [0 ] . $ sValue [1 ], 16 ), null , true , $ oParserState ->currentLine ()),
47
- 'g ' => new Size (\intval ($ sValue [2 ] . $ sValue [3 ], 16 ), null , true , $ oParserState ->currentLine ()),
48
- 'b ' => new Size (\intval ($ sValue [4 ] . $ sValue [5 ], 16 ), null , true , $ oParserState ->currentLine ()),
49
- 'a ' => new Size (
50
- \round (self ::mapRange (\intval ($ sValue [6 ] . $ sValue [7 ], 16 ), 0 , 255 , 0 , 1 ), 2 ),
51
- null ,
52
- true ,
53
- $ oParserState ->currentLine ()
54
- ),
55
- ];
56
- } elseif ($ oParserState ->strlen ($ sValue ) === 6 ) {
57
- $ aColor = [
58
- 'r ' => new Size (\intval ($ sValue [0 ] . $ sValue [1 ], 16 ), null , true , $ oParserState ->currentLine ()),
59
- 'g ' => new Size (\intval ($ sValue [2 ] . $ sValue [3 ], 16 ), null , true , $ oParserState ->currentLine ()),
60
- 'b ' => new Size (\intval ($ sValue [4 ] . $ sValue [5 ], 16 ), null , true , $ oParserState ->currentLine ()),
61
- ];
62
- } else {
63
- throw new UnexpectedTokenException (
64
- 'Invalid hex color value ' ,
65
- $ sValue ,
66
- 'custom ' ,
39
+ /**
40
+ * @throws UnexpectedEOFException
41
+ * @throws UnexpectedTokenException
42
+ */
43
+ private static function parseHexColor (ParserState $ oParserState ): CSSFunction
44
+ {
45
+ $ oParserState ->consume ('# ' );
46
+ $ sValue = $ oParserState ->parseIdentifier (false );
47
+ if ($ oParserState ->strlen ($ sValue ) === 3 ) {
48
+ $ sValue = $ sValue [0 ] . $ sValue [0 ] . $ sValue [1 ] . $ sValue [1 ] . $ sValue [2 ] . $ sValue [2 ];
49
+ } elseif ($ oParserState ->strlen ($ sValue ) === 4 ) {
50
+ $ sValue = $ sValue [0 ] . $ sValue [0 ] . $ sValue [1 ] . $ sValue [1 ] . $ sValue [2 ] . $ sValue [2 ] . $ sValue [3 ]
51
+ . $ sValue [3 ];
52
+ }
53
+
54
+ if ($ oParserState ->strlen ($ sValue ) === 8 ) {
55
+ $ aColor = [
56
+ 'r ' => new Size (\intval ($ sValue [0 ] . $ sValue [1 ], 16 ), null , true , $ oParserState ->currentLine ()),
57
+ 'g ' => new Size (\intval ($ sValue [2 ] . $ sValue [3 ], 16 ), null , true , $ oParserState ->currentLine ()),
58
+ 'b ' => new Size (\intval ($ sValue [4 ] . $ sValue [5 ], 16 ), null , true , $ oParserState ->currentLine ()),
59
+ 'a ' => new Size (
60
+ \round (self ::mapRange (\intval ($ sValue [6 ] . $ sValue [7 ], 16 ), 0 , 255 , 0 , 1 ), 2 ),
61
+ null ,
62
+ true ,
67
63
$ oParserState ->currentLine ()
68
- );
69
- }
64
+ ),
65
+ ];
66
+ } elseif ($ oParserState ->strlen ($ sValue ) === 6 ) {
67
+ $ aColor = [
68
+ 'r ' => new Size (\intval ($ sValue [0 ] . $ sValue [1 ], 16 ), null , true , $ oParserState ->currentLine ()),
69
+ 'g ' => new Size (\intval ($ sValue [2 ] . $ sValue [3 ], 16 ), null , true , $ oParserState ->currentLine ()),
70
+ 'b ' => new Size (\intval ($ sValue [4 ] . $ sValue [5 ], 16 ), null , true , $ oParserState ->currentLine ()),
71
+ ];
70
72
} else {
71
- $ sColorMode = $ oParserState ->parseIdentifier (true );
73
+ throw new UnexpectedTokenException (
74
+ 'Invalid hex color value ' ,
75
+ $ sValue ,
76
+ 'custom ' ,
77
+ $ oParserState ->currentLine ()
78
+ );
79
+ }
80
+
81
+ return new Color ($ aColor , $ oParserState ->currentLine ());
82
+ }
83
+
84
+ /**
85
+ * @throws UnexpectedEOFException
86
+ * @throws UnexpectedTokenException
87
+ */
88
+ private static function parseColorFunction (ParserState $ oParserState ): CSSFunction
89
+ {
90
+ $ aColor = [];
91
+
92
+ $ sColorMode = $ oParserState ->parseIdentifier (true );
93
+ $ oParserState ->consumeWhiteSpace ();
94
+ $ oParserState ->consume ('( ' );
95
+
96
+ // CSS Color Module Level 4 says that `rgb` and `rgba` are now aliases; likewise `hsl` and `hsla`.
97
+ // So, attempt to parse with the `a`, and allow for it not being there.
98
+ switch ($ sColorMode ) {
99
+ case 'rgb ' :
100
+ $ colorModeForParsing = 'rgba ' ;
101
+ $ mayHaveOptionalAlpha = true ;
102
+ break ;
103
+ case 'hsl ' :
104
+ $ colorModeForParsing = 'hsla ' ;
105
+ $ mayHaveOptionalAlpha = true ;
106
+ break ;
107
+ case 'rgba ' :
108
+ // This is handled identically to the following case.
109
+ case 'hsla ' :
110
+ $ colorModeForParsing = $ sColorMode ;
111
+ $ mayHaveOptionalAlpha = true ;
112
+ break ;
113
+ default :
114
+ $ colorModeForParsing = $ sColorMode ;
115
+ $ mayHaveOptionalAlpha = false ;
116
+ }
117
+
118
+ $ bContainsVar = false ;
119
+ $ iLength = $ oParserState ->strlen ($ colorModeForParsing );
120
+ for ($ i = 0 ; $ i < $ iLength ; ++$ i ) {
72
121
$ oParserState ->consumeWhiteSpace ();
73
- $ oParserState ->consume ('( ' );
74
-
75
- // CSS Color Module Level 4 says that `rgb` and `rgba` are now aliases; likewise `hsl` and `hsla`.
76
- // So, attempt to parse with the `a`, and allow for it not being there.
77
- switch ($ sColorMode ) {
78
- case 'rgb ' :
79
- $ colorModeForParsing = 'rgba ' ;
80
- $ mayHaveOptionalAlpha = true ;
81
- break ;
82
- case 'hsl ' :
83
- $ colorModeForParsing = 'hsla ' ;
84
- $ mayHaveOptionalAlpha = true ;
85
- break ;
86
- case 'rgba ' :
87
- // This is handled identically to the following case.
88
- case 'hsla ' :
89
- $ colorModeForParsing = $ sColorMode ;
90
- $ mayHaveOptionalAlpha = true ;
91
- break ;
92
- default :
93
- $ colorModeForParsing = $ sColorMode ;
94
- $ mayHaveOptionalAlpha = false ;
122
+ if ($ oParserState ->comes ('var ' )) {
123
+ $ aColor [$ colorModeForParsing [$ i ]] = CSSFunction::parseIdentifierOrFunction ($ oParserState );
124
+ $ bContainsVar = true ;
125
+ } else {
126
+ $ aColor [$ colorModeForParsing [$ i ]] = Size::parse ($ oParserState , true );
95
127
}
96
128
97
- $ bContainsVar = false ;
98
- $ iLength = $ oParserState ->strlen ($ colorModeForParsing );
99
- for ($ i = 0 ; $ i < $ iLength ; ++$ i ) {
100
- $ oParserState ->consumeWhiteSpace ();
101
- if ($ oParserState ->comes ('var ' )) {
102
- $ aColor [$ colorModeForParsing [$ i ]] = CSSFunction::parseIdentifierOrFunction ($ oParserState );
103
- $ bContainsVar = true ;
104
- } else {
105
- $ aColor [$ colorModeForParsing [$ i ]] = Size::parse ($ oParserState , true );
106
- }
107
-
108
- // This must be done first, to consume comments as well, so that the `comes` test will work.
109
- $ oParserState ->consumeWhiteSpace ();
110
-
111
- // With a `var` argument, the function can have fewer arguments.
112
- // And as of CSS Color Module Level 4, the alpha argument is optional.
113
- $ canCloseNow =
114
- $ bContainsVar ||
115
- ($ mayHaveOptionalAlpha && $ i >= $ iLength - 2 );
116
- if ($ canCloseNow && $ oParserState ->comes (') ' )) {
117
- break ;
118
- }
119
-
120
- if ($ i < ($ iLength - 1 )) {
121
- $ oParserState ->consume (', ' );
122
- }
129
+ // This must be done first, to consume comments as well, so that the `comes` test will work.
130
+ $ oParserState ->consumeWhiteSpace ();
131
+
132
+ // With a `var` argument, the function can have fewer arguments.
133
+ // And as of CSS Color Module Level 4, the alpha argument is optional.
134
+ $ canCloseNow =
135
+ $ bContainsVar ||
136
+ ($ mayHaveOptionalAlpha && $ i >= $ iLength - 2 );
137
+ if ($ canCloseNow && $ oParserState ->comes (') ' )) {
138
+ break ;
123
139
}
124
- $ oParserState ->consume (') ' );
125
140
126
- if ($ bContainsVar ) {
127
- return new CSSFunction ( $ sColorMode , \array_values ( $ aColor ), ' , ' , $ oParserState ->currentLine () );
141
+ if ($ i < ( $ iLength - 1 ) ) {
142
+ $ oParserState ->consume ( ' , ' );
128
143
}
129
144
}
130
- return new Color ($ aColor , $ oParserState ->currentLine ());
145
+ $ oParserState ->consume (') ' );
146
+
147
+ return
148
+ $ bContainsVar
149
+ ? new CSSFunction ($ sColorMode , \array_values ($ aColor ), ', ' , $ oParserState ->currentLine ())
150
+ : new Color ($ aColor , $ oParserState ->currentLine ());
131
151
}
132
152
133
153
private static function mapRange (float $ fVal , float $ fFromMin , float $ fFromMax , float $ fToMin , float $ fToMax ): float
0 commit comments