Chris@0: state = $state; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: * Chris@0: * This class evaluates the aggregation enabled/disabled condition on a group Chris@0: * by group basis by testing whether an aggregate file has been made for the Chris@0: * group rather than by testing the site-wide aggregation setting. This allows Chris@0: * this class to work correctly even if modules have implemented custom Chris@0: * logic for grouping and aggregating files. Chris@0: */ Chris@0: public function render(array $js_assets) { Chris@0: $elements = []; Chris@0: Chris@0: // A dummy query-string is added to filenames, to gain control over Chris@0: // browser-caching. The string changes on every update or full cache Chris@0: // flush, forcing browsers to load a new copy of the files, as the Chris@0: // URL changed. Files that should not be cached get REQUEST_TIME as Chris@0: // query-string instead, to enforce reload on every page request. Chris@0: $default_query_string = $this->state->get('system.css_js_query_string') ?: '0'; Chris@0: Chris@0: // Defaults for each SCRIPT element. Chris@0: $element_defaults = [ Chris@0: '#type' => 'html_tag', Chris@0: '#tag' => 'script', Chris@0: '#value' => '', Chris@0: ]; Chris@0: Chris@0: // Loop through all JS assets. Chris@0: foreach ($js_assets as $js_asset) { Chris@0: // Element properties that do not depend on JS asset type. Chris@0: $element = $element_defaults; Chris@0: $element['#browsers'] = $js_asset['browsers']; Chris@0: Chris@0: // Element properties that depend on item type. Chris@0: switch ($js_asset['type']) { Chris@0: case 'setting': Chris@0: $element['#attributes'] = [ Chris@0: // This type attribute prevents this from being parsed as an Chris@0: // inline script. Chris@0: 'type' => 'application/json', Chris@0: 'data-drupal-selector' => 'drupal-settings-json', Chris@0: ]; Chris@0: $element['#value'] = Json::encode($js_asset['data']); Chris@0: break; Chris@0: Chris@0: case 'file': Chris@0: $query_string = $js_asset['version'] == -1 ? $default_query_string : 'v=' . $js_asset['version']; Chris@0: $query_string_separator = (strpos($js_asset['data'], '?') !== FALSE) ? '&' : '?'; Chris@0: $element['#attributes']['src'] = file_url_transform_relative(file_create_url($js_asset['data'])); Chris@0: // Only add the cache-busting query string if this isn't an aggregate Chris@0: // file. Chris@0: if (!isset($js_asset['preprocessed'])) { Chris@0: $element['#attributes']['src'] .= $query_string_separator . ($js_asset['cache'] ? $query_string : REQUEST_TIME); Chris@0: } Chris@0: break; Chris@0: Chris@0: case 'external': Chris@0: $element['#attributes']['src'] = $js_asset['data']; Chris@0: break; Chris@0: Chris@0: default: Chris@0: throw new \Exception('Invalid JS asset type.'); Chris@0: } Chris@0: Chris@0: // Attributes may only be set if this script is output independently. Chris@0: if (!empty($element['#attributes']['src']) && !empty($js_asset['attributes'])) { Chris@0: $element['#attributes'] += $js_asset['attributes']; Chris@0: } Chris@0: Chris@0: $elements[] = $element; Chris@0: } Chris@0: Chris@0: return $elements; Chris@0: } Chris@0: Chris@0: }