diff -u b/core/misc/ajax.js b/core/misc/ajax.js --- b/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -1054,8 +1054,10 @@ intermediateWrapper.append(value); } if (!intermediateWrapper && value.nodeType !== 1) { - intermediateWrapper = createWrapper(); - intermediateWrapper.append(value); + if ($.trim(value.nodeValue).length > 0) { + intermediateWrapper = createWrapper(); + intermediateWrapper.append(value); + } } if (!intermediateWrapper && value.nodeType === 1) { $new_content.append(value); diff -u b/core/modules/system/tests/modules/ajax_test/js/insert-ajax.js b/core/modules/system/tests/modules/ajax_test/js/insert-ajax.js --- b/core/modules/system/tests/modules/ajax_test/js/insert-ajax.js +++ b/core/modules/system/tests/modules/ajax_test/js/insert-ajax.js @@ -14,7 +14,8 @@ url: event.currentTarget.getAttribute('href'), wrapper: 'ajax-target', base: false, - element: false + element: false, + method: 'html' }; var myAjaxObject = Drupal.ajax(ajaxSettings); myAjaxObject.execute(); diff -u b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php --- b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php +++ b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php @@ -46,31 +46,35 @@ * Example content for testing whether response should be wrapped in div. * * @param string $type - * Type of response. Either 'pre-wrapped', 'not-wrapped', 'mixed'. + * Type of response. * * @return array * Renderable array of AJAX response contents. */ public static function renderTypes($type) { - // This is a regular render array; the keys do not have special meaning. switch ($type) { case 'pre-wrapped': - $markup = '
pre-wrapped
'; + $markup = '
' . $type . '
'; + break; + + case 'pre-wrapped-leading-whitespace': + $markup = '
' . $type . '
'; break; case 'not-wrapped': - $markup = 'not-wrapped'; + $markup = $type; break; case 'mixed': $markup = ' foo foo bar

some string

additional wrapped strings,

final string

'; break; } + $content = [ '#title' => 'AJAX Dialog & contents', 'content' => [ '#type' => 'inline_template', - '#template' => $markup, + '#template' => !empty($markup) ? $markup : '', ], ]; @@ -81,42 +85,33 @@ * Returns a render array of links that directly Drupal.ajax(). */ public function insertLinks() { + $types = [ + 'pre-wrapped', + 'pre-wrapped-leading-whitespace', + 'not-wrapped', + 'mixed', + ]; + $build['links'] = [ 'ajax_target' => [ '#markup' => '
Target
', ], 'links' => [ '#theme' => 'links', - '#links' => [ - 'link1' => [ - 'title' => 'Link 1 (pre-wrapped)', - 'url' => Url::fromRoute('ajax_test.ajax_render_types', ['type' => 'pre-wrapped']), - 'attributes' => [ - 'class' => ['ajax-insert'], - ], - '#attached' => ['library' => ['ajax_test/ajax_insert']], - ], - 'link2' => [ - 'title' => 'Link 2 (not wrapped)', - 'url' => Url::fromRoute('ajax_test.ajax_render_types', ['type' => 'not-wrapped']), - 'attributes' => [ - 'class' => ['ajax-insert'], - ], - '#attached' => ['library' => ['ajax_test/ajax_insert']], - ], - 'link3' => [ - 'title' => 'Link 3 (mixed)', - 'url' => Url::fromRoute('ajax_test.ajax_render_types', ['type' => 'mixed']), - 'attributes' => [ - 'class' => ['ajax-insert'], - ], - '#attached' => ['library' => ['ajax_test/ajax_insert']], - ], - ], '#attached' => ['library' => ['ajax_test/ajax_insert']], ], ]; + foreach ($types as $type) { + $build['links']['links']['#links'][$type] = [ + 'title' => "Link $type", + 'url' => Url::fromRoute('ajax_test.ajax_render_types', ['type' => $type]), + 'attributes' => [ + 'class' => ['ajax-insert'], + ], + ]; + } + return $build; } diff -u b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php --- b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php @@ -83,29 +83,34 @@ } /** - * Tests how various responses are wrapped in divs when using Drupal.ajax(). - * - * @todo These tests pass now but should the correct behavior be? + * Tests that various AJAX responses are correctly wrapped. */ - public function testDivWrap() { + public function testWrap() { $assert = $this->assertSession(); $this->drupalGet('ajax-test/insert'); - $this->clickLink('Link 1 (pre-wrapped)'); + + // Test that no additional wrapper is added when inserting already wrapped + // response data. + $this->clickLink('Link pre-wrapped'); $assert->assertWaitOnAjaxRequest(); $assert->responseContains('
pre-wrapped
'); - $this->drupalGet('ajax-test/insert'); - $this->clickLink('Link 2 (not wrapped)'); + // Test that no additional empty leading div is added when the return + // value had a leading space. + $this->clickLink('Link pre-wrapped-leading-whitespace'); + $assert->assertWaitOnAjaxRequest(); + $assert->responseContains('
pre-wrapped-leading-whitespace
'); + + // Test that unwrapped response data (text node) is inserted wrapped. + $this->clickLink('Link not-wrapped'); $assert->assertWaitOnAjaxRequest(); - $assert->responseContains('not-wrapped'); $assert->responseContains('
not-wrapped
'); - $this->drupalGet('ajax-test/insert'); - $this->clickLink('Link 3 (mixed)'); + // Test that wrappend and unwrapped response data is inserted correctly. + $this->clickLink('Link mixed'); $assert->assertWaitOnAjaxRequest(); - $assert->responseContains('not-wrapped'); + $this->createScreenshot('/tmp/drupal/na4.jpg'); $assert->responseContains('
foo foo bar

some string

additional wrapped strings,

final string

'); - } }