Add weights to asset manager

This commit is contained in:
Dmitriy Simushev 2014-10-13 09:05:35 +00:00
parent 54b4814389
commit 5dafbd2997
2 changed files with 77 additions and 17 deletions

View File

@ -93,11 +93,12 @@ class AssetManager implements AssetManagerInterface
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function attachJs($content, $type = AssetManagerInterface::RELATIVE_URL) public function attachJs($content, $type = AssetManagerInterface::RELATIVE_URL, $weight = 0)
{ {
$this->jsAssets[] = array( $this->jsAssets[] = array(
'content' => $content, 'content' => $content,
'type' => $type, 'type' => $type,
'weight' => $weight,
); );
} }
@ -106,20 +107,23 @@ class AssetManager implements AssetManagerInterface
*/ */
public function getJsAssets() public function getJsAssets()
{ {
return array_merge( return $this->sort(
$this->jsAssets, array_merge(
$this->triggerJsEvent() $this->jsAssets,
$this->triggerJsEvent()
)
); );
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function attachCss($content, $type = AssetManagerInterface::RELATIVE_URL) public function attachCss($content, $type = AssetManagerInterface::RELATIVE_URL, $weight = 0)
{ {
$this->cssAssets[] = array( $this->cssAssets[] = array(
'content' => $content, 'content' => $content,
'type' => $type, 'type' => $type,
'weight' => $weight,
); );
} }
@ -128,9 +132,11 @@ class AssetManager implements AssetManagerInterface
*/ */
public function getCssAssets() public function getCssAssets()
{ {
return array_merge( return $this->sort(
$this->cssAssets, array_merge(
$this->triggerCssEvent() $this->cssAssets,
$this->triggerCssEvent()
)
); );
} }
@ -159,8 +165,8 @@ class AssetManager implements AssetManagerInterface
* request instance. JavaScript files will be attached to the requested * request instance. JavaScript files will be attached to the requested
* page. * page.
* - "js": array of assets. Each asset can be either a string with * - "js": array of assets. Each asset can be either a string with
* absolute URL of a JavaScript file or an array with "content" and * relative URL of a JavaScript file or an array with "content",
* "type" items. See * "type" and "weight" items. See
* {@link \Mibew\Asset\AssetManagerInterface::getJsAssets()} for details * {@link \Mibew\Asset\AssetManagerInterface::getJsAssets()} for details
* of their meaning. Modify this array to add or remove additional * of their meaning. Modify this array to add or remove additional
* JavaScript files. * JavaScript files.
@ -198,6 +204,7 @@ class AssetManager implements AssetManagerInterface
json_encode($event['plugins']) json_encode($event['plugins'])
), ),
'type' => AssetManagerInterface::INLINE, 'type' => AssetManagerInterface::INLINE,
'weight' => 0,
); );
return $assets; return $assets;
@ -211,10 +218,11 @@ class AssetManager implements AssetManagerInterface
* - "request": {@link \Symfony\Component\HttpFoundation\Request}, a * - "request": {@link \Symfony\Component\HttpFoundation\Request}, a
* request instance. CSS files will be attached to the requested page. * request instance. CSS files will be attached to the requested page.
* - "css": array of assets. Each asset can be either a string with * - "css": array of assets. Each asset can be either a string with
* absolute URL of a CSS file or an array with "content" and "type" * relative URL of a CSS file or an array with "content", "type" and
* items. See {@link \Mibew\Asset\AssetManagerInterface::getCssAssets()} * "weight" items. See
* for details of their meaning. Modify this array to add or remove * {@link \Mibew\Asset\AssetManagerInterface::getCssAssets()} for details
* additional CSS files. * of their meaning. Modify this array to add or remove additional CSS
* files.
* *
* @return array Assets list. * @return array Assets list.
*/ */
@ -249,9 +257,11 @@ class AssetManager implements AssetManagerInterface
$normalized_assets[] = array( $normalized_assets[] = array(
'content' => $asset, 'content' => $asset,
'type' => AssetManagerInterface::RELATIVE_URL, 'type' => AssetManagerInterface::RELATIVE_URL,
'weight' => 0,
); );
} elseif (is_array($asset) && !empty($asset['type']) && !empty($asset['content'])) { } elseif (is_array($asset) && !empty($asset['type']) && !empty($asset['content'])) {
$normalized_assets[] = $asset; // Weight is optional so we have to make sure it is in place.
$normalized_assets[] = $asset + array('weight' => 0);
} else { } else {
throw new \InvalidArgumentException('Invalid asset item'); throw new \InvalidArgumentException('Invalid asset item');
} }
@ -259,4 +269,46 @@ class AssetManager implements AssetManagerInterface
return $normalized_assets; return $normalized_assets;
} }
/**
* Sort assets according to their weights.
*
* If weights of two assets are equal the order from the original array will
* be kept.
*
* @param array $assets The original List of assets.
* @return array Sorted list of assets.
*/
protected function sort($assets)
{
// We should keep order for assets with equal weight. Thus we must
// combine original order and weight property before real sort.
$tmp = array();
$offset = 0;
foreach ($assets as $asset) {
$key = $asset['weight'] . '|' . $offset;
$tmp[$key] = $asset;
$offset++;
}
uksort($tmp, function ($a, $b) {
list($a_weight, $a_offset) = explode('|', $a, 2);
list($b_weight, $b_offset) = explode('|', $b, 2);
if ($a_weight != $b_weight) {
return ($a_weight < $b_weight) ? -1 : 1;
}
// Weights are equal. Check the offset to determine which asset was
// attached first.
if ($a_offset != $b_offset) {
return ($a_offset < $b_offset) ? -1 : 1;
}
return 0;
});
// Artificial sorting keys should be removed from the resulting array.
return array_values($tmp);
}
} }

View File

@ -62,8 +62,10 @@ interface AssetManagerInterface
* AssetManagerInterface::ABSOLUTE_URL, * AssetManagerInterface::ABSOLUTE_URL,
* AssetManagerInterface::RELATIVE_URL or AssetManagerInterface::INLINE * AssetManagerInterface::RELATIVE_URL or AssetManagerInterface::INLINE
* constants. * constants.
* @param int $weight Weight of the assets. Assets with lower weight will be
* "float" to the begging of the resulting assets array.
*/ */
public function attachJs($content, $type = self::RELATIVE_URL); public function attachJs($content, $type = self::RELATIVE_URL, $weight = 0);
/** /**
* Retrieves all attached and provided by plugins JavaScript assets. * Retrieves all attached and provided by plugins JavaScript assets.
@ -76,6 +78,8 @@ interface AssetManagerInterface
* AssetManagerInterface::ABSOLUTE_URL, * AssetManagerInterface::ABSOLUTE_URL,
* AssetManagerInterface::RELATIVE_URL or AssetManagerInterface::INLINE * AssetManagerInterface::RELATIVE_URL or AssetManagerInterface::INLINE
* constants. * constants.
* - weight: int, weight of the asset which was set via
* AssetManagerInterface::attachJs method.
*/ */
public function getJsAssets(); public function getJsAssets();
@ -88,8 +92,10 @@ interface AssetManagerInterface
* AssetManagerInterface::ABSOLUTE_URL, * AssetManagerInterface::ABSOLUTE_URL,
* AssetManagerInterface::RELATIVE_URL or AssetManagerInterface::INLINE * AssetManagerInterface::RELATIVE_URL or AssetManagerInterface::INLINE
* constants. * constants.
* @param int $weight Weight of the assets. Assets with lower weight will be
* "float" to the begging of the resulting assets array.
*/ */
public function attachCss($content, $type = self::RELATIVE_URL); public function attachCss($content, $type = self::RELATIVE_URL, $weight = 0);
/** /**
* Retrieves all attached and provided by plugins CSS assets. * Retrieves all attached and provided by plugins CSS assets.
@ -101,6 +107,8 @@ interface AssetManagerInterface
* AssetManagerInterface::ABSOLUTE_URL, * AssetManagerInterface::ABSOLUTE_URL,
* AssetManagerInterface::RELATIVE_URL or AssetManagerInterface::INLINE * AssetManagerInterface::RELATIVE_URL or AssetManagerInterface::INLINE
* constants. * constants.
* - weight: int, weight of the asset which was set via
* AssetManagerInterface::attachCss method.
*/ */
public function getCssAssets(); public function getCssAssets();
} }