diff --git a/src/Compiler.php b/src/Compiler.php index 3d589dc..2f6cff4 100644 --- a/src/Compiler.php +++ b/src/Compiler.php @@ -388,6 +388,7 @@ private function handleAttributeBinding(DOMElement $node) $dynamicValues[] = $templateStringContent; } else { + $value = $this->builder->refactorCondition($value); $this->logger->debug(sprintf('- setAttribute "%s" with value "%s"', $name, $value)); $dynamicValues[] = Replacements::getSanitizedConstant('DOUBLE_CURLY_OPEN') . @@ -579,12 +580,16 @@ private function transformCamelCaseToCSS(string $property): string private function stripEventHandlers(DOMElement $node) { + $removeAttributes = []; /** @var DOMAttr $attribute */ foreach ($node->attributes as $attribute) { if (strpos($attribute->name, 'v-on:') === 0 || strpos($attribute->name, '@') === 0) { - $node->removeAttribute($attribute->name); + $removeAttributes[] = $attribute->name; } } + foreach ($removeAttributes as $removeAttribute) { + $node->removeAttribute($removeAttribute); + } } protected function implodeAttributeValue(string $attribute, array $values, string $oldValue): string diff --git a/src/Utils/TwigBuilder.php b/src/Utils/TwigBuilder.php index 232222a..41e0e4d 100644 --- a/src/Utils/TwigBuilder.php +++ b/src/Utils/TwigBuilder.php @@ -171,6 +171,41 @@ public function sanitizeAttributeValue(string $value): string public function refactorCondition(string $condition): string { + $refactoredCondition = ''; + $charsCount = mb_strlen($condition, 'UTF-8'); + $quoteChar = null; + $lastChar = null; + $buffer = ''; + + for ($i = 0; $i < $charsCount; $i++) { + $char = mb_substr($condition, $i, 1, 'UTF-8'); + if ($quoteChar === null && ($char === '"' || $char === '\'')) { + $quoteChar = $char; + if ($buffer !== '') { + $refactoredCondition .= $this->refactorConditionPart($buffer); + $buffer = ''; + } + $refactoredCondition .= $char; + } elseif ($quoteChar === $char && $lastChar !== '\\') { + $quoteChar = null; + $refactoredCondition .= $char; + } else { + if ($quoteChar === null) { + $buffer .= $char; + } else { + $refactoredCondition .= $char; + } + } + $lastChar = $char; + } + if ($buffer !== '') { + $refactoredCondition .= $this->refactorConditionPart($buffer); + } + + return $refactoredCondition; + } + + private function refactorConditionPart($condition) { $condition = str_replace('===', '==', $condition); $condition = str_replace('!==', '!=', $condition); $condition = str_replace('&&', 'and', $condition); @@ -179,6 +214,8 @@ public function refactorCondition(string $condition): string $condition = str_replace('.length', '|length', $condition); $condition = str_replace('.trim', '|trim', $condition); +// $condition = $this->convertConcat($condition); + foreach (Replacements::getConstants() as $constant => $value) { $condition = str_replace($value, Replacements::getSanitizedConstant($constant), $condition); } @@ -188,9 +225,74 @@ public function refactorCondition(string $condition): string public function refactorTextNode(string $content): string { - $content = str_replace('.length', '|length', $content); - $content = str_replace('.trim', '|trim', $content); + $refactoredContent = ''; + $charsCount = mb_strlen($content, 'UTF-8'); + $open = false; + $lastChar = null; + $quoteChar = null; + $buffer = ''; + + for ($i = 0; $i < $charsCount; $i++) { + $char = mb_substr($content, $i, 1, 'UTF-8'); + if ($open === false) { + $refactoredContent .= $char; + if ($char === '{' && $lastChar === '{') { + $open = true; + } + } else { + $buffer .= $char; + if ($quoteChar === null && ($char === '"' || $char === '\'')) { + $quoteChar = $char; + } elseif ($quoteChar === $char && $lastChar !== '\\') { + $quoteChar = null; + } + if ($quoteChar === null && $char === '}' && $lastChar === '}') { + $open = false; + $buffer = $this->convertTemplateString(trim($buffer, '}')); + $refactoredContent .= $this->refactorCondition($buffer) . '}}'; + $buffer = ''; + } + } + $lastChar = $char; + } + return $refactoredContent; + } + + private function convertConcat($content) { + if (preg_match_all('/(\S*)(\s*\+\s*(\S+))+/', $content, $matches, PREG_SET_ORDER )) { + foreach ($matches as $match) { + $parts = explode('+', $match[0]); + $lastPart = null; + $convertedContent = ''; + foreach ($parts as $part) { + $part = trim($part); + if ($lastPart !== null) { + if (is_numeric($lastPart) && is_numeric($part)) { + $convertedContent .= ' + ' . $part; + } else { + $convertedContent .= ' ~ ' . $part; + } + } else { + $convertedContent = $part; + } + $lastPart = $part; + } + $content = str_replace($match[0], $convertedContent, $content); + } + } + + return $content; + } + + private function convertTemplateString($content) { + if (preg_match_all('/\`([^\`]+)\`/', $content, $matches, PREG_SET_ORDER )) { + foreach ($matches as $match) { + $match[1] = str_replace('${', '\' ~ ', $match[1]); + $match[1] = str_replace('}', ' ~ \'', $match[1]); + $content = str_replace($match[0], '\'' . $match[1] . '\'', $content); + } + } return $content; } diff --git a/tests/TextNodeTest.php b/tests/TextNodeTest.php new file mode 100644 index 0000000..37469de --- /dev/null +++ b/tests/TextNodeTest.php @@ -0,0 +1,67 @@ +