|
12 | 12 | use DOMText; |
13 | 13 | use Exception; |
14 | 14 | use Paneon\VueToTwig\Models\Component; |
| 15 | +use Paneon\VueToTwig\Models\Data; |
15 | 16 | use Paneon\VueToTwig\Models\Pre; |
16 | 17 | use Paneon\VueToTwig\Models\Property; |
17 | 18 | use Paneon\VueToTwig\Models\Replacements; |
@@ -75,6 +76,11 @@ class Compiler |
75 | 76 | */ |
76 | 77 | protected $properties; |
77 | 78 |
|
| 79 | + /** |
| 80 | + * @var Data[]|null |
| 81 | + */ |
| 82 | + protected $data = null; |
| 83 | + |
78 | 84 | /** |
79 | 85 | * @var Pre[] |
80 | 86 | */ |
@@ -171,6 +177,10 @@ public function convert(): string |
171 | 177 | if ($scriptElement) { |
172 | 178 | $this->registerProperties($scriptElement); |
173 | 179 | $this->insertDefaultValues(); |
| 180 | + if ($this->data !== null) { |
| 181 | + $this->registerData($scriptElement); |
| 182 | + $this->insertData(); |
| 183 | + } |
174 | 184 | } |
175 | 185 |
|
176 | 186 | if ($twigBlocks->length) { |
@@ -246,6 +256,9 @@ private function handleTwigConfig(string $twigConfig): void |
246 | 256 | $attributes = array_map(function ($item) { return trim($item); }, $attributes); |
247 | 257 | $this->attributesWithIf = array_merge($this->attributesWithIf, $attributes); |
248 | 258 | } |
| 259 | + if ($config['disable-data-support'] ?? false) { |
| 260 | + $this->data = null; |
| 261 | + } |
249 | 262 | } |
250 | 263 |
|
251 | 264 | /** |
@@ -484,6 +497,74 @@ public function registerProperties(DOMElement $scriptElement): void |
484 | 497 | } |
485 | 498 | } |
486 | 499 |
|
| 500 | + public function registerData(DOMElement $scriptElement): void |
| 501 | + { |
| 502 | + $content = $this->innerHtmlOfNode($scriptElement); |
| 503 | + if ($scriptElement->hasAttribute('lang') && $scriptElement->getAttribute('lang') === 'ts') { |
| 504 | + // TypeScript |
| 505 | + preg_match_all('/private\s+(\S+)\s*=\s*(.+?);\ *\n/msi', $content, $matches, PREG_SET_ORDER); |
| 506 | + foreach ($matches as $match) { |
| 507 | + $this->data[] = new Data( |
| 508 | + trim($match[1]), |
| 509 | + trim($this->builder->refactorCondition(str_replace('this.', '', $match[2]))) |
| 510 | + ); |
| 511 | + } |
| 512 | + } else { |
| 513 | + // JavaScript |
| 514 | + if (preg_match('/data\(\)\s*{\s*return\s*{(.+?)\s*}\s*;\s*}\s*,/msi', $content, $match)) { |
| 515 | + $dataString = $match[1]; |
| 516 | + $charsCount = mb_strlen($dataString, 'UTF-8'); |
| 517 | + $dataArray = []; |
| 518 | + $dataCount = 0; |
| 519 | + $dataArray[$dataCount] = ''; |
| 520 | + $bracketOpenCount = 0; |
| 521 | + $quoteChar = null; |
| 522 | + $lastChar = null; |
| 523 | + $commentOpen = false; |
| 524 | + for ($i = 0; $i < $charsCount; ++$i) { |
| 525 | + $char = mb_substr($dataString, $i, 1, 'UTF-8'); |
| 526 | + $nextChar = mb_substr($dataString, $i + 1, 1, 'UTF-8'); |
| 527 | + if ($char === '*' && $nextChar === '/') { |
| 528 | + ++$i; |
| 529 | + $commentOpen = false; |
| 530 | + continue; |
| 531 | + } |
| 532 | + if (($char === '/' && $nextChar === '*') || $commentOpen) { |
| 533 | + $commentOpen = true; |
| 534 | + continue; |
| 535 | + } |
| 536 | + if ($quoteChar === null && ($char === '"' || $char === '\'')) { |
| 537 | + $quoteChar = $char; |
| 538 | + } elseif ($quoteChar === $char && $lastChar !== '\\') { |
| 539 | + $quoteChar = null; |
| 540 | + } |
| 541 | + if (($char === '[' || $char === '{') && $quoteChar === null) { |
| 542 | + ++$bracketOpenCount; |
| 543 | + $dataArray[$dataCount] .= $char; |
| 544 | + } elseif (($char === ']' || $char === '}') && $quoteChar === null) { |
| 545 | + --$bracketOpenCount; |
| 546 | + $dataArray[$dataCount] .= $char; |
| 547 | + } elseif ($char === ',' && $bracketOpenCount === 0 && $quoteChar === null) { |
| 548 | + ++$dataCount; |
| 549 | + $dataArray[$dataCount] = ''; |
| 550 | + } else { |
| 551 | + $dataArray[$dataCount] .= $char; |
| 552 | + } |
| 553 | + $lastChar = $char; |
| 554 | + } |
| 555 | + foreach ($dataArray as $data) { |
| 556 | + if (substr_count($data, ':')) { |
| 557 | + [$name, $value] = explode(':', $data, 2); |
| 558 | + $this->data[] = new Data( |
| 559 | + trim($name), |
| 560 | + trim($this->builder->refactorCondition(str_replace('this.', '', $value))) |
| 561 | + ); |
| 562 | + } |
| 563 | + } |
| 564 | + } |
| 565 | + } |
| 566 | + } |
| 567 | + |
487 | 568 | /** |
488 | 569 | * @throws Exception |
489 | 570 | */ |
@@ -1147,6 +1228,13 @@ public function disableStyleInclude(): Compiler |
1147 | 1228 | return $this; |
1148 | 1229 | } |
1149 | 1230 |
|
| 1231 | + public function enableDataSupport(): Compiler |
| 1232 | + { |
| 1233 | + $this->data = []; |
| 1234 | + |
| 1235 | + return $this; |
| 1236 | + } |
| 1237 | + |
1150 | 1238 | public function setStyleBlockOutputType(int $outputType): Compiler |
1151 | 1239 | { |
1152 | 1240 | $this->styleBuilder->setOutputType($outputType); |
@@ -1274,6 +1362,13 @@ protected function insertDefaultValues(): void |
1274 | 1362 | } |
1275 | 1363 | } |
1276 | 1364 |
|
| 1365 | + protected function insertData(): void |
| 1366 | + { |
| 1367 | + foreach ($this->data as $data) { |
| 1368 | + $this->rawBlocks[] = '{% set ' . $data->getName() . ' = ' . $data->getValue() . ' %}'; |
| 1369 | + } |
| 1370 | + } |
| 1371 | + |
1277 | 1372 | protected function handleRootNodeAttribute(DOMElement $node, ?string $name = null): DOMElement |
1278 | 1373 | { |
1279 | 1374 | if (!$name) { |
|
0 commit comments