Skip to content

Commit 5c214c1

Browse files
Use textContent, not wholeText, to process text nodes (#31)
The wholeText property [1] [2] contains the text of the current text node together with any text nodes adjacent to it. Given that we’re processing each text node separately, this doesn’t make sense and means we’re potentially processing the same text multiple times – we should just process textContent instead, which is the node’s own text. I initially thought this bug wouldn’t be reproducible in practice without manually constructing a DOM with two adjacent text nodes, but then I realized a v-if with a false condition can easily produce such a DOM naturally, hence the test case. [1]: https://www.php.net/manual/en/class.domtext.php#domtext.props.wholetext [2]: https://developer.mozilla.org/en-US/docs/Web/API/Text/wholeText
1 parent 158a0ff commit 5c214c1

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

src/Component.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ private function stripEventHandlers( DOMNode $node ) {
8888
*/
8989
private function replaceMustacheVariables( DOMNode $node, array $data ) {
9090
if ( $node instanceof DOMText ) {
91-
$text = $node->wholeText;
91+
$text = $node->textContent;
9292

9393
$regex = '/\{\{(?P<expression>.*?)\}\}/x';
9494
preg_match_all( $regex, $text, $matches );
@@ -100,7 +100,7 @@ private function replaceMustacheVariables( DOMNode $node, array $data ) {
100100
$text = str_replace( $matches[0][$index], $value, $text );
101101
}
102102

103-
if ( $text !== $node->wholeText ) {
103+
if ( $text !== $node->textContent ) {
104104
$newNode = $node->ownerDocument->createTextNode( $text );
105105
$node->parentNode->replaceChild( $newNode, $node );
106106
}

tests/php/TemplatingTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,15 @@ public function testTemplateWithMethodAccessInAttributeBindingInsideTheLoop_Corr
272272
$this->assertSame( '<p><a attr1="VALUE1"></a><a attr1="VALUE2"></a></p>', $result );
273273
}
274274

275+
public function testMustacheAfterVIf(): void {
276+
$result = $this->createAndRender(
277+
'<p>a: {{ a }} <span v-if="b">b: {{ b }} </span>c: {{c }}</p>',
278+
[ 'a' => 'A', 'b' => false, 'c' => 'C' ]
279+
);
280+
281+
$this->assertSame( '<p>a: A c: C</p>', $result );
282+
}
283+
275284
/**
276285
* @param string $template HTML
277286
* @param array $data

0 commit comments

Comments
 (0)