Skip to content

Commit f956435

Browse files
authoredAug 6, 2020
Merge pull request #65 from tronsha/feature/some-things-2020-01
Add v-model and v-pre
·
0.32.20.24.0
2 parents 8b09205 + 8a62f5d commit f956435

26 files changed

+675
-34
lines changed
 

‎README.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ Compile vue files to twig templates with PHP
1919
|v-bind|partially working|
2020
|v-bind:style|:white_check_mark:|
2121
|v-bind:class|:white_check_mark:|
22-
|v-model||
23-
|v-pre||
24-
|v-cloak||
22+
|v-model|partially working|
23+
|v-pre|:white_check_mark:|
24+
|v-cloak|:white_check_mark:|
2525
|v-once|:white_check_mark:|
2626

2727

‎src/Compiler.php‎

Lines changed: 201 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use DOMText;
1313
use Exception;
1414
use Paneon\VueToTwig\Models\Component;
15+
use Paneon\VueToTwig\Models\Pre;
1516
use Paneon\VueToTwig\Models\Property;
1617
use Paneon\VueToTwig\Models\Replacements;
1718
use Paneon\VueToTwig\Models\Slot;
@@ -39,6 +40,11 @@ class Compiler
3940
*/
4041
protected $lastCloseIf;
4142

43+
/**
44+
* @var mixed[]|null
45+
*/
46+
protected $selectData;
47+
4248
/**
4349
* @var LoggerInterface
4450
*/
@@ -69,6 +75,11 @@ class Compiler
6975
*/
7076
protected $properties;
7177

78+
/**
79+
* @var Pre[]
80+
*/
81+
protected $pre;
82+
7283
/**
7384
* @var mixed[]
7485
*/
@@ -105,9 +116,11 @@ public function __construct(DOMDocument $document, LoggerInterface $logger)
105116
$this->document = $document;
106117
$this->logger = $logger;
107118
$this->lastCloseIf = [];
119+
$this->selectData = null;
108120
$this->components = [];
109121
$this->banner = [];
110122
$this->properties = [];
123+
$this->pre = [];
111124
$this->rawBlocks = [];
112125

113126
$this->logger->debug("\n--------- New Compiler Instance ----------\n");
@@ -183,6 +196,8 @@ public function convert(): string
183196

184197
$html = $this->builder->concatConvertHandler($html, $this->properties);
185198

199+
$html = $this->replacePre($html);
200+
186201
if ($this->stripWhitespace) {
187202
$html = $this->stripWhitespace($html);
188203
}
@@ -211,9 +226,16 @@ public function convertNode(DOMNode $node, int $level = 0): DOMNode
211226
if ($this->twigRemove($node)) {
212227
return $node;
213228
}
229+
if ($this->handlePre($node)) {
230+
return $node;
231+
}
214232
$this->replaceShowWithIf($node);
215233
$this->handleIf($node, $level);
216234
$this->handleFor($node);
235+
$modelData = $this->handleModel($node);
236+
if ($modelData && $modelData['type'] === 'option') {
237+
$this->selectData = $modelData;
238+
}
217239
$this->handleHtml($node);
218240
$this->handleText($node);
219241
$this->stripEventHandlers($node);
@@ -298,6 +320,10 @@ public function convertNode(DOMNode $node, int $level = 0): DOMNode
298320

299321
if ($node instanceof DOMElement) {
300322
$this->handleAttributeBinding($node);
323+
$this->handleOption($node);
324+
if (isset($modelData)) {
325+
$this->handleRadioOrCheckbox($node, $modelData);
326+
}
301327
if ($level === 1) {
302328
foreach ($this->includeAttributes as $attribute) {
303329
$this->handleRootNodeAttribute($node, $attribute);
@@ -309,6 +335,10 @@ public function convertNode(DOMNode $node, int $level = 0): DOMNode
309335
$this->convertNode($childNode, $level + 1);
310336
}
311337

338+
if ($node->nodeName === 'selected') {
339+
$this->selectData = null;
340+
}
341+
312342
return $node;
313343
}
314344

@@ -373,16 +403,16 @@ public function registerProperties(DOMElement $scriptElement): void
373403
$property->setType($matchType[1]);
374404
}
375405

376-
if (preg_match('/default:\s*(?<default>[^,$]+)\s*,?/mx', $definition, $matchDefault)) {
406+
if (preg_match('/default:\s*(?<default>\[[^\[\]]+\]|[^,$]+)\s*,?/mx', $definition, $matchDefault)) {
377407
$property->setDefault(trim($matchDefault['default']));
378408
}
379409

380410
$this->properties[$propName] = $property;
381411
}
382412
}
383413

384-
$typeScriptRegexProps = '/\@Prop\s*\({(?<propOptions>.*?)}\)[^;]*?(?<propName>[a-zA-Z0-9_$]+)\!?\:\s*(?<propType>[a-zA-Z]+)[^;\@]*;/msx';
385-
$typeScriptRegexDefault = '/default\s*\:\s*(?<defaultValue>\'(?:.(?!(?<![\\\\])\'))*.?\'|"(?:.(?!(?<![\\\\])"))*.?"|[a-zA-Z0-9_]+)/msx';
414+
$typeScriptRegexProps = '/\@Prop\s*\({(?<propOptions>.*?)}\)[^;]*?(?<propName>[a-zA-Z0-9_$]+)\!?\:\s*(?<propType>[a-zA-Z\[\]]+)[^;\@]*;/msx';
415+
$typeScriptRegexDefault = '/default\s*\:\s*(?<defaultValue>\'(?:.(?!(?<![\\\\])\'))*.?\'|"(?:.(?!(?<![\\\\])"))*.?"|[a-zA-Z0-9_]+|\[[^\[\]]+\])/msx';
386416
if (preg_match_all($typeScriptRegexProps, $content, $typeScriptMatches, PREG_SET_ORDER)) {
387417
$this->properties = [];
388418
foreach ($typeScriptMatches as $typeScriptMatch) {
@@ -396,6 +426,42 @@ public function registerProperties(DOMElement $scriptElement): void
396426
}
397427
}
398428

429+
/**
430+
* @throws Exception
431+
*/
432+
public function handlePre(DOMElement $node): bool
433+
{
434+
if (!$node->hasAttribute('v-pre')) {
435+
return false;
436+
}
437+
$node->removeAttribute('v-pre');
438+
$html = $this->document->saveHTML($node);
439+
$parentNode = $node->parentNode;
440+
$parentNode->removeChild($node);
441+
$pre = new Pre('{% verbatim %}' . $html . '{% endverbatim %}');
442+
$key = $pre->getPreContentVariableString();
443+
$replacer = $this->document->createTextNode($key);
444+
$parentNode->appendChild($replacer);
445+
$this->pre[$key] = $pre;
446+
447+
return true;
448+
}
449+
450+
protected function replacePre(string $html): string
451+
{
452+
if (preg_match_all(Pre::PRE_REGEX, $html, $matches)) {
453+
foreach ($matches[0] as $key) {
454+
$html = str_replace(
455+
$key,
456+
$this->pre[$key]->getValue(),
457+
$html
458+
);
459+
}
460+
}
461+
462+
return $html;
463+
}
464+
399465
public function replaceShowWithIf(DOMElement $node): void
400466
{
401467
if ($node->hasAttribute('v-show')) {
@@ -553,7 +619,7 @@ private function cleanupAttributes(DOMElement $node): void
553619
/** @var DOMAttr $attribute */
554620
foreach ($node->attributes as $attribute) {
555621
if (
556-
(preg_match('/^v-([a-z]*)/', $attribute->name, $matches) === 1 && $matches[1] !== 'bind' && $matches[1] !== 'slot')
622+
(preg_match('/^v-([a-z]*)/', $attribute->name, $matches) === 1 && $matches[1] !== 'bind' && $matches[1] !== 'slot' && $matches[1] !== 'cloak')
557623
|| preg_match('/^[:]?ref$/', $attribute->name) === 1
558624
) {
559625
$removeAttributes[] = $attribute->name;
@@ -678,6 +744,135 @@ private function handleFor(DOMElement $node): void
678744
$node->removeAttribute('v-for');
679745
}
680746

747+
/**
748+
* @return mixed|void
749+
*/
750+
private function handleModel(DOMElement $node)
751+
{
752+
if (!$node->hasAttribute('v-model')) {
753+
return;
754+
}
755+
756+
$modelValue = $node->getAttribute('v-model');
757+
$node->removeAttribute('v-mode');
758+
759+
switch ($node->nodeName) {
760+
case 'textarea':
761+
$node->setAttribute('v-text', $modelValue);
762+
763+
return null;
764+
case 'input':
765+
$typeAttribute = $node->getAttribute('type');
766+
if ($typeAttribute === 'checkbox') {
767+
return [
768+
'value' => $modelValue,
769+
'type' => 'checkbox',
770+
];
771+
} elseif ($typeAttribute === 'radio') {
772+
return [
773+
'value' => $modelValue,
774+
'type' => 'radio',
775+
];
776+
} else {
777+
$node->setAttribute(':value', $modelValue);
778+
}
779+
780+
return null;
781+
case 'select':
782+
return [
783+
'value' => $modelValue,
784+
'multiple' => $node->hasAttribute('multiple'),
785+
'type' => 'option',
786+
];
787+
default:
788+
return null;
789+
}
790+
}
791+
792+
/**
793+
* @throws ReflectionException
794+
*/
795+
private function handleOption(DOMElement $node): void
796+
{
797+
if ($node->tagName !== 'option' || $this->selectData === null) {
798+
return;
799+
}
800+
801+
if ($node->hasAttribute('value')) {
802+
$value = $node->getAttribute('value');
803+
} else {
804+
$value = trim($node->textContent);
805+
}
806+
807+
$value = '"' . str_replace(['__DOUBLE_CURLY_OPEN__', '__DOUBLE_CURLY_CLOSE__'], ['" ~', '~ "'], $value) . '"';
808+
809+
if ($this->selectData['multiple']) {
810+
$condition = $this->selectData['value'] . ' is iterable and ' . $value . ' in ' . $this->selectData['value'];
811+
} else {
812+
$condition = $this->selectData['value'] . ' == ' . $value;
813+
}
814+
815+
$this->addAttributeIf($node, $condition, 'selected', 'selected');
816+
}
817+
818+
/**
819+
* @param mixed[] $modelData
820+
*
821+
* @throws ReflectionException
822+
*/
823+
private function handleRadioOrCheckbox(DOMElement $node, array $modelData): void
824+
{
825+
if (!$node->hasAttribute('value')
826+
|| !$node->hasAttribute('type')
827+
|| ($node->getAttribute('type') !== 'radio' && $node->getAttribute('type') !== 'checkbox')) {
828+
return;
829+
}
830+
831+
$value = $node->getAttribute('value');
832+
833+
$value = '"' . str_replace(['__DOUBLE_CURLY_OPEN__', '__DOUBLE_CURLY_CLOSE__'], ['" ~', '~ "'], $value) . '"';
834+
835+
if ($modelData['type'] === 'checkbox') {
836+
$condition = '(' . $modelData['value'] . ' is iterable and ' . $value . ' in ' . $modelData['value'] . ') '
837+
. ' or (' . $modelData['value'] . ' is not iterable and ' . $modelData['value'] . ')';
838+
} else {
839+
$condition = $modelData['value'] . ' == ' . $value;
840+
}
841+
842+
$this->addAttributeIf($node, $condition, 'checked', 'checked');
843+
}
844+
845+
/**
846+
* @throws ReflectionException
847+
*/
848+
private function addAttributeIf(DOMElement $node, string $condition, string $attributeName, string $attributeValue): void
849+
{
850+
/** @var DOMElement $clonedNode */
851+
$clonedNode = $node->cloneNode(true);
852+
$node->setAttribute($attributeName, $attributeValue);
853+
854+
if ($clonedNode->hasAttribute($attributeName)) {
855+
$clonedNode->removeAttribute($attributeName);
856+
}
857+
858+
$node->parentNode->insertBefore(
859+
$this->document->createTextNode($this->builder->createIf($condition)),
860+
$node
861+
);
862+
$node->parentNode->insertBefore(
863+
$this->document->createTextNode($this->builder->createEndIf()),
864+
$node->nextSibling
865+
);
866+
$node->parentNode->insertBefore(
867+
$clonedNode,
868+
$node->nextSibling
869+
);
870+
$node->parentNode->insertBefore(
871+
$this->document->createTextNode($this->builder->createElse()),
872+
$node->nextSibling
873+
);
874+
}
875+
681876
private function handleHtml(DOMElement $node): void
682877
{
683878
if (!$node->hasAttribute('v-html')) {
@@ -689,7 +884,7 @@ private function handleHtml(DOMElement $node): void
689884
while ($node->hasChildNodes()) {
690885
$node->removeChild($node->firstChild);
691886
}
692-
$node->appendChild(new DOMText('{{' . $html . '|raw}}'));
887+
$node->appendChild(new DOMText($this->builder->prepareBindingOutput($html . '|raw')));
693888
}
694889

695890
private function handleText(DOMElement $node): void
@@ -703,7 +898,7 @@ private function handleText(DOMElement $node): void
703898
while ($node->hasChildNodes()) {
704899
$node->removeChild($node->firstChild);
705900
}
706-
$node->appendChild(new DOMText('{{' . $text . '}}'));
901+
$node->appendChild(new DOMText($this->builder->prepareBindingOutput($text)));
707902
}
708903

709904
/**

‎src/Models/Pre.php‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Paneon\VueToTwig\Models;
6+
7+
use Exception;
8+
use Ramsey\Uuid\Uuid;
9+
10+
class Pre
11+
{
12+
public const PRE_REGEX = '/__PRE_[a-f0-9]{8}_[a-f0-9]{4}_[a-f0-9]{4}_[a-f0-9]{4}_[a-f0-9]{12}__/';
13+
14+
/**
15+
* @var string
16+
*/
17+
protected $uuid;
18+
19+
/**
20+
* @var string
21+
*/
22+
protected $value;
23+
24+
/**
25+
* Slot constructor.
26+
*
27+
* @throws Exception
28+
*/
29+
public function __construct(string $value)
30+
{
31+
$this->uuid = Uuid::uuid4()->toString();
32+
$this->value = $value;
33+
}
34+
35+
public function getValue(): string
36+
{
37+
return $this->value;
38+
}
39+
40+
public function setValue(string $value): void
41+
{
42+
$this->value = $value;
43+
}
44+
45+
public function getPreContentVariableString(): string
46+
{
47+
return '__PRE_' . str_replace('-', '_', $this->uuid) . '__';
48+
}
49+
50+
public function getUuid(): string
51+
{
52+
return $this->uuid;
53+
}
54+
}

‎tests/VueCloakTest.php‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Paneon\VueToTwig\Tests;
4+
5+
use Exception;
6+
7+
class VueCloakTest extends AbstractTestCase
8+
{
9+
/**
10+
* @throws Exception
11+
*/
12+
public function testVueCloak()
13+
{
14+
$vueTemplate = '<template><div v-cloak></div></template>';
15+
16+
$expected = '<div v-cloak class="{{ class|default(\'\') }}" style="{{ style|default(\'\') }}"></div>';
17+
18+
$compiler = $this->createCompiler($vueTemplate);
19+
20+
$actual = $compiler->convert();
21+
22+
$this->assertEqualHtml($expected, $actual);
23+
}
24+
}

‎tests/VueModelTest.php‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace Paneon\VueToTwig\Tests;
4+
5+
use Exception;
6+
7+
class VueModelTest extends AbstractTestCase
8+
{
9+
/**
10+
* @dataProvider dataProvider
11+
*
12+
* @param mixed $html
13+
* @param mixed $expected
14+
*
15+
* @throws Exception
16+
*/
17+
public function testComponent($html, $expected)
18+
{
19+
$compiler = $this->createCompiler($html);
20+
21+
$actual = $compiler->convert();
22+
23+
$this->assertEqualHtml($expected, $actual);
24+
}
25+
26+
/**
27+
* @return array
28+
*/
29+
public function dataProvider()
30+
{
31+
return $this->loadFixturesFromDir('vue-model');
32+
}
33+
}

‎tests/VuePreTest.php‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Paneon\VueToTwig\Tests;
4+
5+
use Exception;
6+
7+
class VuePreTest extends AbstractTestCase
8+
{
9+
/**
10+
* @dataProvider dataProvider
11+
12+
*
13+
* @throws Exception
14+
*/
15+
public function testVuePre($template, $expected)
16+
{
17+
$compiler = $this->createCompiler($template);
18+
19+
$actual = $compiler->convert();
20+
21+
$this->assertEqualHtml($expected, $actual);
22+
}
23+
24+
/**
25+
* @return array
26+
*/
27+
public function dataProvider()
28+
{
29+
return [
30+
[
31+
'<template><div v-pre><div v-if="true">{{ 42 }}</div></div></template>',
32+
'{% verbatim %}<div><div v-if="true">{{ 42 }}</div></div>{% endverbatim %}',
33+
],
34+
[
35+
'<template><div v-pre v-if="true" class="foo"><h2 v-if="headline">{{ headline }}</h2><div class="bar"><Spinner><span v-if="button">{{ button }}</span></Spinner></div></div></template>',
36+
'{% verbatim %}<div v-if="true" class="foo"><h2 v-if="headline">{{ headline }}</h2><div class="bar"><spinner><span v-if="button">{{ button }}</span></spinner></div></div>{% endverbatim %}',
37+
],
38+
];
39+
}
40+
}
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
22
<div style="{{ 'fontSize: ' ~ size ~ 'px' }};"></div>
3-
<div>{{'foo' ~ ' bar'}}</div>
4-
<div>{{text ~ ' foo'}}</div>
5-
<div>{{text ~ 1}}</div>
6-
<div>{{size ~ ' foo'}}</div>
7-
<div>{{size + 1}}</div>
8-
<div>{{1 + 1}}</div>
3+
<div>{{ 'foo' ~ ' bar' }}</div>
4+
<div>{{ text ~ ' foo' }}</div>
5+
<div>{{ text ~ 1 }}</div>
6+
<div>{{ size ~ ' foo' }}</div>
7+
<div>{{ size + 1 }}</div>
8+
<div>{{ 1 + 1 }}</div>
99
</div>

‎tests/fixtures/concat/concat.twig‎

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
22
<div style="{{ 'fontSize: ' ~ size ~ 'px' }};"></div>
3-
<div>{{'foo' ~ ' bar'}}</div>
4-
<div>{{text ~ ' foo'}}</div>
5-
<div>{{text ~ 1}}</div>
6-
<div>{{size ~ ' foo'}}</div>
7-
<div>{{size + 1}}</div>
8-
<div>{{1 + 1}}</div>
9-
<div>{{'foo ' ~ size ~ size ~ ' bar'}}</div>
10-
<div>{{'foo ' ~ ( size + size ) ~ ' bar'}}</div>
11-
<div>{{'foo ' ~ ( 1 + size ) ~ ' bar'}}</div>
12-
<div>{{1 ~ ( 'foo' ~ size ) ~ 2}}</div>
13-
<div>{{'foo ' ~ ( ( 1 + 2 ) ~ ( ' bar ' ~ ' baz ' ) ~ ( ' waz ' ~ 3 ) )}}</div>
14-
<div>{{'foo ' ~ ( size * size ) ~ ' bar'}}</div>
15-
<div>{{( size * size ) + 2}}</div>
16-
<div>{{( size * size ) / 2 + 10}}</div>
17-
<div>{{( size * size ) % 2 + 10}}</div>
18-
<div>{{( size - 10 ) * 2 + 10}}</div>
19-
<div>{{'20 - 10 - 5' ~ 10}}</div>
3+
<div>{{ 'foo' ~ ' bar' }}</div>
4+
<div>{{ text ~ ' foo' }}</div>
5+
<div>{{ text ~ 1 }}</div>
6+
<div>{{ size ~ ' foo' }}</div>
7+
<div>{{ size + 1 }}</div>
8+
<div>{{ 1 + 1 }}</div>
9+
<div>{{ 'foo ' ~ size ~ size ~ ' bar' }}</div>
10+
<div>{{ 'foo ' ~ ( size + size ) ~ ' bar' }}</div>
11+
<div>{{ 'foo ' ~ ( 1 + size ) ~ ' bar' }}</div>
12+
<div>{{ 1 ~ ( 'foo' ~ size ) ~ 2 }}</div>
13+
<div>{{ 'foo ' ~ ( ( 1 + 2 ) ~ ( ' bar ' ~ ' baz ' ) ~ ( ' waz ' ~ 3 ) ) }}</div>
14+
<div>{{ 'foo ' ~ ( size * size ) ~ ' bar' }}</div>
15+
<div>{{ ( size * size ) + 2 }}</div>
16+
<div>{{ ( size * size ) / 2 + 10 }}</div>
17+
<div>{{ ( size * size ) % 2 + 10 }}</div>
18+
<div>{{ ( size - 10 ) * 2 + 10 }}</div>
19+
<div>{{ '20 - 10 - 5' ~ 10 }}</div>
2020
</div>

‎tests/fixtures/vue-html/html.twig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{% set rawHtml = '<strong>text</strong>' %}
22
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
33
<span>
4-
{{rawHtml|raw}}
4+
{{ rawHtml|raw }}
55
</span>
66
</div>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{% set foo = foo|default(['2', '4', '5']) %}
2+
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
3+
{% if (foo is iterable and "1" in foo) or (foo is not iterable and foo) %}
4+
<input type="checkbox" value="1" checked>
5+
{% else %}
6+
<input type="checkbox" value="1">
7+
{% endif %}
8+
{% if (foo is iterable and "2" in foo) or (foo is not iterable and foo) %}
9+
<input type="checkbox" value="2" checked>
10+
{% else %}
11+
<input type="checkbox" value="2">
12+
{% endif %}
13+
{% if (foo is iterable and "3" in foo) or (foo is not iterable and foo) %}
14+
<input type="checkbox" value="3" checked>
15+
{% else %}
16+
<input type="checkbox" value="3">
17+
{% endif %}
18+
{% if (foo is iterable and "4" in foo) or (foo is not iterable and foo) %}
19+
<input type="checkbox" value="4" checked>
20+
{% else %}
21+
<input type="checkbox" value="4">
22+
{% endif %}
23+
{% if (foo is iterable and "5" in foo) or (foo is not iterable and foo) %}
24+
<input type="checkbox" value="5" checked>
25+
{% else %}
26+
<input type="checkbox" value="5">
27+
{% endif %}
28+
</div>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<template>
2+
<div>
3+
<input type="checkbox" v-model="foo" value="1">
4+
<input type="checkbox" v-model="foo" value="2">
5+
<input type="checkbox" v-model="foo" value="3">
6+
<input type="checkbox" v-model="foo" value="4">
7+
<input type="checkbox" v-model="foo" value="5">
8+
</div>
9+
</template>
10+
11+
<script>
12+
export default {
13+
props: {
14+
foo: {
15+
type: String,
16+
default: ['2', '4', '5'],
17+
},
18+
},
19+
};
20+
</script>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{% set foo = foo|default('2') %}
2+
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
3+
{% if foo == "1" %}
4+
<input type="radio" value="1" checked>
5+
{% else %}
6+
<input type="radio" value="1">
7+
{% endif %}
8+
{% if foo == "2" %}
9+
<input type="radio" value="2" checked>
10+
{% else %}
11+
<input type="radio" value="2">
12+
{% endif %}
13+
{% if foo == "3" %}
14+
<input type="radio" value="3" checked>
15+
{% else %}
16+
<input type="radio" value="3">
17+
{% endif %}
18+
{% if foo == "4" %}
19+
<input type="radio" value="4" checked>
20+
{% else %}
21+
<input type="radio" value="4">
22+
{% endif %}
23+
{% if foo == "5" %}
24+
<input type="radio" value="5" checked>
25+
{% else %}
26+
<input type="radio" value="5">
27+
{% endif %}
28+
</div>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<template>
2+
<div>
3+
<input type="radio" v-model="foo" value="1">
4+
<input type="radio" v-model="foo" value="2">
5+
<input type="radio" v-model="foo" value="3">
6+
<input type="radio" v-model="foo" value="4">
7+
<input type="radio" v-model="foo" value="5">
8+
</div>
9+
</template>
10+
11+
<script>
12+
export default {
13+
props: {
14+
foo: {
15+
type: String,
16+
default: '2',
17+
},
18+
},
19+
};
20+
</script>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{% set foo = foo|default('bar') %}
2+
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
3+
<input type="text" value="{{ foo }}">
4+
</div>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<template>
2+
<div>
3+
<input type="text" v-model="foo">
4+
</div>
5+
</template>
6+
7+
<script>
8+
export default {
9+
props: {
10+
foo: {
11+
type: String,
12+
default: 'bar',
13+
},
14+
},
15+
};
16+
</script>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{% set foo = foo|default(['2', '3']) %}
2+
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
3+
<select multiple>
4+
{% if foo is iterable and "1" in foo %}
5+
<option value="1" selected>foo</option>
6+
{% else %}
7+
<option value="1">foo</option>
8+
{% endif %}
9+
{% if foo is iterable and "2" in foo %}
10+
<option value="2" selected>bar</option>
11+
{% else %}
12+
<option value="2">bar</option>
13+
{% endif %}
14+
{% if foo is iterable and "3" in foo %}
15+
<option value="3" selected>baz</option>
16+
{% else %}
17+
<option value="3">baz</option>
18+
{% endif %}
19+
</select>
20+
</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<template>
2+
<div>
3+
<select v-model="foo" multiple>
4+
<option value="1">foo</option>
5+
<option value="2">bar</option>
6+
<option value="3">baz</option>
7+
</select>
8+
</div>
9+
</template>
10+
11+
<script lang="ts">
12+
import { Component, Vue, Prop } from 'vue-property-decorator';
13+
@Component
14+
export default class ButtonCollectionContainer extends Vue {
15+
@Prop({ type: Array, default: ['2', '3'] }) readonly foo!: string[];
16+
}
17+
</script>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{% set foo = foo|default(['2', '3']) %}
2+
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
3+
<select multiple>
4+
{% if foo is iterable and "1" in foo %}
5+
<option value="1" selected>foo</option>
6+
{% else %}
7+
<option value="1">foo</option>
8+
{% endif %}
9+
{% if foo is iterable and "2" in foo %}
10+
<option value="2" selected>bar</option>
11+
{% else %}
12+
<option value="2">bar</option>
13+
{% endif %}
14+
{% if foo is iterable and "3" in foo %}
15+
<option value="3" selected>baz</option>
16+
{% else %}
17+
<option value="3">baz</option>
18+
{% endif %}
19+
</select>
20+
</div>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<template>
2+
<div>
3+
<select v-model="foo" multiple>
4+
<option value="1">foo</option>
5+
<option value="2">bar</option>
6+
<option value="3">baz</option>
7+
</select>
8+
</div>
9+
</template>
10+
11+
<script>
12+
export default {
13+
props: {
14+
foo: {
15+
type: Array,
16+
default: ['2', '3'],
17+
},
18+
},
19+
};
20+
</script>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{% set foo = foo|default('2') %}
2+
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
3+
<select>
4+
{% if foo == "1" %}
5+
<option value="1" selected>foo</option>
6+
{% else %}
7+
<option value="1">foo</option>
8+
{% endif %}
9+
{% if foo == "2" %}
10+
<option value="2" selected>bar</option>
11+
{% else %}
12+
<option value="2">bar</option>
13+
{% endif %}
14+
{% if foo == "3" %}
15+
<option value="3" selected>baz</option>
16+
{% else %}
17+
<option value="3">baz</option>
18+
{% endif %}
19+
</select>
20+
</div>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<template>
2+
<div>
3+
<select v-model="foo">
4+
<option value="1">foo</option>
5+
<option value="2">bar</option>
6+
<option value="3">baz</option>
7+
</select>
8+
</div>
9+
</template>
10+
11+
<script>
12+
export default {
13+
props: {
14+
foo: {
15+
type: String,
16+
default: '2',
17+
},
18+
},
19+
};
20+
</script>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{% set foo = foo|default('bar') %}
2+
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
3+
<select>
4+
{% if foo == "foo" %}
5+
<option selected>foo</option>
6+
{% else %}
7+
<option>foo</option>
8+
{% endif %}
9+
{% if foo == "bar" %}
10+
<option selected>bar</option>
11+
{% else %}
12+
<option>bar</option>
13+
{% endif %}
14+
{% if foo == "baz" %}
15+
<option selected>baz</option>
16+
{% else %}
17+
<option>baz</option>
18+
{% endif %}
19+
</select>
20+
</div>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<template>
2+
<div>
3+
<select v-model="foo">
4+
<option>foo</option>
5+
<option>bar</option>
6+
<option>baz</option>
7+
</select>
8+
</div>
9+
</template>
10+
11+
<script>
12+
export default {
13+
props: {
14+
foo: {
15+
type: String,
16+
default: 'bar',
17+
},
18+
},
19+
};
20+
</script>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% set foo = foo|default('bar') %}
2+
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
3+
<textarea>
4+
{{ foo }}
5+
</textarea>
6+
</div>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<template>
2+
<div>
3+
<textarea v-model="foo" />
4+
</div>
5+
</template>
6+
7+
<script>
8+
export default {
9+
props: {
10+
foo: {
11+
type: String,
12+
default: 'bar',
13+
},
14+
},
15+
};
16+
</script>

‎tests/fixtures/vue-text/text.twig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{% set text = 'follow the white rabbit' %}
22
<div class="{{ class|default('') }}" style="{{ style|default('') }}">
33
<span>
4-
{{text}}
4+
{{ text }}
55
</span>
66
</div>

0 commit comments

Comments
 (0)
Please sign in to comment.