From 7f5b77f75113c15ff772d0ebfee8d87b73595c6c Mon Sep 17 00:00:00 2001 From: Fedik Date: Sat, 13 Jan 2024 11:45:30 +0200 Subject: [PATCH 01/12] Web Asset cross dependencies --- libraries/src/WebAsset/WebAssetItem.php | 38 +++++++++++--- ...WebAssetItemCrossDependenciesInterface.php | 34 ++++++++++++ libraries/src/WebAsset/WebAssetManager.php | 52 ++++++++++++++++++- 3 files changed, 117 insertions(+), 7 deletions(-) create mode 100644 libraries/src/WebAsset/WebAssetItemCrossDependenciesInterface.php diff --git a/libraries/src/WebAsset/WebAssetItem.php b/libraries/src/WebAsset/WebAssetItem.php index b7546a7b2afe5..c1c794ab91b27 100644 --- a/libraries/src/WebAsset/WebAssetItem.php +++ b/libraries/src/WebAsset/WebAssetItem.php @@ -25,7 +25,7 @@ * * @since 4.0.0 */ -class WebAssetItem implements WebAssetItemInterface +class WebAssetItem implements WebAssetItemInterface, WebAssetItemCrossDependenciesInterface { /** * Asset name @@ -67,6 +67,14 @@ class WebAssetItem implements WebAssetItemInterface */ protected $dependencies = []; + /** + * Asset cross dependencies + * + * @var string[] + * @since __DEPLOY_VERSION__ + */ + protected $crossDependencies = []; + /** * Asset version * @@ -78,11 +86,11 @@ class WebAssetItem implements WebAssetItemInterface /** * Class constructor * - * @param string $name The asset name - * @param string $uri The URI for the asset - * @param array $options Additional options for the asset - * @param array $attributes Attributes for the asset - * @param array $dependencies Asset dependencies + * @param string $name The asset name + * @param ?string $uri The URI for the asset + * @param array $options Additional options for the asset + * @param array $attributes Attributes for the asset + * @param array $dependencies Asset dependencies * * @since 4.0.0 */ @@ -115,6 +123,11 @@ public function __construct( $this->dependencies = $dependencies; } + if (\array_key_exists('crossDependencies', $options)) { + $this->crossDependencies = (array) $options['crossDependencies']; + unset($options['crossDependencies']); + } + $this->options = $options; } @@ -154,6 +167,19 @@ public function getDependencies(): array return $this->dependencies; } + /** + * Return associative list of dependencies. + * Example: ['script' => ['script1', 'script2'], 'style' => ['style1', 'style2']] + * + * @return array[] + * + * @since __DEPLOY_VERSION__ + */ + public function getCrossDependencies(): array + { + return $this->crossDependencies; + } + /** * Get the file path * diff --git a/libraries/src/WebAsset/WebAssetItemCrossDependenciesInterface.php b/libraries/src/WebAsset/WebAssetItemCrossDependenciesInterface.php new file mode 100644 index 0000000000000..2148fe15d82e5 --- /dev/null +++ b/libraries/src/WebAsset/WebAssetItemCrossDependenciesInterface.php @@ -0,0 +1,34 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\CMS\WebAsset; + +// phpcs:disable PSR1.Files.SideEffects +\defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Interface for Web Asset Item with cross dependencies + * + * Asset Item are "read only" object, all properties must be set through class constructor. + * + * @since __DEPLOY_VERSION__ + */ +interface WebAssetItemCrossDependenciesInterface +{ + /** + * Return associative list of dependencies. + * Example: ['script' => ['script1', 'script2'], 'style' => ['style1', 'style2']] + * + * @return array[] + * + * @since __DEPLOY_VERSION__ + */ + public function getCrossDependencies(): array; +} diff --git a/libraries/src/WebAsset/WebAssetManager.php b/libraries/src/WebAsset/WebAssetManager.php index 23be148c2bbbf..e0fb70d902ce1 100644 --- a/libraries/src/WebAsset/WebAssetManager.php +++ b/libraries/src/WebAsset/WebAssetManager.php @@ -69,6 +69,15 @@ class WebAssetManager implements WebAssetManagerInterface */ public const ASSET_STATE_DEPENDENCY = 2; + /** + * Mark active asset that is enabled as cross dependency to another asset + * + * @var integer + * + * @since __DEPLOY_VERSION__ + */ + public const ASSET_STATE_CROSS_DEPENDENCY = 3; + /** * The WebAsset Registry instance * @@ -747,7 +756,10 @@ protected function enableDependencies(string $type = null, WebAssetItem $asset = // Set dependency state only when it is inactive, to keep a manually activated Asset in their original state if (empty($this->activeAssets[$depType][$depItem->getName()])) { // Add the dependency at the top of the list of active assets - $this->activeAssets[$depType] = [$depItem->getName() => static::ASSET_STATE_DEPENDENCY] + $this->activeAssets[$depType]; + $this->activeAssets[$depType] = [ + // Try to distinguish a cross dependency from a regular one, however it not always accurate + $depItem->getName() => $depType === $type ? static::ASSET_STATE_DEPENDENCY : static::ASSET_STATE_CROSS_DEPENDENCY, + ] + $this->activeAssets[$depType]; } } } @@ -963,6 +975,7 @@ protected function getDependenciesForAsset( $recursionRoot = $recursionRoot ?? $asset; $recursionType = $recursionType ?? $type; + // Check for regular dependencies foreach ($asset->getDependencies() as $depName) { $depType = $type; @@ -989,6 +1002,43 @@ protected function getDependenciesForAsset( $assets = array_replace_recursive($assets, $parentDeps); } + // Check for cross dependencies + if ($asset->getCrossDependencies()) { + // Loop through each type + foreach ($asset->getCrossDependencies() as $crossType => $crossDependencies) { + // Ignore the same type, it should be defined as "dependencies" and not as "crossDependencies" + if ($crossType === $type) { + continue; + } + + foreach ($crossDependencies as $depName) { + $depType = $crossType; + + // Skip already loaded in recursion + if ($recursionRoot->getName() === $depName && $recursionType === $depType) { + continue; + } + + if (!$this->registry->exists($depType, $depName)) { + throw new UnsatisfiedDependencyException( + sprintf('Unsatisfied cross dependency "%s" for an asset "%s" of type "%s"', $depName, $asset->getName(), $depType) + ); + } + + $dep = $this->registry->get($depType, $depName); + + $assets[$depType][$depName] = $dep; + + if (!$recursively) { + continue; + } + + $parentDeps = $this->getDependenciesForAsset($depType, $dep, true, $recursionType, $recursionRoot); + $assets = array_replace_recursive($assets, $parentDeps); + } + } + } + return $assets; } } From 8f49189f08dbee4e45153eb469c3815fef9ad289 Mon Sep 17 00:00:00 2001 From: Fedik Date: Sun, 14 Jan 2024 11:58:46 +0200 Subject: [PATCH 02/12] Web Asset cross dependencies --- libraries/src/WebAsset/WebAssetItem.php | 2 +- ...WebAssetItemCrossDependenciesInterface.php | 2 +- libraries/src/WebAsset/WebAssetManager.php | 57 ++++++++++++------- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/libraries/src/WebAsset/WebAssetItem.php b/libraries/src/WebAsset/WebAssetItem.php index c1c794ab91b27..14adbb6155773 100644 --- a/libraries/src/WebAsset/WebAssetItem.php +++ b/libraries/src/WebAsset/WebAssetItem.php @@ -168,7 +168,7 @@ public function getDependencies(): array } /** - * Return associative list of dependencies. + * Return associative list of cross dependencies. * Example: ['script' => ['script1', 'script2'], 'style' => ['style1', 'style2']] * * @return array[] diff --git a/libraries/src/WebAsset/WebAssetItemCrossDependenciesInterface.php b/libraries/src/WebAsset/WebAssetItemCrossDependenciesInterface.php index 2148fe15d82e5..a5b3f97a61942 100644 --- a/libraries/src/WebAsset/WebAssetItemCrossDependenciesInterface.php +++ b/libraries/src/WebAsset/WebAssetItemCrossDependenciesInterface.php @@ -23,7 +23,7 @@ interface WebAssetItemCrossDependenciesInterface { /** - * Return associative list of dependencies. + * Return associative list of cross dependencies. * Example: ['script' => ['script1', 'script2'], 'style' => ['style1', 'style2']] * * @return array[] diff --git a/libraries/src/WebAsset/WebAssetManager.php b/libraries/src/WebAsset/WebAssetManager.php index e0fb70d902ce1..14ee8bd603878 100644 --- a/libraries/src/WebAsset/WebAssetManager.php +++ b/libraries/src/WebAsset/WebAssetManager.php @@ -749,7 +749,7 @@ protected function enableDependencies(string $type = null, WebAssetItem $asset = if ($asset) { // Get all dependencies of given asset recursively - $allDependencies = $this->getDependenciesForAsset($type, $asset, true); + $allDependencies = $this->getAllDependenciesForAsset($type, $asset, true); foreach ($allDependencies as $depType => $depItems) { foreach ($depItems as $depItem) { @@ -963,6 +963,8 @@ protected function getConnectionsGraph(array $assets): array * @throws UnsatisfiedDependencyException When Dependency cannot be found * * @since 4.0.0 + * + * @deprecated __DEPLOY_VERSION__ Use getAllDependenciesForAsset() instead. Will be removed in 8.0. */ protected function getDependenciesForAsset( string $type, @@ -971,19 +973,41 @@ protected function getDependenciesForAsset( string $recursionType = null, WebAssetItem $recursionRoot = null ): array { - $assets = []; - $recursionRoot = $recursionRoot ?? $asset; - $recursionType = $recursionType ?? $type; + return $this->getAllDependenciesForAsset($type, $asset, $recursively); + } + + /** + * Return dependencies for Asset as associative array of WebAssetItem objects, grouped per type + * + * @param string $type The asset type, script or style + * @param WebAssetItemInterface $asset Asset instance + * @param boolean $recursively Whether to search for dependency recursively + * @param array $visited The list of checked assets visited while resolving recursive dependencies + * + * @return array + * + * @throws UnsatisfiedDependencyException When Dependency cannot be found + * + * @since __DEPLOY_VERSION__ + */ + protected function getAllDependenciesForAsset( + string $type, + WebAssetItemInterface $asset, + bool $recursively = false, + array &$visited = [] + ): array { + $assets = []; + + if (!empty($visited[$type][$asset->getName()])) { + return $assets; + } + + $visited[$type][$asset->getName()] = true; // Check for regular dependencies foreach ($asset->getDependencies() as $depName) { $depType = $type; - // Skip already loaded in recursion - if ($recursionRoot->getName() === $depName && $recursionType === $depType) { - continue; - } - if (!$this->registry->exists($depType, $depName)) { throw new UnsatisfiedDependencyException( sprintf('Unsatisfied dependency "%s" for an asset "%s" of type "%s"', $depName, $asset->getName(), $depType) @@ -998,12 +1022,12 @@ protected function getDependenciesForAsset( continue; } - $parentDeps = $this->getDependenciesForAsset($depType, $dep, true, $recursionType, $recursionRoot); - $assets = array_replace_recursive($assets, $parentDeps); + $parentDeps = $this->getAllDependenciesForAsset($depType, $dep, true, $visited); + $assets = $parentDeps ? array_replace_recursive($assets, $parentDeps) : $assets; } // Check for cross dependencies - if ($asset->getCrossDependencies()) { + if ($asset instanceof WebAssetItemCrossDependenciesInterface) { // Loop through each type foreach ($asset->getCrossDependencies() as $crossType => $crossDependencies) { // Ignore the same type, it should be defined as "dependencies" and not as "crossDependencies" @@ -1014,11 +1038,6 @@ protected function getDependenciesForAsset( foreach ($crossDependencies as $depName) { $depType = $crossType; - // Skip already loaded in recursion - if ($recursionRoot->getName() === $depName && $recursionType === $depType) { - continue; - } - if (!$this->registry->exists($depType, $depName)) { throw new UnsatisfiedDependencyException( sprintf('Unsatisfied cross dependency "%s" for an asset "%s" of type "%s"', $depName, $asset->getName(), $depType) @@ -1033,8 +1052,8 @@ protected function getDependenciesForAsset( continue; } - $parentDeps = $this->getDependenciesForAsset($depType, $dep, true, $recursionType, $recursionRoot); - $assets = array_replace_recursive($assets, $parentDeps); + $parentDeps = $this->getAllDependenciesForAsset($depType, $dep, true, $visited); + $assets = $parentDeps ? array_replace_recursive($assets, $parentDeps) : $assets; } } } From 2b233d6afd2e3981a46a6de252f6cecc9624b170 Mon Sep 17 00:00:00 2001 From: Fedik Date: Sun, 14 Jan 2024 12:10:21 +0200 Subject: [PATCH 03/12] Web Asset cross dependencies --- libraries/src/WebAsset/WebAssetItem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/WebAsset/WebAssetItem.php b/libraries/src/WebAsset/WebAssetItem.php index 14adbb6155773..235ae4bfda2ab 100644 --- a/libraries/src/WebAsset/WebAssetItem.php +++ b/libraries/src/WebAsset/WebAssetItem.php @@ -70,7 +70,7 @@ class WebAssetItem implements WebAssetItemInterface, WebAssetItemCrossDependenci /** * Asset cross dependencies * - * @var string[] + * @var array[] * @since __DEPLOY_VERSION__ */ protected $crossDependencies = []; From 29437540ac67b587ffa642ffa803d02e395c2d95 Mon Sep 17 00:00:00 2001 From: Fedik Date: Tue, 16 Jan 2024 18:31:58 +0200 Subject: [PATCH 04/12] cross-dependency for fancy select --- .../layouts/joomla/form/field/categoryedit.php | 1 - .../layouts/joomla/form/field/modulespositionedit.php | 1 - .../com_modules/tmpl/modules/default_batch_body.php | 1 - .../tmpl/template/default_modal_child_body.php | 2 +- build/build-modules-js/settings.json | 6 +++++- layouts/joomla/form/field/groupedlist-fancy-select.php | 1 - layouts/joomla/form/field/list-fancy-select.php | 1 - layouts/joomla/form/field/tag.php | 1 - libraries/src/Document/Renderer/Html/ScriptsRenderer.php | 5 +++++ 9 files changed, 11 insertions(+), 8 deletions(-) diff --git a/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php b/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php index 79b7c2821cfa2..387fb869ff5b7 100644 --- a/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php +++ b/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php @@ -135,7 +135,6 @@ Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); Factory::getDocument()->getWebAssetManager() - ->usePreset('choicesjs') ->useScript('webcomponent.field-fancy-select'); ?> diff --git a/administrator/components/com_modules/layouts/joomla/form/field/modulespositionedit.php b/administrator/components/com_modules/layouts/joomla/form/field/modulespositionedit.php index 0bca7122aa695..1dbbd774f0192 100644 --- a/administrator/components/com_modules/layouts/joomla/form/field/modulespositionedit.php +++ b/administrator/components/com_modules/layouts/joomla/form/field/modulespositionedit.php @@ -73,7 +73,6 @@ Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); Factory::getDocument()->getWebAssetManager() - ->usePreset('choicesjs') ->useScript('webcomponent.field-fancy-select'); ?> diff --git a/administrator/components/com_modules/tmpl/modules/default_batch_body.php b/administrator/components/com_modules/tmpl/modules/default_batch_body.php index 381a9aad488df..caa60aa88b47c 100644 --- a/administrator/components/com_modules/tmpl/modules/default_batch_body.php +++ b/administrator/components/com_modules/tmpl/modules/default_batch_body.php @@ -33,7 +33,6 @@ Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); $this->document->getWebAssetManager() - ->usePreset('choicesjs') ->useScript('webcomponent.field-fancy-select') ->useScript('joomla.batch-copymove'); diff --git a/administrator/components/com_templates/tmpl/template/default_modal_child_body.php b/administrator/components/com_templates/tmpl/template/default_modal_child_body.php index 507b0767372af..0abd3bdec545b 100644 --- a/administrator/components/com_templates/tmpl/template/default_modal_child_body.php +++ b/administrator/components/com_templates/tmpl/template/default_modal_child_body.php @@ -15,7 +15,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; -Factory::getDocument()->getWebAssetManager()->usePreset('choicesjs'); +Factory::getDocument()->getWebAssetManager()->useScript('choicesjs'); // Generate a list of styles for the child creation modal $options = []; diff --git a/build/build-modules-js/settings.json b/build/build-modules-js/settings.json index c9f7a04454e99..4a8d77d8da6db 100644 --- a/build/build-modules-js/settings.json +++ b/build/build-modules-js/settings.json @@ -268,6 +268,9 @@ "uri": "choices.min.js", "attributes": { "defer": true + }, + "crossDependencies": { + "style": ["choicesjs"] } }, { @@ -276,7 +279,8 @@ "dependencies": [ "choicesjs#style", "choicesjs#script" - ] + ], + "deprecated": true } ], "dependencies": [], diff --git a/layouts/joomla/form/field/groupedlist-fancy-select.php b/layouts/joomla/form/field/groupedlist-fancy-select.php index 35df462ab80c9..0a695c16d39a3 100644 --- a/layouts/joomla/form/field/groupedlist-fancy-select.php +++ b/layouts/joomla/form/field/groupedlist-fancy-select.php @@ -114,7 +114,6 @@ Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); Factory::getApplication()->getDocument()->getWebAssetManager() - ->usePreset('choicesjs') ->useScript('webcomponent.field-fancy-select'); ?> diff --git a/layouts/joomla/form/field/list-fancy-select.php b/layouts/joomla/form/field/list-fancy-select.php index 344303b39d0b7..f0e24e49b8333 100644 --- a/layouts/joomla/form/field/list-fancy-select.php +++ b/layouts/joomla/form/field/list-fancy-select.php @@ -96,7 +96,6 @@ Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); Factory::getApplication()->getDocument()->getWebAssetManager() - ->usePreset('choicesjs') ->useScript('webcomponent.field-fancy-select'); ?> diff --git a/layouts/joomla/form/field/tag.php b/layouts/joomla/form/field/tag.php index ea6c458af2c64..4761b504c33e6 100644 --- a/layouts/joomla/form/field/tag.php +++ b/layouts/joomla/form/field/tag.php @@ -115,7 +115,6 @@ Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); Factory::getDocument()->getWebAssetManager() - ->usePreset('choicesjs') ->useScript('webcomponent.field-fancy-select'); ?> diff --git a/libraries/src/Document/Renderer/Html/ScriptsRenderer.php b/libraries/src/Document/Renderer/Html/ScriptsRenderer.php index a9ffb25cf069b..6eb05fde80081 100644 --- a/libraries/src/Document/Renderer/Html/ScriptsRenderer.php +++ b/libraries/src/Document/Renderer/Html/ScriptsRenderer.php @@ -10,6 +10,7 @@ namespace Joomla\CMS\Document\Renderer\Html; use Joomla\CMS\Document\DocumentRenderer; +use Joomla\CMS\WebAsset\WebAssetItemCrossDependenciesInterface; use Joomla\CMS\WebAsset\WebAssetItemInterface; // phpcs:disable PSR1.Files.SideEffects @@ -163,6 +164,10 @@ private function renderElement($item): string $attribs['data-asset-dependencies'] = implode(',', $asset->getDependencies()); } + if ($asset instanceof WebAssetItemCrossDependenciesInterface && $asset->getCrossDependencies()) { + $attribs['data-asset-cross-dependencies'] = str_replace('"', '', json_encode($asset->getCrossDependencies())); + } + if ($asset->getOption('deprecated')) { @trigger_error( sprintf('Web Asset script [%s] is deprecated. %s', $asset->getName(), $asset->getOption('deprecatedMsg', '')), From 71989bf4299c8343c1314b29ec1d7b6570e35a2d Mon Sep 17 00:00:00 2001 From: Fedik Date: Tue, 16 Jan 2024 18:39:13 +0200 Subject: [PATCH 05/12] cross-dependency check --- libraries/src/WebAsset/WebAssetManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/WebAsset/WebAssetManager.php b/libraries/src/WebAsset/WebAssetManager.php index 14ee8bd603878..24e71e5ca8048 100644 --- a/libraries/src/WebAsset/WebAssetManager.php +++ b/libraries/src/WebAsset/WebAssetManager.php @@ -1027,7 +1027,7 @@ protected function getAllDependenciesForAsset( } // Check for cross dependencies - if ($asset instanceof WebAssetItemCrossDependenciesInterface) { + if ($asset instanceof WebAssetItemCrossDependenciesInterface && $asset->getCrossDependencies()) { // Loop through each type foreach ($asset->getCrossDependencies() as $crossType => $crossDependencies) { // Ignore the same type, it should be defined as "dependencies" and not as "crossDependencies" From 6ac0f765387e9280b09c46e91ae7d7b8fd6719f2 Mon Sep 17 00:00:00 2001 From: Fedik Date: Sat, 20 Jan 2024 10:37:12 +0200 Subject: [PATCH 06/12] deprecate a couple presets --- .../com_templates/tmpl/template/default.php | 2 +- build/build-modules-js/settings.json | 29 +++++++++++++++---- .../com_finder/tmpl/search/default_form.php | 2 +- libraries/src/HTML/Helpers/DraggableList.php | 1 - modules/mod_finder/tmpl/default.php | 2 +- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/administrator/components/com_templates/tmpl/template/default.php b/administrator/components/com_templates/tmpl/template/default.php index 75528e08e0a09..f0c955087bdff 100644 --- a/administrator/components/com_templates/tmpl/template/default.php +++ b/administrator/components/com_templates/tmpl/template/default.php @@ -39,7 +39,7 @@ } if ($this->type == 'image') { - $wa->usePreset('cropperjs'); + $wa->useScript('cropperjs'); } if ($this->type == 'font') { diff --git a/build/build-modules-js/settings.json b/build/build-modules-js/settings.json index 4a8d77d8da6db..f6e0d07b15aa3 100644 --- a/build/build-modules-js/settings.json +++ b/build/build-modules-js/settings.json @@ -26,6 +26,9 @@ "uri": "awesomplete.min.js", "attributes": { "defer": true + }, + "crossDependencies": { + "style": ["awesomplete"] } }, { @@ -34,7 +37,9 @@ "dependencies": [ "awesomplete#style", "awesomplete#script" - ] + ], + "deprecated": true, + "deprecatedMsg": "Use script asset directly. Will be removed in 7.0" } ], "dependencies": [], @@ -219,7 +224,10 @@ "name": "cropper-module", "type": "script", "uri": "cropper.esm.js", - "importmap": true + "importmap": true, + "crossDependencies": { + "style": ["cropperjs"] + } }, { "name": "cropperjs", @@ -228,6 +236,9 @@ "uri": "cropper.min.js", "attributes": { "defer": true + }, + "crossDependencies": { + "style": ["cropperjs"] } }, { @@ -236,7 +247,9 @@ "dependencies": [ "cropperjs#style", "cropperjs#script" - ] + ], + "deprecated": true, + "deprecatedMsg": "Use script asset directly. Will be removed in 7.0" } ], "dependencies": [], @@ -280,7 +293,8 @@ "choicesjs#style", "choicesjs#script" ], - "deprecated": true + "deprecated": true, + "deprecatedMsg": "Use script asset directly. Will be removed in 7.0" } ], "dependencies": [], @@ -326,6 +340,9 @@ "uri": "dragula.min.js", "attributes": { "defer": true + }, + "crossDependencies": { + "style": ["dragula"] } }, { @@ -334,7 +351,9 @@ "dependencies": [ "dragula#style", "dragula#script" - ] + ], + "deprecated": true, + "deprecatedMsg": "Use script asset directly. Will be removed in 7.0" } ], "dependencies": [], diff --git a/components/com_finder/tmpl/search/default_form.php b/components/com_finder/tmpl/search/default_form.php index 0ec0bffd0dd79..ba783d8614468 100644 --- a/components/com_finder/tmpl/search/default_form.php +++ b/components/com_finder/tmpl/search/default_form.php @@ -18,7 +18,7 @@ * This segment of code sets up the autocompleter. */ if ($this->params->get('show_autosuggest', 1)) { - $this->document->getWebAssetManager()->usePreset('awesomplete'); + $this->document->getWebAssetManager()->useScript('awesomplete'); $this->document->addScriptOptions('finder-search', ['url' => Route::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component', false)]); Text::script('JLIB_JS_AJAX_ERROR_OTHER'); diff --git a/libraries/src/HTML/Helpers/DraggableList.php b/libraries/src/HTML/Helpers/DraggableList.php index ebb8a27415449..e0380ac26793d 100644 --- a/libraries/src/HTML/Helpers/DraggableList.php +++ b/libraries/src/HTML/Helpers/DraggableList.php @@ -75,7 +75,6 @@ public static function draggable( } $doc->getWebAssetManager() - ->usePreset('dragula') ->useScript('joomla.draggable'); // Set static array diff --git a/modules/mod_finder/tmpl/default.php b/modules/mod_finder/tmpl/default.php index dcde897991376..108d0bf5e96f1 100644 --- a/modules/mod_finder/tmpl/default.php +++ b/modules/mod_finder/tmpl/default.php @@ -49,7 +49,7 @@ * This segment of code sets up the autocompleter. */ if ($params->get('show_autosuggest', 1)) { - $wa->usePreset('awesomplete'); + $wa->useScript('awesomplete'); $app->getDocument()->addScriptOptions('finder-search', ['url' => Route::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component', false)]); Text::script('JLIB_JS_AJAX_ERROR_OTHER'); From 20decc348cc61f12bad35f41a83483673e37649e Mon Sep 17 00:00:00 2001 From: Fedik Date: Thu, 15 Feb 2024 16:27:43 +0200 Subject: [PATCH 07/12] Cross dependency as string with # --- build/build-modules-js/settings.json | 30 +++++++++--------- libraries/src/WebAsset/WebAssetItem.php | 41 ++++++++++++++++++++----- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/build/build-modules-js/settings.json b/build/build-modules-js/settings.json index f6e0d07b15aa3..e9c260bcb8b77 100644 --- a/build/build-modules-js/settings.json +++ b/build/build-modules-js/settings.json @@ -27,9 +27,9 @@ "attributes": { "defer": true }, - "crossDependencies": { - "style": ["awesomplete"] - } + "crossDependencies": [ + "awesomplete#style" + ] }, { "name": "awesomplete", @@ -225,9 +225,9 @@ "type": "script", "uri": "cropper.esm.js", "importmap": true, - "crossDependencies": { - "style": ["cropperjs"] - } + "crossDependencies": [ + "cropperjs#style" + ] }, { "name": "cropperjs", @@ -237,9 +237,9 @@ "attributes": { "defer": true }, - "crossDependencies": { - "style": ["cropperjs"] - } + "crossDependencies": [ + "cropperjs#style" + ] }, { "name": "cropperjs", @@ -282,9 +282,9 @@ "attributes": { "defer": true }, - "crossDependencies": { - "style": ["choicesjs"] - } + "crossDependencies": [ + "choicesjs#style" + ] }, { "name": "choicesjs", @@ -341,9 +341,9 @@ "attributes": { "defer": true }, - "crossDependencies": { - "style": ["dragula"] - } + "crossDependencies": [ + "dragula#style" + ] }, { "name": "dragula", diff --git a/libraries/src/WebAsset/WebAssetItem.php b/libraries/src/WebAsset/WebAssetItem.php index 235ae4bfda2ab..68e34e2d06e58 100644 --- a/libraries/src/WebAsset/WebAssetItem.php +++ b/libraries/src/WebAsset/WebAssetItem.php @@ -86,11 +86,12 @@ class WebAssetItem implements WebAssetItemInterface, WebAssetItemCrossDependenci /** * Class constructor * - * @param string $name The asset name - * @param ?string $uri The URI for the asset - * @param array $options Additional options for the asset - * @param array $attributes Attributes for the asset - * @param array $dependencies Asset dependencies + * @param string $name The asset name + * @param ?string $uri The URI for the asset + * @param array $options Additional options for the asset + * @param array $attributes Attributes for the asset + * @param array $dependencies Asset dependencies, from assets of the same type + * @param array $crossDependencies Asset dependencies, from assets of another type * * @since 4.0.0 */ @@ -99,7 +100,8 @@ public function __construct( string $uri = null, array $options = [], array $attributes = [], - array $dependencies = [] + array $dependencies = [], + array $crossDependencies = [] ) { $this->name = $name; $this->uri = $uri; @@ -124,10 +126,35 @@ public function __construct( } if (\array_key_exists('crossDependencies', $options)) { - $this->crossDependencies = (array) $options['crossDependencies']; + $crossDependencies = (array) $options['crossDependencies']; unset($options['crossDependencies']); } + if ($crossDependencies) { + // Parse Cross Dependencies which comes in ["name#type"] or ["type" => ["name"]] format + foreach ($crossDependencies as $key => $crossDependency) { + if (\is_array($crossDependency)) { + $this->crossDependencies[$key] = $crossDependency; + } else { + $pos = strrpos($crossDependency, '#'); + $depType = $pos ? substr($crossDependency, $pos + 1) : ''; + $depName = $pos ? substr($crossDependency, 0, $pos) : ''; + + if (!$depType || !$depName) { + throw new \UnexpectedValueException( + sprintf('Incomplete definition for cross dependency, for asset "%s"', $name) + ); + } + + if (empty($this->crossDependencies[$depType])) { + $this->crossDependencies[$depType] = []; + } + + $this->crossDependencies[$depType][] = $depName; + } + } + } + $this->options = $options; } From eeb47d7ab2738d7a3d5dbdd559b008fd720e4b17 Mon Sep 17 00:00:00 2001 From: Fedik Date: Sat, 17 Feb 2024 12:15:22 +0200 Subject: [PATCH 08/12] Cross dependency as string with # --- libraries/src/WebAsset/WebAssetItem.php | 59 ++++++++++++++----------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/libraries/src/WebAsset/WebAssetItem.php b/libraries/src/WebAsset/WebAssetItem.php index 68e34e2d06e58..6b73a4023653a 100644 --- a/libraries/src/WebAsset/WebAssetItem.php +++ b/libraries/src/WebAsset/WebAssetItem.php @@ -67,6 +67,14 @@ class WebAssetItem implements WebAssetItemInterface, WebAssetItemCrossDependenci */ protected $dependencies = []; + /** + * Unparsed cross dependencies + * + * @var array[] + * @since __DEPLOY_VERSION__ + */ + private $rawCrossDependencies = []; + /** * Asset cross dependencies * @@ -126,33 +134,10 @@ public function __construct( } if (\array_key_exists('crossDependencies', $options)) { - $crossDependencies = (array) $options['crossDependencies']; + $this->rawCrossDependencies = (array) $options['crossDependencies']; unset($options['crossDependencies']); - } - - if ($crossDependencies) { - // Parse Cross Dependencies which comes in ["name#type"] or ["type" => ["name"]] format - foreach ($crossDependencies as $key => $crossDependency) { - if (\is_array($crossDependency)) { - $this->crossDependencies[$key] = $crossDependency; - } else { - $pos = strrpos($crossDependency, '#'); - $depType = $pos ? substr($crossDependency, $pos + 1) : ''; - $depName = $pos ? substr($crossDependency, 0, $pos) : ''; - - if (!$depType || !$depName) { - throw new \UnexpectedValueException( - sprintf('Incomplete definition for cross dependency, for asset "%s"', $name) - ); - } - - if (empty($this->crossDependencies[$depType])) { - $this->crossDependencies[$depType] = []; - } - - $this->crossDependencies[$depType][] = $depName; - } - } + } else { + $this->rawCrossDependencies = $crossDependencies; } $this->options = $options; @@ -204,6 +189,28 @@ public function getDependencies(): array */ public function getCrossDependencies(): array { + if ($this->rawCrossDependencies && !$this->crossDependencies) { + // Parse Cross Dependencies which comes in ["name#type"] format + foreach ($this->rawCrossDependencies as $crossDependency) { + $pos = strrpos($crossDependency, '#'); + $depType = $pos ? substr($crossDependency, $pos + 1) : ''; + $depName = $pos ? substr($crossDependency, 0, $pos) : ''; + + if (!$depType || !$depName) { + throw new \UnexpectedValueException( + sprintf('Incomplete definition for cross dependency, for asset "%s"', $this->getName()) + ); + } + + if (empty($this->crossDependencies[$depType])) { + $this->crossDependencies[$depType] = []; + } + + $this->crossDependencies[$depType][] = $depName; + } + $this->rawCrossDependencies = []; + } + return $this->crossDependencies; } From 9db8750967e69f13c30486302bcfb98213f191ff Mon Sep 17 00:00:00 2001 From: Fedik Date: Sat, 17 Feb 2024 12:29:43 +0200 Subject: [PATCH 09/12] Cross dependency as string with # --- libraries/src/WebAsset/WebAssetItem.php | 35 ++++++++++++++----------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/libraries/src/WebAsset/WebAssetItem.php b/libraries/src/WebAsset/WebAssetItem.php index 6b73a4023653a..e22966386e03d 100644 --- a/libraries/src/WebAsset/WebAssetItem.php +++ b/libraries/src/WebAsset/WebAssetItem.php @@ -190,23 +190,28 @@ public function getDependencies(): array public function getCrossDependencies(): array { if ($this->rawCrossDependencies && !$this->crossDependencies) { - // Parse Cross Dependencies which comes in ["name#type"] format - foreach ($this->rawCrossDependencies as $crossDependency) { - $pos = strrpos($crossDependency, '#'); - $depType = $pos ? substr($crossDependency, $pos + 1) : ''; - $depName = $pos ? substr($crossDependency, 0, $pos) : ''; - - if (!$depType || !$depName) { - throw new \UnexpectedValueException( - sprintf('Incomplete definition for cross dependency, for asset "%s"', $this->getName()) - ); - } + // Cross Dependencies as an associative array + if (!\is_int(key($this->rawCrossDependencies))) { + $this->crossDependencies = $this->rawCrossDependencies; + } else { + // Parse Cross Dependencies which comes in ["name#type"] format + foreach ($this->rawCrossDependencies as $crossDependency) { + $pos = strrpos($crossDependency, '#'); + $depType = $pos ? substr($crossDependency, $pos + 1) : ''; + $depName = $pos ? substr($crossDependency, 0, $pos) : ''; + + if (!$depType || !$depName) { + throw new \UnexpectedValueException( + sprintf('Incomplete definition for cross dependency, for asset "%s"', $this->getName()) + ); + } - if (empty($this->crossDependencies[$depType])) { - $this->crossDependencies[$depType] = []; - } + if (empty($this->crossDependencies[$depType])) { + $this->crossDependencies[$depType] = []; + } - $this->crossDependencies[$depType][] = $depName; + $this->crossDependencies[$depType][] = $depName; + } } $this->rawCrossDependencies = []; } From b40aa725c80a1051d9139b478e6049dca142efba Mon Sep 17 00:00:00 2001 From: Fedik Date: Wed, 21 Feb 2024 14:43:07 +0200 Subject: [PATCH 10/12] Preset CrossDependencies --- libraries/src/WebAsset/WebAssetManager.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libraries/src/WebAsset/WebAssetManager.php b/libraries/src/WebAsset/WebAssetManager.php index 1767a0fd21eab..fd875aafe5a82 100644 --- a/libraries/src/WebAsset/WebAssetManager.php +++ b/libraries/src/WebAsset/WebAssetManager.php @@ -393,6 +393,22 @@ protected function usePresetItems($name): WebAssetManagerInterface $this->useAsset($depType, $depName); } + // Call useAsset() to each of its crossDependency + if ($asset instanceof WebAssetItemCrossDependenciesInterface && $asset->getCrossDependencies()) { + foreach ($asset->getCrossDependencies() as $depType => $depItems) { + foreach ($depItems as $depName) { + // Make sure dependency exists + if (!$this->registry->exists($depType, $depName)) { + throw new UnsatisfiedDependencyException( + sprintf('Unsatisfied dependency "%s" for an asset "%s" of type "%s"', $depName, $name, 'preset') + ); + } + + $this->useAsset($depType, $depName); + } + } + } + return $this; } From 22baaedde67c8dfea03363bf07d7c24f11334ffa Mon Sep 17 00:00:00 2001 From: Fedik Date: Wed, 21 Feb 2024 14:44:34 +0200 Subject: [PATCH 11/12] Preset CrossDependencies --- libraries/src/WebAsset/WebAssetManager.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/src/WebAsset/WebAssetManager.php b/libraries/src/WebAsset/WebAssetManager.php index fd875aafe5a82..1451cfcf019d3 100644 --- a/libraries/src/WebAsset/WebAssetManager.php +++ b/libraries/src/WebAsset/WebAssetManager.php @@ -400,7 +400,12 @@ protected function usePresetItems($name): WebAssetManagerInterface // Make sure dependency exists if (!$this->registry->exists($depType, $depName)) { throw new UnsatisfiedDependencyException( - sprintf('Unsatisfied dependency "%s" for an asset "%s" of type "%s"', $depName, $name, 'preset') + sprintf( + 'Unsatisfied dependency "%s" for an asset "%s" of type "%s"', + $depName . '#' . $depType, + $name, + 'preset' + ) ); } From 5128f89441135e255c168202273e292d8bd53aab Mon Sep 17 00:00:00 2001 From: Fedik Date: Sun, 19 Oct 2025 14:37:02 +0300 Subject: [PATCH 12/12] cs --- libraries/src/WebAsset/WebAssetItem.php | 2 +- libraries/src/WebAsset/WebAssetManager.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/src/WebAsset/WebAssetItem.php b/libraries/src/WebAsset/WebAssetItem.php index ea16aca0ac226..cdc1cd1efab07 100644 --- a/libraries/src/WebAsset/WebAssetItem.php +++ b/libraries/src/WebAsset/WebAssetItem.php @@ -202,7 +202,7 @@ public function getCrossDependencies(): array if (!$depType || !$depName) { throw new \UnexpectedValueException( - sprintf('Incomplete definition for cross dependency, for asset "%s"', $this->getName()) + \sprintf('Incomplete definition for cross dependency, for asset "%s"', $this->getName()) ); } diff --git a/libraries/src/WebAsset/WebAssetManager.php b/libraries/src/WebAsset/WebAssetManager.php index bc111d873b36c..1326cafb38386 100644 --- a/libraries/src/WebAsset/WebAssetManager.php +++ b/libraries/src/WebAsset/WebAssetManager.php @@ -406,7 +406,7 @@ protected function usePresetItems($name): WebAssetManagerInterface // Make sure dependency exists if (!$this->registry->exists($depType, $depName)) { throw new UnsatisfiedDependencyException( - sprintf( + \sprintf( 'Unsatisfied dependency "%s" for an asset "%s" of type "%s"', $depName . '#' . $depType, $name, @@ -1092,7 +1092,7 @@ protected function getAllDependenciesForAsset( if (!$this->registry->exists($depType, $depName)) { throw new UnsatisfiedDependencyException( - sprintf('Unsatisfied cross dependency "%s" for an asset "%s" of type "%s"', $depName, $asset->getName(), $depType) + \sprintf('Unsatisfied cross dependency "%s" for an asset "%s" of type "%s"', $depName, $asset->getName(), $depType) ); }