Created
December 17, 2020 15:11
-
-
Save LionsAd/ce4e375cbe0fd9435ba42b7b43125d03 to your computer and use it in GitHub Desktop.
Very WIP code for creating automatic compiled code for <x-alert> style components
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function component($name, $functions) { | |
print_r([$name, $functions]); | |
if ($name == 'alert--0') { | |
$func = $functions['slot_title']; | |
$func(); | |
} | |
} | |
?> | |
<?php component('alert--0', [function() { ?> | |
<?php }, 'slot_title' => function() { ?> | |
<h1 class="alert-{{ $type }}">Error occurred | |
<x-bar> | |
</x-bar> | |
</h1> | |
<?php }, function() { ?> | |
Lorem ipsum … | |
<x-heading-3 tabindex="-1" :heading-attributes="component.attributes"> | |
<x-foo class="x-{{ $type }}" :tabindex="component.tabindex" index="{{ $i }}"> | |
Some heading | |
</x-foo> | |
<x-foo class="x-{{ $type }}" :tabindex="component.tabindex" index="{{ $i }}"> | |
Some heading 2 | |
</x-foo> | |
</x-heading-3> | |
<x-example-content name="alert" alert-type="{{ $type }}" :alert-data="complex" :component-data="component.data" /> | |
<?php }]); ?> | |
<?php component('list--0', [function() { ?> | |
<x-list-item class="item-1"> | |
<x-list class="submenu-1"> | |
<x-list-item class="subitem-1">Hi</x-list-item> | |
</x-list> | |
</x-list-item> | |
<?php }]); ?> | |
<?php component('list--0', [function() { ?> | |
<?php }]); ?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function component($name, $slots=[]) { | |
print_r([$name, $slots]); | |
if ($name == 'alert--0') { | |
$func = $slots['slot_title']; | |
$func(); | |
print_r(['==============']); | |
$func = $slots[1]; | |
$func(); | |
} | |
} | |
?> | |
<?php component('alert--0', [function() { ?> | |
<?php }, 'slot_title' => function() { ?> | |
<h1 class="alert-{{ $type }}">Error occurred | |
<?php component('bar--0', [function() { ?> | |
<?php }, 'slot_xyz_default' => function() { ?>Some data<?php }, function() { ?> | |
<?php }]); ?> | |
</h1> | |
<?php }, function() { ?> | |
Lorem ipsum … | |
<?php component('heading-3--0', [function() { ?> | |
<?php component('foo--0', [function() { ?> | |
Some heading | |
<?php }]); ?> | |
<?php component('foo--0', [function() { ?> | |
Some heading 2 | |
<?php }]); ?> | |
<?php }]); ?> | |
<x-example-content name="alert" alert-type="{{ $type }}" :alert-data="complex" :component-data="component.data" /> | |
<?php }]); ?> | |
<?php component('list--0', [function() { ?> | |
<?php component('list-item--0', [function() { ?> | |
<?php component('list--1', [function() { ?> | |
<?php component('list-item--1', [function() { ?>Hi<?php }]); ?> | |
<?php }]); ?> | |
<?php }]); ?> | |
<?php }]); ?> | |
<?php component('list--0', [function() { ?> | |
<?php }]); ?> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function compileRegularEchos($value) | |
{ | |
$contentTags = ['{{', '}}']; | |
$pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $contentTags[0], $contentTags[1]); | |
$callback = function ($matches) { | |
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3]; | |
//$echoFormat = 'e(%s)'; | |
$echoFormat = '(%s)'; | |
$wrapped = sprintf($echoFormat, $matches[2]); | |
return $matches[1] ? substr($matches[0], 1) : "<?php echo {$wrapped}; ?>{$whitespace}"; | |
}; | |
return preg_replace_callback($pattern, $callback, $value); | |
} | |
function compileAttributeEchos($value) { | |
$value = compileRegularEchos($value); | |
// escapeSingleQuotesOutsideOfPhpBlocks | |
$tokens = token_get_all($value); | |
$data = []; | |
foreach ($tokens as $token) { | |
if (! is_array($token)) { | |
$data[] = $token; | |
continue; | |
} | |
$data[] = $token[0] === T_INLINE_HTML | |
? str_replace("'", "\\'", $token[1]) | |
: $token[1]; | |
} | |
$value = implode('', $data); | |
$value = str_replace('<?php echo ', '\'.', $value); | |
$value = str_replace('; ?>', '.\'', $value); | |
return $value; | |
return $value; | |
}; | |
$value = ' | |
<x-alert class="foo" type="{{ $type }}-foo" :complex-data="$complex"> | |
<x-slot name="title"> | |
<h1 class="alert-{{ $type }}">Error occurred | |
<x-bar> | |
<x-slot name="xyz_default">Some data</x-slot> | |
</x-bar> | |
</h1> | |
</x-slot> | |
Lorem ipsum … | |
<x-heading-3 tabindex="-1" :heading-attributes="$component->attributes"> | |
<x-foo class="x-{{ $type }}" :tabindex="$component->tabindex" index="{{ $i }}"> | |
Some heading | |
</x-foo> | |
<x-foo class="x-{{ $type }}" :tabindex="$component->tabindex" index="{{ $i }}"> | |
Some heading 2 | |
</x-foo> | |
</x-heading-3> | |
<x-example-content name="alert" alert-type="{{ $type }}" :alert-data="$complex" :component-data="$component->data" /> | |
</x-alert> | |
<x-list class="menu-1"> | |
<x-list-item class="item-1"> | |
<x-list class="submenu-1"> | |
<x-list-item class="subitem-1">Hi</x-list-item> | |
</x-list> | |
</x-list-item> | |
</x-list> | |
<x-list class="menu-2"> | |
</x-list> | |
'; | |
$value = preg_replace_callback('/<\s*x[\-\:]slot\s+(:?)name=(?<name>(\"[^\"]+\"|\\\'[^\\\']+\\\'|[^\s>]+))\s*>/', function ($matches) { | |
$name = $matches['name']; | |
/*if ($matches[1] !== ':') { | |
$name = "'{$name}'"; | |
}*/ | |
$name = str_replace('"', '', $name); | |
return "<?php }, 'slot_{$name}' => function(\$variables) { extract(\$variables); ?>"; | |
//return "{% endverbatim %}{% endset %}{% set slot_$name %}{% verbatim %}"; | |
}, $value); | |
// $value = preg_replace('/<\/\s*x[\-\:]slot[^>]*>/', '{% endverbatim %}{% endset %}{% set slot_default %}{{ slot_default }}{% verbatim %}', $value); | |
$value = preg_replace('/<\/\s*x[\-\:]slot[^>]*>/', '<?php }, function($variables) { extract($variables); ?>', $value); | |
$value = preg_replace_callback('/<\s*x[-\:]([\w\-\:\.]*).* \/>/x', function ($matches) { | |
return "<?php component('{$matches[1]}', \$variables); ?>"; | |
}, $value); | |
$pattern = "/ | |
<\/? | |
\s* | |
x[-\:]([\w\-\:\.]*) | |
(?<attributes> | |
(?: | |
\s+ | |
(?: | |
(?: | |
\{\{\s*\\\$attributes(?:[^}]+?)?\s*\}\} | |
) | |
| | |
(?: | |
[\w\-:.@]+ | |
( | |
= | |
(?: | |
\\\"[^\\\"]*\\\" | |
| | |
\'[^\']*\' | |
| | |
[^\'\\\"=<>]+ | |
) | |
)? | |
) | |
) | |
)* | |
\s* | |
) | |
(?<![\/=\-]) | |
> | |
/x"; | |
print_r(['<pre>', $value]); | |
global $depth, $attributes, $x, $curr; | |
$depth = []; | |
$curr = ''; | |
$x = preg_replace_callback($pattern, function (array $matches) { | |
global $depth, $x, $curr; | |
$name = $matches[1]; | |
if (!isset($depth[$name])) { | |
$depth[$name] = 0; | |
} | |
if ($matches[0][1] == '/') { | |
$depth[$name]--; | |
$fullname = $name . '--' . $depth[$name]; | |
} | |
else { | |
$fullname = $name . '--' . $depth[$name]; | |
$depth[$name]++; | |
} | |
/* | |
if ($matches[0][1] == '/') { | |
if ($curr != $fullname) { | |
return $matches[0]; | |
} | |
$curr = ''; | |
} | |
else { | |
if (!empty($curr)) { | |
return $matches[0]; | |
} | |
$curr = $fullname; | |
} | |
*/ | |
print_r([$fullname, $matches, $depth, $curr]); | |
if ($matches[0][1] == '/') { | |
//return "{% endverbatim %}{% endset %}{% endapply %}"; | |
return "<?php }]); ?>"; | |
} | |
$attributeString = $matches['attributes']; | |
$pattern = "/ | |
(?:^|\s+) # start of the string or whitespace between attributes | |
\{\{\s*(\\\$attributes(?:[^}]+?(?<!\s))?)\s*\}\} # exact match of attributes variable being echoed | |
/x"; | |
$attributeString = preg_replace($pattern, ' :attributes="$1"', $attributeString); | |
$pattern = "/ | |
(?:^|\s+) # start of the string or whitespace between attributes | |
: # attribute needs to start with a semicolon | |
([\w\-:.@]+) # match the actual attribute name | |
= # only match attributes that have a value | |
/xm"; | |
$attributeString = preg_replace($pattern, ' bind:$1=', $attributeString); | |
$pattern = '/ | |
(?<attribute>[\w\-:.@]+) | |
( | |
= | |
(?<value> | |
( | |
\"[^\"]+\" | |
| | |
\\\'[^\\\']+\\\' | |
| | |
[^\s>]+ | |
) | |
) | |
)? | |
/x'; | |
$attributes = []; | |
$boundAttributes = []; | |
if (preg_match_all($pattern, $attributeString, $matches, PREG_SET_ORDER)) { | |
print_r([$matches]); | |
foreach ($matches as $match) { | |
$attribute = $match['attribute']; | |
$value = $match['value'] ?? null; | |
if (is_null($value)) { | |
$value = 'true'; | |
//$attribute = Str::start($attribute, 'bind:'); | |
} | |
$value = trim($value, '"\''); | |
if (strpos($attribute, 'bind:') === 0) { | |
$attribute = substr($attribute, strlen('bind:')); | |
$boundAttributes[$attribute] = true; | |
} else { | |
$value = "'". compileAttributeEchos($value). "'"; | |
} | |
$attributes[$attribute] = $value; | |
} | |
} | |
$data = []; | |
foreach ($attributes as $attribute => $value) { | |
$data[] = "'{$attribute}' => {$value}"; | |
} | |
$attributePhp = '[' . implode(', ', $data) . ']'; | |
//return "{% apply component({$fullname}, '{$matches['attributes']}') %}{% set slot_default %}{% verbatim %}"; | |
//return "{% apply reverse %}{% set slot_default %}{% verbatim %}"; | |
return "<?php component('{$name}', $attributePhp, \$variables, [function(\$variables) { extract(\$variables); ?>"; | |
}, $value); | |
print_r([$x]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment