Commit 235d1238 authored by Tim Bozeman's avatar Tim Bozeman Committed by Tim Bozeman
Browse files

Issue #3274321 by Tim Bozeman: CSS assets don't override theme CSS

parent 6f5c305e
Loading
Loading
Loading
Loading
+25 −33
Original line number Diff line number Diff line
@@ -12,53 +12,45 @@ use Drupal\component_library\Form\ComponentOverrideForm;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Serialization\Yaml;
use Drupal\component_library\Entity\ComponentLibraryPattern;
use Drupal\Core\Asset\AttachedAssetsInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Extension\Extension;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\component_library\Entity\ComponentLibraryAsset;

/**
 * Implements hook_library_info_build().
 */
function component_library_library_info_build() {
  $libraries = [];
  /** @var \Drupal\component_library\Entity\ComponentLibraryAsset $asset_entities */
  $asset_entities = ComponentLibraryAsset::loadMultiple();
  /** @var \Drupal\Core\File\FileSystemInterface $file_system */
  $file_system = \Drupal::service('file_system');

  foreach ($asset_entities as $asset) {
    $library_name = 'component_library.' . $asset->get('id');
    foreach (['css', 'js'] as $asset_type) {
      $path = 'public://component_library_assets/' . $asset->get('id') . '/' . $asset_type;
      if (file_exists($path) && $asset->get($asset_type)) {
        $files = $file_system->scanDirectory($path, '/.*/');
        foreach ($files as $file) {
          if ($asset_type == 'css') {
            $asset_path = _file_url_generator_backwards_compatibility($file->uri);
            $libraries[$library_name]['css']['base'][$asset_path] = [];
          }
          elseif ($asset_type == 'js') {
            $asset_path = _file_url_generator_backwards_compatibility($file->uri);
            $libraries[$library_name]['js'][$asset_path] = [];
          }
        }
      }
  \Drupal::service('component_library.asset')->processAllAssetPaths(function ($path_info) use (&$libraries) {
    $type = $path_info['type'];
    $path = $path_info['path'];
    $id = $path_info['id'];
    if ($type === 'css') {
      $libraries["component_library.$id"][$type]['theme'][$path] = [];
    }
    else {
      $libraries["component_library.$id"][$type][$path] = [];
    }
  });

  return $libraries;
}

function _file_url_generator_backwards_compatibility($file_uri) {
  if (version_compare(Drupal::VERSION, '9.3', '>=')) {
    /** @var \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator */
    $file_url_generator = \Drupal::service('file_url_generator');
    return $file_url_generator->generateString($file_uri);
  }
  else {
    return file_create_url($file_uri);
  }
/**
 * Implements hook_css_alter().
 */
function component_library_css_alter(&$css, AttachedAssetsInterface $assets) {
  \Drupal::service('component_library.asset')->processAllAssetPaths(function ($path_info) use (&$css) {
    $path = $path_info['path'];
    $path = ltrim($path, '/');
    if ($path_info['type'] === 'css' && !empty($css[$path])) {
      // Ensure our css overrides are loaded after the theme.
      $css[$path]['group'] = CSS_AGGREGATE_THEME;
      $css[$path]['weight'] = 999999999999;
    }
  });
}

/**
+3 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ services:
    class: Drupal\component_library\Routing\NotAdminRouteSubscriber
    tags:
      - { name: event_subscriber }
  component_library.asset:
    class: Drupal\component_library\Asset
    arguments: []
  component_library.override_mode:
    class: Drupal\component_library\OverrideMode
    arguments: ['@theme.manager', '@theme.registry', '@entity_type.manager', '@redirect.destination', '@logger.factory', '@renderer', '@event_dispatcher', '@uuid', '@twig.loader.component_override', '@config.factory', '@current_user']

src/Asset.php

0 → 100644
+32 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\component_library;

use Drupal\component_library\Entity\ComponentLibraryAsset;

class Asset {

  public function processAllAssetPaths(callable $callback, $url = TRUE) {
    $assets = ComponentLibraryAsset::loadMultiple();
    foreach ($assets as $asset) {
      $paths = $asset->get('paths');
      foreach ($paths as $path_info) {
        $path_info['id'] = $asset->id();
        if ($url) {
          $path_info['path'] = $this->fileUrlGenerator($path_info['path']);
        }
        \call_user_func($callback, $path_info);
      }
    }
  }

  private function fileUrlGenerator($file_uri) {
    if (version_compare(\Drupal::VERSION, '9.3', '>=')) {
      return \Drupal::service('file_url_generator')->generateString($file_uri);
    }
    else {
      return file_create_url($file_uri);
    }
  }

}
+6 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ use Drupal\Core\Entity\EntityStorageInterface;
 *     "theme",
 *     "css",
 *     "js",
 *     "paths",
 *   }
 * )
 */
@@ -89,6 +90,11 @@ class ComponentLibraryAsset extends ConfigEntityBase {
   */
  protected $js = [];

  /**
   * The library files that were generated.
   */
  protected array $paths = [];

  /**
   * {@inheritdoc}
   */
+8 −3
Original line number Diff line number Diff line
@@ -156,12 +156,11 @@ class ComponentLibraryAssetForm extends EntityForm {
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $result = parent::save($form, $form_state);

    // Re-create the files on disk and make sure they are read when aggregation
    // is enabled.
    ComponentLibraryAsset::clearFiles($this->entity);
    $this->generateLibraryFiles($form_state);
    $result = parent::save($form, $form_state);

    $message_args = ['%label' => $this->entity->label()];
    $message = $result == SAVED_NEW
@@ -293,19 +292,25 @@ class ComponentLibraryAssetForm extends EntityForm {
   *   The form state after submission of the form.
   */
  protected function generateLibraryFiles(FormStateInterface $form_state) {
    $paths = [];
    foreach (array_keys($form_state->get('library_files')) as $asset_type) {
      $dir = 'public://component_library_assets/' . $form_state->getValue('id') . '/' . $asset_type;
      $this->fileSystem->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
      foreach ($form_state->getValue($asset_type) as $library_file) {
        $file_name = $library_file['name'];
        $file_path = "$dir/$file_name.$asset_type";
        $this->fileSystem->saveData(
        $path = $this->fileSystem->saveData(
          $library_file['code'],
          $file_path,
          FileSystemInterface::EXISTS_REPLACE
        );
        $paths[] = [
          'type' => $asset_type,
          'path' => $path,
        ];
      }
    }
    $this->getEntity()->set('paths', $paths);
    $this->libraryDiscovery->clearCachedDefinitions();
  }

Loading