‪TYPO3CMS  ‪main
ScriptViewHelper.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
21 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
22 use TYPO3Fluid\Fluid\Core\ViewHelper\TagBuilder;
23 
46 final class ‪ScriptViewHelper extends AbstractTagBasedViewHelper
47 {
53  protected ‪$escapeOutput = false;
54 
61  protected ‪$escapeChildren = false;
62 
64 
66  {
67  $this->assetCollector = ‪$assetCollector;
68  }
69 
70  public function ‪initialize(): void
71  {
72  // Add a tag builder, that does not html encode values, because rendering with encoding happens in AssetRenderer
73  $this->setTagBuilder(
74  new class () extends TagBuilder {
75  public function addAttribute($attributeName, $attributeValue, $escapeSpecialCharacters = false): void
76  {
77  parent::addAttribute($attributeName, $attributeValue, false);
78  }
79  }
80  );
81  parent::initialize();
82  }
83 
84  public function ‪initializeArguments(): void
85  {
86  parent::initializeArguments();
87  $this->registerUniversalTagAttributes();
88  $this->registerTagAttribute('async', 'bool', 'Define that the script will be fetched in parallel to parsing and evaluation.', false);
89  $this->registerTagAttribute('crossorigin', 'string', 'Define how to handle crossorigin requests.', false);
90  $this->registerTagAttribute('defer', 'bool', 'Define that the script is meant to be executed after the document has been parsed.', false);
91  $this->registerTagAttribute('integrity', 'string', 'Define base64-encoded cryptographic hash of the resource that allows browsers to verify what they fetch.', false);
92  $this->registerTagAttribute('nomodule', 'bool', 'Define that the script should not be executed in browsers that support ES2015 modules.', false);
93  $this->registerTagAttribute('nonce', 'string', 'Define a cryptographic nonce (number used once) used to whitelist inline styles in a style-src Content-Security-Policy.', false);
94  $this->registerTagAttribute('referrerpolicy', 'string', 'Define which referrer is sent when fetching the resource.', false);
95  $this->registerTagAttribute('src', 'string', 'Define the URI of the external resource.', false);
96  $this->registerTagAttribute('type', 'string', 'Define the MIME type (usually \'text/javascript\').', false);
97  $this->registerArgument('useNonce', 'bool', 'Whether to use the global nonce value', false, false);
98  $this->registerArgument(
99  'identifier',
100  'string',
101  'Use this identifier within templates to only inject your JS once, even though it is added multiple times.',
102  true
103  );
104  $this->registerArgument(
105  'priority',
106  'boolean',
107  'Define whether the JavaScript should be put in the <head> tag above-the-fold or somewhere in the body part.',
108  false,
109  false
110  );
111  }
112 
113  public function ‪render(): string
114  {
115  ‪$identifier = (string)$this->arguments['identifier'];
116  $attributes = $this->tag->getAttributes();
117 
118  // boolean attributes shall output attr="attr" if set
119  foreach (['async', 'defer', 'nomodule'] as $_attr) {
120  if ($attributes[$_attr] ?? false) {
121  $attributes[$_attr] = $_attr;
122  }
123  }
124 
125  $src = $attributes['src'] ?? null;
126  unset($attributes['src']);
127  $options = [
128  'priority' => $this->arguments['priority'],
129  'useNonce' => $this->arguments['useNonce'],
130  ];
131  if ($src !== null) {
132  $this->assetCollector->addJavaScript(‪$identifier, $src, $attributes, $options);
133  } else {
134  $content = (string)$this->renderChildren();
135  if ($content !== '') {
136  $this->assetCollector->addInlineJavaScript(‪$identifier, $content, $attributes, $options);
137  }
138  }
139  return '';
140  }
141 }
‪TYPO3\CMS\Core\Page\AssetCollector
Definition: AssetCollector.php:42
‪TYPO3\CMS\Fluid\ViewHelpers\Asset\ScriptViewHelper\initializeArguments
‪initializeArguments()
Definition: ScriptViewHelper.php:82
‪TYPO3\CMS\Fluid\ViewHelpers\Asset\ScriptViewHelper\$assetCollector
‪AssetCollector $assetCollector
Definition: ScriptViewHelper.php:61
‪TYPO3\CMS\Fluid\ViewHelpers\Asset\ScriptViewHelper\$escapeOutput
‪bool $escapeOutput
Definition: ScriptViewHelper.php:52
‪TYPO3\CMS\Fluid\ViewHelpers\Asset
Definition: CssViewHelper.php:18
‪TYPO3\CMS\Fluid\ViewHelpers\Asset\ScriptViewHelper\initialize
‪initialize()
Definition: ScriptViewHelper.php:68
‪TYPO3\CMS\Fluid\ViewHelpers\Asset\ScriptViewHelper\$escapeChildren
‪bool $escapeChildren
Definition: ScriptViewHelper.php:59
‪TYPO3\CMS\Fluid\ViewHelpers\Asset\ScriptViewHelper\render
‪render()
Definition: ScriptViewHelper.php:111
‪TYPO3\CMS\Fluid\ViewHelpers\Asset\ScriptViewHelper\injectAssetCollector
‪injectAssetCollector(AssetCollector $assetCollector)
Definition: ScriptViewHelper.php:63
‪TYPO3\CMS\Fluid\ViewHelpers\Asset\ScriptViewHelper
Definition: ScriptViewHelper.php:47
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37