Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion administrator/templates/atum/joomla.asset.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"bootstrap.js.bundle",
"css-vars-ponyfill"
],
"js": []
"js": [],
"weight": 10000
},
"template.atum.ltr": {
"name": "template.atum.ltr",
Expand Down
3 changes: 2 additions & 1 deletion build/media_src/system/joomla.asset.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"name": "core",
"js": [
"media/system/js/core.min.js"
]
],
"weight": 70
},
"keepalive": {
"name": "keepalive",
Expand Down
5 changes: 5 additions & 0 deletions libraries/src/WebAsset/WebAssetItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ public function __construct(string $name, array $data = [])
{
$this->dependencies = (array) $data['dependencies'];
}

if (!empty($data['weight']))
{
$this->weight = (float) $data['weight'];
}
}

/**
Expand Down
122 changes: 77 additions & 45 deletions libraries/src/WebAsset/WebAssetRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,6 @@ class WebAssetRegistry implements DispatcherAwareInterface
{
use DispatcherAwareTrait;

/**
* Mark the new registry file
*
* @var integer
*
* @since 4.0.0
*/
const REGISTRY_FILE_NEW = 1;

/**
* Mark already parsed registry file
*
* @var integer
*
* @since 4.0.0
*/
const REGISTRY_FILE_PARSED = 2;

/**
* Mark a broken/non-existing registry file
*
* @var integer
*
* @since 4.0.0
*/
const REGISTRY_FILE_INVALID = -1;

/**
* Files with Asset info. File path should be relative.
*
Expand Down Expand Up @@ -98,7 +71,16 @@ class WebAssetRegistry implements DispatcherAwareInterface
*
* @since 4.0.0
*/
protected $dataFiles = [];
protected $dataFilesNew = [];

/**
* List of parsed files
*
* @var array
*
* @since 4.0.0
*/
protected $dataFilesParsed = [];

/**
* Registry of available Assets
Expand Down Expand Up @@ -457,6 +439,9 @@ protected function calculateWeightOfActiveAssets(): self
}
}

// Make a copy to be used during weight processing
$graphIncomingCopy = $graphIncoming;

// Find items without incoming connections
$emptyIncoming = array_keys(
array_filter(
Expand Down Expand Up @@ -489,16 +474,69 @@ function ($el){
}

// Update a weight for each active asset
$requestedWeights = [];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than running through like this can we not use an SplPriorityQueue? (http://php.net/manual/en/class.splpriorityqueue.php)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a good idea, I need to check

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, no, SplPriorityQueue not really helpful,
I just need key (string) => value (number) array, in already defined order

foreach (array_reverse($result) as $index => $name)
{
$activeAssets[$name]->setWeight($index + 1);
// Check for existing/requested weight
$requestedWeights[$name] = null;
if ($activeAssets[$name]->getWeight())
{
$requestedWeights[$name] = $activeAssets[$name]->getWeight();
}

$activeAssets[$name]->setWeight($index * 10 + 100);
}

// Try to set a requested weight, or make it close as possible to requested, but keep the Graph order
while ($requestedWeights)
{
$item = key($requestedWeights);
$weight = array_shift($requestedWeights);

// Skip empty items
if ($weight === null)
{
continue;
}

// Check the predecessors (Outgoing vertexes), the weight cannot be lighter than the predecessor have
$topBorder = $weight - 1;
if (!empty($graphOutgoing[$item]))
{
$prevWeights = [];
foreach ($graphOutgoing[$item] as $pItem)
{
$prevWeights[] = $activeAssets[$pItem]->getWeight();
}
$topBorder = max($prevWeights);
}

// Calculate a new weight
$newWeight = $weight > $topBorder ? $weight : $topBorder + 1;

// If a new weight heavier than existing, then we need to update all incoming connections (children)
if ($newWeight > $activeAssets[$item]->getWeight() && !empty($graphIncomingCopy[$item]))
{
// Sort Graph of incoming by actual position
foreach ($graphIncomingCopy[$item] as $incomingItem)
{
// Set a weight heavier than current, then this node to be processed in next iteration
if (empty($requestedWeights[$incomingItem]))
{
$requestedWeights[$incomingItem] = $activeAssets[$incomingItem]->getWeight() + $newWeight;
}
}
}

// Set a new weight
$activeAssets[$item]->setWeight($newWeight);
}

return $this;
}

/**
* Return dependancy for Asset as array of AssetItem objects
* Return dependency for Asset as array of AssetItem objects
*
* @param WebAssetItem $asset Asset instance
* @param boolean $recursively Whether to search for dependancy recursively
Expand Down Expand Up @@ -601,12 +639,15 @@ public function addRegistryFile(string $path): self
{
$path = Path::clean($path);

if (isset($this->dataFiles[$path]))
if (isset($this->dataFilesNew[$path]) || isset($this->dataFilesParsed[$path]))
{
return $this;
}

$this->dataFiles[$path] = is_file(JPATH_ROOT . '/' . $path) ? static::REGISTRY_FILE_NEW : static::REGISTRY_FILE_INVALID;
if (is_file(JPATH_ROOT . '/' . $path))
{
$this->dataFilesNew[$path] = $path;
}

return $this;
}
Expand All @@ -620,27 +661,18 @@ public function addRegistryFile(string $path): self
*/
protected function parseRegistryFiles()
{
// Filter new asset data files and parse each
$constantIsNew = static::REGISTRY_FILE_NEW;
$files = array_filter(
$this->dataFiles,
function($state) use ($constantIsNew)
{
return $state === $constantIsNew;
}
);

if (!$files)
if (!$this->dataFilesNew)
{
return;
}

foreach (array_keys($files) as $path)
foreach ($this->dataFilesNew as $path)
{
$this->parseRegistryFile($path);

// Mark as parsed (not new)
$this->dataFiles[$path] = static::REGISTRY_FILE_PARSED;
unset($this->dataFilesNew[$path]);
$this->dataFilesParsed[$path] = $path;
}
}

Expand Down
3 changes: 2 additions & 1 deletion templates/cassiopeia/joomla.asset.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"js": [
"template.js",
"user.js"
]
],
"weight": 10000
},
"template.cassiopeia.ltr": {
"name": "template.cassiopeia.ltr",
Expand Down