diff --git a/core/modules/block/block.module b/core/modules/block/block.module index 29c6e16..f0bbdd3 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -88,8 +88,13 @@ function block_page_top(array &$page_top) { * An array of theme names. */ function block_themes_installed($theme_list) { + $theme_info = \Drupal::service('theme_handler')->listInfo(); foreach ($theme_list as $theme) { - block_theme_initialize($theme); + // Don't initialize hidden themes as they are not displayed in the block + // management screens. + if (empty($theme_info[$theme]->info['hidden'])) { + block_theme_initialize($theme); + } } } diff --git a/core/modules/block/src/Controller/BlockController.php b/core/modules/block/src/Controller/BlockController.php index 2779a9b..a67b66d 100644 --- a/core/modules/block/src/Controller/BlockController.php +++ b/core/modules/block/src/Controller/BlockController.php @@ -11,6 +11,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Extension\ThemeHandlerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Controller routines for admin block routes. @@ -53,6 +54,14 @@ public static function create(ContainerInterface $container) { * A #type 'page' render array containing the block region demo. */ public function demo($theme) { + // Ensure the theme is installed and not hidden. + $themes = $this->themeHandler->listInfo(); + + // Deny access if the theme is not installed or not found. + if (empty($themes[$theme]) || !$themes[$theme]->status || !empty($themes[$theme]->info['hidden'])) { + throw new NotFoundHttpException(); + } + $page = [ '#title' => Html::escape($this->themeHandler->getName($theme)), '#type' => 'page', diff --git a/core/modules/block/src/Controller/BlockListController.php b/core/modules/block/src/Controller/BlockListController.php index 72aa445..e7bb5d8 100644 --- a/core/modules/block/src/Controller/BlockListController.php +++ b/core/modules/block/src/Controller/BlockListController.php @@ -8,7 +8,10 @@ namespace Drupal\block\Controller; use Drupal\Core\Entity\Controller\EntityListController; +use Drupal\Core\Extension\ThemeHandlerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Defines a controller to list blocks. @@ -16,6 +19,32 @@ class BlockListController extends EntityListController { /** + * The theme handler. + * + * @var \Drupal\Core\Extension\ThemeHandlerInterface + */ + protected $themeHandler; + + /** + * Constructs the BlockListController. + * + * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler + * The theme handler. + */ + public function __construct(ThemeHandlerInterface $theme_handler) { + $this->themeHandler = $theme_handler; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('theme_handler') + ); + } + + /** * Shows the block administration page. * * @param string|null $theme @@ -28,6 +57,14 @@ class BlockListController extends EntityListController { */ public function listing($theme = NULL, Request $request = NULL) { $theme = $theme ?: $this->config('system.theme')->get('default'); + // Ensure the theme is installed and not hidden. + $themes = $this->themeHandler->listInfo(); + + // Deny access if the theme is not installed or not found. + if (empty($themes[$theme]) || !$themes[$theme]->status || !empty($themes[$theme]->info['hidden'])) { + throw new NotFoundHttpException(); + } + return $this->entityManager()->getListBuilder('block')->render($theme, $request); } diff --git a/core/modules/block/src/Plugin/Derivative/ThemeLocalTask.php b/core/modules/block/src/Plugin/Derivative/ThemeLocalTask.php index 4e337db..c5ff9d5 100644 --- a/core/modules/block/src/Plugin/Derivative/ThemeLocalTask.php +++ b/core/modules/block/src/Plugin/Derivative/ThemeLocalTask.php @@ -50,7 +50,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { $default_theme = $this->themeHandler->getDefault(); foreach ($this->themeHandler->listInfo() as $theme_name => $theme) { - if ($theme->status) { + if ($theme->status && empty($theme->info['hidden'])) { $this->derivatives[$theme_name] = $base_plugin_definition; $this->derivatives[$theme_name]['title'] = $theme->info['name']; $this->derivatives[$theme_name]['route_parameters'] = array('theme' => $theme_name); diff --git a/core/modules/block/src/Tests/BlockTest.php b/core/modules/block/src/Tests/BlockTest.php index c98b042..57c1633 100644 --- a/core/modules/block/src/Tests/BlockTest.php +++ b/core/modules/block/src/Tests/BlockTest.php @@ -199,7 +199,7 @@ public function testBlockThemeSelector() { // Install all themes. \Drupal::service('theme_handler')->install(array('bartik', 'seven')); $theme_settings = $this->config('system.theme'); - foreach (array('bartik', 'classy', 'seven') as $theme) { + foreach (array('bartik', 'test_classy', 'seven') as $theme) { $this->drupalGet('admin/structure/block/list/' . $theme); $this->assertTitle(t('Block layout') . ' | Drupal'); // Select the 'Powered by Drupal' block to be placed. @@ -442,7 +442,7 @@ public function testUninstallTheme() { $this->drupalGet(''); $this->assertText('Powered by Drupal'); - $theme_handler->setDefault('classy'); + $theme_handler->setDefault('test_classy'); $theme_handler->uninstall(['seven']); // Ensure that the block configuration does not exist anymore. diff --git a/core/modules/block/src/Tests/BlockUiTest.php b/core/modules/block/src/Tests/BlockUiTest.php index 25b7942..e920d12 100644 --- a/core/modules/block/src/Tests/BlockUiTest.php +++ b/core/modules/block/src/Tests/BlockUiTest.php @@ -83,13 +83,16 @@ protected function setUp() { public function testBlockDemoUiPage() { $this->drupalPlaceBlock('help_block', array('region' => 'help')); $this->drupalGet('admin/structure/block'); - $this->clickLink(t('Demonstrate block regions (@theme)', array('@theme' => 'Classy'))); + $this->clickLink(t('Demonstrate block regions (@theme)', array('@theme' => 'Test Classy'))); $elements = $this->xpath('//div[contains(@class, "region-highlighted")]/div[contains(@class, "block-region") and contains(text(), :title)]', array(':title' => 'Highlighted')); $this->assertTrue(!empty($elements), 'Block demo regions are shown.'); \Drupal::service('theme_handler')->install(array('test_theme')); $this->drupalGet('admin/structure/block/demo/test_theme'); $this->assertEscaped('Test theme'); + + $this->drupalGet('admin/structure/block/demo/classy'); + $this->assertResponse(404, 'Hidden themes are not supported by the block demo screen'); } /** @@ -136,6 +139,20 @@ function testBlockAdminUiPage() { $this->drupalGet('admin/structure/block'); $element = $this->xpath('//tr[contains(@class, :class)]', [':class' => 'region-title-header']); $this->assertTrue(!empty($element)); + + // Ensure hidden themes do not appear in the UI. Enable another non base + // theme and place the local tasks block. + $this->assertTrue(\Drupal::service('theme_handler')->themeExists('classy'), 'The classy base theme is enabled'); + $this->drupalPlaceBlock('local_tasks_block', ['region' => 'header']); + \Drupal::service('theme_installer')->install(['test_theme']); + $this->drupalGet('admin/structure/block'); + $theme_handler = \Drupal::service('theme_handler'); + $this->assertLink($theme_handler->getName('test_classy')); + $this->assertLink($theme_handler->getName('test_theme')); + $this->assertNoLink($theme_handler->getName('classy')); + + $this->drupalGet('admin/structure/block/list/classy'); + $this->assertResponse(404, 'Placing blocks through UI is not possible for the base theme classy.'); } /** @@ -145,7 +162,7 @@ public function testCandidateBlockList() { $arguments = array( ':title' => 'Display message', ':category' => 'Block test', - ':href' => 'admin/structure/block/add/test_block_instantiation/classy', + ':href' => 'admin/structure/block/add/test_block_instantiation/test_classy', ); $pattern = '//tr[.//td/div[text()=:title] and .//td[text()=:category] and .//td//a[contains(@href, :href)]]'; @@ -171,7 +188,7 @@ public function testCandidateBlockList() { public function testContextAwareUnsatisfiedBlocks() { $arguments = array( ':category' => 'Block test', - ':href' => 'admin/structure/block/add/test_context_aware_unsatisfied/classy', + ':href' => 'admin/structure/block/add/test_context_aware_unsatisfied/test_classy', ':text' => 'Test context-aware unsatisfied block', ); @@ -193,7 +210,7 @@ public function testContextAwareBlocks() { $this->assertNoText('Test context-aware block'); $this->assertNoRaw($expected_text); - $block_url = 'admin/structure/block/add/test_context_aware/classy'; + $block_url = 'admin/structure/block/add/test_context_aware/test_classy'; $arguments = array( ':title' => 'Test context-aware block', ':category' => 'Block test', @@ -231,7 +248,7 @@ public function testContextAwareBlocks() { * Tests that the BlockForm populates machine name correctly. */ public function testMachineNameSuggestion() { - $url = 'admin/structure/block/add/test_block_instantiation/classy'; + $url = 'admin/structure/block/add/test_block_instantiation/test_classy'; $this->drupalGet($url); $this->assertFieldByName('id', 'displaymessage', 'Block form uses raw machine name suggestion when no instance already exists.'); $this->drupalPostForm($url, array(), 'Save block'); @@ -253,16 +270,16 @@ public function testBlockPlacementIndicator() { // Select the 'Powered by Drupal' block to be placed. $block = array(); $block['id'] = strtolower($this->randomMachineName()); - $block['theme'] = 'classy'; + $block['theme'] = 'test_classy'; $block['region'] = 'content'; // After adding a block, it will indicate which block was just added. $this->drupalPostForm('admin/structure/block/add/system_powered_by_block', $block, t('Save block')); - $this->assertUrl('admin/structure/block/list/classy?block-placement=' . Html::getClass($block['id'])); + $this->assertUrl('admin/structure/block/list/test_classy?block-placement=' . Html::getClass($block['id'])); // Resaving the block page will remove the block indicator. $this->drupalPostForm(NULL, array(), t('Save blocks')); - $this->assertUrl('admin/structure/block/list/classy'); + $this->assertUrl('admin/structure/block/list/test_classy'); } } diff --git a/core/modules/block/src/Tests/Views/DisplayBlockTest.php b/core/modules/block/src/Tests/Views/DisplayBlockTest.php index f7b3ffe..542567f 100644 --- a/core/modules/block/src/Tests/Views/DisplayBlockTest.php +++ b/core/modules/block/src/Tests/Views/DisplayBlockTest.php @@ -70,7 +70,7 @@ public function testBlockCategory() { $arguments = array( ':href' => \Drupal::Url('block.admin_add', array( 'plugin_id' => 'views_block:' . $edit['id'] . '-block_1', - 'theme' => 'classy', + 'theme' => 'test_classy', )), ':category' => t('Lists (Views)'), ); @@ -107,7 +107,7 @@ public function testBlockCategory() { $arguments = array( ':href' => \Drupal::Url('block.admin_add', array( 'plugin_id' => 'views_block:' . $edit['id'] . '-block_2', - 'theme' => 'classy', + 'theme' => 'test_classy', )), ':category' => t('Lists (Views)'), ); @@ -117,7 +117,7 @@ public function testBlockCategory() { $arguments = array( ':href' => \Drupal::Url('block.admin_add', array( 'plugin_id' => 'views_block:' . $edit['id'] . '-block_3', - 'theme' => 'classy', + 'theme' => 'test_classy', )), ':category' => $category, ); diff --git a/core/modules/block/tests/modules/block_test/config/install/block.block.test_block.yml b/core/modules/block/tests/modules/block_test/config/install/block.block.test_block.yml index be7e06c..32f8e95 100644 --- a/core/modules/block/tests/modules/block_test/config/install/block.block.test_block.yml +++ b/core/modules/block/tests/modules/block_test/config/install/block.block.test_block.yml @@ -13,5 +13,5 @@ dependencies: module: - block_test theme: - - classy + - test_classy visibility: { } diff --git a/core/modules/block_content/src/Tests/BlockContentTypeTest.php b/core/modules/block_content/src/Tests/BlockContentTypeTest.php index e669a72..e176e56 100644 --- a/core/modules/block_content/src/Tests/BlockContentTypeTest.php +++ b/core/modules/block_content/src/Tests/BlockContentTypeTest.php @@ -186,16 +186,14 @@ public function testsBlockContentAddTypes() { // Install all themes. \Drupal::service('theme_handler')->install(array('bartik', 'seven')); - $themes = array('bartik', 'seven', 'classy'); $theme_settings = $this->config('system.theme'); - foreach ($themes as $default_theme) { + foreach (['bartik', 'seven', 'test_classy'] as $default_theme) { // Change the default theme. $theme_settings->set('default', $default_theme)->save(); \Drupal::service('router.builder')->rebuild(); // For each installed theme, go to its block page and test the redirects. - $themes = array('bartik', 'classy', 'seven'); - foreach ($themes as $theme) { + foreach (['bartik', 'test_classy', 'seven'] as $theme) { // Test that adding a block from the 'place blocks' form sends you to the // block configure form. $path = $theme == $default_theme ? 'admin/structure/block' : "admin/structure/block/list/$theme"; diff --git a/core/modules/block_content/tests/modules/block_content_test/config/install/block.block.foobargorilla.yml b/core/modules/block_content/tests/modules/block_content_test/config/install/block.block.foobargorilla.yml index 42858f7..49fbc53 100644 --- a/core/modules/block_content/tests/modules/block_content_test/config/install/block.block.foobargorilla.yml +++ b/core/modules/block_content/tests/modules/block_content_test/config/install/block.block.foobargorilla.yml @@ -4,9 +4,9 @@ dependencies: module: - block_content theme: - - classy + - test_classy id: foobargorilla -theme: classy +theme: test_classy region: content weight: null provider: null diff --git a/core/modules/config/tests/config_override_integration_test/config/install/block.block.config_override_test.yml b/core/modules/config/tests/config_override_integration_test/config/install/block.block.config_override_test.yml index be0616f..0025b84 100644 --- a/core/modules/config/tests/config_override_integration_test/config/install/block.block.config_override_test.yml +++ b/core/modules/config/tests/config_override_integration_test/config/install/block.block.config_override_test.yml @@ -1,5 +1,5 @@ id: config_override_test -theme: classy +theme: test_classy weight: 0 status: true langcode: en @@ -16,7 +16,7 @@ dependencies: module: - block_test theme: - - classy + - test_classy visibility: request_path: id: request_path diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php index cc41f7d..1cc3b38 100644 --- a/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php +++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php @@ -65,8 +65,8 @@ protected function setUp() { parent::setUp(); // Use Classy theme for testing markup output. - \Drupal::service('theme_handler')->install(['classy']); - $this->config('system.theme')->set('default', 'classy')->save(); + \Drupal::service('theme_handler')->install(['test_classy']); + $this->config('system.theme')->set('default', 'test_classy')->save(); // Grant the 'view test entity' permission. $this->installConfig(array('user')); diff --git a/core/modules/rdf/src/Tests/Field/NumberFieldRdfaTest.php b/core/modules/rdf/src/Tests/Field/NumberFieldRdfaTest.php index 120d6f0..a450030 100644 --- a/core/modules/rdf/src/Tests/Field/NumberFieldRdfaTest.php +++ b/core/modules/rdf/src/Tests/Field/NumberFieldRdfaTest.php @@ -32,8 +32,8 @@ public function testIntegerFormatter() { * Tests the integer formatter with settings. */ public function testIntegerFormatterWithSettings() { - \Drupal::service('theme_handler')->install(['classy']); - $this->config('system.theme')->set('default', 'classy')->save(); + \Drupal::service('theme_handler')->install(['test_classy']); + $this->config('system.theme')->set('default', 'test_classy')->save(); $this->fieldType = 'integer'; $formatter = array( 'type' => 'number_integer', @@ -75,8 +75,8 @@ public function testFloatFormatter() { * Tests the float formatter with settings. */ public function testFloatFormatterWithSettings() { - \Drupal::service('theme_handler')->install(['classy']); - $this->config('system.theme')->set('default', 'classy')->save(); + \Drupal::service('theme_handler')->install(['test_classy']); + $this->config('system.theme')->set('default', 'test_classy')->save(); $this->fieldType = 'float'; $formatter = array( 'type' => 'number_decimal', @@ -125,8 +125,8 @@ public function testFloatFormatterWithScale() { * Tests the float formatter with a scale. Scale is exercised. */ public function testFloatFormatterWithScaleExercised() { - \Drupal::service('theme_handler')->install(['classy']); - $this->config('system.theme')->set('default', 'classy')->save(); + \Drupal::service('theme_handler')->install(['test_classy']); + $this->config('system.theme')->set('default', 'test_classy')->save(); $this->fieldType = 'float'; $formatter = array( 'type' => 'number_decimal', @@ -163,8 +163,8 @@ public function testDecimalFormatter() { * Tests the decimal formatter with settings. */ public function testDecimalFormatterWithSettings() { - \Drupal::service('theme_handler')->install(['classy']); - $this->config('system.theme')->set('default', 'classy')->save(); + \Drupal::service('theme_handler')->install(['test_classy']); + $this->config('system.theme')->set('default', 'test_classy')->save(); $this->fieldType = 'decimal'; $formatter = array( 'type' => 'number_decimal', diff --git a/core/modules/search/src/Tests/SearchBlockTest.php b/core/modules/search/src/Tests/SearchBlockTest.php index 8351878..2d3d62f 100644 --- a/core/modules/search/src/Tests/SearchBlockTest.php +++ b/core/modules/search/src/Tests/SearchBlockTest.php @@ -37,7 +37,7 @@ public function testSearchFormBlock() { // Test availability of the search block in the admin "Place blocks" list. $this->drupalGet('admin/structure/block'); $this->clickLinkPartialName('Place block'); - $this->assertLinkByHref('/admin/structure/block/add/search_form_block/classy', 0, + $this->assertLinkByHref('/admin/structure/block/add/search_form_block/test_classy', 0, 'Did not find the search block in block candidate list.'); $block = $this->drupalPlaceBlock('search_form_block'); diff --git a/core/modules/system/src/Form/ThemeSettingsForm.php b/core/modules/system/src/Form/ThemeSettingsForm.php index 395c743..e9d810f 100644 --- a/core/modules/system/src/Form/ThemeSettingsForm.php +++ b/core/modules/system/src/Form/ThemeSettingsForm.php @@ -109,7 +109,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme = $themes = $this->themeHandler->listInfo(); // Deny access if the theme is not installed or not found. - if (!empty($theme) && (empty($themes[$theme]) || !$themes[$theme]->status)) { + if (!empty($theme) && (empty($themes[$theme]) || !$themes[$theme]->status || !empty($themes[$theme]->info['hidden']))) { throw new NotFoundHttpException(); } diff --git a/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php b/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php index 9c9de19..aae7885 100644 --- a/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php +++ b/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php @@ -48,7 +48,7 @@ public static function create(ContainerInterface $container, $base_plugin_id) { */ public function getDerivativeDefinitions($base_plugin_definition) { foreach ($this->themeHandler->listInfo() as $theme_name => $theme) { - if ($theme->status) { + if ($theme->status && empty($theme->info['hidden'])) { $this->derivatives[$theme_name] = $base_plugin_definition; $this->derivatives[$theme_name]['title'] = $theme->info['name']; $this->derivatives[$theme_name]['route_parameters'] = array('theme' => $theme_name); diff --git a/core/modules/system/src/Tests/Render/Element/TableTest.php b/core/modules/system/src/Tests/Render/Element/TableTest.php index 725f339..665ac2e 100644 --- a/core/modules/system/src/Tests/Render/Element/TableTest.php +++ b/core/modules/system/src/Tests/Render/Element/TableTest.php @@ -97,8 +97,8 @@ function testThemeTableWithEmptyMessage() { ); // Enable the Classy theme. - \Drupal::service('theme_handler')->install(['classy']); - $this->config('system.theme')->set('default', 'classy')->save(); + \Drupal::service('theme_handler')->install(['test_classy']); + $this->config('system.theme')->set('default', 'test_classy')->save(); $this->render($table); $this->removeWhiteSpace(); diff --git a/core/modules/system/src/Tests/System/ThemeTest.php b/core/modules/system/src/Tests/System/ThemeTest.php index 8b2836b..d92ed1b 100644 --- a/core/modules/system/src/Tests/System/ThemeTest.php +++ b/core/modules/system/src/Tests/System/ThemeTest.php @@ -52,11 +52,14 @@ function testThemeSettings() { $this->assertResponse(404, 'The theme settings form URL for a uninstalled theme could not be found.'); $this->drupalGet('admin/appearance/settings/' . $this->randomMachineName()); $this->assertResponse(404, 'The theme settings form URL for a non-existent theme could not be found.'); + $this->assertTrue(\Drupal::service('theme_handler')->themeExists('classy')); + $this->drupalGet('admin/appearance/settings/classy'); + $this->assertResponse(404, 'The theme settings form URL for a hidden theme are unavailable.'); // Specify a filesystem path to be used for the logo. $file = current($this->drupalGetTestFiles('image')); $file_relative = strtr($file->uri, array('public:/' => PublicStream::basePath())); - $default_theme_path = 'core/themes/classy'; + $default_theme_path = 'core/modules/system/tests/themes/test_classy'; $supported_paths = array( // Raw stream wrapper URI. @@ -190,6 +193,14 @@ function testThemeSettings() { // The logo field should only be present on the global theme settings form. $this->assertNoFieldByName('logo_path'); $this->drupalPostForm(NULL, [], t('Save configuration')); + + // Ensure only vlaid themes are listed in the local tasks. + $this->drupalPlaceBlock('local_tasks_block', ['region' => 'header']); + $this->drupalGet('admin/appearance/settings'); + $theme_handler = \Drupal::service('theme_handler'); + $this->assertLink($theme_handler->getName('test_classy')); + $this->assertLink($theme_handler->getName('bartik')); + $this->assertNoLink($theme_handler->getName('classy')); } /** @@ -255,8 +266,14 @@ function testAdministrationTheme() { * Test switching the default theme. */ function testSwitchDefaultTheme() { + /** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */ + $theme_handler = \Drupal::service('theme_handler'); + // First, Install Stark and set it as the default theme programmatically. + $theme_handler->install(array('stark')); + $theme_handler->setDefault('stark'); + // Install Bartik and set it as the default theme. - \Drupal::service('theme_handler')->install(array('bartik')); + $theme_handler->install(array('bartik')); $this->drupalGet('admin/appearance'); $this->clickLink(t('Set as default')); $this->assertEqual($this->config('system.theme')->get('default'), 'bartik'); @@ -266,10 +283,10 @@ function testSwitchDefaultTheme() { $this->assertText('Bartik(' . t('active tab') . ')', 'Default local task on blocks admin page is the default theme.'); // Switch back to Stark and test again to test that the menu cache is cleared. $this->drupalGet('admin/appearance'); - // Classy is the first 'Set as default' link. - $this->clickLink(t('Set as default'), 0); + // Stark is the first 'Set as default' link. + $this->clickLink(t('Set as default')); $this->drupalGet('admin/structure/block'); - $this->assertText('Classy(' . t('active tab') . ')', 'Default local task on blocks admin page has changed.'); + $this->assertText('Stark(' . t('active tab') . ')', 'Default local task on blocks admin page has changed.'); } /** @@ -328,8 +345,8 @@ function testUninstallingThemes() { // base theme of bartik. $this->assertNoRaw('Uninstall Classy theme', 'A link to uninstall the Classy theme does not appear on the theme settings page.'); - // Change the default theme to stark, stark is third in the list. - $this->clickLink(t('Set as default'), 2); + // Change the default theme to stark, stark is second in the list. + $this->clickLink(t('Set as default'), 1); // Check that bartik can be uninstalled now. $this->assertRaw('Uninstall Bartik theme', 'A link to uninstall the Bartik theme does appear on the theme settings page.'); @@ -344,9 +361,9 @@ function testUninstallingThemes() { // Seven is the second in the list. $this->clickLink(t('Uninstall')); $this->assertRaw('The Seven theme has been uninstalled'); - // Now uninstall classy. - $this->clickLink(t('Uninstall')); - $this->assertRaw('The Classy theme has been uninstalled'); + + // Check that the classy theme still can't be uninstalled as it is hidden. + $this->assertNoRaw('Uninstall Classy theme', 'A link to uninstall the Classy theme does not appear on the theme settings page.'); } /** diff --git a/core/modules/system/src/Tests/Theme/MessageTest.php b/core/modules/system/src/Tests/Theme/MessageTest.php index db27d2a..6c577b7 100644 --- a/core/modules/system/src/Tests/Theme/MessageTest.php +++ b/core/modules/system/src/Tests/Theme/MessageTest.php @@ -26,8 +26,8 @@ class MessageTest extends KernelTestBase { */ function testMessages() { // Enable the Classy theme. - \Drupal::service('theme_handler')->install(['classy']); - $this->config('system.theme')->set('default', 'classy')->save(); + \Drupal::service('theme_handler')->install(['test_classy']); + $this->config('system.theme')->set('default', 'test_classy')->save(); drupal_set_message('An error occurred', 'error'); drupal_set_message('But then something nice happened'); diff --git a/core/modules/system/tests/modules/theme_test/src/Theme/HighPriorityThemeNegotiator.php b/core/modules/system/tests/modules/theme_test/src/Theme/HighPriorityThemeNegotiator.php index 7934ae3..70fcc24 100644 --- a/core/modules/system/tests/modules/theme_test/src/Theme/HighPriorityThemeNegotiator.php +++ b/core/modules/system/tests/modules/theme_test/src/Theme/HighPriorityThemeNegotiator.php @@ -26,7 +26,7 @@ public function applies(RouteMatchInterface $route_match) { * {@inheritdoc} */ public function determineActiveTheme(RouteMatchInterface $route_match) { - return 'classy'; + return 'test_classy'; } } diff --git a/core/themes/classy/logo.svg b/core/modules/system/tests/themes/test_classy/logo.svg similarity index 100% rename from core/themes/classy/logo.svg rename to core/modules/system/tests/themes/test_classy/logo.svg diff --git a/core/modules/system/tests/themes/test_classy/test_classy.info.yml b/core/modules/system/tests/themes/test_classy/test_classy.info.yml new file mode 100644 index 0000000..363c472 --- /dev/null +++ b/core/modules/system/tests/themes/test_classy/test_classy.info.yml @@ -0,0 +1,6 @@ +name: Test Classy +type: theme +description: A theme that uses classy as a base theme for most testing. +version: VERSION +core: 8.x +base theme: classy diff --git a/core/profiles/standard/config/install/block.block.classy_page_title.yml b/core/profiles/standard/config/install/block.block.classy_page_title.yml deleted file mode 100644 index 4236224..0000000 --- a/core/profiles/standard/config/install/block.block.classy_page_title.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - theme: - - classy -id: classy_page_title -theme: classy -region: content -weight: -50 -provider: null -plugin: page_title_block -settings: - id: page_title_block - label: 'Page title' - provider: core - label_display: '0' -visibility: { } diff --git a/core/profiles/testing/config/install/system.theme.yml b/core/profiles/testing/config/install/system.theme.yml index 0defc7e..5997057 100644 --- a/core/profiles/testing/config/install/system.theme.yml +++ b/core/profiles/testing/config/install/system.theme.yml @@ -1,2 +1,2 @@ # @todo: Remove this file in https://www.drupal.org/node/2352949 -default: classy +default: test_classy diff --git a/core/profiles/testing/testing.info.yml b/core/profiles/testing/testing.info.yml index 28fc4e8..3962c47 100644 --- a/core/profiles/testing/testing.info.yml +++ b/core/profiles/testing/testing.info.yml @@ -11,4 +11,4 @@ dependencies: - dynamic_page_cache # @todo: Remove this in https://www.drupal.org/node/2352949 themes: - - classy + - test_classy diff --git a/core/themes/classy/classy.info.yml b/core/themes/classy/classy.info.yml index 2b7705b..5ed9b80 100644 --- a/core/themes/classy/classy.info.yml +++ b/core/themes/classy/classy.info.yml @@ -5,6 +5,7 @@ package: Core version: VERSION core: 8.x base theme: false +hidden: true libraries: - classy/base diff --git a/core/themes/classy/screenshot.png b/core/themes/classy/screenshot.png deleted file mode 100644 index 4d8e395..0000000 --- a/core/themes/classy/screenshot.png +++ /dev/null @@ -1,159 +0,0 @@ -PNG - - IHDRL[)PLTEjmc>>>WWW;;;QQQBBB®TTT~~~yyy888DDD*)*333lll&&&^^^HHH000LLLFFFNNNccc---pqp"!"YYY󑑒JJJʌvvu{|{[[\eefߚ555sst hghnnn```iiju-*#9C8HB<3 !rrre_T3,$<6.1,>&EHB9"/HDS$*SMC^Q N2\S]ϨBHIL#&NGOgcku:]1EED9gʓ'Iщ/`;chg&<1A}\s@:am wmt  .&隲lǮm]LۘV=;685R !Kj\cCX['$8W }|o?C/SL"I^bi0y2F3=Diev tG4BlL toyi\<{숑+Dt#%>VhF.^+w9;rL.{&L[= r::敝ųm4#+,W\j󶔀Ey70B|Lnι`KGKs/e7(pt \ށ֖K@jBEhM؍;rĕ/g1|$htQt1_a&39go&ۘ޿lq7:}݇h4v'4) 9w,A yXV?ۻ*s67? `.ޜLZ|g7%R^>CsE1`I/m7 7aȩ56ⷜ&Q@3 -382@w;1i '`g& KKjTG|} C7?j'5 4Jo3<|xΦͽ^\czj~ci&gtPt!=@ghJnEDap-$k [[Oca$r64WcSXE1N+ y9;tP-o=aŁq< i]ZcA2> -سG˥r4>֋^>'EVl;G۽hm+"QglaN_a`*-ɩ!ND'N+k 0`2EcVG3wF;g{⤼*H:Suhc -v2pU6Wn-Cn"!foa:Zqa``AXΖđ=G؏@']aWnJA8lyh>?۴Ľma=k~]:Cy[^ ?s:G\0g] &x/"m>$nI, Vu N $9q)G;lAGʼnJcJޔCTyn^i/iDMOϵwdqoMB0׼[{x-m>֧ǁ=R޸f1w7ŦSv)^sn˃~|\jቸs|Pl@=ZgCX"M<)٧سB6)8JJ*IMA͕ǔ@W$H&/6#2rK.Tq7a#G1.-X@ekWOQs{HL4M+,O/"ۙ 0 8.S ׺\b9z"mxG@ux<ǽaI=k -otxpChkBK7+0) DV {jH[_YFGkxz>Q_\1'l TPF?fٳaHWǑH e -ӂ1]܌.\Et!F%@i〾S Rl<9\B}@ YG1# -7PUEO{@w4חFIsh1i4׏FIsh1i4׏FIsh1i41m>nih|a^R8b_QZ#-R;Ђd#Fv,+܂[7pU9ΐB[Z,1픁f}(#u>EٻCa >j`l %PX۔r.u:UgNdՊ_͈{`dP]@r44v8 -J}S~m-WpRZGJqk? J :l5J t:s.r) n{35SMїl"#{_Vi)%YV#ƈ]#1L& ƤƤ4&}d-8_5r0b27 -TZJB KàƝ]z:_g3;Yp? Y -)%k. -tzvϙМeŭl-~rё7AEw -O5z 4 -%2ɂh_L- - [E6f &k'i^gY2gӁhkJ 8%9!• ^pcbLĘ|)F]yxm:6F%Sxn,T^UHU3ϡkzѡPȍ3ޘki+NG`x)s14& `Z!"1F}0_pE)3~} BƘj ^˽~˒Ǵr -íx6rusSFZ|kv@*|Լt$+tD/펩Id,xc"DØ10&Ƙ` }CL7@7&c$#dŜVkỏV{:цvzKyIjcz?ѯJ4Ɍ֡ϘJ{wȂ0`&?amAkp`nCDVc6IӁ@mK=ğCOZj'Ph^BJqOڍ?z5~Ltl[ZZN _=g9S*~Oj=6p/09dȽ f,}q'%D/CA{¦~;Ll* ˶ _m'H+=, b i#°Pݐf^`[Yf9Lh-؏'i *ïgUlՆ8Ƙn Tc%(; <%48T꾑g`1aK#@m?'&+p_ZYƥI ^lZ,MVH21AZs88BT ASy*^8l@%06ND.Ɗ-®,-x0|4ySN>(i, iXLp^v:iV+&KÏ0fek܊\v+ }SSRO3jut[%5);&ŲG`}GhrQ&C{kmm eI,3s/zc%\3#e&|c^^N>O}KLkKK}"Uʺ)a/^pS d܎i ˋi1MTйJ!P9Rɐ"\~3p IEL1 -J%~d+ +x Px $B]cw#ڀq.+K!p6>:<7z;ㇲK IAd")uJ=&rNJIؔ:'tʙ5ML.$}wOO>!^Iy(P!.s b'ӂ44l1TK-'5@)-d^ "ϖ1$]'gSY߲ިg~`ɰ[o[gZ[/-˼JKy(7άSeF{IfY6|؎z-k[fdSjYKUvdT,k,}w'cjYw|h4Qo̎f_ʇb41x*/獩L_b|<^LNjyQ" 8^-M|I_-uխU-wsu]5((Ct -"EЭCP BD!:v{tNAACoT|pfxn_y1Q4&CchLԿDј1y=ӄ*-GgXi+#(No(mM ;v94<bЧ$-Hie@%h`:|4X@7.βHxA-!~ՏD-v3Om`=/ -WOoIwrZى/3k"b/੻N1"-ZBA/i%I-j|8A CX"8/Pu1յKth%rX]q&-YT..sFoWG烮cr&_& :סK熤[F]zI6n\\ @g% -b`#i+ OtVfvCBZ BLSlZ@qr֦H>@+1iĬk*9iiډYvP ]i#+FHsxvS ̪Y&"` ,!(EWꁖqK2t12@^mFr@ӂz[BS.*dQ@5C7!~%ooշܱ~G~`w6Z :#끱 ƀf*|& ld%1jdxp؊Geӷ9 &Bɍk -HYPsL R N ?m|j3@hIofw}v/%lfhIr0nLvϷvk]<}6ݔ2]9hLOc:q؞uiO'?~}m^yxyw&>L4&1]z.޺ -l˷Ϟ=^ߺo煚w7N4&1cn^#|C|C "'ă L.yOXx})KP2 Eu\ B d*~OLvYZ⭻v("!%z*XO&bQs'.\#ssi1IO[z}[G7U<vvb/,-p!E8M 3B N-eL:DeMM59k&I)r&t-S¡DB9׻3}gon^ zttN[JY#TJ-rq9MWAhL|&i|zuf=PSoܟӺlpqtڙN(݁Ae; -qP -|ȔSxi֣fڅ S;PV}i3bص z7ʔ{L[2iȅ"@xMAFƱSv/)Er*LrJN,&ؔ{~~eЍ% rmA&Z1`2N3_,G"|rLQBx{-:~g0gdX8`*z e<''52;I;(V%ʐ"I1(aݭ$X&Ӝyr(zL%\/ENlpc'>s:|eܼNaYHGq$2=4NnjTWcY9\><|%K~_Sadd/zYfY5i -ϑ4H₇@Ҵ&d`֛ J_rƍ%%:2vȄ@%6t`UYTkr,Mh8Մ*^ȹp -P&ȭ8>gCrA(" nl ,J2N5W>ظc1.UG&:xE 6 ܫALΌ8&-;-]4B3Rɪڡeio 8L84ϡ.^Og f0s9f&-d^LQX4NJ(LxeUUCad;ɺ(iՃGӁOŁwa %j!% R҉ Z%?)w2Auxa%J:C`.908p -#8Rl*fCtZQS5p?)($+ϐIR'2aiE,f>a ai,5 +AoP} -8v" rS&oAceXڬ&nBU Y,T4"%`0^J%eY<ye8aRl)yDSD0Qi'j/N%cK2UO%c, =A$g T|]U+s)/U6.R>zSJ:R}_U~aߗ<ed0ayPŹmGks( -X>@0}9%i1J;WW'LLzGx8Yc -1 i{m Z _Q0*>PhR _t|c2A5cvǷl+yH$8ZZW4@r_U泧S_P&H62bhehxɖz+2h -$hqmNܵ@2T$RB-_ C ً^(㴋%1C&VE& }ҭ;Ti5NdL~`oq t>}y7(" B#fbF$E Lű{s{]UgN嵵Sg_JȻ1Ex!KS13(E1w?MGT:Aձik/}l;gά-wG%gf.W rB\.vEQq=m u}XևFv.ԭᰜHJb⅓P& h;Oa8R,أ6TW֝~r{ݞj:[9I$v/GB)zSիP&H62шb0|XgZ**NkN7Ҭ.7g{}w=vld?`*H__ edf38pEXYkڶhm^UeU^gmep#'k"sOlH zÁ!gJM4Ͽm{`Um.\ب-h*TU oU#}r!lHQ!eq($+0I@Xj˖G6Ӵ Ƃ̭yxyyWd(~>~]wyoy04%_0>Ll eAyBoٴ)djh<ݢ7555WUUT6O32[$Fi"CN$IpCp {6 (JPvzOyFiߚط@݇7l'ti:A+u'} J -VO(VASN155S7YTG.^M>-F -),3 -&#L6\kʫhF`Y[>=6y=u ͙XEg(!D@uGp"8+4;&UMƭg\rtj+ ?cFb8e1a8:Yk~wC;NlKy.\q@ :beiAQ3 2pG-CDS[[(b;]R_ ]_LldpfS( ̺s(7:ΉHYM,REޟ_@LL{qG] 7 z1fcG)Y -3Y_$"Eu>t֙x6Ff̆# Ng%.$lCϻ8I W&>2A+ nvt:|*>Ĵ6X&a"mCاμnZEȬg6 L,E,aNq #Nt :8@Mf>ܦw"90L<,Ǡ ϣ;3&'uno7@Z@>744j>D=%>'G=+9E. -8e6 Xe'Dw$yL7D}>j Kjɞ 9rmׅQb'Rf-q6nC90cOLLt=;J^mYXXuAfc8l P )?_w`QN)y0Ѽ; ù+(4؈XqA5Eֺfz>׭?=y?:0-a噹gN>ʹs̝ݣd2>8zKn=ItH} /?cGn% +K^?=zKri̙3`P~_ M|t=nh_~ӏ?{I+tϽpL/sϝ]t)[ -d.s&Bѩ]F\WU~kz걺[~j>t=T9Zx<V|b|/?^t4PHKLݽ\ $~ᒩ@Ω:}Pm't.a0@N'777m䉆&oH$='|uw6{?ujeL&#Dg$LׁJ=|'od2FO|}Ó0OǓA6y1tqy~yx;L6=b6NL_8Qgk{#:1b?Ig`6SSӎŝ~]僯_ ō -&af@&b mA9?m9{% -Fm"&T'wp~r"l.^|-!Y,.d#v 50\,y}zCJ0LU(XWsUL -~k=ZwcOjÔ4MPISnj7xwyA̖Z{sWťL$!&A4°Vt7:jyJV|>ww%x.j*SuίS6%v=&oUKEQT09ƕvf'0yd]Mg Q-V *Uh>My"G^S?1ϨM7IĒEB!\V@E a"0㝏1SH -4-PX4*AeGd {ћ>KXٵLD!Nm,[]HjoMS$L[zCf5EADda`J R"JU1pePш`M=pk=Ͻv9M~80]QKLvqFmd) -BucPU(R6W*'VVˆMNc<ɗ?^DU0-/dYF^ab;rˏ"0C*IT%FL݄)TMusCp3Ozf.nּx"4zQMLfl#" xgO*z5԰Jr{ҊށFR.L^K-Pd*1Amdr-02MHҜq!d^0eGHVЛV[M3 TMjY0^ -;vUTmh,٬e -*+W`JDdA;hiћnn)i@?[/QU) r{T\_Z - . <ZCbd4C}BS, [CRL TA'WzجYK+N]Z0lXL(YA.08 0<b_Y DTNPA {/ritz~l0f2<nTq yJauRWҜaܮ"a", -af!dڎh:ʬ~=`ѽ@d7 -52(>oڅxelqC?e5ۄ|OPJ]żM vWڡ n*ߎLшNs 0ց$-W; jr-T j\us;'0ۗZBvoW)󪍼P@lL -.0"I l@HW5wֿnZ2=B$a@Dj"a"&qᯣX"Ӹ4]SLgvX6fN(ϣkM B!!gb?TDDha)j`tXs4C(wz,K(Z\a.dD? *&b NsPybe+0DkpXqZwzL M-K -`B,!M VE>ɧ0}S>O| -'OaS>&!>w0@-ǝ@:v6/U|ԕ{;`WIG#NX&ni7 h1&lH .c9dꀖ-{brl'dv7~ ̈́yhrdcjuR #aM!,9l01BK:FkB}Ap|><4m՘ $="c fl>W jt 5Yb$Ql6zd94NƦuFᾧ}7kۄz\bCZX7Kt -YL:lڢB ^6Z51gch^A{ˈ݁s>6&F@FK'h-%8TsıԈqvDu-Oz#4WG!Hǽ1)\i6`MR VIY՘cl) CHACzT!a;wk<Gi\ ÷vͷ$)G9u>Fo]x $QH(`$tJ^C* @9J@_3̩y'(]Í옦ZY!&oJ>&~;i"Wd$RFb `(w - > {zɹ2m$LNsK -fˠ&\!2] /t&mLD|WFCyj9f" X~"l] %%Ɠ!d8&e(wO,>7dȂ?ְz.o\x'ea]8tB³!c7ҷ>`-2fGL,E#r0m=מ grůHDOvQ =)֘88A##%2gZIg؜(O0D]D55 -,[HeZ2`b' 7SeqP߉AtRn N}i9h%̃!L -yn ju< -B6`^F,@H -(Vnp +jpl(c J""gv{@tǴ=~.6:pcp1QR@PL -nq/Sklж#휧\ҩW'I@Q$cwΎUZ56smw[Tch@ULlJc X1 ޹yX&-u- `A#|-Z@ޮU]`aa>ܾDڞa2$VVZI@#<D-'A"C @`̠XE܄i7es*=;ҴOȢ07@XwLoW?j7X{Hc--5\q>Iu: c*)Qiƙ(Uܩ8qOG̓#@Be!92x/,l؀6LR&m GL*pϱFM$39@H 3jTKR6ҜDw~~G1[kWt>B:CMLO1ZsY̼ёMrMLż>FL@l}r5Ӹv\RJ,&)`سqA -;w|iB"T$b*'V_n5 -m(.4QL!/>ކ8~Wfl"։"~@ " ΉE$U26hV}IsGgSфvi]qbn$L'ڞ86RwQ+t?++Ĕq8pQ':>HK+/9`2"Ŏ8fU2aҵo]']"@D S90sE֡a+p^9'9^[+t=u` 23%@*;˥Sb>!rfnqޅ yʈ= u٢Vg*0@څЩ(D.r҇**yZoQ@CqJSdlG"VoOTaS5 -uҙ-XhʅbrfY!:Ҍ`U"JȖPnM}шаl1c[8vb6LҙՇ4i3V)"+Xk% ` -w%[\X674dx/W,Jl@X z9@qL'P> V9['SPG*b -x{ -{$OIXz>չJ3 %~,Y gw)•又Bę -xfECY8";I -QC;5!R(/(} -'0Y {_6 C]hd2SGRe=&RJ>»O/+~d7ҕ9V")=΢?ՊboQ_#>{˯縻k?}8? S ­ŻEb ޓ#p޷gxxt:.JfpwA݈]uatFc+˵ՕRw:cӑ:%JBrB?;ܽ_+w5x'{7=ϟlGBJ|Pw@7(rNm]6w1n|ݍW7?f7>{k~a:F}2Z8' G 6 -^a%VT|Aڍ9ܖط͜%(X?r qb1G [-D> -yk'0.kc$lB9k'7Уi)DHmքS{W/~znx_|o/~/ֱZ7o^;y?7߿|-|],dD4Z aLz5LM!'ݑINSqS}+M'{Ubߎ.2P8tvKÝ8SNWS*DtWkJC 2E{ioqvdi)@w㞤<|2}>i$_F!H5h 9,Hr Ր*}qGyd'D)szN_Bih6:ypEG{ݙCѽ}w4K$ ã—?4\-~JQ?݁dB4c)Qd9$:nr7)`CSKz\R~cS`ۃ8sxDO*M'bW,i?߼/ Ͼ|/>mxՏx탧//^_|7Ͼx͏?x?}6L0x 28 !\" lak jdu#=#I: ?7PU6 LR#}jnvBD$a#R`wQqua8)c1NwlXzt-x7XU(J@ye2) PYYԶ$'ke ͤZ1L̛%`񉬻v^2r.#g6#J,@2P[Y/i&91e]08EX $í *{՘hMP͉qѫ]u!7?y)q dgtJJgw_~~ݻ?xËo=w?|NO^<o}/C3O7a|ܾz 򧷿/p&vfj :AƲƾ m\v)#/=5Զ[]$G["H'ӕP,Ssػ0%Aue{]Rɤc5E;階lkR3 --Ud*T}dF]94eYS -2V .RW(A}[ݑ;λ0q"DN|)}= N?Hҿ{f hAIB0 m>ze5˵F)d"iGmBic AHʁ;9:V:X&f69IGG&scۀGn $ E"B0GM1'mkŎxك_}˷?߆%=>7o}w_>}_]3%釷/__|ond3n.vj"ut{7v`a@%wԐ]=.J 6u-.%PHLZV4\\>cUHCÍcڊ -D0q)H7+> W 4&BQbA&{y")-Hb+Xcشk6[DpMI&ԹKLΒtDxΫpLo\GpbްMMi&N5riE{.`D - :-V+ם. ՘ab1LCxiSh1 N&!5QPKxF6>Ajxwo>{?{^<{~?O -g |ӧ~|ӫgW?bo/z淅0D"0"ۂlTr7d{صI6HlQPi p7*xx2Tbd$TZ@`%cJ!{ -Dn ?`r bs΀zE%^G!@"CG3h0[d+[rQa Q_?L`Ξ=l vb=vl (ĂYERP׻Ae sه=j[*[(D"U#Ka -x)J]8Vaaw߼~zś7o޾w?}/>{_?~gϞR|W_w?[~^w|7ㇽy?•|+gL5R$f5>p;}<~ο<Ϟ?x x_|u?Lv]RE!r3Τ5bZx Մ^ ǚ?O07&c5sNz7~U۟=]@7Hd>:oWƇ -f*[NL}>()?@RպKtjm)@&Ÿb(CO; p& 4UJH{AMꇃq'mǝ\@ ~n^FR4+dzw1߳W/߉"> W}[SIG7[:imW8ϐbl%< -D\0kB3WpmJ9ѶI )(G(CEW8s7)[C̀fvޜS{94Jp(jކ[*(xuuX W"~@4`.lŵtrG "LVҖ(h&yr9EF+ -k]m,L!>3 ib¹kumB%=02-I&kOEb? ,棉kk ,\6 -RB8.ѧ4SC̘u,_ 5Gٹ9Dc/vQķ -F } SڛLj}Y'0#Ft4l@93V,{qdUiSw"J RdU4{ -HKu\#TJ:-{N9(b)6OwYĴW%mӉѦˡG }(# -L,]w&*[@A -:1whC[E@TCDzJRvM -5&Vr8mO]*ܓF=7(.,oml5 9O6Hln4_Ri.otKvT'۩*8'e@OƛD27N ʰ_ UO!8XKzBx1{ɈfSNSTp'a]B@o;YNv}7IFrz,|bs ۈ!$ۧˢ\v[Q\AVNwCKxnCj1FTj"E>7E>L- -CL ->l -%@d@6K;Vy"L@eGٓGmZ@V]] 6U8Dr5puCp@z8vq"B@!D2c^ۧpBj&QnHĩP &5[sVZoC>7CZXFn2ߪ47$4::NNDdPN8tz>6xbEnVN[$4,pAiC}#dG ,ۜtf80"z n;@ ެ_"J\U7?tpin?=P DR0v:SAR`8C }}n% 5kt(׽ b8Oebbfx-B -աsm?@hwRނB2ਯEDn3ΩrM_<0w1n'|I،@bx2-Q3R9HFpl-L=uD/4mutm3$R ڨ$A 4mNZv,usHM%,AH1#Y‰ -@I T⊥(~8}sJ?UۯcփU9:JE!gDfV2L\~%'h`g&ώQ,"CRA{CE>Lk`Έ+ qҀk]>VF8 -)QIY\b}/?L3zzmnDuFR w`x 3 $iH ᮓڌnJoNf9[:ޱ e=qP;9*X+@7eI>CY,oϋ%iw;xov|*^]Ap~ގ(;GTE:ӊDmh\v| -p 9E1'r|' @q li etmoJ(T>b`ގf|k{x?_6Dgj̏ oy]"5m 2"2[Zd{trBU(4! -E9qb|W0H Jq~@|VDiWm›8 `quV0&"\H0Hi"ٳy$"4*=,j ^ss"7MapfRC65X#>U -gT,lw -rj -$AIjcI :"]V<9FJ5= ѴB+%!]?8ȉhM(@ J-ZN]qg(="V\(B/C%59싑 Ŕ4A<`UЎ2y* |dEL<قGѭwjB\Ӫ+T|X:㮝A1$dډȤ&RJف?S\mSt4ȉ1,tr*s y-z-E#OS>ׇɳUNk5ER+)Δw|6=5[: |l_,R]ܐk^{z>tzo zO+ʺn(%pR>mʿT -w*AAؿ {p/n]}^w4D3nƈ;S|m,"_- bpȪ <[7Jt@$y̯~{BZ04s"ܸߵjqj­ষ(a2)5UDSP{!%n wȇI,iYnj2jfnIBM۵6V8!441vPgfz4\Mf + rq,h:q8)PMR"L56.=نbfV3ǢC* N9[،}'[HN}.(@= -6i{fN -@2mk5ꐜEh+dCF,W48TBfn"f~ -"/9f AeZܸfJ]\uh¦1yh r&'Q>hƇdQcM?2Tj82"! 4w%E%v#{,ݬZ?Yqcl1uD'tcMNSdSHѳȿ*faΪ攬FO;dmL/ QQ5Fёe􉟔醙mぴX;Ґ*KH` 5y/.H6.\i=Nt8_ѓ*`@iĐ4*TgjU%X/5 yp:nsga[D,. -r$=<Պ-0MZ6aE1۩juΑjoJ Dd#WדTo1H&}(䘞#ZTc%C@|쬚'ˮe1! @r;2A>$D$9۴sMFig Q:V\,?]Tf*wSt ;lӣ̈́ -j\r0QDfG`-yOùb9 rx]zy>HDoI\Ae }qbiڱjN =P=,R1٨66WòJM MP`IJ8EmJ2ef NM;k)k"@eӿuo!g܇]ݦ2=@ȝ$ne2Z)YVOڀY";Ƅ4$ä 6+ L,N-QVS? lUDanaJ$o-*Iv}_3)ވkb=ƀ=а<bMC$BcaCmi٘0aôIyACb͊DjWP6u 8VM-sk%u 27N -ABlw+Y@wiu/ *Ele3G EEa_D 8ߔ<=pK[D]%b KѥyJ(¥)PgR6hhs( 3rr>NZd$+KT%D1X# M.\f>K|@cJ\>?ոV)iӐ?vrI/Vܿgq{E t ^&tà$}7xbN0>DbzaZTgf'H-9ԮG$#" -;'q^!{bbǖ-.84S$OS'}ysv슋}L,9d 7Wsh6:cY 7zä QD -\7P/j+hRLePhRt9Bjsr V)1:IQfM_`oChN6 a]JQ6jIڋA7M`ɣ4Cۊu]E % UШWvE*|t{3eڡ9CI-" u*N`ۉx]JdmWO@D=ckE7xXP(h|jflp#6 Yw`F吨0^;՜|㞨.5ِ}i\։$8Nc{ NB -!RA o ߫e%:[dnZ] Vgm5f:"&?_ //};?!?/b<>S/%a~%O}az0QPe%Y~o{~z31,jOU -/Ƿ- -6K< -Č_ԨO ES h4xi^5VψC|Njn9T&ox"{%~`v$/4{K|Ed[_vf_mJ7"~-!k); -~c?ga:qŧ5,k=Gk^ -3sͨ;%1;N ->>WSiRSMyJ$VGd1,}dl9> Z2O}hW"4 @!+L6$ \CMz0k3( Hr5>ÕP'da{+4N_:DhSE غuZC 1ms`WcŮj笩]約6'!| 8f5u-tRa>LeRlc,ԛX]鬳?#Rhx/ԚB ߐd<{ 8b4@{nv2 rp6؁͸7,)>Eq# 8J4JQёe`43n>=M?[8N[͉U[uν,b~kSqG6-s(J7ѽܥFChk -)VKs(%a+@[o"ժ>%a&:L~2H-h/.`ZMpQt08-hAV!J XYUe|r^T?Ouzv&y V.s8+=pvGF@dn@uWH\x o.=YlPnB+5bν]S(`_˦'(WM(0kOy{!$Qv_@1aw-S?]8kH 8Ոƾ ْяlv Z ]ǀ`z&C)X=qYFUj -,\R4vܧU@s" ӄe li -S{ZSTk4 N{9{跺n=9?yyP&]R]NV wA0pe֤_IN `vl`6e5 -\ΖB/1m  VD,cA+5PN,@T]WA!ihgߑΎ'م$W[DlIfX#MQģs;1 KfeQʹ -f8D:1#;0T'"_wX2$h"q+9$ҡ͟ -Tġx{!HmF)Hb};]Q.{Lڽ -g5h@۠dRӫ(oZFN0ma\8jx;)BK@'WmP"IsċƘOF1q_^kl|]2F~مEzNP@e)k 6X"%9a4T-dz;rm@C$B 1OK= _SC )yU6dh{x-daBc2D.C:\j|Ey݌L⼇RrЎ<Ӊ;۸>Ed*qJr]%-zE) I%q6=2p:΅ᥩd|>RR6`'=I&Ba-GǐRC@EKZc`t\Fґ'iq"jy@k;!FӐ׭0Y#PK"C)7qxLK"6B您%E/l̄OU2!FlpՒ? w7[3b0hx3?~OSO 櫜Px)㋰#`8߭t9=Y/44cxcBgS3aRR@+;*aLâ~-;!QZ,~B)|W=ɀwO;;T$yD @2גDq"9rQ(q6+>*.9r]A%x qY?4cߵxbl:JN'֏ù@Q\M&R1`_4ж׉M:6ݗnggaE7NMxNT*)h^N7q\rriQX5h8 Sfټ8xIDL d~b>¢%v#'Eyb`-dx*j|A4DQ5Nm^ @ -;wUʠhh~:sp% Dc|(C#=A\81%MؼְU(xzy %uxY:>|ijx3==v?fP+Eh_#VG4p_UF׈ay֌{>ąJC`1`&1芙$enLSМCcwom,$/NpB .)`H(ѧ*7]4&=7݈A m]r)q/ޝdD-ܧ{w[Ajlgkf0xvsB"}vvb\|y*W~.G0>E*6ch[]ژX.cPZ!(fh\ ͟`Ŋ? -BaLXh!t# aj6q#jHMp,#жlE xE{ߴ|w_pPIENDB` \ No newline at end of file diff --git a/core/themes/stable/stable.info.yml b/core/themes/stable/stable.info.yml index 687c434..960a683 100644 --- a/core/themes/stable/stable.info.yml +++ b/core/themes/stable/stable.info.yml @@ -5,3 +5,4 @@ package: Core version: VERSION core: 8.x base theme: false +hidden: true