diff --git a/composer.lock b/composer.lock index 52bbed877f75930e2c73f1bf940227249b6bf33b..66975e971c495db4ae061953d7a6e77d6c701c06 100644 --- a/composer.lock +++ b/composer.lock @@ -2285,26 +2285,26 @@ }, { "name": "drupal/bootstrap", - "version": "3.23.0", + "version": "3.25.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/bootstrap.git", - "reference": "8.x-3.23" + "reference": "8.x-3.25" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/bootstrap-8.x-3.23.zip", - "reference": "8.x-3.23", - "shasum": "9849be667cc678a91ad29f77c2baea2cf16878bc" + "url": "https://ftp.drupal.org/files/projects/bootstrap-8.x-3.25.zip", + "reference": "8.x-3.25", + "shasum": "1334aad091973f53ddc4d7b426ee85e7428a3684" }, "require": { - "drupal/core": "^8 || ^9" + "drupal/core": "^9.3 || ^10" }, "type": "drupal-theme", "extra": { "drupal": { - "version": "8.x-3.23", - "datestamp": "1592175762", + "version": "8.x-3.25", + "datestamp": "1654873483", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2330,6 +2330,11 @@ "name": "Fabiano Sant'Ana (wundo)", "homepage": "https://www.drupal.org/u/wundo", "role": "Co-maintainer" + }, + { + "name": "Shelane French (shelane)", + "homepage": "https://www.drupal.org/u/shelane", + "role": "Co-maintainer" } ], "description": "Built to use Bootstrap, a sleek, intuitive, and powerful front-end framework for faster and easier web development.", diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 8b1b270136c1ebec852c0480c7d18c3d3ba149fe..c3dc8aaa1d3b6a31b4030ff34ba3f72bc8d51ac1 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2355,27 +2355,27 @@ }, { "name": "drupal/bootstrap", - "version": "3.23.0", - "version_normalized": "3.23.0.0", + "version": "3.25.0", + "version_normalized": "3.25.0.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/bootstrap.git", - "reference": "8.x-3.23" + "reference": "8.x-3.25" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/bootstrap-8.x-3.23.zip", - "reference": "8.x-3.23", - "shasum": "9849be667cc678a91ad29f77c2baea2cf16878bc" + "url": "https://ftp.drupal.org/files/projects/bootstrap-8.x-3.25.zip", + "reference": "8.x-3.25", + "shasum": "1334aad091973f53ddc4d7b426ee85e7428a3684" }, "require": { - "drupal/core": "^8 || ^9" + "drupal/core": "^9.3 || ^10" }, "type": "drupal-theme", "extra": { "drupal": { - "version": "8.x-3.23", - "datestamp": "1592175762", + "version": "8.x-3.25", + "datestamp": "1654873483", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2402,6 +2402,11 @@ "name": "Fabiano Sant'Ana (wundo)", "homepage": "https://www.drupal.org/u/wundo", "role": "Co-maintainer" + }, + { + "name": "Shelane French (shelane)", + "homepage": "https://www.drupal.org/u/shelane", + "role": "Co-maintainer" } ], "description": "Built to use Bootstrap, a sleek, intuitive, and powerful front-end framework for faster and easier web development.", diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 39935a758fb11e52f335ffa0788f0f6934536af9..730a24da30aec25de72b22641c5af9fd67635174 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'osu-asc-webservices/d8-upstream', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '94cc3b822d657cc885a015bf9c535fc1673b5084', + 'reference' => 'f81c67fdbbb087e73b37cf6229e1b5f65363f729', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -368,9 +368,9 @@ 'dev_requirement' => false, ), 'drupal/bootstrap' => array( - 'pretty_version' => '3.23.0', - 'version' => '3.23.0.0', - 'reference' => '8.x-3.23', + 'pretty_version' => '3.25.0', + 'version' => '3.25.0.0', + 'reference' => '8.x-3.25', 'type' => 'drupal-theme', 'install_path' => __DIR__ . '/../../web/themes/bootstrap', 'aliases' => array(), @@ -1594,7 +1594,7 @@ 'osu-asc-webservices/d8-upstream' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '94cc3b822d657cc885a015bf9c535fc1673b5084', + 'reference' => 'f81c67fdbbb087e73b37cf6229e1b5f65363f729', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/web/themes/bootstrap/bootstrap.info.yml b/web/themes/bootstrap/bootstrap.info.yml index 3e73fc7b52508e21dac4cd70d71ba897f9551c78..e694d2052221cbe36e3597c5bca5ae3caf033e45 100644 --- a/web/themes/bootstrap/bootstrap.info.yml +++ b/web/themes/bootstrap/bootstrap.info.yml @@ -1,7 +1,6 @@ type: theme base theme: false -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9.3 || ^10 name: 'Bootstrap' description: 'Built to use Bootstrap, a sleek, intuitive, and powerful front-end framework for faster and easier web development.' @@ -78,7 +77,7 @@ libraries-override: theme: css/node.preview.css: false -# Information added by Drupal.org packaging script on 2020-06-14 -version: '8.x-3.23' +# Information added by Drupal.org packaging script on 2022-06-10 +version: '8.x-3.25' project: 'bootstrap' -datestamp: 1592175698 +datestamp: 1654873487 diff --git a/web/themes/bootstrap/bootstrap.libraries.yml b/web/themes/bootstrap/bootstrap.libraries.yml index bb5440eb263ffc57a5223d3838f18965ea83ead1..6759f1c3814ae603fc101b255325e40bc5f41cbc 100644 --- a/web/themes/bootstrap/bootstrap.libraries.yml +++ b/web/themes/bootstrap/bootstrap.libraries.yml @@ -49,7 +49,7 @@ theme-settings: js/theme-settings.js: {} dependencies: - core/jquery - - core/jquery.once + - core/once - core/drupal - core/drupalSettings @@ -101,6 +101,8 @@ drupal.autocomplete: drupal.dialog.ajax: js: js/misc/dialog.ajax.js: {} + dependencies: + - bootstrap/drupal.bootstrap drupal.form: js: @@ -144,7 +146,7 @@ drupal.batch: - bootstrap/theme - core/drupal.ajax - core/drupal.progress - - core/jquery.once + - core/once drupal.filter: version: VERSION @@ -153,14 +155,14 @@ drupal.filter: dependencies: - core/jquery - core/drupal - - core/jquery.once + - core/once drupal.text: js: js/text/text.js: {} dependencies: - core/jquery - - core/jquery.once + - core/once - core/drupal drupal.vertical-tabs: @@ -168,5 +170,5 @@ drupal.vertical-tabs: js/misc/vertical-tabs.js: {} dependencies: - bootstrap/theme - - core/jquery.once + - core/once - core/drupal.form diff --git a/web/themes/bootstrap/composer.json b/web/themes/bootstrap/composer.json index a343af92320ecc320637374f1d7c0c047a269357..e7f08a2267d9fbdb95900d48174da3b8ffb2871c 100644 --- a/web/themes/bootstrap/composer.json +++ b/web/themes/bootstrap/composer.json @@ -19,7 +19,12 @@ "name": "Fabiano Sant'Ana (wundo)", "homepage": "https://www.drupal.org/u/wundo", "role": "Co-maintainer" - } + }, + { + "name": "Shelane French (shelane)", + "homepage": "https://www.drupal.org/u/shelane", + "role": "Co-maintainer" + } ], "support": { "docs": "https://drupal-bootstrap.org", @@ -28,6 +33,6 @@ "source": "https://git.drupalcode.org/project/bootstrap" }, "require": { - "drupal/core": "^8 || ^9" + "drupal/core": "^9.3 || ^10" } } diff --git a/web/themes/bootstrap/docs/Sub-Theming.md b/web/themes/bootstrap/docs/Sub-Theming.md index ddf2185aa85cc5c39399da3b186b38f03dad72e4..bb38079f2930e2dcd0d2276e193c912fac6da1a6 100644 --- a/web/themes/bootstrap/docs/Sub-Theming.md +++ b/web/themes/bootstrap/docs/Sub-Theming.md @@ -25,8 +25,9 @@ you've done that, you can override CSS, templates, and theme processing. ## Using the Starterkit {#starterkit} The starterkit provided by this base-theme supplies the basic file structure on -how to construct a proper Bootstrap based sub-theme for use with a [CDN Provider] -(like [jsDelivr]) or for use with compiling [Bootstrap Framework] source files. +how to construct a proper Bootstrap based sub-theme for use with a [CDN +Provider] (like [jsDelivr]) or for use with compiling [Bootstrap Framework] +source files. {.alert.alert-info} **NOTE:** Using a [CDN Provider] is the preferred method for loading the [Bootstrap Framework] CSS and JS on simpler sites that do not @@ -56,15 +57,16 @@ will be superseded by any enabled [CDN Provider]; **do not use both**. to suite your needs. Make sure to rename the library extension name as well: `THEMENAME/framework`. 3. Rename `./themes/THEMENAME/THEMENAME.libraries.yml`. - * (Optional) If you plan on using a local precompiler (i.e. [Less] or [Sass]) - then uncomment the appropriate JavaScript entries inside this file to - enable the assets provided by the [Bootstrap Framework]. + * (Optional) If you plan on using a local precompiler (i.e., [Less] or + [Sass]) then uncomment the appropriate JavaScript entries inside this file + to enable the assets provided by the [Bootstrap Framework]. 4. Rename `./themes/THEMENAME/THEMENAME.theme`. 5. Rename `./themes/THEMENAME/config/schema/THEMENAME.schema.yml` - * Open this file and rename `- THEMENAME.settings:` and `'THEMETITLE settings'` + * Open this file and rename `- THEMENAME.settings:` and `'THEMETITLE + settings'` 6. Rename `./themes/THEMENAME/config/install/THEMENAME.settings.yml` - * (Optional) If you plan on using a local precompiler (i.e. [Less] or [Sass]) - then you will need to disable the `cdn_provider` + * (Optional) If you plan on using a local precompiler (i.e., [Less] or + [Sass]) then you will need to disable the `cdn_provider` [`cdn_provider` theme setting](<!-- @url theme_settings#cdn_provider -->). You can do this several different ways, but it's recommended that you uncomment the following line in this file so the [CDN Provider] is @@ -94,16 +96,16 @@ developer, to figure out which solution is best for your particular needs. ### LESS {#less} - You must understand the basic concept of using the [Less] CSS pre-processor. - You must use a **[local Less compiler](https://www.google.com/search?q=less+compiler)**. -- You must use the latest `3.x.x` version of [Bootstrap Framework LESS Source Files] - ending in the `.less` extension, not files ending in `.css`. +- You must use the latest `3.x.x` version of [Bootstrap Framework LESS Source +Files] ending in the `.less` extension, not files ending in `.css`. - You must download a copy of [Drupal Bootstrap Styles] and copy over the `less` folder located at `./drupal-bootstrap-styles/src/3.x.x/8.x-3.x/less`. ### SASS {#sass} - You must understand the basic concept of using the [Sass] CSS pre-processor. - You must use a **[local Sass compiler](https://www.google.com/search?q=sass+compiler)**. -- You must use the latest `3.x.x` version of [Bootstrap Framework SASS Source Files] - ending in the `.scss` extension, not files ending in `.css`. +- You must use the latest `3.x.x` version of [Bootstrap Framework SASS Source +Files] ending in the `.scss` extension, not files ending in `.css`. - You must download a copy of [Drupal Bootstrap Styles] and copy over the `scss` folder located at `./drupal-bootstrap-styles/src/3.x.x/8.x-3.x/scss`. @@ -140,12 +142,12 @@ set default` link next to your newly created sub-theme. Now that you've enabled your starterkit, please refer to the starterkit's documentation page to customize. -[Drupal Bootstrap]: https://www.drupal.org/project/bootstrap -[Drupal Bootstrap Styles]: https://github.com/unicorn-fail/drupal-bootstrap-styles -[Bootstrap Framework]: https://getbootstrap.com/docs/3.4/ -[Bootstrap Framework LESS Source Files]: https://github.com/twbs/bootstrap/releases -[Bootstrap Framework SASS Source Files]: https://github.com/twbs/bootstrap-sass -[jsDelivr]: http://www.jsdelivr.com -[Less]: http://lesscss.org -[Sass]: http://sass-lang.com -[CDN Provider]: <!-- @url plugins_provider --> +[Drupal Bootstrap](https://www.drupal.org/project/bootstrap) +[Drupal Bootstrap Styles](https://github.com/unicorn-fail/drupal-bootstrap-styles) +[Bootstrap Framework](https://getbootstrap.com/docs/3.4/) +[Bootstrap Framework LESS Source Files](https://github.com/twbs/bootstrap/releases) +[Bootstrap Framework SASS Source Files](https://github.com/twbs/bootstrap-sass) +[jsDelivr](http://www.jsdelivr.com) +[Less](http://lesscss.org) +[Sass](http://sass-lang.com) +[CDN Provider](<!-- @url plugins_provider -->) diff --git a/web/themes/bootstrap/js/misc/dialog.ajax.js b/web/themes/bootstrap/js/misc/dialog.ajax.js index c0fceed28e6ab1e17ede972dcfbde155ebd1fbe7..d4045aed611f6475765c1057375a13c8717d7f41 100644 --- a/web/themes/bootstrap/js/misc/dialog.ajax.js +++ b/web/themes/bootstrap/js/misc/dialog.ajax.js @@ -44,7 +44,7 @@ */ Drupal.behaviors.dialog.ajaxUpdateButtons = function (reset) { if (this.ajaxCurrentButton && this.ajaxOriginalButton) { - this.ajaxCurrentButton.html(this.ajaxOriginalButton.html()); + this.ajaxCurrentButton.html(this.ajaxOriginalButton.html() || this.ajaxOriginalButton.attr('value')); this.ajaxCurrentButton.prop('disabled', this.ajaxOriginalButton.prop('disabled')); } if (reset) { @@ -89,7 +89,7 @@ // Strip all HTML from the actual text value. This value is escaped. // It actual HTML value will be synced with the original button's HTML // below in the "create" method. - text: Bootstrap.stripHtml($originalButton), + text: Bootstrap.stripHtml($originalButton) || $originalButton.attr('value'), class: $originalButton.attr('class').replace('use-ajax-submit', ''), click: function click(e) { e.preventDefault(); diff --git a/web/themes/bootstrap/js/misc/tabledrag.js b/web/themes/bootstrap/js/misc/tabledrag.js index ac41c8f6bd1b9e80f67334a266acc1512e668bb7..c2e36e38563236ca245c03aab6e6ca07567d9b2d 100644 --- a/web/themes/bootstrap/js/misc/tabledrag.js +++ b/web/themes/bootstrap/js/misc/tabledrag.js @@ -121,6 +121,11 @@ */ this.windowHeight = 0; + /** + * @type {?HTMLElement} + */ + this.$toggleWeightButton = null; + /** * Check this table's settings to see if there are parent relationships in * this table. For efficiency, large sections of code can be skipped if we @@ -173,21 +178,24 @@ $table.find('> tr.draggable, > tbody > tr.draggable').each(function () { self.makeDraggable(this); }); // Add a link before the table for users to show or hide weight columns. - var $button = $(Drupal.theme('btn-sm', { + self.$toggleWeightButton = $(Drupal.theme('btn-sm', { 'class': ['tabledrag-toggle-weight'], + 'data-drupal-selector': ['tabledrag-toggle-weight'], title: Drupal.t('Re-order rows by numerical weight instead of dragging.'), 'data-toggle': 'tooltip' })); - $button + self.$toggleWeightButton = $('[data-drupal-selector="tabledrag-toggle-weight"]'); + + self.$toggleWeightButton .on('click', $.proxy(function (e) { e.preventDefault(); this.toggleColumns(); }, this)) .wrap('<div class="tabledrag-toggle-weight-wrapper"></div>') - .parent() - ; - $table.before($button); + .parent(); + + $table.before(self.$toggleWeightButton); // Initialize the specified columns (for example, weight or parent columns) // to show or hide according to user preference. This aids accessibility diff --git a/web/themes/bootstrap/scripts/bootstrap.php b/web/themes/bootstrap/scripts/bootstrap.php index fe98786afb255fe01a00421131122cfa1b25cc31..c5c99384442fc97b03bb6e7bbeca82ec08823934 100644 --- a/web/themes/bootstrap/scripts/bootstrap.php +++ b/web/themes/bootstrap/scripts/bootstrap.php @@ -13,11 +13,14 @@ return \Drupal::service('kernel'); } +/** + * + */ function _find_autoloader($dir) { if (file_exists($autoloadFile = $dir . '/autoload.php') || file_exists($autoloadFile = $dir . '/vendor/autoload.php')) { - return include_once($autoloadFile); + return include_once $autoloadFile; } - else if (empty($dir) || $dir === DIRECTORY_SEPARATOR) { + elseif (empty($dir) || $dir === DIRECTORY_SEPARATOR) { return FALSE; } return _find_autoloader(dirname($dir)); diff --git a/web/themes/bootstrap/src/Bootstrap.php b/web/themes/bootstrap/src/Bootstrap.php index 7c683e31549f1e920bf76e5165c18f36d0f485d3..769773520c104148259e1c75f327726e21dd20c5 100644 --- a/web/themes/bootstrap/src/Bootstrap.php +++ b/web/themes/bootstrap/src/Bootstrap.php @@ -105,7 +105,7 @@ class Bootstrap { * * @todo Enable constant once PHP 5.5 is no longer supported. */ -// const PROJECT_API_SEARCH_URL = self::PROJECT_DOCUMENTATION . '/api/bootstrap/' . self::PROJECT_BRANCH . '/search/@query'; + // Const PROJECT_API_SEARCH_URL = self::PROJECT_DOCUMENTATION . '/api/bootstrap/' . self::PROJECT_BRANCH . '/search/@query';. /** * The Drupal Bootstrap project page. @@ -234,13 +234,13 @@ public static function alter($function, &$data, &$context1 = NULL, &$context2 = $drupal_static_fast['form_managers'] = &drupal_static(__METHOD__ . '__formManagers', []); } - /* @var \Drupal\bootstrap\Plugin\AlterManager[] $alter_managers */ + /** @var \Drupal\bootstrap\Plugin\AlterManager[] $alter_managers */ $alter_managers = &$drupal_static_fast['alter_managers']; if (!isset($alter_managers[$theme_name])) { $alter_managers[$theme_name] = new AlterManager($theme); } - /* @var \Drupal\bootstrap\Plugin\FormManager[] $form_managers */ + /** @var \Drupal\bootstrap\Plugin\FormManager[] $form_managers */ $form_managers = &$drupal_static_fast['form_managers']; if (!isset($form_managers[$theme_name])) { $form_managers[$theme_name] = new FormManager($theme); @@ -548,7 +548,7 @@ public static function cssClassFromString(&$value, $default = '') { break; case 'contains': - if (strpos(Unicode::strtolower($string), Unicode::strtolower($text)) !== FALSE) { + if (strpos(mb_strtolower($string), mb_strtolower($text)) !== FALSE) { return $class; } break; @@ -602,7 +602,7 @@ public static function deprecated($caller = NULL, $show_message = NULL, Translat } if ($show_message || (!isset($show_message) && static::isAdmin() && !static::getTheme()->getSetting('suppress_deprecated_warnings', FALSE))) { - static::message($message, 'warning'); + \Drupal::messenger()->addMessage($message, 'warning'); } // Log message and accompanying backtrace. @@ -900,7 +900,7 @@ public static function glyphiconFromString(&$value, array $default = []) { break; case 'contains': - if (strpos(Unicode::strtolower($string), Unicode::strtolower($text)) !== FALSE) { + if (strpos(mb_strtolower($string), mb_strtolower($text)) !== FALSE) { return self::glyphicon($icon, $default); } break; @@ -1336,7 +1336,7 @@ public static function isFront() { * supported: * - 'status' * - 'warning' - * - 'error' + * - 'error'. * @param bool $repeat * (optional) If this is FALSE and the message is already set, then the * message won't be repeated. Defaults to FALSE. @@ -1383,7 +1383,7 @@ public static function preprocess(array &$variables, $hook, array $info) { $drupal_static_fast['theme_info'] = &drupal_static(__METHOD__ . '__themeInfo', []); } - /* @var \Drupal\bootstrap\Plugin\PreprocessManager[] $preprocess_managers */ + /** @var \Drupal\bootstrap\Plugin\PreprocessManager[] $preprocess_managers */ $preprocess_managers = &$drupal_static_fast['preprocess_managers']; if (!isset($preprocess_managers[$theme_name])) { $preprocess_managers[$theme_name] = new PreprocessManager($theme); diff --git a/web/themes/bootstrap/src/Plugin/Alter/ThemeRegistry.php b/web/themes/bootstrap/src/Plugin/Alter/ThemeRegistry.php index 36f64b50f4ce90657a85e45b088e7b70c0dde36b..9961519e59c6969b14ec6211c62abe807260e7d5 100644 --- a/web/themes/bootstrap/src/Plugin/Alter/ThemeRegistry.php +++ b/web/themes/bootstrap/src/Plugin/Alter/ThemeRegistry.php @@ -42,7 +42,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition } $this->currentTheme = $configuration['theme']; parent::__construct( - \Drupal::service('app.root'), + \Drupal::root(), \Drupal::service('cache.default'), \Drupal::service('lock'), \Drupal::service('module_handler'), diff --git a/web/themes/bootstrap/src/Plugin/Alter/ThemeSuggestions.php b/web/themes/bootstrap/src/Plugin/Alter/ThemeSuggestions.php index db96e669956e99f7b4c84d442271dd9c3801aee4..50983cc983c8eb3c83fcf765caf013fefa3add19 100644 --- a/web/themes/bootstrap/src/Plugin/Alter/ThemeSuggestions.php +++ b/web/themes/bootstrap/src/Plugin/Alter/ThemeSuggestions.php @@ -4,7 +4,6 @@ use Drupal\bootstrap\Bootstrap; use Drupal\bootstrap\Plugin\PluginBase; -use Drupal\bootstrap\Utility\Unicode; use Drupal\bootstrap\Utility\Variables; use Drupal\Core\Entity\EntityInterface; diff --git a/web/themes/bootstrap/src/Plugin/Preprocess/BootstrapDropdown.php b/web/themes/bootstrap/src/Plugin/Preprocess/BootstrapDropdown.php index 532f348c28797e21eaa3e34c5a25ddbfdf50f2e8..cba2d20839aaacabd69e9b7ca48f761cffacf1f7 100644 --- a/web/themes/bootstrap/src/Plugin/Preprocess/BootstrapDropdown.php +++ b/web/themes/bootstrap/src/Plugin/Preprocess/BootstrapDropdown.php @@ -4,7 +4,6 @@ use Drupal\bootstrap\Utility\Crypt; use Drupal\bootstrap\Utility\Element; -use Drupal\bootstrap\Utility\Unicode; use Drupal\bootstrap\Utility\Variables; use Drupal\Component\Utility\Html; use Drupal\Component\Utility\NestedArray; @@ -50,8 +49,8 @@ protected function preprocessVariables(Variables $variables) { */ protected function preprocessLinks(Variables $variables) { // Convert "dropbutton" theme suggestion variables. - if (Unicode::strpos($variables->theme_hook_original, 'links__dropbutton') !== FALSE && !empty($variables->links)) { - $operations = !!Unicode::strpos($variables->theme_hook_original, 'operations'); + if (mb_strpos($variables->theme_hook_original, 'links__dropbutton') !== FALSE && !empty($variables->links)) { + $operations = !!mb_strpos($variables->theme_hook_original, 'operations'); // Normal dropbutton links are not actually render arrays, convert them. foreach ($variables->links as &$element) { diff --git a/web/themes/bootstrap/src/Plugin/Preprocess/Breadcrumb.php b/web/themes/bootstrap/src/Plugin/Preprocess/Breadcrumb.php index bb4008077488158bd90ede474ae8d0e55e4ce006..511714f4388c27185f0d9a2f2b9a91e0bd58b640 100644 --- a/web/themes/bootstrap/src/Plugin/Preprocess/Breadcrumb.php +++ b/web/themes/bootstrap/src/Plugin/Preprocess/Breadcrumb.php @@ -52,7 +52,7 @@ public function preprocessVariables(Variables $variables) { } // Add cache context based on url. - $variables->addCacheContexts(['url']); + $variables->addCacheContexts(['route', 'url.path', 'languages']); } } diff --git a/web/themes/bootstrap/src/Plugin/Preprocess/FileLink.php b/web/themes/bootstrap/src/Plugin/Preprocess/FileLink.php index df0ba6e7627e79f61e38ea3b88b73b5f8e62720c..62af1fc8339b25834a9f7ad1f96e062bb7c5a792 100644 --- a/web/themes/bootstrap/src/Plugin/Preprocess/FileLink.php +++ b/web/themes/bootstrap/src/Plugin/Preprocess/FileLink.php @@ -27,7 +27,7 @@ public function preprocessVariables(Variables $variables) { $options = []; $file = ($variables['file'] instanceof File) ? $variables['file'] : File::load($variables['file']->fid); - $url = file_create_url($file->getFileUri()); + $url = \Drupal::service('file_url_generator')->generateAbsoluteString($file->getFileUri()); $file_size = $file->getSize(); $mime_type = $file->getMimeType(); diff --git a/web/themes/bootstrap/src/Plugin/Preprocess/ForumList.php b/web/themes/bootstrap/src/Plugin/Preprocess/ForumList.php new file mode 100644 index 0000000000000000000000000000000000000000..0c9f172013fa30e1c4a9efae7b0b6e3aa942a9f4 --- /dev/null +++ b/web/themes/bootstrap/src/Plugin/Preprocess/ForumList.php @@ -0,0 +1,12 @@ +<?php + +namespace Drupal\bootstrap\Plugin\Preprocess; + +/** + * Pre-processes variables for the "forum_list" theme hook. + * + * @ingroup plugins_preprocess + * + * @BootstrapPreprocess("forum_list") + */ +class ForumList extends Table {} diff --git a/web/themes/bootstrap/src/Plugin/Preprocess/Menu.php b/web/themes/bootstrap/src/Plugin/Preprocess/Menu.php index f51b027a34ea7886593ec12eeec0859990692879..877d60ff35b46059b2b2fd0ee26d51216468914e 100644 --- a/web/themes/bootstrap/src/Plugin/Preprocess/Menu.php +++ b/web/themes/bootstrap/src/Plugin/Preprocess/Menu.php @@ -40,7 +40,7 @@ protected function convertAttributes(array &$items) { $wrapperAttributes->setAttributes($item['url']->getOption('wrapper_attributes') ?: []); $wrapperAttributes->setAttributes($item['url']->getOption('container_attributes') ?: []); $linkAttributes->setAttributes($item['url']->getOption('attributes') ?: []); - + // If URL isn't a link, it's rendered as a <span> element. Add the // "navbar-text" class so it doesn't disrupt the navbar items. // @see https://www.drupal.org/project/bootstrap/issues/3053464 @@ -54,7 +54,7 @@ protected function convertAttributes(array &$items) { // around this, just rewrap attributes in core's native Attribute class. $item['attributes'] = new Attribute($wrapperAttributes->getArrayCopy()); $item['link_attributes'] = new Attribute($linkAttributes->getArrayCopy()); - if ($item['below']) { + if (!empty($item['below']) && is_array($item['below'])) { $this->convertAttributes($item['below']); } } diff --git a/web/themes/bootstrap/src/Plugin/Prerender/PrerenderBase.php b/web/themes/bootstrap/src/Plugin/Prerender/PrerenderBase.php index 1e368ac533f706c5e592056b649467144812a044..4299047d04bd7260bd1ace2564ef1865fa0c2294 100644 --- a/web/themes/bootstrap/src/Plugin/Prerender/PrerenderBase.php +++ b/web/themes/bootstrap/src/Plugin/Prerender/PrerenderBase.php @@ -2,7 +2,7 @@ namespace Drupal\bootstrap\Plugin\Prerender; -use Drupal\bootstrap\BcSupport\TrustedCallbackInterface; +use Drupal\Core\Security\TrustedCallbackInterface; use Drupal\bootstrap\Utility\Element; /** diff --git a/web/themes/bootstrap/src/Plugin/PrerenderManager.php b/web/themes/bootstrap/src/Plugin/PrerenderManager.php index f453d71205a2d7129a1a54f5f8b7e48776695f6e..890b0f9f86fb028ece33cc5cd8773201eef07489 100644 --- a/web/themes/bootstrap/src/Plugin/PrerenderManager.php +++ b/web/themes/bootstrap/src/Plugin/PrerenderManager.php @@ -2,7 +2,7 @@ namespace Drupal\bootstrap\Plugin; -use Drupal\bootstrap\BcSupport\TrustedCallbackInterface; +use Drupal\Core\Security\TrustedCallbackInterface; use Drupal\bootstrap\Theme; use Drupal\bootstrap\Utility\Element; diff --git a/web/themes/bootstrap/src/Plugin/Provider/Broken.php b/web/themes/bootstrap/src/Plugin/Provider/Broken.php index 6e22f0804b5496a4324cca84de48e05b7d07d105..833d5611d08c5094115e76759b0ac20c8c48e722 100644 --- a/web/themes/bootstrap/src/Plugin/Provider/Broken.php +++ b/web/themes/bootstrap/src/Plugin/Provider/Broken.php @@ -94,9 +94,7 @@ public function supportsVersions() { } /**************************************************************************** - * - * Deprecated methods - * + * Deprecated methods. ***************************************************************************/ /** diff --git a/web/themes/bootstrap/src/Plugin/Provider/ProviderBase.php b/web/themes/bootstrap/src/Plugin/Provider/ProviderBase.php index c9ca1041e7baa16486aa36bc231525491399de51..8c9425426aa5dd35f2f627699bf2f76bbf2058a8 100644 --- a/web/themes/bootstrap/src/Plugin/Provider/ProviderBase.php +++ b/web/themes/bootstrap/src/Plugin/Provider/ProviderBase.php @@ -586,9 +586,7 @@ public function trackCdnExceptions(callable $callable) { } /**************************************************************************** - * - * Deprecated methods - * + * Deprecated methods. ***************************************************************************/ /** diff --git a/web/themes/bootstrap/src/Plugin/Provider/ProviderInterface.php b/web/themes/bootstrap/src/Plugin/Provider/ProviderInterface.php index 10f52f08a158a7b34d189cd9fe152442336d1bcc..4a19861689674508537f3c08fd92375da27df39d 100644 --- a/web/themes/bootstrap/src/Plugin/Provider/ProviderInterface.php +++ b/web/themes/bootstrap/src/Plugin/Provider/ProviderInterface.php @@ -237,9 +237,7 @@ public function supportsVersions(); public function trackCdnExceptions(callable $callable); /**************************************************************************** - * - * Deprecated methods - * + * Deprecated methods. ***************************************************************************/ /** diff --git a/web/themes/bootstrap/src/Plugin/Setting/Advanced/Cdn/CdnProvider.php b/web/themes/bootstrap/src/Plugin/Setting/Advanced/Cdn/CdnProvider.php index 7d0d213c87abc9e64cd87be5ab2be3761ecd4ac8..5ad58bb711d4f7e846ecb6f56ec594b763c1ea69 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/Advanced/Cdn/CdnProvider.php +++ b/web/themes/bootstrap/src/Plugin/Setting/Advanced/Cdn/CdnProvider.php @@ -216,17 +216,14 @@ public static function validateFormElement(Element $form, FormStateInterface $fo * @todo Import functionality is deprecated, remove in a future release. */ protected function importProviderData(Element $group, FormStateInterface $form_state) { - if ($form_state->getValue('clicked_button') === t('Save provider data')->render()) { + if ($form_state->getValue('clicked_button') === $this->t('Save provider data')->render()) { $provider_path = ProviderManager::FILE_PATH; // FILE_CREATE_DIRECTORY = 1 | FILE_MODIFY_PERMISSIONS = 2. $options = 1 | 2; - if ($fileSystem = Bootstrap::fileSystem('prepareDirectory')) { + if ($fileSystem = \Drupal::service('file_system')) { $fileSystem->prepareDirectory($provider_path, $options); } - else { - file_prepare_directory($provider_path, $options); - } $provider = $form_state->getValue('cdn_provider', $this->theme->getSetting('cdn_provider')); $file = "$provider_path/$provider.json"; @@ -234,20 +231,14 @@ protected function importProviderData(Element $group, FormStateInterface $form_s if ($import_data = $form_state->getValue('cdn_provider_import_data', FALSE)) { // FILE_EXISTS_REPLACE = 1. $replace = 1; - if ($fileSystem = Bootstrap::fileSystem('saveData')) { + if ($fileSystem = \Drupal::service('file_system')) { $fileSystem->saveData($import_data, $file, $replace); } - else { - file_unmanaged_save_data($import_data, $file, $replace); - } } elseif ($file && file_exists($file)) { - if ($fileSystem = Bootstrap::fileSystem('delete')) { + if ($fileSystem = \Drupal::service('file_system')) { $fileSystem->delete($file); } - else { - file_unmanaged_delete($file); - } } // Clear the cached definitions so they can get rebuilt. @@ -289,8 +280,8 @@ protected function importProviderData(Element $group, FormStateInterface $form_s $group->import = [ '#type' => 'details', - '#title' => t('Imported @title data', ['@title' => $provider->getLabel()]), - '#description' => t('The provider will attempt to parse the data entered here each time it is saved. If no data has been entered, any saved files associated with this provider will be removed and the provider will again attempt to request the API data normally through the following URL: <a href=":provider_api" target="_blank">:provider_api</a>.', [ + '#title' => $this->t('Imported @title data', ['@title' => $provider->getLabel()]), + '#description' => $this->t('The provider will attempt to parse the data entered here each time it is saved. If no data has been entered, any saved files associated with this provider will be removed and the provider will again attempt to request the API data normally through the following URL: <a href=":provider_api" target="_blank">:provider_api</a>.', [ ':provider_api' => $provider->getPluginDefinition()['api'], ]), '#weight' => 10, @@ -304,7 +295,7 @@ protected function importProviderData(Element $group, FormStateInterface $form_s $group->import->submit = $this->setCdnProvidersAjax([ '#type' => 'submit', - '#value' => t('Save provider data'), + '#value' => $this->t('Save provider data'), '#executes_submit_callback' => FALSE, ]); } diff --git a/web/themes/bootstrap/src/Plugin/Setting/Advanced/Cdn/CdnProviderBase.php b/web/themes/bootstrap/src/Plugin/Setting/Advanced/Cdn/CdnProviderBase.php index 94eda0ea92c30a8822687dafc6aa3679421d689c..3b7d703dcaa3092b332fc21ead7e7a846ac03dec 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/Advanced/Cdn/CdnProviderBase.php +++ b/web/themes/bootstrap/src/Plugin/Setting/Advanced/Cdn/CdnProviderBase.php @@ -68,7 +68,7 @@ public function alterForm(array &$form, FormStateInterface $form_state, $form_id protected static function checkCdnExceptions(ProviderInterface $provider, $reset = TRUE) { $exceptions = $provider->getCdnExceptions($reset); if ($exceptions) { - Bootstrap::message(t('Unable to parse @provider data. <a href=":logs">Check the logs for more details.</a> If your issues are network related, consider using the "custom" CDN Provider instead to statically set the URLs that should be used.', [ + \Drupal::messenger()->addMessage(t('Unable to parse @provider data. <a href=":logs">Check the logs for more details.</a> If your issues are network related, consider using the "custom" CDN Provider instead to statically set the URLs that should be used.', [ ':logs' => Url::fromRoute('dblog.overview')->toString(), '@provider' => $provider->getLabel(), ]), 'error'); diff --git a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Modals/ModalAnimation.php b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Modals/ModalAnimation.php index bf9f5901df51a7e752caa335e8705e86665eb1cb..6ac57029a21552cb15803219fa6ab21cd5f930e2 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Modals/ModalAnimation.php +++ b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Modals/ModalAnimation.php @@ -37,7 +37,7 @@ public function alterFormElement(Element $form, FormStateInterface $form_state, '#weight' => -1, '#attributes' => ['class' => ['alert', 'alert-info', 'alert-sm']], 0 => [ - '#markup' => t('<strong>Note:</strong> jQuery UI dialog options will be mapped to Bootstrap modal options whenever possible, however they always take precedent over any global Bootstrap modal options set here for compatibility reasons.'), + '#markup' => $this->t('<strong>Note:</strong> jQuery UI dialog options will be mapped to Bootstrap modal options whenever possible, however they always take precedent over any global Bootstrap modal options set here for compatibility reasons.'), ], '#states' => [ 'visible' => [ @@ -46,7 +46,7 @@ public function alterFormElement(Element $form, FormStateInterface $form_state, ], ], ]; - $group->setProperty('description', t('These are global options. Each modal can independently override desired settings by appending the option name to <code>data-</code>. Example: <code>data-backdrop="false"</code>.')); + $group->setProperty('description', $this->t('These are global options. Each modal can independently override desired settings by appending the option name to <code>data-</code>. Example: <code>data-backdrop="false"</code>.')); $group->setProperty('states', [ 'visible' => [ ':input[name="modal_enabled"]' => ['checked' => TRUE], diff --git a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Modals/ModalEnabled.php b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Modals/ModalEnabled.php index 57002e25b9d924dfca9715989b7c7c089846528f..516e8f6a16b9dd8fbb55002f269390ff89b8f25f 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Modals/ModalEnabled.php +++ b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Modals/ModalEnabled.php @@ -31,7 +31,7 @@ class ModalEnabled extends SettingBase { public function alterFormElement(Element $form, FormStateInterface $form_state, $form_id = NULL) { parent::alterFormElement($form, $form_state, $form_id); $group = $this->getGroupElement($form, $form_state); - $group->setProperty('description', t('Modals are streamlined, but flexible, dialog prompts with the minimum required functionality and smart defaults. See <a href=":url" target="_blank">Bootstrap Modals</a> for more documentation.', [ + $group->setProperty('description', $this->t('Modals are streamlined, but flexible, dialog prompts with the minimum required functionality and smart defaults. See <a href=":url" target="_blank">Bootstrap Modals</a> for more documentation.', [ ':url' => 'https://getbootstrap.com/docs/3.4/javascript/#modals', ])); } diff --git a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Popovers/PopoverAnimation.php b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Popovers/PopoverAnimation.php index 475d906872db82dc0b628ee32f3ed52faa26ced2..d8c1dd451ea62f6d60979d63ec1e501a280e939e 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Popovers/PopoverAnimation.php +++ b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Popovers/PopoverAnimation.php @@ -33,7 +33,7 @@ public function alterFormElement(Element $form, FormStateInterface $form_state, parent::alterFormElement($form, $form_state, $form_id); $group = $this->getGroupElement($form, $form_state); - $group->setProperty('description', t('These are global options. Each popover can independently override desired settings by appending the option name to <code>data-</code>. Example: <code>data-animation="false"</code>.')); + $group->setProperty('description', $this->t('These are global options. Each popover can independently override desired settings by appending the option name to <code>data-</code>. Example: <code>data-animation="false"</code>.')); $group->setProperty('states', [ 'visible' => [ ':input[name="popover_enabled"]' => ['checked' => TRUE], diff --git a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Popovers/PopoverEnabled.php b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Popovers/PopoverEnabled.php index 186e66b2b0096ad8a44e9df3760977602a107645..29d35611605257cc4d052da4031109034905a76b 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Popovers/PopoverEnabled.php +++ b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Popovers/PopoverEnabled.php @@ -33,7 +33,7 @@ public function alterFormElement(Element $form, FormStateInterface $form_state, parent::alterFormElement($form, $form_state, $form_id); $group = $this->getGroupElement($form, $form_state); - $group->setProperty('description', t('Add small overlays of content, like those on the iPad, to any element for housing secondary information.')); + $group->setProperty('description', $this->t('Add small overlays of content, like those on the iPad, to any element for housing secondary information.')); } /** diff --git a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Tooltips/TooltipAnimation.php b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Tooltips/TooltipAnimation.php index ac4b1671924497dd26134f2e777df34e77ad90fd..bbf3dfc505b4c3ad35a2f44cda549ad331f5bf57 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Tooltips/TooltipAnimation.php +++ b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Tooltips/TooltipAnimation.php @@ -33,7 +33,7 @@ public function alterFormElement(Element $form, FormStateInterface $form_state, parent::alterFormElement($form, $form_state, $form_id); $group = $this->getGroupElement($form, $form_state); - $group->setProperty('description', t('These are global options. Each tooltip can independently override desired settings by appending the option name to <code>data-</code>. Example: <code>data-animation="false"</code>.')); + $group->setProperty('description', $this->t('These are global options. Each tooltip can independently override desired settings by appending the option name to <code>data-</code>. Example: <code>data-animation="false"</code>.')); $group->setProperty('states', [ 'visible' => [ ':input[name="tooltip_enabled"]' => ['checked' => TRUE], diff --git a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Tooltips/TooltipEnabled.php b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Tooltips/TooltipEnabled.php index a0003397cf66be56354e79c928d3bb0e87bdcccc..a3b75732aac5bda34fc1aa9b5a94e546d689e417 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Tooltips/TooltipEnabled.php +++ b/web/themes/bootstrap/src/Plugin/Setting/JavaScript/Tooltips/TooltipEnabled.php @@ -33,7 +33,7 @@ public function alterFormElement(Element $form, FormStateInterface $form_state, parent::alterFormElement($form, $form_state, $form_id); $group = $this->getGroupElement($form, $form_state); - $group->setProperty('description', t('Inspired by the excellent jQuery.tipsy plugin written by Jason Frame; Tooltips are an updated version, which don\'t rely on images, use CSS3 for animations, and data-attributes for local title storage. See <a href=":url" target="_blank">Bootstrap tooltips</a> for more documentation.', [ + $group->setProperty('description', $this->t('Inspired by the excellent jQuery.tipsy plugin written by Jason Frame; Tooltips are an updated version, which don\'t rely on images, use CSS3 for animations, and data-attributes for local title storage. See <a href=":url" target="_blank">Bootstrap tooltips</a> for more documentation.', [ ':url' => 'https://getbootstrap.com/docs/3.4/javascript/#tooltips', ])); } diff --git a/web/themes/bootstrap/src/Plugin/Setting/Schemas.php b/web/themes/bootstrap/src/Plugin/Setting/Schemas.php index cbbc56e48e049a8c4b8c0e2ec0d048232f7278d5..69f8b797979dcfe94ffbf385a8c483579ce822c6 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/Schemas.php +++ b/web/themes/bootstrap/src/Plugin/Setting/Schemas.php @@ -200,7 +200,7 @@ public static function batchFinished($success, array $results, $operations) { '#items' => $results['success'], '#context' => ['type' => 'success'], ]); - Bootstrap::message(new FormattableMarkup('@message' . $list->renderPlain(), [ + \Drupal::messenger()->addMessage(new FormattableMarkup('@message' . $list->renderPlain(), [ '@message' => t('Successfully completed the following theme updates:'), ])); } @@ -212,7 +212,7 @@ public static function batchFinished($success, array $results, $operations) { '#items' => $results['errors'], '#context' => ['type' => 'errors'], ]); - Bootstrap::message(new FormattableMarkup('@message' . $list->renderPlain(), [ + \Drupal::messenger()->addMessage(new FormattableMarkup('@message' . $list->renderPlain(), [ '@message' => t('The following theme updates could not be completed:'), ]), 'error'); } diff --git a/web/themes/bootstrap/src/Plugin/Setting/SettingBase.php b/web/themes/bootstrap/src/Plugin/Setting/SettingBase.php index 8860c487e7655546aa5bc62cfa7bb63bbdbde3e2..3a488027218357903f52f87fbe54fa97c956bb67 100644 --- a/web/themes/bootstrap/src/Plugin/Setting/SettingBase.php +++ b/web/themes/bootstrap/src/Plugin/Setting/SettingBase.php @@ -211,7 +211,7 @@ public function getSettingElement(Element $form, FormStateInterface $form_state) } if (!empty($links)) { $description .= '<br>'; - $description .= t('See also:'); + $description .= $this->t('See also:'); $description .= ' ' . implode(', ', $links); $group->$plugin_id->setProperty('description', $description); } diff --git a/web/themes/bootstrap/src/Theme.php b/web/themes/bootstrap/src/Theme.php index 71358b016143740a7f3efac5af33476c206273ce..2b42588a93a8c84e01dffced399161fe35e9c2ef 100644 --- a/web/themes/bootstrap/src/Theme.php +++ b/web/themes/bootstrap/src/Theme.php @@ -351,12 +351,9 @@ public function fileScan($mask, $subdir = NULL, array $options = []) { $hash = Crypt::generateBase64HashIdentifier($options, [$mask, $path]); if (!$cache->has($hash)) { - if ($fileSystem = Bootstrap::fileSystem('scanDirectory')) { + if ($fileSystem = \Drupal::service('file_system')) { $files = $fileSystem->scanDirectory($path, $mask, $options); } - else { - $files = file_scan_directory($path, $mask, $options); - } $cache->set($hash, $files); } return $cache->get($hash, []); @@ -667,7 +664,7 @@ public function includeOnce($file, $path = 'includes') { if (!isset($includes[$include])) { $includes[$include] = !!@include_once $include; if (!$includes[$include]) { - Bootstrap::message(t('Could not include file: @include', ['@include' => $include]), 'error'); + \Drupal::messenger()->addMessage(t('Could not include file: @include', ['@include' => $include]), 'error'); } } return $includes[$include]; @@ -774,9 +771,7 @@ public function subthemeOf($theme) { } /**************************************************************************** - * - * Deprecated methods - * + * Deprecated methods. ***************************************************************************/ /** diff --git a/web/themes/bootstrap/src/ThemeSettings.php b/web/themes/bootstrap/src/ThemeSettings.php index bee5249b19b702a0e9ef3f15aeaeac4023f7659e..64da9471c186b2e542b5f7374d9916d0e0167f3c 100644 --- a/web/themes/bootstrap/src/ThemeSettings.php +++ b/web/themes/bootstrap/src/ThemeSettings.php @@ -3,7 +3,6 @@ namespace Drupal\bootstrap; use Drupal\bootstrap\Plugin\Setting\DeprecatedSettingInterface; -use Drupal\bootstrap\Plugin\Setting\SettingInterface; use Drupal\Core\Theme\ThemeSettings as CoreThemeSettings; use Drupal\Component\Utility\DiffArray; use Drupal\Component\Utility\NestedArray; @@ -246,6 +245,8 @@ public function getOriginal($key = '', $apply_overrides = TRUE) { */ public function getThemeConfig(Theme $theme, $active_theme = FALSE) { $config = new CoreThemeSettings($theme->getName()); + /** @var \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator */ + $file_url_generator = \Drupal::service('file_url_generator'); // Retrieve configured theme-specific settings, if any. try { @@ -276,7 +277,7 @@ public function getThemeConfig(Theme $theme, $active_theme = FALSE) { $logo_url = FALSE; foreach (['svg', 'png', 'jpg'] as $type) { if (file_exists($theme->getPath() . "/logo.$type")) { - $logo_url = file_create_url($theme->getPath() . "/logo.$type"); + $logo_url = $file_url_generator->generateString($theme->getPath() . "/logo.$type"); break; } } @@ -284,18 +285,21 @@ public function getThemeConfig(Theme $theme, $active_theme = FALSE) { $config->set('logo.url', $logo_url); } elseif (($logo_path = $config->get('logo.path')) && file_exists($logo_path)) { - $config->set('logo.url', file_create_url($logo_path)); + $config->set('logo.url', $file_url_generator->generateString($logo_path)); } } // Generate the path to the favicon. if ($config->get('features.favicon')) { $favicon_url = $theme->getPath() . '/favicon.ico'; - if ($config->get('favicon.use_default') && file_exists($favicon_url)) { - $config->set('favicon.url', file_create_url($favicon_url)); + if ($favicon_url && $config->get('favicon.use_default') && file_exists($favicon_url)) { + $config->set('favicon.url', $file_url_generator->generateString($favicon_url)); } - elseif ($favicon_path = $config->get('favicon.path')) { - $config->set('favicon.url', file_create_url($favicon_path)); + else { + $favicon_path = $config->get('favicon.path'); + if (file_exists($favicon_path)) { + $config->set('favicon.url', $file_url_generator->generateString($favicon_path)); + } } } @@ -305,10 +309,14 @@ public function getThemeConfig(Theme $theme, $active_theme = FALSE) { // Retrieve a diff of settings that override the defaults. $diff = DiffArray::diffAssocRecursive($data, $this->defaults); - // Ensure core features are always present in the diff. The theme settings - // form will not work properly otherwise. + // Ensure core features and complex (array) settings are always present in + // the diff. The theme settings form will not work properly otherwise. // @todo Just rebuild the features section of the form? - foreach (['favicon', 'features', 'logo'] as $key) { + $core_settings = ['favicon', 'features', 'logo']; + $complex_settings = array_keys(array_filter($diff, 'is_array')); + $all_complex_settings = array_unique(array_merge($core_settings, $complex_settings)); + + foreach ($all_complex_settings as $key) { $arrays = []; $arrays[] = isset($this->defaults[$key]) ? $this->defaults[$key] : []; $arrays[] = isset($data[$key]) ? $data[$key] : []; diff --git a/web/themes/bootstrap/src/Utility/ArrayObject.php b/web/themes/bootstrap/src/Utility/ArrayObject.php index 5d646503f30d4f9b0b6455a279b87b208de9f917..11d39638eba4d2b3adadbb0f2964fb4bd4dd3476 100644 --- a/web/themes/bootstrap/src/Utility/ArrayObject.php +++ b/web/themes/bootstrap/src/Utility/ArrayObject.php @@ -166,6 +166,7 @@ public function bubbleRenderArray(array $build) { * @return int * The count. */ + #[\ReturnTypeWillChange] public function count() { return count($this->array); } @@ -238,6 +239,7 @@ public function getCacheMaxAge() { * @return \ArrayIterator * An array iterator. */ + #[\ReturnTypeWillChange] public function getIterator() { return new \ArrayIterator($this->array); } @@ -297,6 +299,7 @@ public function natsort() { * @return bool * TRUE or FALSE */ + #[\ReturnTypeWillChange] public function offsetExists($key) { return isset($this->array[$key]); } @@ -312,6 +315,7 @@ public function offsetExists($key) { * @return mixed * The value. */ + #[\ReturnTypeWillChange] public function &offsetGet($key, $default = NULL) { if (!$this->offsetExists($key)) { $this->array[$key] = $default; @@ -328,6 +332,7 @@ public function &offsetGet($key, $default = NULL) { * @param mixed $value * A value. */ + #[\ReturnTypeWillChange] public function offsetSet($key, $value) { $this->array[$key] = $value; } @@ -338,6 +343,7 @@ public function offsetSet($key, $value) { * @param mixed $key * A key. */ + #[\ReturnTypeWillChange] public function offsetUnset($key) { if ($this->offsetExists($key)) { unset($this->array[$key]); @@ -354,6 +360,15 @@ public function serialize() { return serialize(get_object_vars($this)); } + /** + * Serialize an ArrayObject. + * + * @return array + */ + public function __serialize() { + return get_object_vars($this); + } + /** * {@inheritdoc} */ @@ -397,4 +412,13 @@ public function unserialize($data) { $this->exchangeArray($data['array']); } + /** + * Unserialize an ArrayObject. + * + * @param array $data + */ + public function __unserialize(array $data) { + $this->exchangeArray($data['array']); + } + } diff --git a/web/themes/bootstrap/src/Utility/Attributes.php b/web/themes/bootstrap/src/Utility/Attributes.php index 6b1e35814e6c8bc12b6d1230d8183cb47f15235c..6edd048b97f3341905ffffbe57a4de8432b993a9 100644 --- a/web/themes/bootstrap/src/Utility/Attributes.php +++ b/web/themes/bootstrap/src/Utility/Attributes.php @@ -63,6 +63,11 @@ public function &getAttribute($name, $default = NULL) { */ public function &getClasses() { $classes = &$this->offsetGet('class', []); + if(is_array($classes)) { + $classes = array_unique($classes); + } else { + $classes = array($classes); + } $classes = array_unique($classes); return $classes; } diff --git a/web/themes/bootstrap/src/Utility/Crypt.php b/web/themes/bootstrap/src/Utility/Crypt.php index 54d0e4b9e3d41ebc239c5cc1bd42e4698a58f99b..70c7435a5a99d5108b3730033c4a8e3491e23533 100644 --- a/web/themes/bootstrap/src/Utility/Crypt.php +++ b/web/themes/bootstrap/src/Utility/Crypt.php @@ -8,7 +8,7 @@ /** * Extends \Drupal\Component\Utility\Crypt. * - * @ingroup utility + * @ingroup utility crypt functions. */ class Crypt extends CoreCrypt { @@ -165,10 +165,9 @@ public static function parseSriIntegrity($integrity) { } /**************************************************************************** - * - * Deprecated methods - * - ***************************************************************************/ + * Deprecated methods. + * ***************************************************************************. + */ /** * Generates a unique hash name. @@ -179,9 +178,9 @@ public static function parseSriIntegrity($integrity) { * @return string * The generated hash identifier. * - * @deprecated since 8.x-3.18. Will be removed in a future release. - * - * @see \Drupal\bootstrap\Utility\Crypt::generateBase64HashIdentifier() + * @deprecated in 8.x-3.18 and is removed from project:5.0.0. Use + * \Drupal\bootstrap\Utility\Crypt::generateBase64HashIdentifier() instead. + * @see */ public static function generateHash() { Bootstrap::deprecated(); diff --git a/web/themes/bootstrap/src/Utility/Element.php b/web/themes/bootstrap/src/Utility/Element.php index 06cb647ee27d6b7f7b4efec40595626aee9ff458..cd34d7f7f0bc99d007f3862be16b01dd3a898a8b 100644 --- a/web/themes/bootstrap/src/Utility/Element.php +++ b/web/themes/bootstrap/src/Utility/Element.php @@ -682,7 +682,7 @@ public function setError($message = '', FormStateInterface $form_state = NULL) { $form_state->setError($this->array, $message); } else { - Bootstrap::message($message, 'error'); + \Drupal::messenger()->addMessage($message, 'error'); } return $this; } @@ -831,7 +831,7 @@ public function smartDescription(&$target_element = NULL, $input_only = TRUE, $l || $target->hasAttribute('data-toggle') // Ignore if the target element is #disabled. - || $target->hasProperty('disabled') + || ($target->hasProperty('disabled') && $target->getProperty('disabled') === TRUE) // Ignore if either the actual element or target element has an explicit // #smart_description property set to FALSE. diff --git a/web/themes/bootstrap/src/Utility/Storage.php b/web/themes/bootstrap/src/Utility/Storage.php index 36a54e1a0d08009f6dd877cb8f047651bee07c62..cce2f1cc48e72afa360e2a2b5fead35907c9de0e 100644 --- a/web/themes/bootstrap/src/Utility/Storage.php +++ b/web/themes/bootstrap/src/Utility/Storage.php @@ -104,6 +104,7 @@ public function changed() { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function current() { return current($this->data); } @@ -160,6 +161,7 @@ public function isEmpty() { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function key() { return key($this->data); } @@ -167,6 +169,7 @@ public function key() { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function next() { return next($this->data); } @@ -182,6 +185,7 @@ public function rename($key, $new_key) { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function rewind() { return reset($this->data); } @@ -243,6 +247,7 @@ public function setMultiple(array $data) { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function valid() { return key($this->data) !== NULL; } diff --git a/web/themes/bootstrap/src/Utility/StorageItem.php b/web/themes/bootstrap/src/Utility/StorageItem.php index f281669ad2621affe98705c0c8778b7ed91559ce..841fe4fea4d7b9fa58ee80478c0ae9a90bbb67c3 100644 --- a/web/themes/bootstrap/src/Utility/StorageItem.php +++ b/web/themes/bootstrap/src/Utility/StorageItem.php @@ -54,6 +54,7 @@ public function changed() { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function current() { return current($this->data); } @@ -95,6 +96,7 @@ public function isEmpty() { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function key() { return key($this->data); } @@ -102,6 +104,7 @@ public function key() { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function next() { return next($this->data); } @@ -117,6 +120,7 @@ public function rename($key, $new_key) { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function rewind() { return reset($this->data); } @@ -152,6 +156,7 @@ public function setMultiple(array $data) { /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function valid() { return key($this->data) !== NULL; } diff --git a/web/themes/bootstrap/src/Utility/Unicode.php b/web/themes/bootstrap/src/Utility/Unicode.php index b2ce0b93758f8e415b506c4b1956e6e6bc8af819..22d3b953db6d8924a86a527129a2507a8b6ca9dd 100644 --- a/web/themes/bootstrap/src/Utility/Unicode.php +++ b/web/themes/bootstrap/src/Utility/Unicode.php @@ -82,9 +82,9 @@ public static function convertCallback($callback, $array = FALSE) { $callback = implode('::', $callback); } if ($callback[0] === '\\') { - $callback = static::substr($callback, 1); + $callback = mb_substr($callback, 1); } - if ($array && static::strpos($callback, '::') !== FALSE) { + if ($array && mb_substr($callback, '::') !== FALSE) { $callback = explode('::', $callback); } return $callback; @@ -288,7 +288,8 @@ public static function substr($text, $start, $length = NULL) { if ($start > 0) { // Count all the characters except continuation bytes from the start // until we have found $start characters or the end of the string. - $bytes = -1; $chars = -1; + $bytes = -1; + $chars = -1; while ($bytes < $strlen - 1 && $chars < $start) { $bytes++; $c = ord($text[$bytes]); @@ -301,7 +302,8 @@ public static function substr($text, $start, $length = NULL) { // Count all the characters except continuation bytes from the end // until we have found abs($start) characters. $start = abs($start); - $bytes = $strlen; $chars = 0; + $bytes = $strlen; + $chars = 0; while ($bytes > 0 && $chars < $start) { $bytes--; $c = ord($text[$bytes]); @@ -342,7 +344,8 @@ public static function substr($text, $start, $length = NULL) { // Count all the characters except continuation bytes from the end // until we have found abs($start) characters, then backtrace one byte. $length = abs($length); - $iend = $strlen; $chars = 0; + $iend = $strlen; + $chars = 0; while ($iend > 0 && $chars < $length) { $iend--; $c = ord($text[$iend]); diff --git a/web/themes/bootstrap/templates/bootstrap/item-list--dropdown.html.twig b/web/themes/bootstrap/templates/bootstrap/item-list--dropdown.html.twig index a9cee12ab03046f89389134f65ae44685a2f52ae..de30d3376f541a3db7d1fa8702fae6b73e54f29b 100644 --- a/web/themes/bootstrap/templates/bootstrap/item-list--dropdown.html.twig +++ b/web/themes/bootstrap/templates/bootstrap/item-list--dropdown.html.twig @@ -33,7 +33,7 @@ {%- if items -%} <{{ list_type }}{{ attributes.addClass(classes) }} role="menu"> {%- for item in items -%} - <li{{ item.attributes }}>{{ item.value }}</li> + <li{{ item.attributes }} role="menuitem">{{ item.value }}</li> {%- endfor -%} </{{ list_type }}> {%- else -%} diff --git a/web/themes/bootstrap/templates/file/file-link.html.twig b/web/themes/bootstrap/templates/file/file-link.html.twig index 54ae38b437ce5a089e6269c5e7e8970b423d7d9c..e5c87aae6ce22d8930174bc3a200656258b42f1f 100644 --- a/web/themes/bootstrap/templates/file/file-link.html.twig +++ b/web/themes/bootstrap/templates/file/file-link.html.twig @@ -15,7 +15,7 @@ * @see \Drupal\bootstrap\Plugin\Preprocess\FileLink::preprocessVariables */ #} -{% spaceless %} +{% apply spaceless %} {% set classes = [ icon_only ? 'icon-only', @@ -37,4 +37,4 @@ {% endif %} {% endif %} </span> -{% endspaceless %} +{% endapply %} diff --git a/web/themes/bootstrap/templates/forum/forum-list.html.twig b/web/themes/bootstrap/templates/forum/forum-list.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..6059f3d431784af0e45bb4b1dc4d9c95bb6aef03 --- /dev/null +++ b/web/themes/bootstrap/templates/forum/forum-list.html.twig @@ -0,0 +1,100 @@ +{# +/** + * @file + * Default theme implementation to display a list of forums and containers. + * + * Available variables: + * - forums: A collection of forums and containers to display. It is keyed to + * the numeric IDs of all child forums and containers. Each forum in forums + * contains: + * - is_container: A flag indicating if the forum can contain other + * forums. Otherwise, the forum can only contain topics. + * - depth: How deep the forum is in the current hierarchy. + * - zebra: 'even' or 'odd', used for row class. + * - icon_class: 'default' or 'new', used for forum icon class. + * - icon_title: Text alternative for the forum icon. + * - name: The name of the forum. + * - link: The URL to link to this forum. + * - description: The description field for the forum, containing: + * - value: The descriptive text for the forum. + * - new_topics: A flag indicating if the forum contains unread posts. + * - new_url: A URL to the forum's unread posts. + * - new_text: Text for the above URL, which tells how many new posts. + * - old_topics: A count of posts that have already been read. + * - num_posts: The total number of posts in the forum. + * - last_reply: Text representing the last time a forum was posted or + * commented in. + * - forum_id: Forum ID for the current forum. Parent to all items within the + * forums array. + * - bordered: Flag indicating whether or not the table should be bordered. + * - condensed: Flag indicating whether or not the table should be condensed. + * - hover: Flag indicating whether or not table rows should be hoverable. + * - striped: Flag indicating whether or not table rows should be striped. + * - responsive: Flag indicating whether or not the table should be wrapped to + * be responsive (using the Bootstrap Framework .table-responsive wrapper). + * + * @see template_preprocess_forum_list() + * + * @ingroup themeable + */ +#} +{% if responsive %} + <div class="table-responsive"> +{% endif %} +{% set table_attributes = create_attribute() %} +{% + set table_classes = [ + 'table', + bordered ? 'table-bordered', + condensed ? 'table-condensed', + hover ? 'table-hover', + striped ? 'table-striped', + sticky ? 'sticky-enabled', +] +%} +<table{{ table_attributes.addClass(table_classes) }}> + <thead> + <tr> + <th>{{ 'Forum'|t }}</th> + <th>{{ 'Topics'|t }}</th> + <th>{{ 'Posts'|t }}</th> + <th>{{ 'Last post'|t }}</th> + </tr> + </thead> + <tbody> + {% for child_id, forum in forums %} + <tr> + <td{% if forum.is_container == true %} colspan="4"{% endif %}> + {# + Enclose the contents of this cell with X divs, where X is the + depth this forum resides at. This will allow us to use CSS + left-margin for indenting. + #} + {% if forum.depth > 0 %}{% for i in 1..forum.depth %}<div class="indent">{% endfor %}{% endif %} + <div title="{{ forum.icon_title }}"> + <span class="visually-hidden">{{ forum.icon_title }}</span> + </div> + <div><a href="{{ forum.link }}">{{ forum.label }}</a></div> + {% if forum.description.value %} + <div>{{ forum.description.value }}</div> + {% endif %} + {% if forum.depth > 0 %}{% for i in 1..forum.depth %}</div>{% endfor %}{% endif %} + </td> + {% if forum.is_container == false %} + <td> + {{ forum.num_topics }} + {% if forum.new_topics == true %} + <br /> + <a href="{{ forum.new_url }}">{{ forum.new_text }}</a> + {% endif %} + </td> + <td>{{ forum.num_posts }}</td> + <td>{{ forum.last_reply }}</td> + {% endif %} + </tr> + {% endfor %} + </tbody> +</table> +{% if responsive %} + </div> +{% endif %} diff --git a/web/themes/bootstrap/templates/input/input--button--split.html.twig b/web/themes/bootstrap/templates/input/input--button--split.html.twig index c7d6f0107679bcee184c0bc174fbe0ef7091ebd1..dfef5f579dc255203d565827ab7e35d27cafd3e9 100644 --- a/web/themes/bootstrap/templates/input/input--button--split.html.twig +++ b/web/themes/bootstrap/templates/input/input--button--split.html.twig @@ -22,15 +22,15 @@ * @see template_preprocess_input() */ #} -{% spaceless %} - {% - set classes = [ + + {% block input %}{% apply spaceless %} + {% + set classes = [ 'btn', type == 'submit' ? 'js-form-submit', icon and icon_position and not icon_only ? 'icon-' ~ icon_position, ] - %} - {% block input %} + %} {% if icon_only %} <button{{ attributes.addClass(classes, 'icon-only') }}> <span class="sr-only">{{ label }}</span> @@ -54,5 +54,5 @@ <span class="sr-only">{{ 'Toggle Dropdown'|t }}</span> </button> {{ children }} - {% endblock %} -{% endspaceless %} + {% endapply %}{% endblock %} + diff --git a/web/themes/bootstrap/templates/input/input--button.html.twig b/web/themes/bootstrap/templates/input/input--button.html.twig index 7166b1a56e4ed542ea8350c69752b3428a88bae9..2885226bfdf280359b217818668d2b5324d3c47c 100644 --- a/web/themes/bootstrap/templates/input/input--button.html.twig +++ b/web/themes/bootstrap/templates/input/input--button.html.twig @@ -22,15 +22,14 @@ * @see template_preprocess_input() */ #} -{% spaceless %} - {% - set classes = [ + {% block input %}{% apply spaceless %} + {% + set classes = [ 'btn', type == 'submit' ? 'js-form-submit', icon and icon_position and not icon_only ? 'icon-' ~ icon_position, ] - %} - {% block input %} + %} {% if icon and icon_only %} <button{{ attributes.addClass(classes, 'icon-only') }}> <span class="sr-only">{{ label }}</span> @@ -44,5 +43,5 @@ {% endif %} {% endif %} {{ children }} - {% endblock %} -{% endspaceless %} + {% endapply %}{% endblock %} + diff --git a/web/themes/bootstrap/templates/input/input--form-control.html.twig b/web/themes/bootstrap/templates/input/input--form-control.html.twig index 5694480c1396bf1f9de3e7e0d76be564a37685f7..a5b235d35cdc0e0f6bc4222121d38a29922067ef 100644 --- a/web/themes/bootstrap/templates/input/input--form-control.html.twig +++ b/web/themes/bootstrap/templates/input/input--form-control.html.twig @@ -20,13 +20,13 @@ * @see template_preprocess_input() */ #} -{% spaceless %} - {% - set classes = [ + + {% block input %}{% apply spaceless %} + {% + set classes = [ 'form-control', ] - %} - {% block input %} + %} <input{{ attributes.addClass(classes) }} /> - {% endblock %} -{% endspaceless %} + {% endapply %}{% endblock %} + diff --git a/web/themes/bootstrap/templates/input/input.html.twig b/web/themes/bootstrap/templates/input/input.html.twig index 662a6abc7e01a3108a836a4b087e8215edb7b854..7ecf9edf919023a2735f1af781155d2b37ea4528 100644 --- a/web/themes/bootstrap/templates/input/input.html.twig +++ b/web/themes/bootstrap/templates/input/input.html.twig @@ -19,7 +19,7 @@ * @see template_preprocess_input() */ #} -{% spaceless %} +{% apply spaceless %} {% if input_group %} <div class="input-group"> {% endif %} @@ -41,4 +41,4 @@ {% endif %} {{ children }} -{% endspaceless %} +{% endapply %} diff --git a/web/themes/bootstrap/templates/input/select.html.twig b/web/themes/bootstrap/templates/input/select.html.twig index 8d75f0ef989ba633dfe3f1f7f5ddbe2f78be339d..99e14b3695f9ec6e6def4e3a1fb6c343bcd99143 100644 --- a/web/themes/bootstrap/templates/input/select.html.twig +++ b/web/themes/bootstrap/templates/input/select.html.twig @@ -15,7 +15,7 @@ * @see template_preprocess_select() */ #} -{% spaceless %} +{% apply spaceless %} {% if input_group %} <div class="input-group"> {% endif %} @@ -58,4 +58,4 @@ {% if input_group %} </div> {% endif %} -{% endspaceless %} +{% endapply %} diff --git a/web/themes/bootstrap/templates/system/page.html.twig b/web/themes/bootstrap/templates/system/page.html.twig index 70f8c1d9f9fe4b836a2c3c9a45b93b5dbb27452e..3c362574bcee4120fdfdf9fbe79ef6930a33cdc6 100644 --- a/web/themes/bootstrap/templates/system/page.html.twig +++ b/web/themes/bootstrap/templates/system/page.html.twig @@ -70,7 +70,7 @@ {{ page.navigation }} {# .btn-navbar is used as the toggle for collapsed navbar content #} {% if page.navigation_collapsible %} - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse"> + <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false"> <span class="sr-only">{{ 'Toggle navigation'|t }}</span> <span class="icon-bar"></span> <span class="icon-bar"></span> diff --git a/web/themes/bootstrap/templates/system/pager.html.twig b/web/themes/bootstrap/templates/system/pager.html.twig index 5e5bb287c354a5b7bf3aa2283f1f48bf851e932e..6a7258c78cd0aadfa0c23d259c9e4f1c07ccae29 100644 --- a/web/themes/bootstrap/templates/system/pager.html.twig +++ b/web/themes/bootstrap/templates/system/pager.html.twig @@ -56,6 +56,11 @@ </li> {% endif %} + {# Add an ellipsis if there are further previous pages. #} + {% if ellipses.previous %} + <li class="page-item" role="presentation"><span class="page-link">…</span></li> + {% endif %} + {# Now generate the actual pager piece. #} {% for key, item in items.pages %} <li class="pager__item{{ current == key ? ' is-active active' : '' }}"> @@ -73,6 +78,11 @@ </li> {% endfor %} + {# Add an ellipsis if there are further next pages. #} + {% if ellipses.next %} + <li class="page-item" role="presentation"><span class="page-link">…</span></li> + {% endif %} + {# Print next item if we are not on the last page. #} {% if items.next %} <li class="pager__item pager__item--next">