Skip to content

Commit

Permalink
feat(OC/Template): Add type="module" for ES6 scripts
Browse files Browse the repository at this point in the history
Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Jan 22, 2023
1 parent afd410f commit f2e0272
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
16 changes: 11 additions & 5 deletions lib/private/legacy/template/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,19 @@ function emit_css_loading_tags($obj) {
* Prints a <script> tag with nonce and defer depending on config
* @param string $src the source URL, ignored when empty
* @param string $script_content the inline script content, ignored when empty
* @param string $content_type the type of the source (e.g. 'module')
*/
function emit_script_tag($src, $script_content = '') {
function emit_script_tag(string $src, string $script_content = '', string $content_type = '') {
$nonceManager = \OC::$server->get(\OC\Security\CSP\ContentSecurityPolicyNonceManager::class);

$defer_str = ' defer';
$s = '<script nonce="' . \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() . '"';
$type = $content_type !== '' ? ' type="' . $content_type . '"' : '';

$s = '<script nonce="' . $nonceManager->getNonce() . '"';
if (!empty($src)) {
// emit script tag for deferred loading from $src
$s .= $defer_str.' src="' . $src .'">';
} elseif (!empty($script_content)) {
$s .= $defer_str.' src="' . $src .'"' . $type . '>';
} elseif ($script_content !== '') {
// emit script tag for inline script from $script_content without defer (see MDN)
$s .= ">\n".$script_content."\n";
} else {
Expand All @@ -96,7 +101,8 @@ function emit_script_tag($src, $script_content = '') {
*/
function emit_script_loading_tags($obj) {
foreach ($obj['jsfiles'] as $jsfile) {
emit_script_tag($jsfile, '');
$type = str_ends_with($jsfile, '.mjs') ? 'module' : '';
emit_script_tag($jsfile, '', $type);
}
if (!empty($obj['inline_ocjs'])) {
emit_script_tag('', $obj['inline_ocjs']);
Expand Down
24 changes: 24 additions & 0 deletions tests/lib/TemplateFunctionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,30 @@ public function testPrintUnescapedNormalString() {
print_unescaped($string);
}

public function testEmitScriptTagWithContent() {
$this->expectOutputRegex('/<script nonce=".*">\nalert()\n<\/script>/');
emit_script_tag('', 'alert()');
}

public function testEmitScriptTagWithSource() {
$this->expectOutputRegex('/<script nonce=".*" defer src="some.js"><\/script>/');
emit_script_tag('some.js');
}

public function testEmitScriptTagWithModuleSource() {
$this->expectOutputRegex('/<script nonce=".*" defer src="some.mjs" type="module"><\/script>/');
emit_script_tag('some.mjs', '', 'module');
}

public function testEmitScriptLoadingTags() {
// Test mjs js and inline content
$this->expectOutputRegex('/<script.+src="some.mjs".+type="module".*>.+<script.+src="other.js".+>.+<script[^>]*>.+inline.+<\/script>/');
emit_script_loading_tags([
'jsfiles' => ['/some.mjs', '/other.js'],
'inline_ocjs' => '// inline'
]);
}

// ---------------------------------------------------------------------------
// Test relative_modified_date with dates only
// ---------------------------------------------------------------------------
Expand Down

0 comments on commit f2e0272

Please sign in to comment.