diff --git a/public_html/lib-common.php b/public_html/lib-common.php index 6c10ec445..cfc7b51d5 100644 --- a/public_html/lib-common.php +++ b/public_html/lib-common.php @@ -1301,7 +1301,8 @@ function COM_createHTMLDocument(&$content = '', $information = array()) ); $_SCRIPTS->setJavaScriptFile( 'cookie_consent', 'https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js', - true, 100 + false, 100, false, + array('data-cfasync' => 'false') ); // To customize appearance and behavior, edit the following file diff --git a/system/classes/Resource.php b/system/classes/Resource.php index 199491c9c..78bb9f541 100644 --- a/system/classes/Resource.php +++ b/system/classes/Resource.php @@ -41,7 +41,7 @@ class Resource const DEFAULT_CACHE_LIFESPAN = 604800; // 1 week const JS_TAG_TEMPLATE = ''; - const EXTERNAL_JS_TAG_TEMPLATE = ''; + const EXTERNAL_JS_TAG_TEMPLATE = ''; // Default theme const DEFAULT_THEME = 'denim'; @@ -501,13 +501,15 @@ public function setJavaScript($code, $wrap = false, $isFooter = true) /** * Set JavaScript file to load * - * @param string $name (not used) - * @param string $file relative to public_html (must start with '/') + * @param string $name (not used) + * @param string $file relative to public_html (must start with '/') * @param bool $isFooter * @param int $priority + * @param bool $isDefer whether to set "defer" property for external files + * @param array $attributes additional attributes for script tag * @return bool */ - public function setJavaScriptFile($name, $file, $isFooter = true, $priority = 100) + public function setJavaScriptFile($name, $file, $isFooter = true, $priority = 100, $isDefer = true, array $attributes = array()) { if ($this->isHeaderSet && !$isFooter) { return false; @@ -517,8 +519,10 @@ public function setJavaScriptFile($name, $file, $isFooter = true, $priority = 10 if ($this->isExternal($file) && array_search($file, array_column($this->externalJsFiles[$position], 'file')) == 0) { $this->externalJsFiles[$position][] = array( - 'file' => $file, - 'priority' => $priority, + 'file' => $file, + 'priority' => (int) $priority, + 'isDefer' => (bool) $isDefer, + 'attributes' => $attributes, ); return true; @@ -526,8 +530,9 @@ public function setJavaScriptFile($name, $file, $isFooter = true, $priority = 10 // See if file exists and has not already been added (could happen on multiple calls of the same function by different plugins) if ($this->exists($this->config['path_html'] . $file) && array_search($file, array_column($this->localJsFiles[$position], 'file')) == 0) { $this->localJsFiles[$position][] = array( - 'file' => $file, - 'priority' => $priority, + 'file' => $file, + 'priority' => (int) $priority, + 'attributes' => $attributes, ); return true; @@ -1055,6 +1060,29 @@ private function makeTagsForSystemLibraries($isFooter = true) return $retval; } + /** + * Format attributes for script tag + * + * @param array $attributes + * @return string + */ + private function formatAttributes(array $attributes = array()) + { + $retval = ''; + + if (count($attributes) > 0) { + foreach ($attributes as $key => $value) { + $retval .= sprintf( + ' %s="%s"', + htmlspecialchars($key, ENT_QUOTES, 'utf-8'), + htmlspecialchars($value, ENT_QUOTES, 'utf-8') + ); + } + } + + return $retval; + } + /** * Returns header code (JavaScript and CSS) to include in the Head of the web page * @@ -1138,7 +1166,13 @@ public function getHeader() usort($this->externalJsFiles['header'], array('\\Geeklog\\Resource', 'comparePriority')); foreach ($this->externalJsFiles['header'] as $jsFile) { - $retval .= sprintf(self::EXTERNAL_JS_TAG_TEMPLATE, $jsFile['file']) . PHP_EOL; + $defer = isset($jsFile['isDefer']) && $jsFile['isDefer'] ? ' defer' : ''; + $attributes = ''; + if (isset($jsFile['attributes'])) { + $attributes = $this->formatAttributes($jsFile['attributes']); + } + + $retval .= sprintf(self::EXTERNAL_JS_TAG_TEMPLATE, $jsFile['file'], $defer, $attributes) . PHP_EOL; } } @@ -1213,7 +1247,13 @@ public function getFooter() usort($this->externalJsFiles['footer'], array('\\Geeklog\\Resource', 'comparePriority')); foreach ($this->externalJsFiles['footer'] as $jsFile) { - $retval .= sprintf(self::EXTERNAL_JS_TAG_TEMPLATE, $jsFile['file']) . PHP_EOL; + $defer = isset($jsFile['isDefer']) && $jsFile['isDefer'] ? ' defer' : ''; + $attributes = ''; + if (isset($jsFile['attributes'])) { + $attributes = $this->formatAttributes($jsFile['attributes']); + } + + $retval .= sprintf(self::EXTERNAL_JS_TAG_TEMPLATE, $jsFile['file'], $defer, $attributes) . PHP_EOL; } }