diff --git a/core/lib/Drupal/Core/Ajax/AjaxResponseRenderer.php b/core/lib/Drupal/Core/Ajax/AjaxResponseRenderer.php index 5fa31f4..642e2b9 100644 --- a/core/lib/Drupal/Core/Ajax/AjaxResponseRenderer.php +++ b/core/lib/Drupal/Core/Ajax/AjaxResponseRenderer.php @@ -26,8 +26,8 @@ class AjaxResponseRenderer { * An Ajax response containing the controller result. */ public function render($content) { - // If there is already an AjaxResponse, then return it without manipulation. - if ($content instanceof AjaxResponse && $content->isOk()) { + // If there is already an response object return it without manipulation. + if ($content instanceof Response && $content->isOk()) { return $content; } @@ -35,9 +35,6 @@ public function render($content) { if ($content instanceof HtmlFragment) { $content = $content->getContent(); } - elseif ($content instanceof Response) { - $content = $content->getContent(); - } // Most controllers return a render array, but some return a string. if (!is_array($content)) { $content = array( @@ -50,7 +47,7 @@ public function render($content) { if (isset($content['#type']) && ($content['#type'] == 'ajax')) { // Complex Ajax callbacks can return a result that contains an error // message or a specific set of commands to send to the browser. - $content += element_info('ajax'); + $content += $this->elementInfo('ajax'); $error = $content['#error']; if (!empty($error)) { // Fall back to some default message otherwise use the specific one. @@ -61,18 +58,34 @@ public function render($content) { } } - $html = drupal_render($content); + $html = $this->drupalRender($content); // The selector for the insert command is NULL as the new content will // replace the element making the Ajax call. The default 'replaceWith' // behavior can be changed with #ajax['method']. $response->addCommand(new InsertCommand(NULL, $html)); $status_messages = array('#theme' => 'status_messages'); - $output = drupal_render($status_messages); + $output = $this->drupalRender($status_messages); if (!empty($output)) { $response->addCommand(new PrependCommand(NULL, $output)); } return $response; } + /** + * Wraps drupal_render(). + * + * @todo: Remove as part of https://drupal.org/node/2182149 + */ + protected function drupalRender(&$elements, $is_recursive_call = FALSE) { + return drupal_render($elements, $is_recursive_call); + } + + /** + * Wraps element_info(). + */ + protected function elementInfo($type) { + return element_info($type); + } + } diff --git a/core/modules/toolbar/toolbar.routing.yml b/core/modules/toolbar/toolbar.routing.yml index 2e1e4cd..6e2f255 100644 --- a/core/modules/toolbar/toolbar.routing.yml +++ b/core/modules/toolbar/toolbar.routing.yml @@ -3,4 +3,4 @@ toolbar.subtrees: defaults: _controller: '\Drupal\toolbar\Controller\ToolbarController::subtreesJsonp' requirements: - _custom_access: '\Drupal\toolbar\Routing\ToolbarController::checkSubTreeAccess' + _custom_access: '\Drupal\toolbar\Controller\ToolbarController::checkSubTreeAccess' diff --git a/core/tests/Drupal/Tests/Core/Ajax/AjaxResponseRendererTest.php b/core/tests/Drupal/Tests/Core/Ajax/AjaxResponseRendererTest.php new file mode 100644 index 0000000..2278e75 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Ajax/AjaxResponseRendererTest.php @@ -0,0 +1,144 @@ + 'Tests \Drupal\Core\Ajax\AjaxResponseRenderer.', + 'description' => '', + 'group' => 'Ajax', + ); + } + + /** + * {@inheritdoc} + */ + protected function setUp() { + $this->ajaxResponseRenderer = new TestAjaxResponseRenderer(); + } + + /** + * Tests the render method with an HtmlFragment object. + * + * @covers \Drupal\Core\Ajax\AjaxResponseRenderer::render + */ + public function testRenderWithFragmentObject() { + $html_fragment = new HtmlFragment('example content'); + /** @var \Drupal\Core\Ajax\AjaxResponse $result */ + $result = $this->ajaxResponseRenderer->render($html_fragment); + + $this->assertInstanceOf('Drupal\Core\Ajax\AjaxResponse', $result); + + $commands = $result->getCommands(); + $this->assertEquals('insert', $commands[0]['command']); + $this->assertEquals('example content', $commands[0]['data']); + + $this->assertEquals('insert', $commands[1]['command']); + $this->assertEquals('status_messages', $commands[1]['data']); + } + + /** + * Tests the render method with an HtmlFragment object. + * + * @covers \Drupal\Core\Ajax\AjaxResponseRenderer::render + */ + public function testRenderWithString() { + $html_fragment = 'example content'; + /** @var \Drupal\Core\Ajax\AjaxResponse $result */ + $result = $this->ajaxResponseRenderer->render($html_fragment); + + $this->assertInstanceOf('Drupal\Core\Ajax\AjaxResponse', $result); + + $commands = $result->getCommands(); + $this->assertEquals('insert', $commands[0]['command']); + $this->assertEquals('example content', $commands[0]['data']); + + $this->assertEquals('insert', $commands[1]['command']); + $this->assertEquals('status_messages', $commands[1]['data']); + } + + + /** + * Tests the render method with an response object. + * + * @covers \Drupal\Core\Ajax\AjaxResponseRenderer::render + */ + public function testRenderWithResponseObject() { + $json_response = new JsonResponse(array('foo' => 'bar')); + $this->assertSame($json_response, $this->ajaxResponseRenderer->render($json_response)); + } + + /** + * Tests the render method with an Ajax response object. + * + * @covers \Drupal\Core\Ajax\AjaxResponseRenderer::render + */ + public function testRenderWithAjaxResponseObject() { + $ajax_response = new AjaxResponse(array('foo' => 'bar')); + $this->assertSame($ajax_response, $this->ajaxResponseRenderer->render($ajax_response)); + } + +} + +class TestAjaxResponseRenderer extends AjaxResponseRenderer { + + /** + * {@inheritdoc} + */ + protected function drupalRender(&$elements, $is_recursive_call = FALSE) { + if (isset($elements['#markup'])) { + return $elements['#markup']; + } + elseif (isset($elements['#theme'])) { + return $elements['#theme']; + } + else { + return 'Markup'; + } + } + + /** + * {@inheritdoc} + */ + protected function elementInfo($type) { + if ($type == 'ajax') { + return array( + '#header' => TRUE, + '#commands' => array(), + '#error' => NULL, + ); + } + else { + return array(); + } + } + +}