/** * Tests the add and getCommands method. * * @see \Drupal\Core\Ajax\AjaxResponse::addCommand() * @see \Drupal\Core\Ajax\AjaxResponse::getCommands() */ public function testCommands() { $command_one = $this->getMock('Drupal\\Core\\Ajax\\CommandInterface'); $command_one->expects($this->once())->method('render')->will($this->returnValue(array('command' => 'one'))); $command_two = $this->getMock('Drupal\\Core\\Ajax\\CommandInterface'); $command_two->expects($this->once())->method('render')->will($this->returnValue(array('command' => 'two'))); $command_three = $this->getMock('Drupal\\Core\\Ajax\\CommandInterface'); $command_three->expects($this->once())->method('render')->will($this->returnValue(array('command' => 'three'))); $this->ajaxResponse->addCommand($command_one); $this->ajaxResponse->addCommand($command_two); $this->ajaxResponse->addCommand($command_three, TRUE); // Ensure that the added commands are in the right order. $commands =& $this->ajaxResponse->getCommands(); $this->assertSame($commands[1], array('command' => 'one')); $this->assertSame($commands[2], array('command' => 'two')); $this->assertSame($commands[0], array('command' => 'three')); // Remove one and change one element from commands and ensure the reference // worked as expected. unset($commands[2]); $commands[0]['class'] = 'test-class'; $commands = $this->ajaxResponse->getCommands(); $this->assertSame($commands[1], array('command' => 'one')); $this->assertFalse(isset($commands[2])); $this->assertSame($commands[0], array('command' => 'three', 'class' => 'test-class')); }
/** * Prepares the AJAX commands to attach assets. * * @param \Drupal\Core\Ajax\AjaxResponse $response * The AJAX response to update. * @param \Symfony\Component\HttpFoundation\Request $request * The request object that the AJAX is responding to. * * @return array * An array of commands ready to be returned as JSON. */ protected function buildAttachmentsCommands(AjaxResponse $response, Request $request) { $ajax_page_state = $request->request->get('ajax_page_state'); // Aggregate CSS/JS if necessary, but only during normal site operation. $optimize_css = !defined('MAINTENANCE_MODE') && $this->config->get('css.preprocess'); $optimize_js = !defined('MAINTENANCE_MODE') && $this->config->get('js.preprocess'); $attachments = $response->getAttachments(); // Resolve the attached libraries into asset collections. $assets = new AttachedAssets(); $assets->setLibraries(isset($attachments['library']) ? $attachments['library'] : [])->setAlreadyLoadedLibraries(isset($ajax_page_state['libraries']) ? explode(',', $ajax_page_state['libraries']) : [])->setSettings(isset($attachments['drupalSettings']) ? $attachments['drupalSettings'] : []); $css_assets = $this->assetResolver->getCssAssets($assets, $optimize_css); list($js_assets_header, $js_assets_footer) = $this->assetResolver->getJsAssets($assets, $optimize_js); // Render the HTML to load these files, and add AJAX commands to insert this // HTML in the page. Settings are handled separately, afterwards. $settings = []; if (isset($js_assets_header['drupalSettings'])) { $settings = $js_assets_header['drupalSettings']['data']; unset($js_assets_header['drupalSettings']); } if (isset($js_assets_footer['drupalSettings'])) { $settings = $js_assets_footer['drupalSettings']['data']; unset($js_assets_footer['drupalSettings']); } // Prepend commands to add the assets, preserving their relative order. $resource_commands = array(); if ($css_assets) { $css_render_array = $this->cssCollectionRenderer->render($css_assets); $resource_commands[] = new AddCssCommand((string) $this->renderer->renderPlain($css_render_array)); } if ($js_assets_header) { $js_header_render_array = $this->jsCollectionRenderer->render($js_assets_header); $resource_commands[] = new PrependCommand('head', (string) $this->renderer->renderPlain($js_header_render_array)); } if ($js_assets_footer) { $js_footer_render_array = $this->jsCollectionRenderer->render($js_assets_footer); $resource_commands[] = new AppendCommand('body', (string) $this->renderer->renderPlain($js_footer_render_array)); } foreach (array_reverse($resource_commands) as $resource_command) { $response->addCommand($resource_command, TRUE); } // Prepend a command to merge changes and additions to drupalSettings. if (!empty($settings)) { // During Ajax requests basic path-specific settings are excluded from // new drupalSettings values. The original page where this request comes // from already has the right values. An Ajax request would update them // with values for the Ajax request and incorrectly override the page's // values. // @see system_js_settings_alter() unset($settings['path']); $response->addCommand(new SettingsCommand($settings, TRUE), TRUE); } $commands = $response->getCommands(); $this->moduleHandler->alter('ajax_render', $commands); return $commands; }
/** * Regression test: Settings command exists regardless of JS aggregation. */ public function testAttachedSettings() { $assert = function ($message) { $response = new AjaxResponse(); $response->setAttachments(['library' => ['core/drupalSettings'], 'drupalSettings' => ['foo' => 'bar']]); $ajax_response_attachments_processor = \Drupal::service('ajax_response.attachments_processor'); $subscriber = new AjaxResponseSubscriber($ajax_response_attachments_processor); $event = new FilterResponseEvent(\Drupal::service('http_kernel'), new Request(), HttpKernelInterface::MASTER_REQUEST, $response); $subscriber->onResponse($event); $expected = ['command' => 'settings']; $this->assertCommand($response->getCommands(), $expected, $message); }; $config = $this->config('system.performance'); $config->set('js.preprocess', FALSE)->save(); $assert('Settings command exists when JS aggregation is disabled.'); $config->set('js.preprocess', TRUE)->save(); $assert('Settings command exists when JS aggregation is enabled.'); }
/** * Regression test: Settings command exists regardless of JS aggregation. */ public function testAttachedSettings() { $assert = function ($message) { $response = new AjaxResponse(); $response->setAttachments(['library' => ['core/drupalSettings'], 'drupalSettings' => ['foo' => 'bar']]); $response->prepare(new Request()); $expected = ['command' => 'settings']; $this->assertCommand($response->getCommands(), $expected, $message); }; $config = $this->config('system.performance'); $config->set('js.preprocess', FALSE)->save(); $assert('Settings command exists when JS aggregation is disabled.'); $config->set('js.preprocess', TRUE)->save(); $assert('Settings command exists when JS aggregation is enabled.'); }