Skip to content

Commit 45ced32

Browse files
JakeQZoliverklee
authored andcommitted
[BUGFIX] Parse @font-face src property as comma-delimited list
Fixes #789. Also adds an initial `TestCase` for `Rule/Rule`. This is the 8.x backport of #790.
1 parent 6098bee commit 45ced32

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
1515

1616
### Fixed
1717

18+
- Parse `@font-face` `src` property as comma-delimited list (#794)
19+
1820
## 8.7.0: Add support for PHP 8.4
1921

2022
### Added

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)
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)
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/Rule/RuleTest.php

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

0 commit comments

Comments
 (0)