function JsCollectionOptimizerLazy::optimize

Same name in other branches
  1. 10 core/lib/Drupal/Core/Asset/JsCollectionOptimizerLazy.php \Drupal\Core\Asset\JsCollectionOptimizerLazy::optimize()

Overrides AssetCollectionOptimizerInterface::optimize

File

core/lib/Drupal/Core/Asset/JsCollectionOptimizerLazy.php, line 61

Class

JsCollectionOptimizerLazy
Optimizes JavaScript assets.

Namespace

Drupal\Core\Asset

Code

public function optimize(array $js_assets, array $libraries) {
    // File names are generated based on library/asset definitions. This
    // includes a hash of the assets and the group index. Additionally, the full
    // set of libraries, already loaded libraries and theme are sent as query
    // parameters to allow a PHP controller to generate a valid file with
    // sufficient information. Files are not generated by this method since
    // they're assumed to be successfully returned from the URL created whether
    // on disk or not.
    // Group the assets.
    $js_groups = $this->grouper
        ->group($js_assets);
    $js_assets = [];
    foreach ($js_groups as $order => $js_group) {
        // We have to return a single asset, not a group of assets. It is now up
        // to one of the pieces of code in the switch statement below to set the
        // 'data' property to the appropriate value.
        $js_assets[$order] = $js_group;
        switch ($js_group['type']) {
            case 'file':
                // No preprocessing, single JS asset: just use the existing URI.
                if (!$js_group['preprocess']) {
                    $uri = $js_group['items'][0]['data'];
                    $js_assets[$order]['data'] = $uri;
                }
                else {
                    // To reproduce the full context of assets outside of the request,
                    // we must know the entire set of libraries used to generate all CSS
                    // groups, whether or not files in a group are from a particular
                    // library or not.
                    $js_assets[$order]['preprocessed'] = TRUE;
                }
                break;
            case 'external':
                // We don't do any aggregation and hence also no caching for external
                // JS assets.
                $uri = $js_group['items'][0]['data'];
                $js_assets[$order]['data'] = $uri;
                break;
            case 'setting':
                $js_assets[$order]['data'] = $js_group['data'];
                break;
        }
    }
    if ($libraries) {
        // All group URLs have the same query arguments apart from the delta and
        // scope, so prepare them in advance.
        $language = $this->languageManager
            ->getCurrentLanguage()
            ->getId();
        $query_args = [
            'language' => $language,
            'theme' => $this->themeManager
                ->getActiveTheme()
                ->getName(),
            'include' => UrlHelper::compressQueryParameter(implode(',', $this->dependencyResolver
                ->getMinimalRepresentativeSubset($libraries))),
        ];
        $ajax_page_state = $this->requestStack
            ->getCurrentRequest()
            ->get('ajax_page_state');
        $already_loaded = isset($ajax_page_state) ? explode(',', $ajax_page_state['libraries']) : [];
        if ($already_loaded) {
            $query_args['exclude'] = UrlHelper::compressQueryParameter(implode(',', $this->dependencyResolver
                ->getMinimalRepresentativeSubset($already_loaded)));
        }
        // Generate a URL for the group, but do not process it inline, this is
        // done by \Drupal\system\controller\JsAssetController.
        foreach ($js_assets as $order => $js_asset) {
            if (!empty($js_asset['preprocessed'])) {
                $query = [
                    'scope' => $js_asset['scope'] === 'header' ? 'header' : 'footer',
                    'delta' => "{$order}",
                ] + $query_args;
                // Add a filename prefix to mitigate ad blockers which can block
                // any script beginning with 'ad'.
                $filename = 'js_' . $this->generateHash($js_asset) . '.js';
                $uri = 'assets://js/' . $filename;
                $js_assets[$order]['data'] = $this->fileUrlGenerator
                    ->generateString($uri) . '?' . UrlHelper::buildQuery($query);
            }
            unset($js_assets[$order]['items']);
        }
    }
    return $js_assets;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.