Skip to content

Commit 071993a

Browse files
authored
feat(view): support single-quote attributes (#1678)
1 parent 3851bb5 commit 071993a

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

packages/view/src/Parser/TempestViewLexer.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,12 @@ private function lexTag(): array
131131
);
132132

133133
if ($hasValue) {
134-
$attributeValue = $this->consumeIncluding('"');
135-
$attributeValue .= $this->consumeIncluding('"');
134+
$quote = $this->seek() === '\''
135+
? '\''
136+
: '"';
137+
138+
$attributeValue = $this->consumeIncluding($quote);
139+
$attributeValue .= $this->consumeIncluding($quote);
136140

137141
$tokens[] = new Token(
138142
content: $attributeValue,

packages/view/src/Parser/Token.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ private function attributeName(string $name): string
142142

143143
private function attributeValue(string $value): string
144144
{
145-
return str($value)->afterFirst('"')->beforeLast('"')->toString();
145+
$value = str($value);
146+
147+
$quote = $value->startsWith('"') ? '"' : "'";
148+
149+
return str($value)->afterFirst($quote)->beforeLast($quote)->toString();
146150
}
147151
}

packages/view/tests/TempestViewLexerTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,26 @@ public function test_xml(): void
346346
);
347347
}
348348

349+
public function test_single_quote_attributes(): void
350+
{
351+
$html = <<<HTML
352+
<div class='hello'></div>
353+
HTML;
354+
355+
$tokens = new TempestViewLexer($html)->lex();
356+
357+
$this->assertTokens(
358+
expected: [
359+
new Token('<div', TokenType::OPEN_TAG_START),
360+
new Token(' class=', TokenType::ATTRIBUTE_NAME),
361+
new Token('\'hello\'', TokenType::ATTRIBUTE_VALUE),
362+
new Token('>', TokenType::OPEN_TAG_END),
363+
new Token('</div>', TokenType::CLOSING_TAG),
364+
],
365+
actual: $tokens,
366+
);
367+
}
368+
349369
private function assertTokens(array $expected, TokenCollection $actual): void
350370
{
351371
$this->assertCount(count($expected), $actual);

tests/Integration/View/TempestViewRendererTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,4 +847,13 @@ public function test_parse_rss_feed(): void
847847
</feed>
848848
RSS, $parsed);
849849
}
850+
851+
public function test_attributes_with_single_quotes(): void
852+
{
853+
$html = $this->render(<<<'HTML'
854+
<div class='hello'></div>
855+
HTML);
856+
857+
$this->assertSnippetsMatch('<div class="hello"></div>', $html);
858+
}
850859
}

0 commit comments

Comments
 (0)