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