diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 74f82baca8490e6a1b623b3cdd24814538cf2628..d335e651d78cf4ca962aec698e291767c766d6e2 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -910,7 +910,6 @@ function install_display_output($output, $install_state) { '#theme' => 'task_list', '#items' => install_tasks_to_display($install_state), '#active' => $active_task, - '#variant' => 'install', ); drupal_add_region_content('sidebar_first', drupal_render($task_list)); } diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc index d3023b9a65f51f20c194a54819643cc152896ad8..57183d6d4baea62469c10fcf208d63676e1b84dc 100644 --- a/core/includes/theme.maintenance.inc +++ b/core/includes/theme.maintenance.inc @@ -109,23 +109,16 @@ function _drupal_maintenance_theme() { * An associative array containing: * - items: An associative array of maintenance tasks. * - active: The key for the currently active maintenance task. - * - variant: A variant name to be used for a CSS class. * * @ingroup themeable */ function theme_task_list($variables) { $items = $variables['items']; $active = $variables['active']; - if (isset($variables['variant'])) { - $class = $variables['variant'] . '-task-list'; - } - else { - $class = 'task-list'; - } $done = isset($items[$active]) || $active == NULL; $output = '<h2 class="visually-hidden">Installation tasks</h2>'; - $output .= '<ol class="' . $class . '">'; + $output .= '<ol class="task-list">'; foreach ($items as $k => $item) { if ($active == $k) { diff --git a/core/lib/Drupal/Component/Utility/Unicode.php b/core/lib/Drupal/Component/Utility/Unicode.php index c5e0d82e9ac029d7efe86f93b24eb144afcbd280..f819abd516c9885969977f548c1fa4b4132c611f 100644 --- a/core/lib/Drupal/Component/Utility/Unicode.php +++ b/core/lib/Drupal/Component/Utility/Unicode.php @@ -258,7 +258,7 @@ public static function strlen($text) { } /** - * Uppercase a UTF-8 string. + * Converts a UTF-8 string to uppercase. * * @param string $text * The string to run the operation on. @@ -280,7 +280,7 @@ public static function strtoupper($text) { } /** - * Lowercase a UTF-8 string. + * Converts a UTF-8 string to lowercase. * * @param string $text * The string to run the operation on. @@ -302,18 +302,52 @@ public static function strtolower($text) { } /** - * Capitalizes the first letter of a UTF-8 string. + * Capitalizes the first character of a UTF-8 string. * * @param string $text * The string to convert. * * @return string - * The string with the first letter as uppercase. + * The string with the first character as uppercase. */ public static function ucfirst($text) { return static::strtoupper(static::substr($text, 0, 1)) . static::substr($text, 1); } + /** + * Converts the first character of a UTF-8 string to lowercase. + * + * @param string $text + * The string that will be converted. + * + * @return string + * The string with the first character as lowercase. + * + * @ingroup php_wrappers + */ + public static function lcfirst($text) { + // Note: no mbstring equivalent! + return static::strtolower(static::substr($text, 0, 1)) . static::substr($text, 1); + } + + /** + * Capitalizes the first character of each word in a UTF-8 string. + * + * @param string $text + * The text that will be converted. + * + * @return string + * The input $text with each word capitalized. + * + * @ingroup php_wrappers + */ + public static function ucwords($text) { + $regex = '/(^|[' . static::PREG_CLASS_WORD_BOUNDARY . '])([^' . static::PREG_CLASS_WORD_BOUNDARY . '])/u'; + return preg_replace_callback($regex, function(array $matches) { + return $matches[1] . Unicode::strtoupper($matches[2]); + }, $text); + } + /** * Cuts off a piece of a string based on character indices and counts. * diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php index 2b02ab0e0c1ab5d30819a19433dc48986b719ef1..ca764ab8e70375667feae98621ebee36cfba5be1 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php @@ -263,14 +263,9 @@ protected function caseTransform($string, $option) { case 'lower': return drupal_strtolower($string); case 'ucfirst': - return drupal_strtoupper(drupal_substr($string, 0, 1)) . drupal_substr($string, 1); + return Unicode::ucfirst($string); case 'ucwords': - if (Unicode::getStatus() == Unicode::STATUS_MULTIBYTE) { - return mb_convert_case($string, MB_CASE_TITLE); - } - else { - return ucwords($string); - } + return Unicode::ucwords($string); } } diff --git a/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php b/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php index ee45829bb07cb5c2ac82d1cfc874fd2283251409..350fa25301af7919630f1a64c72d8e72668713ad 100644 --- a/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php +++ b/core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php @@ -193,6 +193,70 @@ public function providerUcfirst() { ); } + /** + * Tests Unicode::lcfirst(). + * + * @dataProvider providerLcfirst + */ + public function testLcfirst($text, $expected, $multibyte = FALSE) { + $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE; + Unicode::setStatus($status); + $this->assertEquals($expected, Unicode::lcfirst($text)); + } + + /** + * Data provider for testLcfirst(). + * + * @see testLcfirst() + * + * @return array + * An array containing a string, its lowercase version and whether it should + * be processed as multibyte. + */ + public function providerLcfirst() { + return array( + array('tHe QUIcK bRoWn', 'tHe QUIcK bRoWn'), + array('FrançAIS is ÜBER-åwesome', 'françAIS is ÜBER-åwesome'), + array('Über', 'über'), + array('Åwesome', 'åwesome'), + // Add a multibyte string. + array('ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', 'αΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', TRUE), + ); + } + + /** + * Tests Unicode::ucwords(). + * + * @dataProvider providerUcwords + */ + public function testUcwords($text, $expected, $multibyte = FALSE) { + $status = $multibyte ? Unicode::STATUS_MULTIBYTE : Unicode::STATUS_SINGLEBYTE; + Unicode::setStatus($status); + $this->assertEquals($expected, Unicode::ucwords($text)); + } + + /** + * Data provider for testUcwords(). + * + * @see testUcwords() + * + * @return array + * An array containing a string, its capitalized version and whether it should + * be processed as multibyte. + */ + public function providerUcwords() { + return array( + array('tHe QUIcK bRoWn', 'THe QUIcK BRoWn'), + array('françAIS', 'FrançAIS'), + array('über', 'Über'), + array('åwesome', 'Åwesome'), + // Make sure we don't mangle extra spaces. + array('frànçAIS is über-åwesome', 'FrànçAIS Is Über-Åwesome'), + // Add a multibyte string. + array('σion', 'Σion', TRUE), + ); + } + /** * Tests Unicode::strlen(). * diff --git a/core/themes/seven/install-page.css b/core/themes/seven/install-page.css index 7981932a6db93ec40a87398887894dbe45a33108..5c3bf83c48fb69bcec06fcd58985015898c5bb85 100644 --- a/core/themes/seven/install-page.css +++ b/core/themes/seven/install-page.css @@ -23,171 +23,6 @@ background-position: left top, 50% 50%; min-height: 100%; } -.install-page { - background: none; -} -.name-and-slogan h1 { - font-size: 2em; - line-height: 1.2em; - color: #0074bd; -} - -/** - * Layout - */ -.install-page .l-container { - background: #fff; - width: auto; - margin-left: 1.25em; - margin-right: 1.25em; -} -.install-page .l-container:after { /* no reason for a clearfix in the markup */ - content: ""; - display: table; - clear: both; -} -@media all and (max-width: 48em) { /* 768px */ - .install-page .l-container { - margin-top: 1.25em; - padding: 10px 20px 0; - } - .install-page .name-and-slogan { - margin: 0 0 1.45em 0; - } -} - -@media all and (min-width: 48em) { /* 768px */ - html { - display: table; - } - .install-page { - display: table-cell; - padding: 1em 0; - vertical-align: middle; - } - html, .install-page { - margin: 0; - width: 100%; - height: 100%; - } - .install-page .l-container { - margin: 0 auto; - max-width: 770px; - width: 75%; - border-radius: 5px; - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); - padding: 20px 0 40px 0; - } - - /* Positioning sidebar & content */ - .install-page [role="main"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - clear: none; - float: left; - padding-left: 3.85em; - padding-right: 3.85em; - width: 65%; - } - [dir="rtl"] .install-page [role="main"] { - float: right; - } - ul { - padding: 15px; - margin: 0.25em 0; - } - .install-page .l-sidebar-first { - float: left; - width: 35%; - } - [dir="rtl"] .install-page .l-sidebar-first { - float: right; - } - - /* Margins for sitename */ - .install-page .name-and-slogan h1 { - margin: 0.75em 0 0.75em 1.9em; /* LTR */ - } - [dir="rtl"] .install-page .name-and-slogan h1 { - margin: 0.75em 1.9em 0.75em 0; - } -} - -/** - * Task list & step indicator - */ -@media all and (max-width: 48em) { /* 768px */ - header[role="banner"] { - position: relative; - } - .step-indicator { - display: block; - font-size: 1.385em; - position: absolute; - top: 0.2em; - right: 0.5em; - } - [dir="rtl"] .step-indicator { - left: 2em; - right: auto; - } - .install-task-list { - display: none; - } -} - -@media all and (min-width: 48em) { /* 768px */ - .step-indicator { - display: none; - } - .install-task-list { - margin-left: 0; /* LTR */ - list-style-type: none; - list-style-image: none; - padding-left: 0; /* LTR */ - padding-bottom: 1em; - } - [dir="rtl"] .install-task-list { - margin-right: 0; - padding-right: 0; - } - .install-task-list li { - padding: 0.5em 1em 0.5em 3.85em; /* LTR */ - color: #1a1a1a; - } - [dir="rtl"] .install-task-list li { - padding: 0.5em 1em 0.5em 1em; - } - .install-task-list .active { - background: #ebeae4; - position: relative; - font-weight: normal; - } - .install-task-list .active:after { - left: 100%; /* LTR */ - border: solid transparent; - border-color: rgba(235, 234, 228, 0); - border-left-color: #ebeae4; /* LTR */ - border-width: 1.35em; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - top: 50%; - margin-top: -1.32em; - } - [dir="rtl"] .install-task-list .active:after { - left: auto; - right: 100%; - border-left-color: transparent; - border-right-color: #ebeae4; - } - .install-task-list .done { - color: #adadad; - } -} /** * Password widget diff --git a/core/themes/seven/js/mobile.install.js b/core/themes/seven/js/mobile.install.js index 2326c241f6275dcfb22cc7375fb4756469a60b56..28268bfe0d7ef89b18e71684cfa3996e56b9f2de 100644 --- a/core/themes/seven/js/mobile.install.js +++ b/core/themes/seven/js/mobile.install.js @@ -16,7 +16,7 @@ } function installStepsSetup () { - var steps = document.querySelectorAll('.install-task-list li'); + var steps = document.querySelectorAll('.task-list li'); if (steps.length) { var header = document.querySelector('header[role="banner"]'); var stepIndicator = document.createElement('div'); diff --git a/core/themes/seven/maintenance-page.css b/core/themes/seven/maintenance-page.css new file mode 100644 index 0000000000000000000000000000000000000000..bc56fa065b57e6077a25b98eef785b66b60762df --- /dev/null +++ b/core/themes/seven/maintenance-page.css @@ -0,0 +1,184 @@ +/** + * @file + * Maintenance theming. + */ +.maintenance-background { + background-color: #e0e0d8; + background-image: -webkit-radial-gradient(hsl(203, 2%, 90%), hsl(203, 2%, 95%)); + background-image: -moz-radial-gradient(hsl(203, 2%, 90%), hsl(203, 2%, 95%)); + background-image: -o-radial-gradient(hsl(203, 2%, 90%), hsl(203, 2%, 95%)); + background-image: radial-gradient(hsl(203, 2%, 90%), hsl(203, 2%, 95%)); + background-repeat: repeat; + background-position: left top, 50% 50%; + min-height: 100%; +} + +/* Maintenance theming */ +.install-page, +.in-maintenance { + background: none; +} +.name-and-slogan h1 { + font-size: 2em; + line-height: 1.2em; + color: #0074bd; +} + +/** + * Task list & step indicator + */ +@media all and (max-width: 48em) { /* 768px */ + header[role="banner"] { + position: relative; + } + .step-indicator { + display: block; + font-size: 1.385em; + position: absolute; + top: 0.2em; + right: 0.5em; + } + [dir="rtl"] .step-indicator { + left: 2em; + right: auto; + } + .task-list { + display: none; + } +} + +@media all and (min-width: 48em) { /* 768px */ + .step-indicator { + display: none; + } + .task-list { + margin-left: 0; /* LTR */ + list-style-type: none; + list-style-image: none; + padding-left: 0; /* LTR */ + padding-bottom: 1em; + } + [dir="rtl"] .task-list { + margin-right: 0; + padding-right: 0; + } + .task-list li { + padding: 0.5em 1em 0.5em 3.85em; /* LTR */ + color: #1a1a1a; + } + [dir="rtl"] .task-list li { + padding: 0.5em 1em 0.5em 1em; + } + .task-list .active { + background: #ebeae4; + position: relative; + font-weight: normal; + } + .task-list .active:after { + left: 100%; /* LTR */ + border: solid transparent; + border-color: rgba(235, 234, 228, 0); + border-left-color: #ebeae4; /* LTR */ + border-width: 1.35em; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + top: 50%; + margin-top: -1.32em; + } + [dir="rtl"] .task-list .active:after { + left: auto; + right: 100%; + border-left-color: transparent; + border-right-color: #ebeae4; + } + .task-list .done { + color: #adadad; + } +} + +/** + * Layout + */ +.l-container { + background: #fff; + width: auto; + margin-left: 1.25em; + margin-right: 1.25em; +} +.l-container:after { /* no reason for a clearfix in the markup */ + content: ""; + display: table; + clear: both; +} +@media all and (max-width: 48em) { /* 768px */ + .l-container { + margin: 1.25em; + padding: 10px 20px; + } + .name-and-slogan { + margin: 0 0 1.45em 0; + } +} + +@media all and (min-width: 48em) { /* 768px */ + html { + display: table; + } + .in-maintenance, + .install-page { + display: table-cell; + padding: 1em 0; + vertical-align: middle; + } + html, .install-page, .in-maintenance { + margin: 0; + width: 100%; + height: 100%; + } + .l-container { + margin: 0 auto; + max-width: 770px; + width: 75%; + border-radius: 5px; + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); + padding: 20px 0 40px 0; + } + + /* Positioning sidebar & content */ + main { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + clear: none; + float: left; + padding-left: 3.85em; + padding-right: 3.85em; + width: 65%; + } + [dir="rtl"] main { + float: right; + } + ul { + padding: 15px; + margin: 0.25em 0; + } + .l-sidebar-first { + float: left; + width: 35%; + } + [dir="rtl"] .l-sidebar-first { + float: right; + } + + /* Margins for sitename */ + h1.page-title, + .name-and-slogan h1 { + margin: 0.75em 0 0.75em 1.9em; /* LTR */ + } + [dir="rtl"] .name-and-slogan h1 { + margin: 0.75em 1.9em 0.75em 0; + } +} diff --git a/core/themes/seven/seven.base.css b/core/themes/seven/seven.base.css index 59f4d5e5f5a3b303fbb884d69b944649ddd569fc..844712dad19701258842a953b4ee6f234c58c436 100644 --- a/core/themes/seven/seven.base.css +++ b/core/themes/seven/seven.base.css @@ -116,6 +116,7 @@ ul { ol { list-style-type: decimal; margin: 0.25em 0 0.25em 2em; /* LTR */ + padding: 0; } [dir="rtl"] ol { margin: 0.25em 2em 0.25em 0; diff --git a/core/themes/seven/seven.libraries.yml b/core/themes/seven/seven.libraries.yml index 4d0dac11c48a7e52d429d1fdcb881941edcac80e..fb22ac1287a4147a06f2c6e049fc9b33627c93f8 100644 --- a/core/themes/seven/seven.libraries.yml +++ b/core/themes/seven/seven.libraries.yml @@ -1,3 +1,13 @@ +maintenance-page: + version: VERSION + js: + js/mobile.install.js: {} + css: + theme: + maintenance-page.css: {} + dependencies: + - system/maintenance + install-page: version: VERSION js: diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme index 6f5ce6b3f0c01933c714956ad96eeae092199257..c0a5a086817eded0996e2b55dabe98793fb0c475 100644 --- a/core/themes/seven/seven.theme +++ b/core/themes/seven/seven.theme @@ -274,7 +274,32 @@ function seven_preprocess_install_page(&$variables) { // Normally we could attach libraries via hook_page_alter(), but when the // database is inactive it's not called so we add them here. - $libraries['#attached']['library'][] = 'seven/install-page'; + $libraries = array( + '#attached' => array( + 'library' => array( + 'seven/maintenance-page', + 'seven/install-page', + ), + ), + ); + drupal_render($libraries); +} + +/** + * Implements hook_preprocess_maintenance_page(). + */ +function seven_preprocess_maintenance_page(&$variables) { + $variables['styles'] = new RenderWrapper('drupal_get_css'); + $variables['scripts'] = new RenderWrapper('drupal_get_js'); + // // Normally we could attach libraries via hook_page_alter(), but when the + // // database is inactive it's not called so we add them here. + $libraries = array( + '#attached' => array( + 'library' => array( + 'seven/maintenance-page', + ), + ), + ); drupal_render($libraries); } diff --git a/core/themes/seven/style.css b/core/themes/seven/style.css index 2fba3e361b0ed1950c514baf04a0895590ef278b..3370d5818d076e62c9eb1088fdc187dde0f9cca9 100644 --- a/core/themes/seven/style.css +++ b/core/themes/seven/style.css @@ -992,87 +992,6 @@ div.admin-options div.form-item { border: none; } -/* Maintenance theming */ -body.in-maintenance #sidebar-first { - float: left; /* LTR */ - max-width: 200px; - width: 25%; -} -[dir="rtl"] body.in-maintenance #sidebar-first { - float: right; -} -body.in-maintenance #content { - float: right; /* LTR */ - clear: none; - width: 72%; -} -[dir="rtl"] body.in-maintenance #content { - float: left; -} -body.in-maintenance #page { - max-width: 770px; - margin: 0 auto; - padding-top: 2em; - width: 90%; -} -body.in-maintenance .branding__inner { - max-width: 770px; - margin: 0 auto; - float: none; - width: 90%; -} -body.in-maintenance .form-radios .form-type-radio { - padding: 2px 0; -} -body.in-maintenance div.form-item:after { - content: ""; - display: none; - clear: none; -} -body.in-maintenance .form-submit { - display: block; -} -body.in-maintenance #logo { - margin-bottom: 1.5em; - max-width: 180px; -} -@media all and (max-width: 768px) { - body.in-maintenance #sidebar-first, - body.in-maintenance #content { - float: none; - max-width: none; - width: auto; - } -} -.task-list { - margin-left: 0; /* LTR */ - list-style-type: none; - list-style-image: none; -} -[dir="rtl"] .task-list { - margin-right: 0; -} -.task-list li { - padding: 0.5em 1em 0.5em 20px; /* LTR */ - color: #adadad; -} -[dir="rtl"] .task-list li { - padding: 0.5em 20px 0.5em 1em; -} -.task-list li.active { - background: transparent url(images/task-item.png) no-repeat 3px 50%; /* LTR */ - padding: 0.5em 1em 0.5em 20px; /* LTR */ - color: #000; -} -[dir="rtl"] .task-list li.active { - background: transparent url(images/task-item-rtl.png) no-repeat right 50%; - padding: 0.5em 20px 0.5em 1em; -} -.task-list li.done { - background: transparent url(images/task-check.png) no-repeat 0 50%; - color: green; -} - /* Field UI */ #field-display-overview input.field-plugin-settings-edit { diff --git a/core/themes/seven/templates/maintenance-page.html.twig b/core/themes/seven/templates/maintenance-page.html.twig index dc691c17b31ea5734fba65424d1be98ce531e329..a3d78d1461cb764e957ead01368e32af1ef11e49 100644 --- a/core/themes/seven/templates/maintenance-page.html.twig +++ b/core/themes/seven/templates/maintenance-page.html.twig @@ -12,47 +12,53 @@ */ #} <!DOCTYPE html> -<html{{ html_attributes }}> - <head> - <title>{{ head_title }}</title> - {{ head }} - {{ styles }} - {{ scripts }} - </head> - <body{{ attributes }}> +<html{{ html_attributes }} class="maintenance-background"> +<head> + {{ head }} + <title>{{ head_title }}</title> + {{ styles }} + {{ scripts }} +</head> +<body{{ attributes }}> + +<div class="l-container"> {{ page_top }} - <header id="branding"> - <div class="branding__inner"> - {% if title %}<h1 class="page-title">{{ title }}</h1>{% endif %} - </div> + <header role="banner"> + {% if site_name or site_slogan %} + <div class="name-and-slogan"> + {% if site_name %} + <h1>{{ site_name }}</h1> + {% endif %} + {% if site_slogan %} + <div class="site-slogan">{{ site_slogan }}</div> + {% endif %} + </div>{# /.name-and-slogan #} + {% endif %} </header> - <div id="page"> - <div id="sidebar-first" class="sidebar"> - {% if logo %} - <img id="logo" src="{{ logo }}" alt="{{ site_name }}" /> - {% endif %} + {% if sidebar_first %} + <aside class="l-sidebar-first" role="complementary"> {{ sidebar_first }} - </div> - - <main id="content" class="clearfix"> - {% if messages %} - <div id="console">{{ messages }}</div> - {% endif %} - {% if help %} - <div id="help"> - {{ help }} - </div> - {% endif %} - {{ content }} - </main> - </div> - - <footer role="contentinfo"> - {{ page_bottom }} - </footer> - - </body> + </aside>{# /.l-sidebar-first #} + {% endif %} + + <main role="main"> + {% if title %} + <h1>{{ title }}</h1> + {% endif %} + {{ messages }} + {{ content }} + </main> + + {% if footer %} + <footer role="contentinfo"> + {{ footer }} + </footer> + {% endif %} + +</div>{# /.l-container #} + +</body> </html> diff --git a/core/update.php b/core/update.php index cd94972eafadf95c48186c57a02a9d32afa6d476..8f7c325707b270ae99f92ad8e4364459dcaed441 100644 --- a/core/update.php +++ b/core/update.php @@ -211,7 +211,7 @@ function update_info_page() { $output .= "</ol>\n"; $output .= "<p>When you have performed the steps above, you may proceed.</p>\n"; $form_action = check_url(drupal_current_script_url(array('op' => 'selection', 'token' => $token))); - $output .= '<form method="post" action="' . $form_action . '"><p><input type="submit" value="Continue" class="form-submit button button-primary" /></p></form>'; + $output .= '<form method="post" action="' . $form_action . '"><div class="form-actions form-wrapper" id="edit-actions"><input type="submit" value="Continue" class="button button--primary form-submit" /></div></form>'; $output .= "\n"; $build = array(