/**
  * Processes asset libraries into render arrays.
  *
  * @param array $attached
  *   The attachments to process.
  * @param array $placeholders
  *   The placeholders that exist in the response.
  *
  * @return array
  *   An array keyed by asset type, with keys:
  *     - styles
  *     - scripts
  *     - scripts_bottom
  */
 protected function processAssetLibraries(array $attached, array $placeholders)
 {
     $all_attached = ['#attached' => $attached];
     $assets = AttachedAssets::createFromRenderArray($all_attached);
     // Take Ajax page state into account, to allow for something like Turbolinks
     // to be implemented without altering core.
     // @see https://github.com/rails/turbolinks/
     // @todo https://www.drupal.org/node/2497115 - Below line is broken due to ->request.
     $ajax_page_state = $this->requestStack->getCurrentRequest()->request->get('ajax_page_state');
     $assets->setAlreadyLoadedLibraries(isset($ajax_page_state) ? explode(',', $ajax_page_state['libraries']) : []);
     $variables = [];
     // Print styles - if present.
     if (isset($placeholders['styles'])) {
         // Optimize CSS if necessary, but only during normal site operation.
         $optimize_css = !defined('MAINTENANCE_MODE') && $this->config->get('css.preprocess');
         $variables['styles'] = $this->cssCollectionRenderer->render($this->assetResolver->getCssAssets($assets, $optimize_css));
     }
     // Print scripts - if any are present.
     if (isset($placeholders['scripts']) || isset($placeholders['scripts_bottom'])) {
         // Optimize JS if necessary, but only during normal site operation.
         $optimize_js = !defined('MAINTENANCE_MODE') && !\Drupal::state()->get('system.maintenance_mode') && $this->config->get('js.preprocess');
         list($js_assets_header, $js_assets_footer) = $this->assetResolver->getJsAssets($assets, $optimize_js);
         $variables['scripts'] = $this->jsCollectionRenderer->render($js_assets_header);
         $variables['scripts_bottom'] = $this->jsCollectionRenderer->render($js_assets_footer);
     }
     return $variables;
 }
 /**
  * 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;
 }
 /**
  * Tests JavaScript files that have querystrings attached get added right.
  */
 function testAddJsFileWithQueryString()
 {
     $build['#attached']['library'][] = 'common_test/querystring';
     $assets = AttachedAssets::createFromRenderArray($build);
     $css = $this->assetResolver->getCssAssets($assets, FALSE);
     $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
     $this->assertTrue(array_key_exists('core/modules/system/tests/modules/common_test/querystring.css?arg1=value1&arg2=value2', $css), 'CSS file with query string is correctly added.');
     $this->assertTrue(array_key_exists('core/modules/system/tests/modules/common_test/querystring.js?arg1=value1&arg2=value2', $js), 'JavaScript file with query string is correctly added.');
     $css_render_array = \Drupal::service('asset.css.collection_renderer')->render($css);
     $rendered_css = $this->renderer->renderPlain($css_render_array);
     $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
     $rendered_js = $this->renderer->renderPlain($js_render_array);
     $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0';
     $this->assertNotIdentical(strpos($rendered_css, '<link rel="stylesheet" href="' . str_replace('&', '&amp;', file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/querystring.css?arg1=value1&arg2=value2'))) . '&amp;' . $query_string . '" media="all" />'), FALSE, 'CSS file with query string gets version query string correctly appended..');
     $this->assertNotIdentical(strpos($rendered_js, '<script src="' . str_replace('&', '&amp;', file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/querystring.js?arg1=value1&arg2=value2'))) . '&amp;' . $query_string . '"></script>'), FALSE, 'JavaScript file with query string gets version query string correctly appended.');
 }
 /**
  * Generate the HTML for our entity.
  *
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *   The entity we're rendering.
  * @param bool $use_default_css
  *   TRUE if we should inject our default CSS otherwise FALSE.
  * @param bool $optimize_css
  *   TRUE if we should compress the CSS otherwise FALSE.
  *
  * @return string
  *   The generated HTML.
  *
  * @throws \Exception
  */
 protected function getHtml(ContentEntityInterface $entity, $use_default_css, $optimize_css)
 {
     $render_controller = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
     $render = ['#theme' => 'entity_print__' . $entity->getEntityTypeId() . '__' . $entity->id(), '#entity' => $entity, '#entity_array' => $render_controller->view($entity, 'pdf'), '#attached' => []];
     // Inject some generic CSS across all templates.
     if ($use_default_css) {
         $render['#attached']['library'][] = 'entity_print/default';
     }
     // Allow other modules to add their own CSS.
     $this->moduleHandler->alter('entity_print_css', $render, $entity);
     // Inject CSS from the theme info files and then render the CSS.
     $render = $this->addCss($render, $entity);
     $css_assets = $this->assetResolver->getCssAssets(AttachedAssets::createFromRenderArray($render), $optimize_css);
     $rendered_css = $this->cssRenderer->render($css_assets);
     $render['#entity_print_css'] = $this->renderer->render($rendered_css);
     return $this->renderer->render($render);
 }
 /**
  * Processes asset libraries into render arrays.
  *
  * @param \Drupal\Core\Asset\AttachedAssetsInterface $assets
  *   The attached assets collection for the current response.
  * @param array $placeholders
  *   The placeholders that exist in the response.
  *
  * @return array
  *   An array keyed by asset type, with keys:
  *     - styles
  *     - scripts
  *     - scripts_bottom
  */
 protected function processAssetLibraries(AttachedAssetsInterface $assets, array $placeholders)
 {
     $variables = [];
     // Print styles - if present.
     if (isset($placeholders['styles'])) {
         // Optimize CSS if necessary, but only during normal site operation.
         $optimize_css = !defined('MAINTENANCE_MODE') && $this->config->get('css.preprocess');
         $variables['styles'] = $this->cssCollectionRenderer->render($this->assetResolver->getCssAssets($assets, $optimize_css));
     }
     // Print scripts - if any are present.
     if (isset($placeholders['scripts']) || isset($placeholders['scripts_bottom'])) {
         // Optimize JS if necessary, but only during normal site operation.
         $optimize_js = !defined('MAINTENANCE_MODE') && !\Drupal::state()->get('system.maintenance_mode') && $this->config->get('js.preprocess');
         list($js_assets_header, $js_assets_footer) = $this->assetResolver->getJsAssets($assets, $optimize_js);
         $variables['scripts'] = $this->jsCollectionRenderer->render($js_assets_header);
         $variables['scripts_bottom'] = $this->jsCollectionRenderer->render($js_assets_footer);
     }
     return $variables;
 }