Skip to content

Commit 9e79e16

Browse files
authored
[CLEANUP] Split Color::parse into separate methods (#799)
One for hex colors, and one for color functions. This reduces cyclomatic complexity on a per-method basis.
1 parent f3ea6a7 commit 9e79e16

File tree

1 file changed

+108
-88
lines changed

1 file changed

+108
-88
lines changed

src/Value/Color.php

Lines changed: 108 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -30,104 +30,124 @@ public function __construct(array $aColor, $iLineNo = 0)
3030
*/
3131
public static function parse(ParserState $oParserState, bool $bIgnoreCase = false): CSSFunction
3232
{
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+
}
4338

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,
6763
$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+
];
7072
} 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) {
72121
$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);
95127
}
96128

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;
123139
}
124-
$oParserState->consume(')');
125140

126-
if ($bContainsVar) {
127-
return new CSSFunction($sColorMode, \array_values($aColor), ',', $oParserState->currentLine());
141+
if ($i < ($iLength - 1)) {
142+
$oParserState->consume(',');
128143
}
129144
}
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());
131151
}
132152

133153
private static function mapRange(float $fVal, float $fFromMin, float $fFromMax, float $fToMin, float $fToMax): float

0 commit comments

Comments
 (0)