Commit 25053462 authored by alexpott's avatar alexpott
Browse files

Issue #3050374 by bnjmnm, lauriii, alexpott, DyanneNova, xjm: Create Drupal 9 stable theme

parent 79cca074
......@@ -442,6 +442,8 @@
"assets/vendor/**/*.css",
"tests/Drupal/Tests/Core/Asset/css_test_files/**/*.css",
"modules/media/css/plugins/drupalmedia/ckeditor.drupalmedia.css",
"themes/stable/css/core/assets/vendor/**/*.css"
"themes/stable/css/core/assets/vendor/**/*.css",
"themes/stable9/css/core/assets/vendor/**/*.css",
"themes/stable9/css/media/plugins/drupalmedia/ckeditor.drupalmedia.css"
]
}
<?php
namespace Drupal\KernelTests\Core\Theme;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests Stable 9's library overrides.
*
* @group Theme
*/
class Stable9LibraryOverrideTest extends KernelTestBase {
/**
* The theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface
*/
protected $themeManager;
/**
* The theme initialization.
*
* @var \Drupal\Core\Theme\ThemeInitializationInterface
*/
protected $themeInitialization;
/**
* The library discovery service.
*
* @var \Drupal\Core\Asset\LibraryDiscoveryInterface
*/
protected $libraryDiscovery;
/**
* A list of all core modules.
*
* @var string[]
*/
protected $allModules;
/**
* A list of libraries to skip checking, in the format extension/library_name.
*
* @var string[]
*/
protected $librariesToSkip = [];
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'user', 'path_alias'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->container->get('theme_installer')->install(['stable9']);
// Enable all core modules.
$all_modules = $this->container->get('extension.list.module')->getList();
$all_modules = array_filter($all_modules, function ($module) {
// Filter contrib, hidden, experimental, already enabled modules, and
// modules in the Testing package.
if ($module->origin !== 'core' || !empty($module->info['hidden']) || $module->status == TRUE || $module->info['package'] == 'Testing' || $module->info['package'] == 'Core (Experimental)') {
return FALSE;
}
return TRUE;
});
$this->allModules = array_keys($all_modules);
$this->allModules[] = 'system';
$this->allModules[] = 'user';
$this->allModules[] = 'path_alias';
sort($this->allModules);
$this->container->get('module_installer')->install($this->allModules);
$this->themeManager = $this->container->get('theme.manager');
$this->themeInitialization = $this->container->get('theme.initialization');
$this->libraryDiscovery = $this->container->get('library.discovery');
}
/**
* Ensures that Stable 9 overrides all relevant core library assets.
*/
public function testStable9LibraryOverrides() {
// First get the clean library definitions with no active theme.
$libraries_before = $this->getAllLibraries();
$libraries_before = $this->removeVendorAssets($libraries_before);
$this->themeManager->setActiveTheme($this->themeInitialization->getActiveThemeByName('stable9'));
$this->libraryDiscovery->clearCachedDefinitions();
// Now get the library definitions with Stable 9 as the active theme.
$libraries_after = $this->getAllLibraries();
$libraries_after = $this->removeVendorAssets($libraries_after);
foreach ($libraries_before as $extension => $libraries) {
foreach ($libraries as $library_name => $library) {
// Allow skipping libraries.
if (in_array("$extension/$library_name", $this->librariesToSkip)) {
continue;
}
$library_after = $libraries_after[$extension][$library_name];
// Check that all the CSS assets are overridden.
foreach ($library['css'] as $index => $asset) {
$clean_path = $asset['data'];
$stable_path = $library_after['css'][$index]['data'];
// Make core/misc assets look like they are coming from a "core"
// module.
$replacements = [
'core/misc/' => "core/modules/core/css/",
];
$expected_path = strtr($clean_path, $replacements);
// Adjust the module asset paths to correspond with the Stable 9
// folder structure.
$replacements = [
"core/modules/$extension/css/" => "core/themes/stable9/css/$extension/",
"core/modules/$extension/layouts/" => "core/themes/stable9/layouts/$extension/",
];
$expected_path = strtr($expected_path, $replacements);
$assert_path = str_replace("core/modules/$extension/", '', $clean_path);
$this->assertEqual($expected_path, $stable_path, "$assert_path from the $extension/$library_name library is overridden in Stable 9.");
$this->assertFileExists("{$this->root}/$clean_path", "$clean_path exists.");
$this->assertFileExists("{$this->root}/$stable_path", "$stable_path exists.");
}
}
}
}
/**
* Removes all vendor libraries and assets from the library definitions.
*
* @param array[] $all_libraries
* An associative array of libraries keyed by extension, then by library
* name, and so on.
*
* @return array[]
* The reduced array of libraries.
*/
protected function removeVendorAssets(array $all_libraries) {
foreach ($all_libraries as $extension => $libraries) {
foreach ($libraries as $library_name => $library) {
if (isset($library['remote'])) {
unset($all_libraries[$extension][$library_name]);
}
foreach (['css', 'js'] as $asset_type) {
foreach ($library[$asset_type] as $index => $asset) {
if (strpos($asset['data'], 'core/assets/vendor') !== FALSE) {
unset($all_libraries[$extension][$library_name][$asset_type][$index]);
// Re-key the array of assets. This is needed because
// libraries-override doesn't always preserve the order.
if (!empty($all_libraries[$extension][$library_name][$asset_type])) {
$all_libraries[$extension][$library_name][$asset_type] = array_values($all_libraries[$extension][$library_name][$asset_type]);
}
}
}
}
}
}
return $all_libraries;
}
/**
* Gets all libraries for core and all installed modules.
*
* @return array[]
* An associative array of libraries keyed by extension, then by library
* name, and so on.
*/
protected function getAllLibraries() {
$modules = \Drupal::moduleHandler()->getModuleList();
$module_list = array_keys($modules);
sort($module_list);
$this->assertEqual($this->allModules, $module_list, 'All core modules are installed.');
$libraries['core'] = $this->libraryDiscovery->getLibrariesByExtension('core');
foreach ($modules as $module_name => $module) {
$library_file = $module->getPath() . '/' . $module_name . '.libraries.yml';
if (is_file($this->root . '/' . $library_file)) {
$libraries[$module_name] = $this->libraryDiscovery->getLibrariesByExtension($module_name);
}
}
return $libraries;
}
}
<?php
namespace Drupal\KernelTests\Core\Theme;
use Drupal\Core\Theme\Registry;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests Stable 9's template overrides.
*
* @group Theme
*/
class Stable9TemplateOverrideTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'user'];
/**
* An array of template names to skip, without the extension.
*
* @var string[]
*/
protected $templatesToSkip = [
// Registered as a template in the views_theme() function in views.module
// but an actual template does not exist.
'views-form-views-form',
];
/**
* The theme handler.
*
* @var \Drupal\Core\Extension\ThemeHandlerInterface
*/
protected $themeHandler;
/**
* A list of all core modules.
*
* @var string[]
*/
protected $allModules;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->themeHandler = $this->container->get('theme_handler');
$this->container->get('theme_installer')->install(['stable9']);
$this->installAllModules();
}
/**
* Installs all core modules.
*/
protected function installAllModules() {
// Enable all core modules.
$all_modules = $this->container->get('extension.list.module')->getList();
$all_modules = array_filter($all_modules, function ($module) {
// Filter contrib, hidden, experimental, already enabled modules, and
// modules in the Testing package.
if ($module->origin !== 'core' || !empty($module->info['hidden']) || $module->status == TRUE || $module->info['package'] == 'Testing' || $module->info['package'] == 'Core (Experimental)') {
return FALSE;
}
return TRUE;
});
$this->allModules = array_keys($all_modules);
sort($this->allModules);
$module_installer = $this->container->get('module_installer');
$module_installer->install($this->allModules);
$this->installConfig(['system', 'user']);
}
/**
* Ensures that Stable 9 overrides all relevant core templates.
*/
public function testStable9TemplateOverrides() {
$registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $this->themeHandler, \Drupal::service('theme.initialization'), 'stable9');
$registry->setThemeManager(\Drupal::theme());
$registry_full = $registry->get();
foreach ($registry_full as $hook => $info) {
if (isset($info['template'])) {
// Allow skipping templates.
if (in_array($info['template'], $this->templatesToSkip)) {
continue;
}
$this->assertEquals('core/themes/stable9', $info['theme path'], $info['template'] . '.html.twig overridden in Stable 9.');
}
}
}
}
ABOUT STABLE 9
--------------
Stable allows core markup and styling to evolve by functioning as a backwards
compatibility layer for themes against changes to core markup and CSS. If you
browse Stable's contents, you will find copies of all the Twig templates and
CSS files provided by core.
Warning: Themes that decide to not use Stable 9 as a base theme will need
continuous maintenance as core changes, so only opt out if you are prepared to
keep track of those changes and how they affect your theme.
ABOUT DRUPAL THEMING
--------------------
For more information, see Drupal.org's theming guide.
https://www.drupal.org/docs/8/theming
/* Block listing page */
.region-title__action {
display: inline-block;
margin-left: 1em; /* LTR */
}
[dir="rtl"] .region-title__action {
margin-right: 1em;
margin-left: 0;
}
/* Block demo mode */
.block-region {
margin-top: 4px;
margin-bottom: 4px;
padding: 3px;
background-color: #ff6;
}
a.block-demo-backlink,
a.block-demo-backlink:link,
a.block-demo-backlink:visited {
position: fixed;
z-index: 499;
left: 20px; /* LTR */
padding: 5px 10px;
color: #000;
border-radius: 0 0 10px 10px;
background-color: #b4d7f0;
font-family: "Lucida Grande", Verdana, sans-serif;
font-size: small;
line-height: 20px;
}
a.block-demo-backlink:hover {
text-decoration: underline;
}
/* Configure block form - Block description */
.block-form .form-item-settings-admin-label label {
display: inline;
}
.block-form .form-item-settings-admin-label label:after {
content: ":";
}
.block-disabled:not(:hover) {
opacity: 0.675;
background: #fcfcfa;
}
/**
* CSS added to iframe-based instances only.
*/
body {
margin: 8px;
color: #222;
background-color: #fff;
font-family: Arial, Verdana, sans-serif;
font-size: 15px;
}
@media screen and (max-width: 600px) {
/* A font-size of 16px prevents iOS from zooming. */
body {
font-size: 16px;
}
}
ol,
ul,
dl {
/* Preserved spaces for list items with text direction other than the list.
* (CKEditor issues #6249,#8049) */
padding: 0 40px;
}
/**
* @file
* Styles for configuration of CKEditor module.
*
* Many of these styles are adapted directly from the default CKEditor theme
* "moono".
*/
.ckeditor-toolbar {
margin: 5px 0;
padding: 0.1667em 0.1667em 0.08em;
/* Disallow any user selections in the drag-and-drop toolbar config UI. */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
border: 1px solid #b6b6b6;
background: #cfd1cf;
background-image: -webkit-linear-gradient(top, whiteSmoke, #cfd1cf);
background-image: linear-gradient(top, whiteSmoke, #cfd1cf);
box-shadow: 0 1px 0 white inset;
}
.ckeditor-toolbar-active {
margin-top: 0.25em;
}
.ckeditor-toolbar-disabled {
margin-bottom: 0.5em;
}
.ckeditor-toolbar ul,
.ckeditor-toolbar-disabled ul {
margin: 0;
padding: 0;
list-style: none;
}
/* This is required to win over specificity of [dir="rtl"] ul */
[dir="rtl"] .ckeditor-toolbar ul,
[dir="rtl"] .ckeditor-toolbar-disabled ul {
margin-right: 0;
}
.ckeditor-row {
padding: 2px 0 3px;
border-radius: 3px;
}
.ckeditor-group-names-are-visible .ckeditor-row {
border: 1px solid whitesmoke;
}
.ckeditor-row + .ckeditor-row {
margin-top: 0.25em;
}
.ckeditor-toolbar-group,
.ckeditor-toolbar-group-placeholder,
.ckeditor-add-new-group {
float: left; /* LTR */
}
[dir="rtl"] .ckeditor-toolbar-group,
[dir="rtl"] .ckeditor-toolbar-group-placeholder,
[dir="rtl"] .ckeditor-add-new-group {
float: right;
}
.ckeditor-toolbar-groups {
min-height: 2em;
}
.ckeditor-toolbar-group {
margin: 0 0.3333em;
cursor: move;
}
.ckeditor-group-names-are-visible .ckeditor-toolbar-group,
.ckeditor-add-new-group {
padding: 0.2em 0.4em;
border: 1px dotted #a6a6a6;
border-radius: 3px;
}
.ckeditor-toolbar-group.placeholder,
.ckeditor-toolbar-group.placeholder .ckeditor-toolbar-group-name {
cursor: not-allowed;
}
.ckeditor-toolbar-group.placeholder .ckeditor-toolbar-group-name {
font-style: italic;
}
.ckeditor-toolbar-group-name {
display: none;
margin: 0.25em 0;
font-size: 1em;
font-weight: normal;
}
.ckeditor-group-names-are-visible .ckeditor-toolbar-group-name {
display: block;
cursor: pointer;
}
.ckeditor-toolbar-active .placeholder,
.ckeditor-toolbar-active .ckeditor-add-new-group {
display: none;
}
.ckeditor-group-names-are-visible .placeholder,
.ckeditor-group-names-are-visible .ckeditor-add-new-group {
display: block;
}
.ckeditor-toolbar-group-buttons {
float: left; /* LTR */
}
[dir="rtl"] .ckeditor-toolbar-group-buttons {
float: right;
}
.ckeditor-groupnames-toggle {
float: right; /* LTR */
cursor: pointer;
}
[dir="rtl"] .ckeditor-groupnames-toggle {
float: left;
}
.ckeditor-toolbar .ckeditor-toolbar-group > li {
margin: 3px 6px;
padding: 3px;
border: 1px solid white;
border-radius: 5px;
background-image: -webkit-linear-gradient(transparent 60%, rgba(0, 0, 0, 0.1));
background-image: linear-gradient(transparent 60%, rgba(0, 0, 0, 0.1));
}
.ckeditor-toolbar-configuration .fieldset-description {
margin-bottom: 1em;
}
.ckeditor-toolbar-disabled .ckeditor-toolbar-available,
.ckeditor-toolbar-disabled .ckeditor-toolbar-dividers {
box-sizing: border-box;
}
.ckeditor-toolbar-disabled .ckeditor-toolbar-available {
float: left; /* LTR */
width: 80%;
}
[dir="rtl"] .ckeditor-toolbar-disabled .ckeditor-toolbar-available {
float: right;
}
.ckeditor-toolbar-disabled .ckeditor-toolbar-dividers {
float: right; /* LTR */
width: 20%;
}
[dir="rtl"] .ckeditor-toolbar-disabled .ckeditor-toolbar-dividers {
float: left;
}
.ckeditor-toolbar-disabled .ckeditor-buttons li a,
.ckeditor-toolbar .ckeditor-buttons,
.ckeditor-add-new-group button {
border: 1px solid #a6a6a6;
border-bottom-color: #979797;
border-radius: 3px;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5), 0 0 2px rgba(255, 255, 255, 0.15) inset, 0 1px 0 rgba(255, 255, 255, 0.15) inset;
}
.ckeditor-toolbar-disabled .ckeditor-buttons {
border: 0;
}
.ckeditor-toolbar-disabled .ckeditor-buttons li {
margin: 2px;
}
.ckeditor-buttons {
min-width: 26px;
min-height: 26px;
}
.ckeditor-buttons li {
float: left; /* LTR */
margin: 0;
padding: 0;
}
[dir="rtl"] .ckeditor-buttons li {
float: right;
}
.ckeditor-buttons li a,
.ckeditor-add-new-group button {
color: #474747;
background: #e4e4e4;
background-image: -webkit-linear-gradient(top, white, #e4e4e4);
background-image: linear-gradient(top, white, #e4e4e4);
}
.ckeditor-buttons li a {
position: relative;
display: block;
min-height: 18px;
padding: 4px 6px;
cursor: move;
white-space: nowrap;
text-decoration: none;
border: 0;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
line-height: 1.4;
}
.ckeditor-toolbar-dividers {
float: right; /* LTR */
}
[dir="rtl"] .ckeditor-toolbar-dividers {
float: left;
}
.ckeditor-buttons li .cke-icon-only {