Skip to content

Commit 1312700

Browse files
authored
[BUGFIX] Parse @font-face src property as comma-delimited list (#790)
Fixes #789. Also adds an initial `TestCase` for `Rule/Rule`.
1 parent d783f0e commit 1312700

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Please also have a look at our
4242

4343
### Fixed
4444

45+
- Parse `@font-face` `src` property as comma-delimited list (#790)
4546
- Fix type errors in PHP strict mode (#664)
4647
- Fix undefined local variable in `CalcFunction::parse()` (#593)
4748
- Fix PHP notice caused by parsing invalid color values having less than 6

src/Rule/Rule.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,26 @@ public static function parse(ParserState $oParserState): Rule
114114
}
115115

116116
/**
117+
* Returns a list of delimiters (or separators).
118+
* The first item is the innermost separator (or, put another way, the highest-precedence operator).
119+
* The sequence continues to the outermost separator (or lowest-precedence operator).
120+
*
117121
* @param string $sRule
118122
*
119-
* @return array<int, string>
123+
* @return list<non-empty-string>
120124
*/
121125
private static function listDelimiterForRule($sRule): array
122126
{
123127
if (\preg_match('/^font($|-)/', $sRule)) {
124128
return [',', '/', ' '];
125129
}
126-
return [',', ' ', '/'];
130+
131+
switch ($sRule) {
132+
case 'src':
133+
return [' ', ','];
134+
default:
135+
return [',', ' ', '/'];
136+
}
127137
}
128138

129139
/**

tests/Unit/.gitkeep

Whitespace-only changes.

tests/Unit/Rule/RuleTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sabberworm\CSS\Tests\Unit\Rule;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Sabberworm\CSS\Parsing\ParserState;
9+
use Sabberworm\CSS\Settings;
10+
use Sabberworm\CSS\Rule\Rule;
11+
use Sabberworm\CSS\Value\RuleValueList;
12+
use Sabberworm\CSS\Value\ValueList;
13+
14+
/**
15+
* @covers \Sabberworm\CSS\Rule\Rule
16+
*/
17+
final class RuleTest extends TestCase
18+
{
19+
/**
20+
* @return array<string, array{0: string, 1: list<class-string>}>
21+
*/
22+
public static function provideRulesAndExpectedParsedValueListTypes(): array
23+
{
24+
return [
25+
'src (e.g. in @font-face)' => [
26+
"
27+
src: url('../fonts/open-sans-italic-300.woff2') format('woff2'),
28+
url('../fonts/open-sans-italic-300.ttf') format('truetype');
29+
",
30+
[RuleValueList::class, RuleValueList::class],
31+
],
32+
];
33+
}
34+
35+
/**
36+
* @test
37+
*
38+
* @param list<class-string> $expectedTypeClassnames
39+
*
40+
* @dataProvider provideRulesAndExpectedParsedValueListTypes
41+
*/
42+
public function parsesValuesIntoExpectedTypeList(string $rule, array $expectedTypeClassnames): void
43+
{
44+
$subject = Rule::parse(new ParserState($rule, Settings::create()));
45+
46+
$value = $subject->getValue();
47+
self::assertInstanceOf(ValueList::class, $value);
48+
49+
$actualClassnames = \array_map(
50+
/**
51+
* @param Value|string $component
52+
*/
53+
static function ($component): string {
54+
return \is_string($component) ? 'string' : \get_class($component);
55+
},
56+
$value->getListComponents()
57+
);
58+
59+
self::assertSame($expectedTypeClassnames, $actualClassnames);
60+
}
61+
}

0 commit comments

Comments
 (0)