3 namespace Drupal\bootstrap\Plugin\Alter;
5 use Drupal\bootstrap\Bootstrap;
6 use Drupal\bootstrap\Plugin\PluginBase;
7 use Drupal\Component\Utility\NestedArray;
10 * Implements hook_library_info_alter().
12 * @ingroup plugins_alter
14 * @BootstrapAlter("library_info")
16 class LibraryInfo extends PluginBase implements AlterInterface {
21 public function alter(&$libraries, &$extension = NULL, &$context2 = NULL) {
22 $livereload = $this->theme->livereloadUrl();
24 // Disable preprocess on all CSS/JS if "livereload" is enabled.
26 $this->processLibrary($libraries, function (&$info, &$key, $type) {
27 if ($type === 'css' || $type === 'js') {
28 $info['preprocess'] = FALSE;
33 if ($extension === 'bootstrap') {
34 // Alter the "livereload.js" placeholder with the correct URL.
36 $libraries['livereload']['js'][$livereload] = $libraries['livereload']['js']['livereload.js'];
37 unset($libraries['livereload']['js']['livereload.js']);
40 // Retrieve the theme's CDN provider and assets.
41 $provider = $this->theme->getProvider();
42 $assets = $provider ? $provider->getAssets() : [];
44 // Immediately return if there is no provider or assets.
45 if (!$provider || !$assets) {
49 // Merge the assets into the library info.
50 $libraries['framework'] = NestedArray::mergeDeepArray([$assets, $libraries['framework']], TRUE);
52 // Add a specific version and theme CSS overrides file.
53 // @todo This should be retrieved by the Provider API.
54 $version = $this->theme->getSetting('cdn_' . $provider->getPluginId() . '_version') ?: Bootstrap::FRAMEWORK_VERSION;
55 $libraries['framework']['version'] = $version;
56 $provider_theme = $this->theme->getSetting('cdn_' . $provider->getPluginId() . '_theme') ?: 'bootstrap';
57 $provider_theme = $provider_theme === 'bootstrap' || $provider_theme === 'bootstrap_theme' ? '' : "-$provider_theme";
59 foreach ($this->theme->getAncestry(TRUE) as $ancestor) {
60 $overrides = $ancestor->getPath() . "/css/$version/overrides$provider_theme.min.css";
61 if (file_exists($overrides)) {
62 // Since this uses a relative path to the ancestor from DRUPAL_ROOT,
63 // we must prepend the entire path with forward slash (/) so it
64 // doesn't prepend the active theme's path.
65 $overrides = "/$overrides";
67 // The overrides file must also be stored in the "base" category so
68 // it isn't added after any potential sub-theme's "theme" category.
69 // There's no weight, so it will be added after the provider's assets.
70 // @see https://www.drupal.org/node/2770613
71 $libraries['framework']['css']['base'][$overrides] = [];
77 elseif ($extension === 'core') {
78 // Replace core dialog/jQuery UI implementations with Bootstrap Modals.
79 if ($this->theme->getSetting('modal_enabled')) {
80 // Replace dependencies if using bridge so jQuery UI is not loaded
81 // and remove dialog.jquery-ui.js since the dialog widget isn't loaded.
82 if ($this->theme->getSetting('modal_jquery_ui_bridge')) {
83 // Remove core's jquery.ui.dialog dependency.
84 $key = array_search('core/jquery.ui.dialog', $libraries['drupal.dialog']['dependencies']);
86 unset($libraries['drupal.dialog']['dependencies'][$key]);
89 // Remove core's dialog.jquery-ui.js.
90 unset($libraries['drupal.dialog']['js']['misc/dialog/dialog.jquery-ui.js']);
92 // Add the Modal jQuery UI Bridge.
93 $libraries['drupal.dialog']['dependencies'][] = 'bootstrap/modal.jquery.ui.bridge';
95 // Otherwise, just append the modal.
97 $libraries['drupal.dialog']['dependencies'][] = 'bootstrap/modal';
104 * Processes library definitions.
106 * @param array $libraries
107 * The libraries array, passed by reference.
108 * @param callable $callback
109 * The callback to perform processing on the library.
111 public function processLibrary(array &$libraries, callable $callback) {
112 foreach ($libraries as &$library) {
113 foreach ($library as $type => $definition) {
114 if (is_array($definition)) {
116 // CSS needs special handling since it contains grouping.
117 if ($type === 'css') {
118 foreach ($definition as $group => $files) {
119 foreach ($files as $key => $info) {
120 call_user_func_array($callback, [&$info, &$key, $type]);
121 $modified[$group][$key] = $info;
126 foreach ($definition as $key => $info) {
127 call_user_func_array($callback, [&$info, &$key, $type]);
128 $modified[$key] = $info;
131 $library[$type] = $modified;