Commit f7cabeb6 authored by catch's avatar catch

Issue #2113015 by Wim Leers, amateescu: Add drupal_merge_attached() function,...

Issue #2113015 by Wim Leers, amateescu: Add drupal_merge_attached() function, to merge #attached assets.
parent 00fbdd6b
......@@ -2438,6 +2438,21 @@ function drupal_merge_js_settings($settings_items) {
return NestedArray::mergeDeepArray($settings_items, TRUE);
}
/**
* Merges two #attached arrays.
*
* @param array $a
* An #attached array.
* @param array $b
* Another #attached array.
*
* @return array
* The merged #attached array.
*/
function drupal_merge_attached(array $a, array $b) {
return NestedArray::mergeDeep($a, $b);
}
/**
* #pre_render callback to add the elements needed for JavaScript tags to be rendered.
*
......@@ -3580,7 +3595,7 @@ function drupal_pre_render_link($element) {
* properties of the parent are used.
*/
function drupal_pre_render_links($element) {
$element += array('#links' => array());
$element += array('#links' => array(), '#attached' => array());
foreach (element_children($element) as $key) {
$child = &$element[$key];
// If the child has links which have not been printed yet and the user has
......@@ -3591,6 +3606,10 @@ function drupal_pre_render_links($element) {
// cannot be mistakenly rendered twice).
$child['#printed'] = TRUE;
}
// Merge attachments.
if (isset($child['#attached'])) {
$element['#attached'] = drupal_merge_attached($element['#attached'], $child['#attached']);
}
}
return $element;
}
......@@ -4139,12 +4158,7 @@ function drupal_render_collect_attached($elements, $return = FALSE) {
// Collect all #attached for this element.
if (isset($elements['#attached'])) {
foreach ($elements['#attached'] as $key => $value) {
if (!isset($attached[$key])) {
$attached[$key] = array();
}
$attached[$key] = array_merge($attached[$key], $value);
}
$attached = drupal_merge_attached($attached, $elements['#attached']);
}
if ($children = element_children($elements)) {
foreach ($children as $child) {
......
<?php
/**
* @file
* Contains \Drupal\system\Tests\Common\MergeAttachmentsTest.
*/
namespace Drupal\system\Tests\Common;
use Drupal\simpletest\DrupalUnitTestBase;
/**
* Tests the merging of attachments.
*/
class MergeAttachmentsTest extends DrupalUnitTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('system');
public static function getInfo() {
return array(
'name' => 'Attachment merging',
'description' => 'Tests the merging of attachments.',
'group' => 'Common',
);
}
function setUp() {
parent::setUp();
}
/**
* Tests justs library asset merging.
*/
function testLibraryMerging() {
$a['#attached'] = array(
'library' => array(
array('system', 'drupal'),
array('system', 'drupalSettings'),
),
);
$b['#attached'] = array(
'library' => array(
array('system', 'jquery'),
),
);
$expected['#attached'] = array(
'library' => array(
array('system', 'drupal'),
array('system', 'drupalSettings'),
array('system', 'jquery'),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($a['#attached'], $b['#attached']), 'Attachments merged correctly.');
// Merging in the opposite direction yields the opposite library order.
$expected['#attached'] = array(
'library' => array(
array('system', 'jquery'),
array('system', 'drupal'),
array('system', 'drupalSettings'),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($b['#attached'], $a['#attached']), 'Attachments merged correctly; opposite merging yields opposite order.');
// Merging with duplicates: duplicates are simply retained, it's up to the
// rest of the system to handle duplicates.
$b['#attached']['library'][] = array('system', 'drupalSettings');
$expected['#attached'] = array(
'library' => array(
array('system', 'drupal'),
array('system', 'drupalSettings'),
array('system', 'jquery'),
array('system', 'drupalSettings'),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($a['#attached'], $b['#attached']), 'Attachments merged correctly; duplicates are retained.');
}
/**
* Tests justs CSS asset merging.
*/
function testCssMerging() {
$a['#attached'] = array(
'css' => array(
'foo.css' => array(),
'bar.css' => array(),
),
);
$b['#attached'] = array(
'css' => array(
'baz.css' => array(),
),
);
$expected['#attached'] = array(
'css' => array(
'foo.css' => array(),
'bar.css' => array(),
'baz.css' => array(),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($a['#attached'], $b['#attached']), 'Attachments merged correctly.');
// Merging in the opposite direction yields the opposite CSS asset order.
$expected['#attached'] = array(
'css' => array(
'baz.css' => array(),
'foo.css' => array(),
'bar.css' => array(),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($b['#attached'], $a['#attached']), 'Attachments merged correctly; opposite merging yields opposite order.');
// Merging with duplicates: duplicates are automatically removed because the
// values have unique keys.
$b['#attached']['css']['bar.css'] = array();
$expected['#attached'] = array(
'css' => array(
'foo.css' => array(),
'bar.css' => array(),
'baz.css' => array(),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($a['#attached'], $b['#attached']), 'Attachments merged correctly; CSS asset duplicates removed.');
}
/**
* Tests justs JavaScript asset merging.
*/
function testJsMerging() {
$a['#attached'] = array(
'js' => array(
'foo.js' => array(),
'bar.js' => array(),
),
);
$b['#attached'] = array(
'js' => array(
'baz.js' => array(),
),
);
$expected['#attached'] = array(
'js' => array(
'foo.js' => array(),
'bar.js' => array(),
'baz.js' => array(),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($a['#attached'], $b['#attached']), 'Attachments merged correctly.');
// Merging in the opposite direction yields the opposite JS asset order.
$expected['#attached'] = array(
'js' => array(
'baz.js' => array(),
'foo.js' => array(),
'bar.js' => array(),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($b['#attached'], $a['#attached']), 'Attachments merged correctly; opposite merging yields opposite order.');
// Merging with duplicates: duplicates are automatically removed because the
// values have unique keys.
$b['#attached']['js']['bar.js'] = array();
$expected['#attached'] = array(
'js' => array(
'foo.js' => array(),
'bar.js' => array(),
'baz.js' => array(),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($a['#attached'], $b['#attached']), 'Attachments merged correctly; JS asset duplicates removed.');
}
/**
* Tests justs JavaScript and JavaScript setting asset merging.
*/
function testJsSettingMerging() {
$a['#attached'] = array(
'js' => array(
'foo.js' => array(),
array(
'type' => 'setting',
'data' => array('foo' => array('d')),
),
'bar.js' => array(),
),
);
$b['#attached'] = array(
'js' => array(
83 => array(
'type' => 'setting',
'data' => array('bar' => array('a', 'b', 'c')),
),
'baz.js' => array(),
),
);
$expected['#attached'] = array(
'js' => array(
'foo.js' => array(),
0 => array(
'type' => 'setting',
'data' => array('foo' => array('d')),
),
'bar.js' => array(),
1 => array(
'type' => 'setting',
'data' => array('bar' => array('a', 'b', 'c')),
),
'baz.js' => array(),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($a['#attached'], $b['#attached']), 'Attachments merged correctly.');
// Merging in the opposite direction yields the opposite JS setting asset
// order.
$expected['#attached'] = array(
'js' => array(
0 => array(
'type' => 'setting',
'data' => array('bar' => array('a', 'b', 'c')),
),
'baz.js' => array(),
'foo.js' => array(),
1 => array(
'type' => 'setting',
'data' => array('foo' => array('d')),
),
'bar.js' => array(),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($b['#attached'], $a['#attached']), 'Attachments merged correctly; opposite merging yields opposite order.');
// Merging with duplicates: JavaScript setting duplicates are simply
// retained, it's up to the rest of the system (drupal_merge_js_settings())
// to handle duplicates.
$b['#attached']['js'][] = array(
'type' => 'setting',
'data' => array('foo' => array('a', 'b', 'c')),
);
$expected['#attached'] = array(
'js' => array(
'foo.js' => array(),
0 => array(
'type' => 'setting',
'data' => array('foo' => array('d')),
),
'bar.js' => array(),
1 => array(
'type' => 'setting',
'data' => array('bar' => array('a', 'b', 'c')),
),
'baz.js' => array(),
2 => array(
'type' => 'setting',
'data' => array('foo' => array('a', 'b', 'c')),
),
),
);
$this->assertIdentical($expected['#attached'], drupal_merge_attached($a['#attached'], $b['#attached']), 'Attachments merged correctly; JavaScript asset duplicates removed, JavaScript setting asset duplicates retained.');
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment