Skip to content

Commit 1b3433d

Browse files
authored
fix(view): comment out empty slots (#938)
1 parent a18f422 commit 1b3433d

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

src/Tempest/Debug/src/DOMDebug.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace Tempest\Debug;
4+
5+
use Dom\Comment;
6+
use Dom\Document;
7+
use Dom\DocumentType;
8+
use Dom\Element as DomElement;
9+
use Dom\Node;
10+
use Dom\NodeList;
11+
use Dom\Text;
12+
13+
final readonly class DOMDebug
14+
{
15+
public static function dump(Document|NodeList $dom): void
16+
{
17+
if ($dom instanceof Document) {
18+
$dom = $dom->childNodes;
19+
}
20+
21+
$content = [];
22+
23+
foreach ($dom as $node) {
24+
$content[] = self::dumpNode($node);
25+
}
26+
27+
lw(implode(PHP_EOL, $content));
28+
}
29+
30+
private static function dumpNode(Node $node, int $depth = 0): string
31+
{
32+
$content = str_repeat(' ', $depth * 4);
33+
34+
$content .= match (true) {
35+
$node instanceof DocumentType => 'doctype',
36+
$node instanceof Text => trim($node->textContent) !== '' ? 'text' : '',
37+
$node instanceof Comment => '// comment',
38+
$node instanceof DomElement => "<{$node->tagName}>",
39+
default => 'unknown',
40+
};
41+
42+
foreach ($node->childNodes as $child) {
43+
$content .= PHP_EOL . self::dumpNode($child, $depth + 1);
44+
}
45+
46+
return $content;
47+
}
48+
}

src/Tempest/View/src/Elements/ViewComponentElement.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ public function compile(): string
104104
$slot = $this->getSlot($name);
105105

106106
if ($slot === null) {
107-
return $matches[0];
107+
// A slot doesn't have any content, so we'll comment it out.
108+
// This is to prevent DOM parsing errors (slots in <head> tags is one example, see #937)
109+
return '<!--' . $matches[0] . '-->';
108110
}
109111

110112
return $slot->compile();

tests/Integration/View/ViewComponentTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,4 +482,25 @@ public function test_full_html_document_as_component(): void
482482
</body></html>
483483
HTML, $html);
484484
}
485+
486+
public function test_empty_slots_are_commented_out(): void
487+
{
488+
$this->registerViewComponent('x-layout', <<<'HTML'
489+
<html lang="en">
490+
<head>
491+
<x-slot name="styles" />
492+
<link rel="stylesheet" href="#" />
493+
</head>
494+
</html>
495+
HTML);
496+
497+
$html = $this->render(<<<'HTML'
498+
<x-layout>
499+
</x-layout>
500+
HTML);
501+
502+
$this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML'
503+
<html lang="en"><head><!--<x-slot name="styles" ></x-slot>--><link rel="stylesheet" href="#"></link></head><body></body></html>
504+
HTML, $html);
505+
}
485506
}

0 commit comments

Comments
 (0)