diff --git a/core/lib/Drupal/Core/Ajax/AfterCommand.php b/core/lib/Drupal/Core/Ajax/AfterCommand.php index 05cf95c..50c5714 100644 --- a/core/lib/Drupal/Core/Ajax/AfterCommand.php +++ b/core/lib/Drupal/Core/Ajax/AfterCommand.php @@ -34,6 +34,7 @@ public function render() { 'selector' => $this->selector, 'data' => $this->getRenderedContent(), 'settings' => $this->settings, + 'wrapper' => $this->wrapper, ); } diff --git a/core/lib/Drupal/Core/Ajax/AppendCommand.php b/core/lib/Drupal/Core/Ajax/AppendCommand.php index 26061b2..9a20e2f 100644 --- a/core/lib/Drupal/Core/Ajax/AppendCommand.php +++ b/core/lib/Drupal/Core/Ajax/AppendCommand.php @@ -34,6 +34,7 @@ public function render() { 'selector' => $this->selector, 'data' => $this->getRenderedContent(), 'settings' => $this->settings, + 'wrapper' => $this->wrapper, ); } diff --git a/core/lib/Drupal/Core/Ajax/BeforeCommand.php b/core/lib/Drupal/Core/Ajax/BeforeCommand.php index 7bf8f41..ec3fff6 100644 --- a/core/lib/Drupal/Core/Ajax/BeforeCommand.php +++ b/core/lib/Drupal/Core/Ajax/BeforeCommand.php @@ -34,6 +34,7 @@ public function render() { 'selector' => $this->selector, 'data' => $this->getRenderedContent(), 'settings' => $this->settings, + 'wrapper' => $this->wrapper, ); } diff --git a/core/lib/Drupal/Core/Ajax/HtmlCommand.php b/core/lib/Drupal/Core/Ajax/HtmlCommand.php index 96a8d33..c7fec89 100644 --- a/core/lib/Drupal/Core/Ajax/HtmlCommand.php +++ b/core/lib/Drupal/Core/Ajax/HtmlCommand.php @@ -34,6 +34,7 @@ public function render() { 'selector' => $this->selector, 'data' => $this->getRenderedContent(), 'settings' => $this->settings, + 'wrapper' => $this->wrapper, ); } diff --git a/core/lib/Drupal/Core/Ajax/InsertCommand.php b/core/lib/Drupal/Core/Ajax/InsertCommand.php index 8c477f5..67bcb0c 100644 --- a/core/lib/Drupal/Core/Ajax/InsertCommand.php +++ b/core/lib/Drupal/Core/Ajax/InsertCommand.php @@ -60,10 +60,11 @@ class InsertCommand implements CommandInterface, CommandWithAttachedAssetsInterf * @param array $settings * An array of JavaScript settings to be passed to any attached behaviors. */ - public function __construct($selector, $content, array $settings = NULL) { + public function __construct($selector, $content, array $settings = NULL, $wrapper = TRUE) { $this->selector = $selector; $this->content = $content; $this->settings = $settings; + $this->wrapper = $wrapper; } /** @@ -77,6 +78,7 @@ public function render() { 'selector' => $this->selector, 'data' => $this->getRenderedContent(), 'settings' => $this->settings, + 'wrapper' => $this->wrapper, ); } diff --git a/core/lib/Drupal/Core/Ajax/PrependCommand.php b/core/lib/Drupal/Core/Ajax/PrependCommand.php index 0ccc6d8..4075e1c 100644 --- a/core/lib/Drupal/Core/Ajax/PrependCommand.php +++ b/core/lib/Drupal/Core/Ajax/PrependCommand.php @@ -34,6 +34,7 @@ public function render() { 'selector' => $this->selector, 'data' => $this->getRenderedContent(), 'settings' => $this->settings, + 'wrapper' => $this->wrapper, ); } diff --git a/core/lib/Drupal/Core/Ajax/ReplaceCommand.php b/core/lib/Drupal/Core/Ajax/ReplaceCommand.php index 615f4eb..309a1ba 100644 --- a/core/lib/Drupal/Core/Ajax/ReplaceCommand.php +++ b/core/lib/Drupal/Core/Ajax/ReplaceCommand.php @@ -35,6 +35,7 @@ public function render() { 'selector' => $this->selector, 'data' => $this->getRenderedContent(), 'settings' => $this->settings, + 'wrapper' => $this->wrapper, ); } diff --git a/core/misc/ajax.js b/core/misc/ajax.js index b63bc03..33ad56a 100644 --- a/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -891,13 +891,17 @@ var method = response.method || ajax.method; var effect = ajax.getEffect(response); var settings; + var element_wrapper = '
'; + if (response.wrapper && response.wrapper !== true) { + element_wrapper = response.wrapper; + } // We don't know what response.data contains: it might be a string of text // without HTML, so don't rely on jQuery correctly interpreting // $(response.data) as new HTML rather than a CSS selector. Also, if // response.data contains top-level text nodes, they get lost with either // $(response.data) or $('
').replaceWith(response.data). - var new_content_wrapped = $('
').html(response.data); + var new_content_wrapped = $(element_wrapper).html(response.data.trim()); var new_content = new_content_wrapped.contents(); // For legacy reasons, the effects processing code assumes that @@ -911,7 +915,10 @@ // top-level element, and only use the container DIV created above when // it doesn't. For more information, please see // https://www.drupal.org/node/736066. - if (new_content.length !== 1 || new_content.get(0).nodeType !== 1) { + if ((new_content.length !== 1 || new_content.get(0).nodeType !== 1) && response.wrapper === true) { + new_content = new_content_wrapped; + } + else if (response.wrapper && response.wrapper !== true) { new_content = new_content_wrapped; } diff --git a/core/tests/Drupal/Tests/Core/Ajax/AjaxCommandsTest.php b/core/tests/Drupal/Tests/Core/Ajax/AjaxCommandsTest.php index 8606f2b..21c0b71 100644 --- a/core/tests/Drupal/Tests/Core/Ajax/AjaxCommandsTest.php +++ b/core/tests/Drupal/Tests/Core/Ajax/AjaxCommandsTest.php @@ -63,6 +63,7 @@ public function testAfterCommand() { 'selector' => '#page-title', 'data' => '

New Text!

', 'settings' => array('my-setting' => 'setting'), + 'wrapper' => TRUE, ); $this->assertEquals($expected, $command->render()); @@ -93,6 +94,7 @@ public function testAppendCommand() { 'selector' => '#page-title', 'data' => '

New Text!

', 'settings' => array('my-setting' => 'setting'), + 'wrapper' => TRUE, ); $this->assertEquals($expected, $command->render()); @@ -110,6 +112,7 @@ public function testBeforeCommand() { 'selector' => '#page-title', 'data' => '

New Text!

', 'settings' => array('my-setting' => 'setting'), + 'wrapper' => TRUE, ); $this->assertEquals($expected, $command->render()); @@ -178,6 +181,7 @@ public function testHtmlCommand() { 'selector' => '#page-title', 'data' => '

New Text!

', 'settings' => array('my-setting' => 'setting'), + 'wrapper' => TRUE, ); $this->assertEquals($expected, $command->render()); @@ -195,6 +199,7 @@ public function testInsertCommand() { 'selector' => '#page-title', 'data' => '

New Text!

', 'settings' => array('my-setting' => 'setting'), + 'wrapper' => TRUE, ); $this->assertEquals($expected, $command->render()); @@ -228,6 +233,7 @@ public function testPrependCommand() { 'selector' => '#page-title', 'data' => '

New Text!

', 'settings' => array('my-setting' => 'setting'), + 'wrapper' => TRUE, ); $this->assertEquals($expected, $command->render()); @@ -259,6 +265,7 @@ public function testReplaceCommand() { 'selector' => '#page-title', 'data' => '

New Text!

', 'settings' => array('my-setting' => 'setting'), + 'wrapper' => TRUE, ); $this->assertEquals($expected, $command->render()); diff --git a/core/tests/Drupal/Tests/Core/Form/EventSubscriber/FormAjaxSubscriberTest.php b/core/tests/Drupal/Tests/Core/Form/EventSubscriber/FormAjaxSubscriberTest.php index 035965f..4830172 100644 --- a/core/tests/Drupal/Tests/Core/Form/EventSubscriber/FormAjaxSubscriberTest.php +++ b/core/tests/Drupal/Tests/Core/Form/EventSubscriber/FormAjaxSubscriberTest.php @@ -190,6 +190,7 @@ public function testOnExceptionBrokenPostRequest() { 'selector' => NULL, 'data' => $rendered_output, 'settings' => NULL, + 'wrapper' => TRUE, ]; $this->assertSame($expected_commands, $actual_response->getCommands()); }