From 6792be18e66fa3f5fa099253b78de448709643f8 Mon Sep 17 00:00:00 2001
From: Vladimir Roudakov <44088-VladimirAus@users.noreply.drupalcode.org>
Date: Thu, 23 May 2024 13:31:25 +0000
Subject: [PATCH] Issue #3405523 by VladimirAus, Jasjeet Kaur Brar, Diwakar07,
 nitin_lama, jannakha: Add gitlab CI and fix errors

---
 .cspell-project-words.txt                 | 12 ++++++
 .eslintignore                             |  2 +
 .gitlab-ci.yml                            | 25 ++++++++++++
 .stylelintignore                          |  3 ++
 README.md                                 |  2 +-
 bootstrap5.theme                          | 15 ++++---
 js/nav-tabs.es6.js                        | 35 ----------------
 js/nav-tabs.js                            | 43 +++++++++++---------
 src/Drush/Commands/Bootstrap5Commands.php | 18 +++++++--
 src/SettingsManager.php                   | 13 ++----
 src/SubthemeFormManager.php               | 21 +++++++++-
 src/SubthemeManager.php                   | 49 ++++++++++++++---------
 12 files changed, 142 insertions(+), 96 deletions(-)
 create mode 100644 .cspell-project-words.txt
 create mode 100644 .eslintignore
 create mode 100644 .gitlab-ci.yml
 create mode 100644 .stylelintignore
 delete mode 100644 js/nav-tabs.es6.js

diff --git a/.cspell-project-words.txt b/.cspell-project-words.txt
new file mode 100644
index 00000000..2f150a3f
--- /dev/null
+++ b/.cspell-project-words.txt
@@ -0,0 +1,12 @@
+cheatsheet
+commandfile
+cpath
+csvg
+matchmedia
+replatform
+sglink
+subnesting
+twbstools
+updb
+Webform
+webform
\ No newline at end of file
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 00000000..37d5871d
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,2 @@
+bin/**
+dist/**
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 00000000..a6d694ec
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,25 @@
+include:
+  - project: $_GITLAB_TEMPLATES_REPO
+    ref: $_GITLAB_TEMPLATES_REF
+    file:
+      - '/includes/include.drupalci.main.yml'
+      - '/includes/include.drupalci.variables.yml'
+      - '/includes/include.drupalci.workflows.yml'
+
+variables:
+  _CSPELL_IGNORE_PATHS: '"dist/**", "css/**", "bin/**"'
+  OPT_IN_TEST_CURRENT: 0
+  OPT_IN_TEST_NEXT_MINOR: 1
+  OPT_IN_TEST_NEXT_MAJOR: 1
+phpcs:
+  allow_failure: false
+phpstan:
+  allow_failure: false
+phpstan (next minor):
+  allow_failure: false
+phpstan (next major):
+  allow_failure: false
+phpunit (next minor):
+  allow_failure: false
+phpunit (next major):
+  allow_failure: true
diff --git a/.stylelintignore b/.stylelintignore
new file mode 100644
index 00000000..2e07e61f
--- /dev/null
+++ b/.stylelintignore
@@ -0,0 +1,3 @@
+bin/**
+dist/**
+css/**
diff --git a/README.md b/README.md
index beed96ae..158e35b3 100644
--- a/README.md
+++ b/README.md
@@ -172,7 +172,7 @@ We call a macro which calls itself to render the full tree.
 
 ### Configuration
 
-If using configuration synchronisation, make sure your core.extension.yml contains
+If using configuration synchronization, make sure your core.extension.yml contains
 
 ```
 theme:
diff --git a/bootstrap5.theme b/bootstrap5.theme
index 184b2d15..3df5aef7 100644
--- a/bootstrap5.theme
+++ b/bootstrap5.theme
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * bootstrap5 theme file.
+ * Bootstrap5 theme file.
  */
 
 use Drupal\block\Entity\Block;
@@ -40,7 +40,7 @@ function bootstrap5_form_system_theme_settings_alter(&$form, FormStateInterface
  * Validate callback to ensure filter order and allowed_html are compatible.
  */
 function bootstrap5_form_system_theme_settings_subtheme_validate(array &$form, FormStateInterface $form_state) {
-  $subtheme_form_manager = new SubthemeFormManager();
+  $subtheme_form_manager = new SubthemeFormManager(\Drupal::service('file_system'), \Drupal::service('messenger'), \Drupal::service('extension.list.theme'));
   return $subtheme_form_manager->validateForm($form, $form_state);
 }
 
@@ -50,7 +50,7 @@ function bootstrap5_form_system_theme_settings_subtheme_validate(array &$form, F
  * @see bootstrap5_form_system_theme_settings_alter()
  */
 function bootstrap5_form_system_theme_settings_subtheme_submit($form, FormStateInterface $form_state) {
-  $subtheme_form_manager = new SubthemeFormManager();
+  $subtheme_form_manager = new SubthemeFormManager(\Drupal::service('file_system'), \Drupal::service('messenger'), \Drupal::service('extension.list.theme'));
   return $subtheme_form_manager->submitForm($form, $form_state);
 }
 
@@ -277,7 +277,8 @@ function bootstrap5_views_pre_render(ViewExecutable $view) {
   if ($view->id() === 'media_library') {
     if ($view->display_handler->options['defaults']['css_class']) {
       $add_classes($view->displayHandlers->get('default')->options['css_class'], ['media-library-view']);
-    } else {
+    }
+    else {
       $add_classes($view->display_handler->options['css_class'], ['media-library-view']);
     }
 
@@ -296,7 +297,8 @@ function bootstrap5_views_pre_render(ViewExecutable $view) {
         $add_classes($view->field['delete_media']->options['alter']['link_class'], ['media-library-item__remove']);
         $add_classes($view->field['delete_media']->options['alter']['link_class'], ['icon-link']);
       }
-    } elseif (strpos($view->current_display, 'widget') === 0) {
+    }
+    elseif (strpos($view->current_display, 'widget') === 0) {
       if (array_key_exists('rendered_entity', $view->field)) {
         $add_classes($view->field['rendered_entity']->options['element_class'], ['media-library-item__content']);
       }
@@ -306,7 +308,8 @@ function bootstrap5_views_pre_render(ViewExecutable $view) {
 
       if ($view->display_handler->options['defaults']['css_class']) {
         $add_classes($view->displayHandlers->get('default')->options['css_class'], ['media-library-view--widget']);
-      } else {
+      }
+      else {
         $add_classes($view->display_handler->options['css_class'], ['media-library-view--widget']);
       }
     }
diff --git a/js/nav-tabs.es6.js b/js/nav-tabs.es6.js
deleted file mode 100644
index bdcbcbec..00000000
--- a/js/nav-tabs.es6.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file
- * Responsive navigation tabs (local tasks)
- *
- * Element requires to have class .is-collapsible and attribute
- *   [data-drupal-nav-tabs]
- */
-(($, Drupal, once) => {
-  function init(i, tab) {
-    const $tab = $(tab);
-    const $target = $tab.find('[data-drupal-nav-tabs-target]');
-
-    const openMenu = () => {
-      $target.toggleClass('is-open');
-      const $toggle = $target.find('.tab-toggle');
-      $toggle.attr(
-        'aria-expanded',
-        (_, isExpanded) => !(isExpanded === 'true'),
-      );
-    };
-
-    $tab.on('click.tabs', '[data-drupal-nav-tabs-toggle]', openMenu);
-  }
-  /**
-   * Initialize the tabs JS.
-   */
-  Drupal.behaviors.navTabs = {
-    attach(context) {
-      once('nav-tabs', '[data-drupal-nav-tabs].is-collapsible', context)
-        .forEach((value, i) => {
-          $(value).each(init);
-        });
-    },
-  };
-})(jQuery, Drupal, once);
diff --git a/js/nav-tabs.js b/js/nav-tabs.js
index fd546aba..a605031e 100644
--- a/js/nav-tabs.js
+++ b/js/nav-tabs.js
@@ -1,31 +1,36 @@
 /**
- * DO NOT EDIT THIS FILE.
- * See the following change record for more information,
- * https://www.drupal.org/node/2815083
- * @preserve
- **/
-
-(function ($, Drupal, once) {
+ * @file
+ * Responsive navigation tabs (local tasks).
+ *
+ * Element requires to have class .is-collapsible and attribute
+ *   [data-drupal-nav-tabs]
+ */
+(($, Drupal, once) => {
   function init(i, tab) {
-    var $tab = $(tab);
-    var $target = $tab.find('[data-drupal-nav-tabs-target]');
+    const tabObj = $(tab);
+    const target = tab.find('[data-drupal-nav-tabs-target]');
 
-    var openMenu = function openMenu() {
-      $target.toggleClass('is-open');
-      var $toggle = $target.find('.tab-toggle');
-      $toggle.attr('aria-expanded', function (_, isExpanded) {
-        return !(isExpanded === 'true');
-      });
+    const openMenu = () => {
+      target.toggleClass('is-open');
+      const toggle = target.find('.tab-toggle');
+      toggle.attr('aria-expanded', (_, isExpanded) => !(isExpanded === 'true'));
     };
 
-    $tab.on('click.tabs', '[data-drupal-nav-tabs-toggle]', openMenu);
+    tabObj.on('click.tabs', '[data-drupal-nav-tabs-toggle]', openMenu);
   }
 
+  /**
+   * Initialize the tabs JS.
+   */
   Drupal.behaviors.navTabs = {
-    attach: function attach(context) {
-      once('nav-tabs', '[data-drupal-nav-tabs].is-collapsible', context).forEach(function (value, i) {
+    attach(context) {
+      once(
+        'nav-tabs',
+        '[data-drupal-nav-tabs].is-collapsible',
+        context,
+      ).forEach((value, i) => {
         $(value).each(init);
       });
-    }
+    },
   };
 })(jQuery, Drupal, once);
diff --git a/src/Drush/Commands/Bootstrap5Commands.php b/src/Drush/Commands/Bootstrap5Commands.php
index f895513d..3a1d6134 100644
--- a/src/Drush/Commands/Bootstrap5Commands.php
+++ b/src/Drush/Commands/Bootstrap5Commands.php
@@ -4,6 +4,7 @@ namespace Drush\Commands;
 
 use Consolidation\AnnotatedCommand\CommandError;
 use Drupal\bootstrap5\SubthemeManager;
+use Drupal\Core\Extension\ThemeExtensionList;
 use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Messenger\MessengerInterface;
 use Drush\Attributes as CLI;
@@ -20,10 +21,18 @@ final class Bootstrap5Commands extends DrushCommands {
 
   /**
    * Constructs a Subtheme Commands object.
+   *
+   * @param \Drupal\Core\File\FileSystemInterface $fileSystem
+   *   The file system service.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger interface.
+   * @param \Drupal\Core\Extension\ThemeExtensionList $themeExtensionList
+   *   The theme extension list.
    */
   public function __construct(
-    private readonly FileSystemInterface $fileSystem,
-    private readonly MessengerInterface $messenger,
+    protected FileSystemInterface $fileSystem,
+    protected MessengerInterface $messenger,
+    protected ThemeExtensionList $themeExtensionList,
   ) {
     parent::__construct();
   }
@@ -35,6 +44,7 @@ final class Bootstrap5Commands extends DrushCommands {
     return new static(
       $container->get('file_system'),
       $container->get('messenger'),
+      $container->get('extension.list.theme'),
     );
   }
 
@@ -52,9 +62,9 @@ final class Bootstrap5Commands extends DrushCommands {
     array $options = [
       'subtheme-name' => 'B5 subtheme',
       'subtheme-folder' => 'themes/custom',
-    ]
+    ],
   ) {
-    $subthemeManager = new SubthemeManager($this->fileSystem, $this->messenger);
+    $subthemeManager = new SubthemeManager($this->fileSystem, $this->messenger, $this->themeExtensionList);
     $result = $subthemeManager->validateSubtheme($options['subtheme-folder'], $machine_name);
 
     if (is_array($result)) {
diff --git a/src/SettingsManager.php b/src/SettingsManager.php
index 3309c361..223fa8a5 100644
--- a/src/SettingsManager.php
+++ b/src/SettingsManager.php
@@ -102,7 +102,7 @@ class SettingsManager {
     $form['body_details'] = [
       '#type' => 'details',
       '#title' => $this->t('Body options'),
-      '#description' => $this->t('Combination of theme/background colour may affect background colour/text colour contrast. To fix any contrast issues, override corresponding variables in scss file: <code>[bootstrap 5 theme]/dist/boostrap/[version]/scss/_variables.scss</code>'),
+      '#description' => $this->t('Combination of theme/background colour may affect background colour/text colour contrast. To fix any contrast issues, override corresponding variables in scss file: <code>[bootstrap 5 theme]/dist/bootstrap/[version]/scss/_variables.scss</code>'),
       '#open' => TRUE,
     ];
 
@@ -140,7 +140,7 @@ class SettingsManager {
     $form['nav_details'] = [
       '#type' => 'details',
       '#title' => $this->t('Navbar options'),
-      '#description' => $this->t("Combination of theme/background colour may affect background colour/text colour contrast. To fix any contrast issues, override \$navbar-light-*/\$navbar-dark-* variables (refer to dist/boostrap/scss/_variables.scss)"),
+      '#description' => $this->t("Combination of theme/background colour may affect background colour/text colour contrast. To fix any contrast issues, override \$navbar-light-*/\$navbar-dark-* variables (refer to dist/bootstrap/scss/_variables.scss)"),
       '#open' => TRUE,
     ];
 
@@ -163,7 +163,7 @@ class SettingsManager {
     $form['footer_details'] = [
       '#type' => 'details',
       '#title' => $this->t('Footer options'),
-      '#description' => $this->t("Combination of theme/background colour may affect background colour/text colour contrast. To fix any contrast issues, override corresponding variables in scss (refer to dist/boostrap/scss/_variables.scss)"),
+      '#description' => $this->t("Combination of theme/background colour may affect background colour/text colour contrast. To fix any contrast issues, override corresponding variables in scss (refer to dist/bootstrap/scss/_variables.scss)"),
       '#open' => TRUE,
     ];
 
@@ -190,13 +190,6 @@ class SettingsManager {
       '#open' => TRUE,
     ];
 
-    /*$form['text_formats']['b5_ckeditor_enable'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('CKEditor with bootstrap support'),
-      '#default_value' => theme_get_setting('b5_ckeditor_enable'),
-      '#description' => $this->t("Enable bootstrap support inside bootstrap editor. If enabled, containers, cards and other styles will be rendered inside CKEditor."),
-    ];*/
-
     $form['subtheme'] = [
       '#type' => 'details',
       '#title' => $this->t('Subtheme'),
diff --git a/src/SubthemeFormManager.php b/src/SubthemeFormManager.php
index 0bc20e5c..dfe208cb 100644
--- a/src/SubthemeFormManager.php
+++ b/src/SubthemeFormManager.php
@@ -2,7 +2,10 @@
 
 namespace Drupal\bootstrap5;
 
+use Drupal\Core\Extension\ThemeExtensionList;
+use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
 
 /**
  * Bootstrap5 subtheme form manager.
@@ -16,11 +19,25 @@ class SubthemeFormManager {
    */
   protected SubthemeManager $subthemeManager;
 
+  /**
+   * The theme extension list.
+   *
+   * @var \Drupal\Core\Extension\ThemeExtensionList
+   */
+  protected $themeExtensionList;
+
   /**
    * SubthemeFormManager constructor.
+   *
+   * @param \Drupal\Core\File\FileSystemInterface $file_system
+   *   The file system service.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger interface.
+   * @param \Drupal\Core\Extension\ThemeExtensionList $theme_extension_list
+   *   The theme extension list.
    */
-  public function __construct() {
-    $this->subthemeManager = new SubthemeManager(\Drupal::service('file_system'), \Drupal::service('messenger'));
+  public function __construct(FileSystemInterface $file_system, MessengerInterface $messenger, ThemeExtensionList $theme_extension_list) {
+    $this->subthemeManager = new SubthemeManager($file_system, $messenger, $theme_extension_list);
   }
 
   /**
diff --git a/src/SubthemeManager.php b/src/SubthemeManager.php
index 82f424f5..ad5e20b2 100644
--- a/src/SubthemeManager.php
+++ b/src/SubthemeManager.php
@@ -3,6 +3,7 @@
 namespace Drupal\bootstrap5;
 
 use Drupal\Component\Serialization\Yaml;
+use Drupal\Core\Extension\ThemeExtensionList;
 use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
@@ -28,6 +29,13 @@ class SubthemeManager {
    */
   protected $messenger;
 
+  /**
+   * The theme extension list.
+   *
+   * @var \Drupal\Core\Extension\ThemeExtensionList
+   */
+  protected $themeExtensionList;
+
   /**
    * SubthemeManager constructor.
    *
@@ -35,10 +43,13 @@ class SubthemeManager {
    *   The file system service.
    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
    *   The messenger.
+   * @param \Drupal\Core\Extension\ThemeExtensionList $them_extension_list
+   *   The theme extension list.
    */
-  public function __construct(FileSystemInterface $file_system, MessengerInterface $messenger) {
+  public function __construct(FileSystemInterface $file_system, MessengerInterface $messenger, ThemeExtensionList $them_extension_list) {
     $this->fileSystem = $file_system;
     $this->messenger = $messenger;
+    $this->themeExtensionList = $them_extension_list;
   }
 
   /**
@@ -110,7 +121,7 @@ class SubthemeManager {
       ];
     }
     // Validate machine name to ensure correct format.
-    if(!preg_match("/^[a-z]+[0-9a-z_]+$/", $subtheme_machine_name)) {
+    if (!preg_match("/^[a-z]+[0-9a-z_]+$/", $subtheme_machine_name)) {
       return [
         'subtheme_machine_name',
         $this->t('Subtheme machine name format is incorrect.'),
@@ -152,20 +163,20 @@ class SubthemeManager {
     $themePath = DRUPAL_ROOT . DIRECTORY_SEPARATOR . $subtheme_folder . DIRECTORY_SEPARATOR . $subtheme_machine_name;
     if (!is_dir($themePath)) {
       // Copy CSS file replace empty one.
-      $subforders = ['css'];
-      foreach ($subforders as $subforder) {
-        $directory = $themePath . DIRECTORY_SEPARATOR . $subforder . DIRECTORY_SEPARATOR;
+      $subfolders = ['css'];
+      foreach ($subfolders as $subfolder) {
+        $directory = $themePath . DIRECTORY_SEPARATOR . $subfolder . DIRECTORY_SEPARATOR;
         $fs->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
 
         $files = $fs->scanDirectory(
-          \Drupal::service('extension.list.theme')->getPath('bootstrap5') . DIRECTORY_SEPARATOR . $subforder . DIRECTORY_SEPARATOR, '/.*css/', [
+          $this->themeExtensionList->getPath('bootstrap5') . DIRECTORY_SEPARATOR . $subfolder . DIRECTORY_SEPARATOR, '/.*css/', [
             'recurse' => FALSE,
-        ]);
+          ]);
         foreach ($files as $file) {
           $fileName = $file->filename;
           $fs->copy(
-            \Drupal::service('extension.list.theme')->getPath('bootstrap5') . DIRECTORY_SEPARATOR . $subforder . DIRECTORY_SEPARATOR . $fileName,
-            $themePath . DIRECTORY_SEPARATOR . $subforder . DIRECTORY_SEPARATOR . $fileName, TRUE);
+            $this->themeExtensionList->getPath('bootstrap5') . DIRECTORY_SEPARATOR . $subfolder . DIRECTORY_SEPARATOR . $fileName,
+            $themePath . DIRECTORY_SEPARATOR . $subfolder . DIRECTORY_SEPARATOR . $fileName, TRUE);
         }
       }
 
@@ -176,7 +187,7 @@ class SubthemeManager {
         'screenshot.png',
       ];
       foreach ($files as $fileName) {
-        $fs->copy(\Drupal::service('extension.list.theme')->getPath('bootstrap5') . DIRECTORY_SEPARATOR . $fileName,
+        $fs->copy($this->themeExtensionList->getPath('bootstrap5') . DIRECTORY_SEPARATOR . $fileName,
           $themePath . DIRECTORY_SEPARATOR . $fileName, TRUE);
       }
 
@@ -195,7 +206,7 @@ class SubthemeManager {
           '',
           '/**',
           ' * @file',
-          ' * ' . $subtheme_name .' theme file.',
+          ' * ' . $subtheme_name . ' theme file.',
           ' */',
           '',
         ],
@@ -217,7 +228,7 @@ class SubthemeManager {
 
       foreach ($files as $fileName => $lines) {
         // Get file content.
-        $content = str_replace('bootstrap5', $subtheme_machine_name, file_get_contents(\Drupal::service('extension.list.theme')->getPath('bootstrap5') . DIRECTORY_SEPARATOR . $fileName));
+        $content = str_replace('bootstrap5', $subtheme_machine_name, file_get_contents($this->themeExtensionList->getPath('bootstrap5') . DIRECTORY_SEPARATOR . $fileName));
         if (is_array($lines)) {
           $content = implode(PHP_EOL, $lines);
         }
@@ -226,7 +237,7 @@ class SubthemeManager {
       }
 
       // Info yml file generation.
-      $infoYml = Yaml::decode(file_get_contents(\Drupal::service('extension.list.theme')->getPath('bootstrap5') . DIRECTORY_SEPARATOR . 'bootstrap5.info.yml'));
+      $infoYml = Yaml::decode(file_get_contents($this->themeExtensionList->getPath('bootstrap5') . DIRECTORY_SEPARATOR . 'bootstrap5.info.yml'));
       $infoYml['name'] = $subtheme_name;
       $infoYml['description'] = $subtheme_name . ' subtheme based on Bootstrap 5 theme.';
       $infoYml['base theme'] = 'bootstrap5';
@@ -234,7 +245,7 @@ class SubthemeManager {
       $infoYml['libraries'] = [];
       $infoYml['libraries'][] = $subtheme_machine_name . '/global-styling';
       $infoYml['libraries-override'] = [
-        'bootstrap5/global-styling' => false,
+        'bootstrap5/global-styling' => FALSE,
       ];
 
       foreach ([
@@ -255,7 +266,7 @@ class SubthemeManager {
 
       // SCSS files generation.
       $scssPath = $themePath . DIRECTORY_SEPARATOR . 'scss';
-      $b5ScssPath = \Drupal::service('extension.list.theme')->getPath('bootstrap5') . DIRECTORY_SEPARATOR . 'scss' . DIRECTORY_SEPARATOR;
+      $b5ScssPath = $this->themeExtensionList->getPath('bootstrap5') . DIRECTORY_SEPARATOR . 'scss' . DIRECTORY_SEPARATOR;
       $fs->prepareDirectory($scssPath, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
 
       $files = [
@@ -263,14 +274,14 @@ class SubthemeManager {
           "// Sub theme styling.",
           "@import 'variables_drupal';",
           '',
-          "// Bootstrap overriden variables.",
+          "// Bootstrap overridden variables.",
           "// @see https://getbootstrap.com/docs/5.2/customize/sass/#variable-defaults.",
           "@import 'variables_bootstrap';",
           '',
           "// Include bootstrap.",
           "@import '" .
           str_repeat('../', count(explode(DIRECTORY_SEPARATOR, $subtheme_folder)) + 2) .
-          \Drupal::service('extension.list.theme')->getPath('bootstrap5') . "/scss/style';",
+          $this->themeExtensionList->getPath('bootstrap5') . "/scss/style';",
           '',
         ],
         'ck5style.scss' => $b5ScssPath . 'ck5style.scss',
@@ -290,7 +301,7 @@ class SubthemeManager {
       }
 
       // Add block config to subtheme.
-      $orig_config_path = \Drupal::service('extension.list.theme')->getPath('bootstrap5') . DIRECTORY_SEPARATOR . 'config/optional';
+      $orig_config_path = $this->themeExtensionList->getPath('bootstrap5') . DIRECTORY_SEPARATOR . 'config/optional';
       $config_path = $themePath . DIRECTORY_SEPARATOR . 'config/optional';
       $files = scandir($orig_config_path);
       $fs->prepareDirectory($config_path, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
@@ -308,7 +319,7 @@ class SubthemeManager {
       }
 
       // Add install config to subtheme.
-      $orig_config_path = \Drupal::service('extension.list.theme')->getPath('bootstrap5') . DIRECTORY_SEPARATOR . 'config/install';
+      $orig_config_path = $this->themeExtensionList->getPath('bootstrap5') . DIRECTORY_SEPARATOR . 'config/install';
       $config_path = $themePath . DIRECTORY_SEPARATOR . 'config/install';
       $files = scandir($orig_config_path);
       $fs->prepareDirectory($config_path, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
-- 
GitLab