From a82e9ea9662a30f6e3a7e24400f812920f2f3228 Mon Sep 17 00:00:00 2001 From: webchick Date: Wed, 2 Jan 2013 08:45:24 -0800 Subject: [PATCH] Issue #1875632 by Wim Leers: Fixed Change Drupal JS settings merging behavior: preserve integer keys (allow for array literals in drupalSettings) --- core/includes/common.inc | 2 +- .../system/Tests/Common/JavaScriptTest.php | 52 ++++++++++++++----- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/core/includes/common.inc b/core/includes/common.inc index 9ec3d0d5fa5..a8ba090f7f9 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3949,7 +3949,7 @@ function drupal_pre_render_scripts($elements) { switch ($item['type']) { case 'setting': $element['#value_prefix'] = $embed_prefix; - $element['#value'] = 'var drupalSettings = ' . drupal_json_encode(NestedArray::mergeDeepArray($item['data'])) . ";"; + $element['#value'] = 'var drupalSettings = ' . drupal_json_encode(NestedArray::mergeDeepArray($item['data'], TRUE)) . ";"; $element['#value_suffix'] = $embed_suffix; break; diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php index 255ed28e0af..3c54ad4c8eb 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php @@ -150,28 +150,52 @@ class JavaScriptTest extends WebTestBase { // Only the second of these two entries should appear in Drupal.settings. drupal_add_js(array('commonTest' => 'commonTestShouldNotAppear'), 'setting'); drupal_add_js(array('commonTest' => 'commonTestShouldAppear'), 'setting'); - // All three of these entries should appear in Drupal.settings. - drupal_add_js(array('commonTestArray' => array('commonTestValue0')), 'setting'); - drupal_add_js(array('commonTestArray' => array('commonTestValue1')), 'setting'); - drupal_add_js(array('commonTestArray' => array('commonTestValue2')), 'setting'); + // Only the second of these entries should appear in Drupal.settings. + drupal_add_js(array('commonTestJsArrayLiteral' => array('commonTestJsArrayLiteralOldValue')), 'setting'); + drupal_add_js(array('commonTestJsArrayLiteral' => array('commonTestJsArrayLiteralNewValue')), 'setting'); // Only the second of these two entries should appear in Drupal.settings. - drupal_add_js(array('commonTestArray' => array('key' => 'commonTestOldValue')), 'setting'); - drupal_add_js(array('commonTestArray' => array('key' => 'commonTestNewValue')), 'setting'); + drupal_add_js(array('commonTestJsObjectLiteral' => array('key' => 'commonTestJsObjectLiteralOldValue')), 'setting'); + drupal_add_js(array('commonTestJsObjectLiteral' => array('key' => 'commonTestJsObjectLiteralNewValue')), 'setting'); + // Real world test case: multiple elements in a render array are adding the + // same (or nearly the same) JavaScript settings. When merged, they should + // contain all settings and not duplicate some settings. + $settings_one = array('moduleName' => array('ui' => array('button A', 'button B'), 'magical flag' => 3.14159265359)); + drupal_add_js(array('commonTestRealWorldIdentical' => $settings_one), 'setting'); + drupal_add_js(array('commonTestRealWorldIdentical' => $settings_one), 'setting'); + $settings_two = array('moduleName' => array('ui' => array('button A', 'button B'), 'magical flag' => 3.14159265359, 'thingiesOnPage' => array('id1' => array()))); + drupal_add_js(array('commonTestRealWorldAlmostIdentical' => $settings_two), 'setting'); + $settings_two = array('moduleName' => array('ui' => array('button C', 'button D'), 'magical flag' => 3.14, 'thingiesOnPage' => array('id2' => array()))); + drupal_add_js(array('commonTestRealWorldAlmostIdentical' => $settings_two), 'setting'); $javascript = drupal_get_js('header'); + // Test whether drupal_add_js can be used to override a previous setting. $this->assertTrue(strpos($javascript, 'commonTestShouldAppear') > 0, 'Rendered JavaScript header returns custom setting.'); $this->assertTrue(strpos($javascript, 'commonTestShouldNotAppear') === FALSE, 'drupal_add_js() correctly overrides a custom setting.'); - // Test whether drupal_add_js can be used to add numerically indexed values - // to an array. - $array_values_appear = strpos($javascript, 'commonTestValue0') > 0 && strpos($javascript, 'commonTestValue1') > 0 && strpos($javascript, 'commonTestValue2') > 0; - $this->assertTrue($array_values_appear, 'drupal_add_js() correctly adds settings to the end of an indexed array.'); + // Test whether drupal_add_js can be used to add and override a JavaScript + // array literal (an indexed PHP array) values. + $array_override = strpos($javascript, 'commonTestJsArrayLiteralNewValue') > 0 && strpos($javascript, 'commonTestJsArrayLiteralOldValue') === FALSE; + $this->assertTrue($array_override, 'drupal_add_js() correctly overrides settings within an array literal (indexed array).'); + + // Test whether drupal_add_js can be used to add and override a JavaScript + // object literal (an associate PHP array) values. + $associative_array_override = strpos($javascript, 'commonTestJsObjectLiteralNewValue') > 0 && strpos($javascript, 'commonTestJsObjectLiteralOldValue') === FALSE; + $this->assertTrue($associative_array_override, 'drupal_add_js() correctly overrides settings within an object literal (associative array).'); + + // Parse the generated drupalSettings