Skip to content

Commit cb27a80

Browse files
PerryvanderMeerNickSdot
authored andcommitted
short hand false props (#57104)
1 parent c575e8e commit cb27a80

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

src/Illuminate/View/Compilers/ComponentTagCompiler.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ protected function compileOpeningTags(string $value)
127127
(\:\\\$)(\w+)
128128
)
129129
|
130+
(?:
131+
(![\w]+)
132+
)
133+
|
130134
(?:
131135
[\w\-:.@%]+
132136
(
@@ -192,6 +196,10 @@ protected function compileSelfClosingTags(string $value)
192196
(\:\\\$)(\w+)
193197
)
194198
|
199+
(?:
200+
(![\w]+)
201+
)
202+
|
195203
(?:
196204
[\w\-:.@%]+
197205
(
@@ -597,6 +605,7 @@ public function compileSlots(string $value)
597605
protected function getAttributesFromAttributeString(string $attributeString)
598606
{
599607
$attributeString = $this->parseShortAttributeSyntax($attributeString);
608+
$attributeString = $this->parseShortFalseSyntax($attributeString);
600609
$attributeString = $this->parseAttributeBag($attributeString);
601610
$attributeString = $this->parseComponentTagClassStatements($attributeString);
602611
$attributeString = $this->parseComponentTagStyleStatements($attributeString);
@@ -665,6 +674,29 @@ protected function parseShortAttributeSyntax(string $value)
665674
}, $value);
666675
}
667676

677+
/**
678+
* Parses a short false syntax like !required into a fully-qualified syntax like :required="false".
679+
*
680+
* @param string $value
681+
* @return string
682+
*/
683+
protected function parseShortFalseSyntax(string $value)
684+
{
685+
$parts = preg_split('/(".*?(?<!\\\\)")/', $value, -1, PREG_SPLIT_DELIM_CAPTURE);
686+
687+
return (new Collection($parts))
688+
->map(function (string $value) {
689+
if (preg_match('/^".*"$/s', $value)) {
690+
return $value;
691+
}
692+
693+
return preg_replace_callback('/!(\w+)/', function ($matches) {
694+
return " :{$matches[1]}=\"false\"";
695+
}, $value);
696+
})
697+
->implode('');
698+
}
699+
668700
/**
669701
* Parse the attribute bag in a given attribute string into its fully-qualified syntax.
670702
*

tests/View/Blade/BladeComponentTagCompilerTest.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,81 @@ public function testSelfClosingComponentWithColonDataMultipleAttributesAndStatic
303303
'@endComponentClass##END-COMPONENT-CLASS##', trim($result));
304304
}
305305

306+
public function testFalseShortSyntax()
307+
{
308+
$this->mockViewFactory();
309+
$result = $this->compiler(['bool' => TestBoolComponent::class])->compileTags('<x-bool !bool></x-bool>');
310+
311+
$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\Tests\View\Blade\TestBoolComponent', 'bool', ['bool' => false])
312+
<?php if (isset(\$attributes) && \$attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
313+
<?php \$attributes = \$attributes->except(\Illuminate\Tests\View\Blade\TestBoolComponent::ignoredParameterNames()); ?>
314+
<?php endif; ?>
315+
<?php \$component->withAttributes([]); ?> @endComponentClass##END-COMPONENT-CLASS##", trim($result));
316+
}
317+
318+
public function testFalseShortSyntaxAsValue()
319+
{
320+
$this->mockViewFactory();
321+
$result = $this->compiler(['bool' => TestBoolComponent::class])->compileTags('<x-bool :bool="!false"></x-bool>');
322+
323+
$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\Tests\View\Blade\TestBoolComponent', 'bool', ['bool' => !false])
324+
<?php if (isset(\$attributes) && \$attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
325+
<?php \$attributes = \$attributes->except(\Illuminate\Tests\View\Blade\TestBoolComponent::ignoredParameterNames()); ?>
326+
<?php endif; ?>
327+
<?php \$component->withAttributes([]); ?> @endComponentClass##END-COMPONENT-CLASS##", trim($result));
328+
}
329+
330+
public function testFalseShortSyntaxWithinValue()
331+
{
332+
$this->mockViewFactory();
333+
$result = $this->compiler(['bool' => TestBoolComponent::class])->compileTags('<x-bool :bool="$value && !old(\'value\')"></x-bool>');
334+
335+
$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\Tests\View\Blade\TestBoolComponent', 'bool', ['bool' => \$value && !old('value')])
336+
<?php if (isset(\$attributes) && \$attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
337+
<?php \$attributes = \$attributes->except(\Illuminate\Tests\View\Blade\TestBoolComponent::ignoredParameterNames()); ?>
338+
<?php endif; ?>
339+
<?php \$component->withAttributes([]); ?> @endComponentClass##END-COMPONENT-CLASS##", trim($result));
340+
}
341+
342+
public function testSelfClosingComponentWithFalseShortSyntax()
343+
{
344+
$this->mockViewFactory();
345+
$result = $this->compiler(['bool' => TestBoolComponent::class])->compileTags('<x-bool !bool />');
346+
347+
$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\Tests\View\Blade\TestBoolComponent', 'bool', ['bool' => false])
348+
<?php if (isset(\$attributes) && \$attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
349+
<?php \$attributes = \$attributes->except(\Illuminate\Tests\View\Blade\TestBoolComponent::ignoredParameterNames()); ?>
350+
<?php endif; ?>
351+
<?php \$component->withAttributes([]); ?>\n".
352+
'@endComponentClass##END-COMPONENT-CLASS##', trim($result));
353+
}
354+
355+
public function testSelfClosingComponentWithFalseShortSyntaxAsValue()
356+
{
357+
$this->mockViewFactory();
358+
$result = $this->compiler(['bool' => TestBoolComponent::class])->compileTags('<x-bool :bool="!false" />');
359+
360+
$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\Tests\View\Blade\TestBoolComponent', 'bool', ['bool' => !false])
361+
<?php if (isset(\$attributes) && \$attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
362+
<?php \$attributes = \$attributes->except(\Illuminate\Tests\View\Blade\TestBoolComponent::ignoredParameterNames()); ?>
363+
<?php endif; ?>
364+
<?php \$component->withAttributes([]); ?>\n".
365+
'@endComponentClass##END-COMPONENT-CLASS##', trim($result));
366+
}
367+
368+
public function testSelfClosingComponentWithFalseShortSyntaxWithinValue()
369+
{
370+
$this->mockViewFactory();
371+
$result = $this->compiler(['bool' => TestBoolComponent::class])->compileTags('<x-bool :bool="$value && !old(\'value\')" />');
372+
373+
$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\Tests\View\Blade\TestBoolComponent', 'bool', ['bool' => \$value && !old('value')])
374+
<?php if (isset(\$attributes) && \$attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
375+
<?php \$attributes = \$attributes->except(\Illuminate\Tests\View\Blade\TestBoolComponent::ignoredParameterNames()); ?>
376+
<?php endif; ?>
377+
<?php \$component->withAttributes([]); ?>\n".
378+
'@endComponentClass##END-COMPONENT-CLASS##', trim($result));
379+
}
380+
306381
public function testEscapedColonAttribute()
307382
{
308383
$this->mockViewFactory();
@@ -1010,6 +1085,21 @@ public function render()
10101085
}
10111086
}
10121087

1088+
class TestBoolComponent extends Component
1089+
{
1090+
public $bool;
1091+
1092+
public function __construct($bool)
1093+
{
1094+
$this->bool = $bool;
1095+
}
1096+
1097+
public function render()
1098+
{
1099+
return 'bool';
1100+
}
1101+
}
1102+
10131103
class TestContainerComponent extends Component
10141104
{
10151105
public function render()

0 commit comments

Comments
 (0)