Skip to content

Commit

Permalink
feat: Allow JS assets to be defined as modules or not
Browse files Browse the repository at this point in the history
  • Loading branch information
hellopablo committed May 1, 2024
1 parent 3de4038 commit ea50b5f
Showing 1 changed file with 52 additions and 18 deletions.
70 changes: 52 additions & 18 deletions src/Common/Service/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,7 @@ public function addLibrary(string $sKey, array $aUrls): self
* @param string|null $sForceType The asset's file type (e.g., JS or CSS)
* @param bool $bAsync Whether to load the asset asynchronously
* @param bool $bDefer Whether to defer loading the asset
* @param bool|null $bModule Whether asset is a JS module or not (null = undefined)
*
* @return $this
* @throws AssetException
Expand All @@ -572,7 +573,8 @@ public function load(
string $sAssetLocation = null,
string $sForceType = null,
bool $bAsync = false,
bool $bDefer = false
bool $bDefer = false,
bool $bModule = null
): self {

$aAssets = (array) $mAssets;
Expand Down Expand Up @@ -600,13 +602,13 @@ public function load(

foreach ($aAssets as $sAsset) {
if (preg_match('#^https?://#', $sAsset)) {
$this->loadUrl($sAsset, $sForceType, $bAsync, $bDefer);
$this->loadUrl($sAsset, $sForceType, $bAsync, $bDefer, $bModule);

} elseif (substr($sAsset, 0, 0) === '/') {
$this->loadAbsolute(substr($sAsset, 1), $sForceType, $bAsync, $bDefer);
$this->loadAbsolute(substr($sAsset, 1), $sForceType, $bAsync, $bDefer, $bModule);

} else {
$this->{$sAssetLocationMethod}($sAsset, $sForceType, $bAsync, $bDefer, $sAssetLocation);
$this->{$sAssetLocationMethod}($sAsset, $sForceType, $bAsync, $bDefer, $bModule, $sAssetLocation);
}
}

Expand All @@ -624,11 +626,12 @@ public function load(
* @param string|null $sForceType Force a particular type of asset (i.e. JS or CSS)
* @param bool $bAsync Whether to load the asset asynchronously
* @param bool $bDefer Whether to defer loading the asset
* @param bool|null $bModule Whether asset is a JS module or not (null = undefined)
*
* @return $this
* @throws AssetException
*/
protected function loadUrl(string $sAsset, ?string $sForceType, bool $bAsync, bool $bDefer): self
protected function loadUrl(string $sAsset, ?string $sForceType, bool $bAsync, bool $bDefer, bool $bModule = null): self
{
$sType = $this->determineType($sAsset, $sForceType);

Expand All @@ -640,11 +643,11 @@ protected function loadUrl(string $sAsset, ?string $sForceType, bool $bAsync, bo

case static::TYPE_JS:
case static::TYPE_JS_FOOTER:
$this->aJs['URL-' . $sAsset] = [$sAsset, $bAsync, $bDefer];
$this->aJs['URL-' . $sAsset] = [$sAsset, $bAsync, $bDefer, $bModule];
break;

case static::TYPE_JS_HEADER:
$this->aJsHeader['URL-' . $sAsset] = [$sAsset, $bAsync, $bDefer];
$this->aJsHeader['URL-' . $sAsset] = [$sAsset, $bAsync, $bDefer, $bModule];
break;
}

Expand All @@ -660,11 +663,12 @@ protected function loadUrl(string $sAsset, ?string $sForceType, bool $bAsync, bo
* @param string|null $sForceType Force a particular type of asset (i.e. JS or CSS)
* @param bool $bAsync Whether to load the asset asynchronously
* @param bool $bDefer Whether to defer loading the asset
* @param bool|null $bModule Whether asset is a JS module or not (null = undefined)
*
* @return $this
* @throws AssetException
*/
protected function loadAbsolute(string $sAsset, ?string $sForceType, bool $bAsync, bool $bDefer): self
protected function loadAbsolute(string $sAsset, ?string $sForceType, bool $bAsync, bool $bDefer, bool $bModule = null): self
{
$sType = $this->determineType($sAsset, $sForceType);

Expand All @@ -676,11 +680,11 @@ protected function loadAbsolute(string $sAsset, ?string $sForceType, bool $bAsyn

case static::TYPE_JS:
case static::TYPE_JS_FOOTER:
$this->aJs['ABSOLUTE-' . $sAsset] = [$this->buildUrl($sAsset), $bAsync, $bDefer];
$this->aJs['ABSOLUTE-' . $sAsset] = [$this->buildUrl($sAsset), $bAsync, $bDefer, $bModule];
break;

case static::TYPE_JS_HEADER:
$this->aJsHeader['ABSOLUTE-' . $sAsset] = [$this->buildUrl($sAsset), $bAsync, $bDefer];
$this->aJsHeader['ABSOLUTE-' . $sAsset] = [$this->buildUrl($sAsset), $bAsync, $bDefer, $bModule];
break;
}

Expand Down Expand Up @@ -757,15 +761,31 @@ public function output(string $sType = self::TYPE_ALL, bool $bOutput = true): ar
// Linked JS
if (!empty($this->aJs) && ($sType === static::TYPE_JS || $sType === static::TYPE_ALL)) {
foreach ($this->aJs as $aAsset) {
[$sAsset, $bAsync, $bDefer] = $aAsset;
$aOut[] = '<script ' . ($bAsync ? 'async ' : '') . ($bDefer ? 'defer ' : '') . 'src="' . $sAsset . '"></script>';
[$sAsset, $bAsync, $bDefer, $bModule] = $aAsset;
$aOut[] = sprintf(
'<script src="%s"%s%s%s></script>',
$sAsset,
$bAsync ? 'async ' : '',
$bDefer ? 'defer ' : '',
isset($bModule)
? ($bModule ? 'type="module"' : 'nomodule') . ' '
: ''
);
}
}

if (!empty($this->aJsHeader) && ($sType === static::TYPE_JS_HEADER || $sType === static::TYPE_ALL)) {
foreach ($this->aJsHeader as $aAsset) {
[$sAsset, $bAsync, $bDefer] = $aAsset;
$aOut[] = '<script ' . ($bAsync ? 'async ' : '') . ($bDefer ? 'defer ' : '') . 'src="' . $sAsset . '"></script>';
[$sAsset, $bAsync, $bDefer, $bModule] = $aAsset;
$aOut[] = sprintf(
'<script src="%s"%s%s%s></script>',
$sAsset,
$bAsync ? ' async' : '',
$bDefer ? ' defer' : '',
isset($bModule)
? ' ' . ($bModule ? 'type="module"' : 'nomodule')
: ''
);
}
}

Expand Down Expand Up @@ -935,11 +955,12 @@ public function inline($mScript = null, string $sForceType = null, $sJsLocation
* @param bool $bAsync Whether to load the asset asynchronously
* @param bool $bDefer Whether to defer loading the asset
* @param array|string $mModule The module to load from
* @param bool|null $bModule Whether asset is a JS module or not (null = undefined)
*
* @return $this
* @throws AssetException
*/
protected function loadModule(string $sAsset, ?string $sForceType, bool $bAsync, bool $bDefer, $mModule): self
protected function loadModule(string $sAsset, ?string $sForceType, bool $bAsync, bool $bDefer, bool $bModule = null, $mModule): self
{
if (is_array($mModule)) {
$sModule = !empty($mModule[0]) ? $mModule[0] : null;
Expand All @@ -964,6 +985,7 @@ protected function loadModule(string $sAsset, ?string $sForceType, bool $bAsync,
$this->addCacheBuster($this->sBaseModuleUrl . $sModule . '/assets/js/' . $sAsset),
$bAsync,
$bDefer,
$bModule,
];
break;

Expand All @@ -972,6 +994,7 @@ protected function loadModule(string $sAsset, ?string $sForceType, bool $bAsync,
$this->addCacheBuster($this->sBaseModuleUrl . $sModule . '/assets/js/' . $sAsset),
$bAsync,
$bDefer,
$bModule,
];
break;
}
Expand Down Expand Up @@ -1111,11 +1134,12 @@ public function getCacheBuster(): ?string
* @param string|null $sForceType Force a particular type of asset (i.e. JS or CSS)
* @param bool $bAsync Whether to load the asset asynchronously
* @param bool $bDefer Whether to defer loading the asset
* @param bool|null $bModule Whether asset is a JS module or not (null = undefined)
*
* @return $this
* @throws AssetException
*/
protected function loadApp(string $sAsset, ?string $sForceType, bool $bAsync, bool $bDefer): self
protected function loadApp(string $sAsset, ?string $sForceType, bool $bAsync, bool $bDefer, bool $bModule = null): self
{
$sType = $this->determineType($sAsset, $sForceType);

Expand All @@ -1127,11 +1151,21 @@ protected function loadApp(string $sAsset, ?string $sForceType, bool $bAsync, bo

case static::TYPE_JS:
case static::TYPE_JS_FOOTER:
$this->aJs['APP-' . $sAsset] = [$this->buildUrl($this->sJsDir . $sAsset), $bAsync, $bDefer];
$this->aJs['APP-' . $sAsset] = [
$this->buildUrl($this->sJsDir . $sAsset),
$bAsync,
$bDefer,
$bModule,
];
break;

case static::TYPE_JS_HEADER:
$this->aJsHeader['APP-' . $sAsset] = [$this->buildUrl($this->sJsDir . $sAsset), $bAsync, $bDefer];
$this->aJsHeader['APP-' . $sAsset] = [
$this->buildUrl($this->sJsDir . $sAsset),
$bAsync,
$bDefer,
$bModule,
];
break;
}

Expand Down

0 comments on commit ea50b5f

Please sign in to comment.