Issue #784626 by Wim Leers, Manuel Garcia, jcisio, joelpittet, Bevan, fcaspani, dcmouyard: Default all JS to the footer, allow asset libraries to force their JS to the header
							parent
							
								
									5f7ec33ace
								
							
						
					
					
						commit
						ea568f1d13
					
				| 
						 | 
				
			
			@ -48,6 +48,7 @@ drupal:
 | 
			
		|||
    misc/drupal.js: { weight: -18 }
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - core/domready
 | 
			
		||||
    - core/drupalSettings
 | 
			
		||||
 | 
			
		||||
drupalSettings:
 | 
			
		||||
  version: VERSION
 | 
			
		||||
| 
						 | 
				
			
			@ -308,6 +309,8 @@ drupal.vertical-tabs:
 | 
			
		|||
    - core/drupal.form
 | 
			
		||||
 | 
			
		||||
html5shiv:
 | 
			
		||||
  # Block the page from being loaded until html5shiv is initialized.
 | 
			
		||||
  header: true
 | 
			
		||||
  remote: https://github.com/aFarkas/html5shiv
 | 
			
		||||
  version: 3.7.2
 | 
			
		||||
  license:
 | 
			
		||||
| 
						 | 
				
			
			@ -807,6 +810,8 @@ matchmedia.addListener:
 | 
			
		|||
    - core/matchmedia
 | 
			
		||||
 | 
			
		||||
modernizr:
 | 
			
		||||
  # Block the page from being loaded until Modernizr is initialized.
 | 
			
		||||
  header: true
 | 
			
		||||
  remote: https://github.com/Modernizr/Modernizr
 | 
			
		||||
  license:
 | 
			
		||||
    name: MIT
 | 
			
		||||
| 
						 | 
				
			
			@ -814,7 +819,7 @@ modernizr:
 | 
			
		|||
    gpl-compatible: true
 | 
			
		||||
  version: v2.8.3
 | 
			
		||||
  js:
 | 
			
		||||
    assets/vendor/modernizr/modernizr.min.js: { every_page: true, preprocess: 0, scope: header, weight: -21, minified: true }
 | 
			
		||||
    assets/vendor/modernizr/modernizr.min.js: { every_page: true, preprocess: 0, weight: -21, minified: true }
 | 
			
		||||
 | 
			
		||||
normalize:
 | 
			
		||||
  remote: https://github.com/necolas/normalize.css
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -135,8 +135,15 @@ class AjaxResponse extends JsonResponse {
 | 
			
		|||
 | 
			
		||||
    // Render the HTML to load these files, and add AJAX commands to insert this
 | 
			
		||||
    // HTML in the page. Settings are handled separately, afterwards.
 | 
			
		||||
    $settings = (isset($js_assets_header['drupalSettings'])) ? $js_assets_header['drupalSettings']['data'] : [];
 | 
			
		||||
    unset($js_assets_header['drupalSettings']);
 | 
			
		||||
    $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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,8 +214,23 @@ class AssetResolver implements AssetResolverInterface {
 | 
			
		|||
   */
 | 
			
		||||
  public function getJsAssets(AttachedAssetsInterface $assets, $optimize) {
 | 
			
		||||
    $javascript = [];
 | 
			
		||||
    $libraries_to_load = $this->getLibrariesToLoad($assets);
 | 
			
		||||
 | 
			
		||||
    foreach ($this->getLibrariesToLoad($assets) as $library) {
 | 
			
		||||
    // Collect all libraries that contain JS assets and are in the header.
 | 
			
		||||
    $header_js_libraries = [];
 | 
			
		||||
    foreach ($libraries_to_load as $library) {
 | 
			
		||||
      list($extension, $name) = explode('/', $library, 2);
 | 
			
		||||
      $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
 | 
			
		||||
      if (isset($definition['js']) && !empty($definition['header'])) {
 | 
			
		||||
        $header_js_libraries[] = $library;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // The current list of header JS libraries are only those libraries that are
 | 
			
		||||
    // in the header, but their dependencies must also be loaded for them to
 | 
			
		||||
    // function correctly, so update the list with those.
 | 
			
		||||
    $header_js_libraries = $this->libraryDependencyResolver->getLibrariesWithDependencies($header_js_libraries);
 | 
			
		||||
 | 
			
		||||
    foreach ($libraries_to_load as $library) {
 | 
			
		||||
      list($extension, $name) = explode('/', $library, 2);
 | 
			
		||||
      $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
 | 
			
		||||
      if (isset($definition['js'])) {
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +240,6 @@ class AssetResolver implements AssetResolverInterface {
 | 
			
		|||
            'group' => JS_DEFAULT,
 | 
			
		||||
            'every_page' => FALSE,
 | 
			
		||||
            'weight' => 0,
 | 
			
		||||
            'scope' => 'header',
 | 
			
		||||
            'cache' => TRUE,
 | 
			
		||||
            'preprocess' => TRUE,
 | 
			
		||||
            'attributes' => array(),
 | 
			
		||||
| 
						 | 
				
			
			@ -233,6 +247,10 @@ class AssetResolver implements AssetResolverInterface {
 | 
			
		|||
            'browsers' => array(),
 | 
			
		||||
          );
 | 
			
		||||
 | 
			
		||||
          // 'scope' is a calculated option, based on which libraries are marked
 | 
			
		||||
          // to be loaded from the header (see above).
 | 
			
		||||
          $options['scope'] = in_array($library, $header_js_libraries) ? 'header' : 'footer';
 | 
			
		||||
 | 
			
		||||
          // Preprocess can only be set if caching is enabled and no attributes
 | 
			
		||||
          // are set.
 | 
			
		||||
          $options['preprocess'] = $options['cache'] && empty($options['attributes']) ? $options['preprocess'] : FALSE;
 | 
			
		||||
| 
						 | 
				
			
			@ -267,8 +285,6 @@ class AssetResolver implements AssetResolverInterface {
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // @todo Refactor this when the default scope is changed to 'footer' in
 | 
			
		||||
    //    https://www.drupal.org/node/784626
 | 
			
		||||
    // If the core/drupalSettings library is being loaded or is already loaded,
 | 
			
		||||
    // get the JavaScript settings assets, and convert them into a single
 | 
			
		||||
    // "regular" JavaScript asset.
 | 
			
		||||
| 
						 | 
				
			
			@ -278,7 +294,6 @@ class AssetResolver implements AssetResolverInterface {
 | 
			
		|||
    if ($settings_needed && $settings_have_changed) {
 | 
			
		||||
      $settings = $this->getJsSettingsAssets($assets);
 | 
			
		||||
      if (!empty($settings)) {
 | 
			
		||||
        // Prepend to the list of JavaScript assets, to render it first.
 | 
			
		||||
        $settings_as_inline_javascript = [
 | 
			
		||||
          'type' => 'setting',
 | 
			
		||||
          'group' => JS_SETTING,
 | 
			
		||||
| 
						 | 
				
			
			@ -287,7 +302,15 @@ class AssetResolver implements AssetResolverInterface {
 | 
			
		|||
          'browsers' => array(),
 | 
			
		||||
          'data' => $settings,
 | 
			
		||||
        ];
 | 
			
		||||
        $js_assets_header = ['drupalSettings' => $settings_as_inline_javascript] + $js_assets_header;
 | 
			
		||||
        $settings_js_asset = ['drupalSettings' => $settings_as_inline_javascript];
 | 
			
		||||
        // Prepend to the list of JS assets, to render it first. Preferably in
 | 
			
		||||
        // the footer, but in the header if necessary.
 | 
			
		||||
        if (in_array('core/drupalSettings', $header_js_libraries)) {
 | 
			
		||||
          $js_assets_header = $settings_js_asset + $js_assets_header;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          $js_assets_footer = $settings_js_asset + $js_assets_footer;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,6 +86,10 @@ class LibraryDiscoveryParser {
 | 
			
		|||
      }
 | 
			
		||||
      $library += array('dependencies' => array(), 'js' => array(), 'css' => array());
 | 
			
		||||
 | 
			
		||||
      if (isset($library['header']) && !is_bool($library['header'])) {
 | 
			
		||||
        throw new \LogicException(sprintf("The 'header' key in the library definition '%s' in extension '%s' is invalid: it must be a boolean.", $id, $extension));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (isset($library['version'])) {
 | 
			
		||||
        // @todo Retrieve version of a non-core extension.
 | 
			
		||||
        if ($library['version'] === 'VERSION') {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ drupal.editor.dialog:
 | 
			
		|||
quickedit.inPlaceEditor.formattedText:
 | 
			
		||||
  version: VERSION
 | 
			
		||||
  js:
 | 
			
		||||
    js/editor.formattedTextEditor.js: { scope: footer, attributes: { defer: true } }
 | 
			
		||||
    js/editor.formattedTextEditor.js: { attributes: { defer: true } }
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - quickedit/quickedit
 | 
			
		||||
    - editor/drupal.editor
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,6 @@ api:
 | 
			
		|||
mark-as-read:
 | 
			
		||||
  version: VERSION
 | 
			
		||||
  js:
 | 
			
		||||
    js/mark-as-read.js: { scope: footer }
 | 
			
		||||
    js/mark-as-read.js: {}
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - history/api
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ class LocaleLibraryAlterTest extends WebTestBase {
 | 
			
		|||
  public function testLibraryAlter() {
 | 
			
		||||
    $assets = new AttachedAssets();
 | 
			
		||||
    $assets->setLibraries(['core/jquery.ui.datepicker']);
 | 
			
		||||
    $js_assets = $this->container->get('asset.resolver')->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js_assets = $this->container->get('asset.resolver')->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $this->assertTrue(array_key_exists('core/modules/locale/locale.datepicker.js', $js_assets), 'locale.datepicker.js added to scripts.');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,24 +2,24 @@ quickedit:
 | 
			
		|||
  version: VERSION
 | 
			
		||||
  js:
 | 
			
		||||
    # Core.
 | 
			
		||||
    js/quickedit.js: { scope: footer }
 | 
			
		||||
    js/util.js: { scope: footer }
 | 
			
		||||
    js/quickedit.js: {}
 | 
			
		||||
    js/util.js: {}
 | 
			
		||||
    # Models.
 | 
			
		||||
    js/models/BaseModel.js: { scope: footer }
 | 
			
		||||
    js/models/AppModel.js: { scope: footer }
 | 
			
		||||
    js/models/EntityModel.js: { scope: footer }
 | 
			
		||||
    js/models/FieldModel.js: { scope: footer }
 | 
			
		||||
    js/models/EditorModel.js: { scope: footer }
 | 
			
		||||
    js/models/BaseModel.js: {}
 | 
			
		||||
    js/models/AppModel.js: {}
 | 
			
		||||
    js/models/EntityModel.js: {}
 | 
			
		||||
    js/models/FieldModel.js: {}
 | 
			
		||||
    js/models/EditorModel.js: {}
 | 
			
		||||
    # Views.
 | 
			
		||||
    js/views/AppView.js: { scope: footer }
 | 
			
		||||
    js/views/FieldDecorationView.js: { scope: footer }
 | 
			
		||||
    js/views/EntityDecorationView.js: { scope: footer }
 | 
			
		||||
    js/views/EntityToolbarView.js: { scope: footer }
 | 
			
		||||
    js/views/ContextualLinkView.js: { scope: footer }
 | 
			
		||||
    js/views/FieldToolbarView.js: { scope: footer }
 | 
			
		||||
    js/views/EditorView.js: { scope: footer }
 | 
			
		||||
    js/views/AppView.js: {}
 | 
			
		||||
    js/views/FieldDecorationView.js: {}
 | 
			
		||||
    js/views/EntityDecorationView.js: {}
 | 
			
		||||
    js/views/EntityToolbarView.js: {}
 | 
			
		||||
    js/views/ContextualLinkView.js: {}
 | 
			
		||||
    js/views/FieldToolbarView.js: {}
 | 
			
		||||
    js/views/EditorView.js: {}
 | 
			
		||||
    # Other.
 | 
			
		||||
    js/theme.js: { scope: footer }
 | 
			
		||||
    js/theme.js: {}
 | 
			
		||||
  css:
 | 
			
		||||
    component:
 | 
			
		||||
      css/quickedit.module.css: {}
 | 
			
		||||
| 
						 | 
				
			
			@ -44,13 +44,13 @@ quickedit:
 | 
			
		|||
quickedit.inPlaceEditor.form:
 | 
			
		||||
  version: VERSION
 | 
			
		||||
  js:
 | 
			
		||||
    js/editors/formEditor.js: { scope: footer }
 | 
			
		||||
    js/editors/formEditor.js: {}
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - quickedit/quickedit
 | 
			
		||||
 | 
			
		||||
quickedit.inPlaceEditor.plainText:
 | 
			
		||||
  version: VERSION
 | 
			
		||||
  js:
 | 
			
		||||
    js/editors/plainTextEditor.js: { scope: footer }
 | 
			
		||||
    js/editors/plainTextEditor.js: {}
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - quickedit/quickedit
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
drupal.statistics:
 | 
			
		||||
  version: VERSION
 | 
			
		||||
  js:
 | 
			
		||||
    statistics.js: { scope: footer }
 | 
			
		||||
    statistics.js: {}
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - core/jquery
 | 
			
		||||
    - core/drupal
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,8 @@ class FrameworkTest extends AjaxTestBase {
 | 
			
		|||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
    $css_render_array = $css_collection_renderer->render($asset_resolver->getCssAssets($assets, FALSE));
 | 
			
		||||
    $expected_commands[1] = new AddCssCommand($renderer->render($css_render_array));
 | 
			
		||||
    $build['#attached']['library'][] = 'ajax_test/order-js-command';
 | 
			
		||||
    $build['#attached']['library'][] = 'ajax_test/order-header-js-command';
 | 
			
		||||
    $build['#attached']['library'][] = 'ajax_test/order-footer-js-command';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
    list($js_assets_header, $js_assets_footer) = $asset_resolver->getJsAssets($assets, FALSE);
 | 
			
		||||
    $js_header_render_array = $js_collection_renderer->render($js_assets_header);
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +127,7 @@ class FrameworkTest extends AjaxTestBase {
 | 
			
		|||
 | 
			
		||||
    $assets->setLibraries([$expected['library_2']])
 | 
			
		||||
      ->setAlreadyLoadedLibraries($original_libraries);
 | 
			
		||||
    $js_assets = $asset_resolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js_assets = $asset_resolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    unset($js_assets['drupalSettings']);
 | 
			
		||||
    $js_render_array = $js_collection_renderer->render($js_assets);
 | 
			
		||||
    $expected_js_html = $renderer->render($js_render_array);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,7 +86,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $css = $this->assetResolver->getCssAssets($assets, FALSE);
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $this->assertTrue(array_key_exists('bar.css', $css), 'CSS files are correctly added.');
 | 
			
		||||
    $this->assertTrue(array_key_exists('core/modules/system/tests/modules/common_test/foo.js', $js), 'JavaScript files are correctly added.');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,11 +107,11 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $build['#attached']['library'][] = 'core/drupalSettings';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $javascript = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $javascript = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $this->assertTrue(array_key_exists('currentPath', $javascript['drupalSettings']['data']['path']), 'The current path JavaScript setting is set correctly.');
 | 
			
		||||
 | 
			
		||||
    $assets->setSettings(['drupal' => 'rocks', 'dries' => 280342800]);
 | 
			
		||||
    $javascript = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $javascript = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $this->assertEqual(280342800, $javascript['drupalSettings']['data']['dries'], 'JavaScript setting is set correctly.');
 | 
			
		||||
    $this->assertEqual('rocks', $javascript['drupalSettings']['data']['drupal'], 'The other JavaScript setting is set correctly.');
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -124,7 +124,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $css = $this->assetResolver->getCssAssets($assets, FALSE);
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $this->assertTrue(array_key_exists('http://example.com/stylesheet.css', $css), 'External CSS files are correctly added.');
 | 
			
		||||
    $this->assertTrue(array_key_exists('http://example.com/script.js', $js), 'External JavaScript files are correctly added.');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +143,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $build['#attached']['library'][] = 'common_test/js-attributes';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
    $expected_1 = '<script src="http://example.com/deferred-external.js" foo="bar" defer></script>';
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +159,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $build['#attached']['library'][] = 'common_test/js-attributes';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, TRUE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, TRUE)[1];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
    $expected_1 = '<script src="http://example.com/deferred-external.js" foo="bar" defer></script>';
 | 
			
		||||
| 
						 | 
				
			
			@ -169,16 +169,16 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests drupal_get_js() for JavaScript settings.
 | 
			
		||||
   * Tests JavaScript settings.
 | 
			
		||||
   */
 | 
			
		||||
  function testHeaderSetting() {
 | 
			
		||||
  function testSettings() {
 | 
			
		||||
    $build = array();
 | 
			
		||||
    $build['#attached']['library'][] = 'core/drupalSettings';
 | 
			
		||||
    // Nonsensical value to verify if it's possible to override path settings.
 | 
			
		||||
    $build['#attached']['drupalSettings']['path']['pathPrefix'] = 'yarhar';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -207,17 +207,19 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests JS assets assigned to the 'footer' scope.
 | 
			
		||||
   * Tests JS assets depending on the 'core/<head>' virtual library.
 | 
			
		||||
   */
 | 
			
		||||
  function testFooterHTML() {
 | 
			
		||||
    $build['#attached']['library'][] = 'common_test/js-footer';
 | 
			
		||||
  function testHeaderHTML() {
 | 
			
		||||
    $build['#attached']['library'][] = 'common_test/js-header';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
    $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0';
 | 
			
		||||
    $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_create_url('core/modules/system/tests/modules/common_test/footer.js') . '?' . $query_string . '"></script>'), FALSE, 'Rendering an external JavaScript file.');
 | 
			
		||||
    $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_create_url('core/modules/system/tests/modules/common_test/header.js') . '?' . $query_string . '"></script>'), FALSE, 'The JS asset in common_test/js-header appears in the header.');
 | 
			
		||||
    $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_create_url('core/misc/drupal.js')), FALSE, 'The JS asset of the direct dependency (core/drupal) of common_test/js-header appears in the header.');
 | 
			
		||||
    $this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_create_url('core/assets/vendor/domready/ready.min.js')), FALSE, 'The JS asset of the indirect dependency (core/domready) of common_test/js-header appears in the header.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +229,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $build['#attached']['library'][] = 'common_test/no-cache';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $this->assertFalse($js['core/modules/system/tests/modules/common_test/nocache.js']['preprocess'], 'Setting cache to FALSE sets preprocess to FALSE when adding JavaScript.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +244,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $build['#attached']['library'][] = 'common_test/browsers';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
    $expected_1 = "<!--[if lte IE 8]>\n" . '<script src="' . file_create_url('core/modules/system/tests/modules/common_test/old-ie.js') . '?' . $default_query_string . '"></script>' . "\n<![endif]-->";
 | 
			
		||||
| 
						 | 
				
			
			@ -260,7 +262,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $build['#attached']['library'][] = 'core/domready';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
    $this->assertTrue(strpos($rendered_js, 'core/assets/vendor/backbone/backbone-min.js?v=1.1.2') > 0 && strpos($rendered_js, 'core/assets/vendor/domready/ready.min.js?v=1.0.7') > 0 , 'JavaScript version identifiers correctly appended to URLs');
 | 
			
		||||
| 
						 | 
				
			
			@ -288,7 +290,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    ];
 | 
			
		||||
 | 
			
		||||
    // Retrieve the rendered JavaScript and test against the regex.
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
    $matches = array();
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +355,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $build['#attached']['library'][] = 'common_test/weight';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
    $this->assertTrue(strpos($rendered_js, 'lighter.css') < strpos($rendered_js, 'first.js'), 'Lighter CSS assets are rendered first.');
 | 
			
		||||
| 
						 | 
				
			
			@ -375,7 +377,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    // Render the JavaScript, testing if simpletest.js was altered to be before
 | 
			
		||||
    // tableselect.js. See simpletest_js_alter() to see where this alteration
 | 
			
		||||
    // takes place.
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
    $this->assertTrue(strpos($rendered_js, 'simpletest.js') < strpos($rendered_js, 'core/misc/tableselect.js'), 'Altering JavaScript weight through the alter hook.');
 | 
			
		||||
| 
						 | 
				
			
			@ -396,7 +398,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    // common_test_library_info_alter() also added a dependency on jQuery Form.
 | 
			
		||||
    $build['#attached']['library'][] = 'core/jquery.farbtastic';
 | 
			
		||||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
 | 
			
		||||
    $rendered_js = $this->renderer->render($js_render_array);
 | 
			
		||||
    $this->assertTrue(strpos($rendered_js, 'core/assets/vendor/jquery-form/jquery.form.js'), 'Altered library dependencies are added to the page.');
 | 
			
		||||
| 
						 | 
				
			
			@ -444,7 +446,7 @@ class AttachedAssetsTest extends KernelTestBase {
 | 
			
		|||
    $assets = AttachedAssets::createFromRenderArray($build);
 | 
			
		||||
 | 
			
		||||
    $css = $this->assetResolver->getCssAssets($assets, FALSE);
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
 | 
			
		||||
    $js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
 | 
			
		||||
    $this->assertTrue(array_key_exists('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.');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,8 @@ order:
 | 
			
		|||
   ajax: test
 | 
			
		||||
 dependencies:
 | 
			
		||||
   - ajax_test/order-css-command
 | 
			
		||||
   - ajax_test/order-js-command
 | 
			
		||||
   - ajax_test/order-footer-js-command
 | 
			
		||||
   - ajax_test/order-header-js-command
 | 
			
		||||
 | 
			
		||||
order-css-command:
 | 
			
		||||
  css:
 | 
			
		||||
| 
						 | 
				
			
			@ -12,9 +13,11 @@ order-css-command:
 | 
			
		|||
       a.css: {}
 | 
			
		||||
       b.css: {}
 | 
			
		||||
 | 
			
		||||
order-js-command:
 | 
			
		||||
order-footer-js-command:
 | 
			
		||||
  js:
 | 
			
		||||
   # Two JavaScript files (first to the footer, should appear last).
 | 
			
		||||
   footer.js: { scope: footer }
 | 
			
		||||
   header.js: {}
 | 
			
		||||
    footer.js: {}
 | 
			
		||||
 | 
			
		||||
order-header-js-command:
 | 
			
		||||
  header: true
 | 
			
		||||
  js:
 | 
			
		||||
    header.js: {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,9 +36,12 @@ js-attributes:
 | 
			
		|||
        foo: bar
 | 
			
		||||
        defer: true
 | 
			
		||||
 | 
			
		||||
js-footer:
 | 
			
		||||
js-header:
 | 
			
		||||
  header: true
 | 
			
		||||
  js:
 | 
			
		||||
    footer.js: { scope: footer }
 | 
			
		||||
    header.js: {}
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - core/drupal
 | 
			
		||||
 | 
			
		||||
# Library to test setting cache = FALSE, to prevent aggregation.
 | 
			
		||||
no-cache:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue