Skip to content

Commit edde774

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

File tree

1 file changed

+108
-87
lines changed

1 file changed

+108
-87
lines changed

src/Value/Color.php

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

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,
6764
$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+
];
7073
} 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) {
72122
$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);
95128
}
96129

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

126-
if ($bContainsVar) {
127-
return new CSSFunction($sColorMode, \array_values($aColor), ',', $oParserState->currentLine());
142+
if ($i < ($iLength - 1)) {
143+
$oParserState->consume(',');
128144
}
129145
}
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());
131152
}
132153

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

0 commit comments

Comments
 (0)