diff --git a/core/misc/ajax.es6.js b/core/misc/ajax.es6.js index 742fe68..1033713 100644 --- a/core/misc/ajax.es6.js +++ b/core/misc/ajax.es6.js @@ -1053,20 +1053,27 @@ else if (type === 'fade') { const onlyElementNodes = responseDataNodes.every( element => element.nodeType === Node.ELEMENT_NODE || element.nodeType === Node.COMMENT_NODE - || element.textContent.trim().length === 0, + // Ignore any TEXT_NODE that only contains whitespace. + || (element.nodeType === Node.TEXT_NODE && element.textContent.trim().length === 0), ); + // Find the first node that is not COMMENT_NODE. + const firstNonCommentNode = responseDataNodes.filter(element => element.nodeType !== Node.COMMENT_NODE)[0]; - // When there are only element and/or comment nodes in the response, no - // extra wrapping necessary. - if (onlyElementNodes && trimmedData !== '') { + // When there are only element and/or comment nodes in the response or if + // the method is 'html' and the element can be safely converted a jQuery + // object, no extra wrapping necessary. + if (onlyElementNodes || (method === 'html' && firstNonCommentNode.nodeType === Node.ELEMENT_NODE)) { $newContent = $(trimmedData); } // When there are other types of top-level nodes, the response needs to be // wrapped. else { - // If response.data contains mixed node types and the wrapping element - // is not styled as a block, response.data will be wrapped with SPAN. - if ($wrapper.css('display') !== 'block') { + const onlyTextOrCommentNodes = responseDataNodes.every( + element => element.nodeType === Node.COMMENT_NODE || element.nodeType === Node.TEXT_NODE, + ); + // If response.data contains only nodes of the type TEXT_NODE or + // COMMENT_NODE, response.data will be wrapped with SPAN. + if (onlyTextOrCommentNodes) { $newContent = $(''); } else { diff --git a/core/misc/ajax.js b/core/misc/ajax.js index d453144..3fa9aff 100644 --- a/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -494,13 +494,21 @@ function loadAjaxBehavior(base) { } var onlyElementNodes = responseDataNodes.every(function (element) { - return element.nodeType === Node.ELEMENT_NODE || element.nodeType === Node.COMMENT_NODE || element.textContent.trim().length === 0; + return element.nodeType === Node.ELEMENT_NODE || element.nodeType === Node.COMMENT_NODE || element.nodeType === Node.TEXT_NODE && element.textContent.trim().length === 0; }); - if (onlyElementNodes && trimmedData !== '') { + var firstNonCommentNode = responseDataNodes.filter(function (element) { + return element.nodeType !== Node.COMMENT_NODE; + })[0]; + + if (onlyElementNodes || method === 'html' && firstNonCommentNode.nodeType === Node.ELEMENT_NODE) { $newContent = $(trimmedData); } else { - if ($wrapper.css('display') !== 'block') { + var onlyTextOrCommentNodes = responseDataNodes.every(function (element) { + return element.nodeType === Node.COMMENT_NODE || element.nodeType === Node.TEXT_NODE; + }); + + if (onlyTextOrCommentNodes) { $newContent = $(''); } else { $newContent = $('
'); diff --git a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php index ce2cc59..28e565c 100644 --- a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php +++ b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php @@ -327,7 +327,8 @@ protected function getRenderTypes() { 'mixed' => ' foo foo bar

some string

additional not wrapped strings,

final string

', 'top-level-only' => '
element #1
element #2
', 'top-level-only-pre-whitespace' => '
element #1
element #2
', - 'top-level-only-middle-whitespace' => '
element #1
element #2
', + 'top-level-only-middle-whitespace-span' => 'element #1 element #2', + 'top-level-only-middle-whitespace-div' => '
element #1
element #2
', 'empty' => '', ]; } diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php index f95dbcb..ecabd55 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php @@ -113,8 +113,6 @@ public function testDrupalSettingsCachingRegression() { public function testInsertBlock($render_type, $expected) { $assert = $this->assertSession(); - $expected = str_replace('WRAPPER_PLACEHOLDER', 'div', $expected); - $this->drupalGet('ajax-test/insert-block-wrapper'); $this->clickLink("Link html $render_type"); $assert->assertWaitOnAjaxRequest(); @@ -140,8 +138,6 @@ public function testInsertBlock($render_type, $expected) { public function testInsertInline($render_type, $expected) { $assert = $this->assertSession(); - $expected = str_replace('WRAPPER_PLACEHOLDER', 'span', $expected); - $this->drupalGet('ajax-test/insert-inline-wrapper'); $this->clickLink("Link html $render_type"); $assert->assertWaitOnAjaxRequest(); @@ -156,7 +152,7 @@ public function testInsertInline($render_type, $expected) { } /** - * Provides test result data + * Provides test result data. */ public function providerTestInsert() { $test_cases = []; @@ -183,14 +179,14 @@ public function providerTestInsert() { // all top-level node elements (context) are processed correctly. $test_cases['not_wrapped'] = [ 'not-wrapped', - 'not-wrapped', + 'not-wrapped', ]; // Test that not wrapped response data (text node and comment node) is // inserted wrapped and all top-level node elements // (context) are processed correctly. $test_cases['comment_string_not_wrapped'] = [ 'comment-string-not-wrapped', - 'comment-string-not-wrapped', + 'comment-string-not-wrapped', ]; // Test that top-level comments (which are not lead by text nodes) are // inserted without wrapper. @@ -202,7 +198,7 @@ public function providerTestInsert() { // is inserted correctly. $test_cases['mixed'] = [ 'mixed', - ' foo foo bar

some string

additional not wrapped strings,

final string

', + '
foo foo bar

some string

additional not wrapped strings,

final string

', ]; // Test that when the response has only top-level node elements, they // are processed properly without extra wrapping. @@ -216,18 +212,23 @@ public function providerTestInsert() { 'top-level-only-pre-whitespace', '
element #1
element #2
', ]; - // Test that when there are whitespaces between top-level nodes, the - // response is wrapped. - $test_cases['top_level_only_middle_whitespace'] = [ - 'top-level-only-middle-whitespace', + // Test when there are whitespaces between top-level divs. + $test_cases['top_level_only_middle_whitespace-div'] = [ + 'top-level-only-middle-whitespace-div', '
element #1
element #2
', ]; + // Test when there are whitespaces between top-level spans. + $test_cases['top_level_only_middle_whitespace-span'] = [ + 'top-level-only-middle-whitespace-span', + 'element #1 element #2', + ]; // Test that empty response data. $test_cases['empty'] = [ 'empty', - '', + '', ]; return $test_cases; } + }