Skip to content

Commit c609746

Browse files
committed
[Twig] Fixing bug with HTML embedded components + default block
1 parent 3fd96bf commit c609746

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

src/TwigComponent/src/Twig/TwigPreLexer.php

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ public function __construct(int $startingLine = 1)
3030
$this->line = $startingLine;
3131
}
3232

33-
public function preLexComponents(string $input): string
33+
/**
34+
* @param bool $insideOfBlock Are we sub-parsing the content inside a block?
35+
*/
36+
public function preLexComponents(string $input, bool $insideOfBlock = false): string
3437
{
3538
$this->input = $input;
3639
$this->length = \strlen($input);
@@ -53,6 +56,15 @@ public function preLexComponents(string $input): string
5356
continue;
5457
}
5558

59+
// if we're already inside a component, and we're not inside a block,
60+
// *and* we've just found a new component, then we should try to
61+
// open the default block
62+
if (!$insideOfBlock
63+
&& !empty($this->currentComponents)
64+
&& !$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock']) {
65+
$output .= $this->addDefaultBlock();
66+
}
67+
5668
$attributes = $this->consumeAttributes($componentName);
5769
$isSelfClosing = $this->consume('/>');
5870
if (!$isSelfClosing) {
@@ -100,13 +112,12 @@ public function preLexComponents(string $input): string
100112
++$this->line;
101113
}
102114

103-
// handle adding a default block if needed
115+
// handle adding a default block if we find non-whitespace outside of a block
104116
if (!empty($this->currentComponents)
105117
&& !$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock']
106118
&& preg_match('/\S/', $char)
107119
) {
108-
$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock'] = true;
109-
$output .= '{% block content %}';
120+
$output .= $this->addDefaultBlock();
110121
}
111122

112123
$output .= $char;
@@ -202,10 +213,15 @@ private function consumeAttributes(string $componentName): string
202213
return implode(', ', $attributes);
203214
}
204215

216+
/**
217+
* If the next character(s) exactly matches the given string, then
218+
* consume it (move forward) and return true.
219+
*/
205220
private function consume(string $string): bool
206221
{
207-
if (substr($this->input, $this->position, \strlen($string)) === $string) {
208-
$this->position += \strlen($string);
222+
$stringLength = \strlen($string);
223+
if (substr($this->input, $this->position, $stringLength) === $string) {
224+
$this->position += $stringLength;
209225

210226
return true;
211227
}
@@ -317,7 +333,7 @@ private function consumeBlock(string $componentName): string
317333
$blockContents = $this->consumeUntilEndBlock();
318334

319335
$subLexer = new self($this->line);
320-
$output .= $subLexer->preLexComponents($blockContents);
336+
$output .= $subLexer->preLexComponents($blockContents, true);
321337

322338
$this->consume($closingTag);
323339
$output .= '{% endblock %}';
@@ -395,4 +411,10 @@ private function doesStringEventuallyExist(string $needle): bool
395411

396412
return str_contains($remainingString, $needle);
397413
}
414+
415+
private function addDefaultBlock(): string
416+
{
417+
$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock'] = true;
418+
return '{% block content %}';
419+
}
398420
}

src/TwigComponent/tests/Unit/TwigPreLexerTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,17 @@ public function getLexTests(): iterable
116116
{% endblock %}{% endcomponent %}
117117
EOF
118118
];
119+
yield 'component_where_entire_default_block_is_embedded_component_self_closing' => [
120+
<<<EOF
121+
<twig:foo>
122+
<twig:bar />
123+
</twig:foo>
124+
EOF,
125+
<<<EOF
126+
{% component 'foo' %}
127+
{% block content %}{{ component('bar') }}
128+
{% endblock %}{% endcomponent %}
129+
EOF
130+
];
119131
}
120132
}

0 commit comments

Comments
 (0)