diff --git a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/AbstractStimulusViewHelper.php b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/AbstractStimulusViewHelper.php new file mode 100644 index 00000000..27d0c001 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/AbstractStimulusViewHelper.php @@ -0,0 +1,41 @@ + + */ +class AbstractStimulusViewHelper extends AbstractViewHelper +{ + /** + * This method is taken from symfony/webpack-encore-bundle + * + * Normalize a Stimulus controller name into its HTML equivalent (no special character and / becomes --). + * + * @see https://stimulus.hotwire.dev/reference/controllers + */ + protected static function normalizeControllerName(string $str): string + { + return preg_replace('/^@/', '', str_replace('_', '-', str_replace('/', '--', $str))); + } + + /** + * This method is taken from symfony/webpack-encore-bundle + * + * Normalize a Stimulus Value API key into its HTML equivalent ("kebab case"). + * Backport features from symfony/string. + * + * @see https://stimulus.hotwire.dev/reference/values + */ + protected static function normalizeKeyName(string $str): string + { + // Adapted from ByteString::camel + $str = ucfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $str)))); + + // Adapted from ByteString::snake + return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], '\1-\2', $str)); + } +} diff --git a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/ActionViewHelper.php b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/ActionViewHelper.php new file mode 100644 index 00000000..6b9108f8 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/ActionViewHelper.php @@ -0,0 +1,88 @@ + + */ +class ActionViewHelper extends AbstractStimulusViewHelper +{ + use CompileWithRenderStatic; + + protected $escapeOutput = false; + + public function initializeArguments() + { + parent::initializeArguments(); + + $this->registerArgument('controller', 'mixed', 'Controller name(s)', true); + $this->registerArgument('action', 'string', 'Action name', false); + $this->registerArgument('event', 'string', 'Event name', false); + } + + /** + * @param array $arguments + * @param \Closure $renderChildrenClosure + * @param RenderingContextInterface $renderingContext + * @return string + */ + public static function renderStatic( + array $arguments, + \Closure $renderChildrenClosure, + RenderingContextInterface $renderingContext + ) + { + $dataOrControllerName = $arguments['controller']; + $actionName = $arguments['action']; + $eventName = $arguments['event']; + + if (\is_string($dataOrControllerName)) { + $data = [$dataOrControllerName => null === $eventName ? [[$actionName]] : [[$eventName => $actionName]]]; + } else { + if ($actionName || $eventName) { + throw new \InvalidArgumentException('You cannot pass a string to the second or third argument while passing an array to the first argument of stimulus_action(): check the documentation.'); + } + + $data = $dataOrControllerName; + + if (!$data) { + return ''; + } + } + + $actions = []; + + foreach ($data as $controllerName => $controllerActions) { + $controllerName = static::normalizeControllerName($controllerName); + + if (\is_string($controllerActions)) { + $controllerActions = [[$controllerActions]]; + } + + foreach ($controllerActions as $possibleEventName => $controllerAction) { + if (\is_string($possibleEventName) && \is_string($controllerAction)) { + $controllerAction = [$possibleEventName => $controllerAction]; + } elseif (\is_string($controllerAction)) { + $controllerAction = [$controllerAction]; + } + + foreach ($controllerAction as $eventName => $actionName) { + $action = $controllerName.'#'.htmlspecialchars($actionName, ENT_QUOTES); + + if (\is_string($eventName)) { + $action = $eventName.'->'.$action; + } + + $actions[] = $action; + } + } + } + + return 'data-action="'.implode(' ', $actions).'"'; + } + +} diff --git a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/ControllerViewHelper.php b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/ControllerViewHelper.php new file mode 100644 index 00000000..8f517a1f --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/ControllerViewHelper.php @@ -0,0 +1,81 @@ + + */ +class ControllerViewHelper extends AbstractStimulusViewHelper +{ + use CompileWithRenderStatic; + + protected $escapeOutput = false; + + public function initializeArguments() + { + parent::initializeArguments(); + + $this->registerArgument('controller', 'mixed', 'Controller name(s)', true); + $this->registerArgument('values', 'array', 'Controller values', false, []); + } + + /** + * @param array $arguments + * @param \Closure $renderChildrenClosure + * @param RenderingContextInterface $renderingContext + * @return string + */ + public static function renderStatic( + array $arguments, + \Closure $renderChildrenClosure, + RenderingContextInterface $renderingContext + ) + { + $dataOrControllerName = $arguments['controller']; + $controllerValues = $arguments['values']; + + if (\is_string($dataOrControllerName)) { + $data = [$dataOrControllerName => $controllerValues]; + } else { + if ($controllerValues) { + throw new \InvalidArgumentException('You cannot pass an array to the first and second argument of stimulus_controller(): check the documentation.'); + } + + $data = $dataOrControllerName; + + if (!$data) { + return ''; + } + } + + $controllers = []; + $values = []; + + foreach ($data as $controllerName => $controllerValues) { + $controllerName = static::normalizeControllerName($controllerName); + $controllers[] = $controllerName; + + foreach ($controllerValues as $key => $value) { + if (!is_scalar($value)) { + $value = json_encode($value); + } + + if (\is_bool($value)) { + $value = $value ? 'true' : 'false'; + } + + $key = static::normalizeKeyName($key); + $value = htmlspecialchars($value, ENT_QUOTES); + + $values[] = 'data-'.$controllerName.'-'.$key.'-value="'.$value.'"'; + } + } + + return rtrim('data-controller="'.implode(' ', $controllers).'" '.implode(' ', $values)); + } + +} diff --git a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/TargetViewHelper.php b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/TargetViewHelper.php new file mode 100644 index 00000000..cbaaeb91 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Stimulus/TargetViewHelper.php @@ -0,0 +1,68 @@ + + */ +class TargetViewHelper extends AbstractStimulusViewHelper +{ + use CompileWithRenderStatic; + + protected $escapeOutput = false; + + public function initializeArguments() + { + parent::initializeArguments(); + + $this->registerArgument('controller', 'mixed', 'Controller name(s)', true); + $this->registerArgument('targets', 'string', 'Target names', false); + } + + /** + * @param array $arguments + * @param \Closure $renderChildrenClosure + * @param RenderingContextInterface $renderingContext + * @return string + */ + public static function renderStatic( + array $arguments, + \Closure $renderChildrenClosure, + RenderingContextInterface $renderingContext + ) + { + $dataOrControllerName = $arguments['controller']; + $targetNames = $arguments['target']; + + if (\is_string($dataOrControllerName)) { + $data = [$dataOrControllerName => $targetNames]; + } else { + if ($targetNames) { + throw new \InvalidArgumentException('You cannot pass a string to the second argument while passing an array to the first argument of stimulus_target(): check the documentation.'); + } + + $data = $dataOrControllerName; + + if (!$data) { + return ''; + } + } + + $targets = []; + + foreach ($data as $controllerName => $targetNames) { + $controllerName = static::normalizeControllerName($controllerName); + + $targets['data-'.$controllerName.'-target'] = htmlspecialchars($targetNames, ENT_QUOTES); + } + + return implode(' ', array_map(static function (string $attribute, string $value): string { + return $attribute.'="'.$value.'"'; + }, array_keys($targets), $targets)); + } + +} diff --git a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/StimulusActionViewHelper.php b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/StimulusActionViewHelper.php deleted file mode 100644 index f930c2b1..00000000 --- a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/StimulusActionViewHelper.php +++ /dev/null @@ -1,83 +0,0 @@ -, dreipunktnull - * - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; -use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; -use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; - -class StimulusActionViewHelper extends AbstractViewHelper -{ - use CompileWithRenderStatic; - - protected $escapeOutput = false; - - public function initializeArguments() - { - parent::initializeArguments(); - - $this->registerArgument('controller', 'string', 'Controller name', true); - $this->registerArgument('action', 'string', 'Action name', true); - $this->registerArgument('event', 'string', 'Event name', false); - } - - /** - * @param array $arguments - * @param \Closure $renderChildrenClosure - * @param RenderingContextInterface $renderingContext - * @return string - */ - public static function renderStatic( - array $arguments, - \Closure $renderChildrenClosure, - RenderingContextInterface $renderingContext - ) - { - $controllerName = static::normalizeControllerName($arguments['controller']); - $action = $arguments['action']; - $event = $arguments['event']; - - if (!$event) { - return sprintf('data-action="%s#%s"', $controllerName, $action); - } - - return sprintf('data-action="%s->%s#%s"', $event, $controllerName, $action); - } - - /** - * Method taken from symfony/webpack-encore-bundle - * - * @param string $str - * @return string - */ - private static function normalizeControllerName(string $str): string - { - return preg_replace('/^@/', '', str_replace('_', '-', str_replace('/', '--', $str))); - } - -} diff --git a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/StimulusControllerViewHelper.php b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/StimulusControllerViewHelper.php deleted file mode 100644 index 02fa34ea..00000000 --- a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/StimulusControllerViewHelper.php +++ /dev/null @@ -1,108 +0,0 @@ -, dreipunktnull - * - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; -use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; -use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; - -class StimulusControllerViewHelper extends AbstractViewHelper -{ - use CompileWithRenderStatic; - - protected $escapeOutput = false; - - public function initializeArguments() - { - parent::initializeArguments(); - - $this->registerArgument('controller', 'string', 'Controller name', true); - $this->registerArgument('values', 'array', 'Controller values', false, []); - } - - /** - * @param array $arguments - * @param \Closure $renderChildrenClosure - * @param RenderingContextInterface $renderingContext - * @return string - */ - public static function renderStatic( - array $arguments, - \Closure $renderChildrenClosure, - RenderingContextInterface $renderingContext - ) - { - $controllerName = static::normalizeControllerName($arguments['controller']); - $attributes = [ - sprintf('data-controller="%s"', $controllerName), - ]; - - foreach ($arguments['values'] as $key => $value) { - if (!is_scalar($value)) { - $value = htmlspecialchars(json_encode($value), ENT_QUOTES); - } - - if (\is_bool($value)) { - $value = $value ? 'true' : 'false'; - } - - $key = static::normalizeKeyName($key); - - $attributes[] = sprintf('data-%s-%s-value="%s"', $controllerName, $key, $value); - } - - return implode(' ', $attributes); - } - - /** - * Method taken from symfony/webpack-encore-bundle - * - * @param string $str - * @return string - */ - private static function normalizeControllerName(string $str): string - { - return preg_replace('/^@/', '', str_replace('_', '-', str_replace('/', '--', $str))); - } - - /** - * Method taken from symfony/webpack-encore-bundle - * - * @param string $str - * @return string - */ - private static function normalizeKeyName(string $str): string - { - // Adapted from ByteString::camel - $str = ucfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $str)))); - - // Adapted from ByteString::snake - return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], '\1-\2', $str)); - } - -}