diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index 751fb51..e65a2cc 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -716,27 +716,6 @@ function shortcut_preprocess_page(&$variables) { * Implements hook_toolbar(). */ function shortcut_toolbar() { - $items['shortcuts'] = array( - 'tab' => array( - 'title' => t('Shortcuts'), - 'href' => 'admin/config/user-interface/shortcut', - 'html' => FALSE, - 'attributes' => array( - 'title' => t('Shortcuts'), - ), - ), - 'tray' => array( - '#pre_render' => array('shortcut_toolbar_pre_render'), - ), - 'weight' => -10, - ); - return $items; -} - -/** - * Pre-render function for adding shortcuts to the toolbar. - */ -function shortcut_toolbar_pre_render($toolbar) { $links = shortcut_renderable_links(); $links['#attached'] = array( 'css' => array( @@ -755,7 +734,7 @@ function shortcut_toolbar_pre_render($toolbar) { ); } - $links_wrapper = array( + $links_tray = array( 'shortcuts' => array( '#type' => 'container', '#attributes' => array( @@ -766,7 +745,19 @@ function shortcut_toolbar_pre_render($toolbar) { 'configure' => $configure_link, ); - return $links_wrapper; + $items['shortcuts'] = array( + 'tab' => array( + 'title' => t('Shortcuts'), + 'href' => 'admin/config/user-interface/shortcut', + 'html' => FALSE, + 'attributes' => array( + 'title' => t('Shortcuts'), + ), + ), + 'tray' => $links_tray, + 'weight' => -10, + ); + return $items; } /** diff --git a/core/modules/toolbar/config/toolbar.breakpoints.yml b/core/modules/toolbar/config/toolbar.breakpoints.yml index 1acf114..6c1ac8c 100644 --- a/core/modules/toolbar/config/toolbar.breakpoints.yml +++ b/core/modules/toolbar/config/toolbar.breakpoints.yml @@ -1 +1,2 @@ +narrow: 'all and (min-width: 38.125em)' wide: 'all and (min-width: 50em)' diff --git a/core/modules/toolbar/config/toolbar.config.yml b/core/modules/toolbar/config/toolbar.config.yml index 79522f0..8a98715 100644 --- a/core/modules/toolbar/config/toolbar.config.yml +++ b/core/modules/toolbar/config/toolbar.config.yml @@ -1,2 +1,3 @@ breakpoints: + - 'module.toolbar.narrow' - 'module.toolbar.wide' diff --git a/core/modules/toolbar/css/toolbar.base.css b/core/modules/toolbar/css/toolbar.base.css index 08481df..ba9624a 100644 --- a/core/modules/toolbar/css/toolbar.base.css +++ b/core/modules/toolbar/css/toolbar.base.css @@ -135,10 +135,10 @@ class .toolbar-main */ * At larger screen sizes, the tray pushes the page content * using padding instead of left. */ -@media screen and (min-width: 28.125em) { +@media screen and (min-width: 38.125em) { body.toolbar-tray-open.toolbar-vertical { - padding-left: 240px; - padding-left: 15rem; + margin-left: 240px; + margin-left: 15rem; } } /** diff --git a/core/modules/toolbar/css/toolbar.icons.css b/core/modules/toolbar/css/toolbar.icons.css index 6293a4f..35457d6 100644 --- a/core/modules/toolbar/css/toolbar.icons.css +++ b/core/modules/toolbar/css/toolbar.icons.css @@ -71,8 +71,8 @@ .toolbar-main .bar .tab, .toolbar-main .bar .active .tab, .toolbar-main .bar .tab:active { - background-position: 0.5em center; - padding-left: 2.5em; /* LTR */ + background-position: 1em center; + padding-left: 3.25em; /* LTR */ text-indent: 0; width: auto; } diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js index a871394..f479c47 100644 --- a/core/modules/toolbar/js/toolbar.js +++ b/core/modules/toolbar/js/toolbar.js @@ -15,19 +15,21 @@ Drupal.toolbar = Drupal.toolbar || {}; var activeTab = JSON.parse(localStorage.getItem('Drupal.toolbar.activeTab')); /** - * Store the state of the tray orientations to maintain them across page loads. + * Store the state of the trays to maintain them across page loads. */ -var trayOrientations = JSON.parse(localStorage.getItem('Drupal.toolbar.trayOrientations')) || []; +var orientation = JSON.parse(localStorage.getItem('Drupal.toolbar.trayOrientation')) || 'vertical'; +var locked = JSON.parse(localStorage.getItem('Drupal.toolbar.trayLocked')) || false; /** - * Holds the jQuery object of the toolbar DOM element. + * Holds the jQuery objects of the toolbar DOM element and the trays. */ var $toolbar; +var $trays; /** * Holds the mediaQueryList object. */ - var mql; +var mql; /** * Register tabs with the toolbar. @@ -35,7 +37,7 @@ var $toolbar; * The Drupal toolbar allows modules to register top-level tabs. These may point * directly to a resource or toggle the visibility of a tray. * - * Modules register tabs with hook_toolbar. + * Modules register tabs with hook_toolbar(). */ Drupal.behaviors.toolbar = { attach: function(context) { @@ -43,29 +45,25 @@ Drupal.behaviors.toolbar = { $toolbar = $(context).find('#toolbar').once('toolbar'); if ($toolbar.length) { $toolbar.addClass('toolbar-main'); - // Set the initial orientation of the trays. - var $tray = $toolbar.find('.tray') - .attr('data-toolbar-orientation', 'vertical') - .addClass('vertical'); - // Add the tray orientation toggles. - $tray + // Store the trays in a scoped variable. + $trays = $toolbar.find('.tray'); + $trays + // Add the tray orientation toggles. .find('.lining') .append(Drupal.theme('toolbarOrientationToggle')); - + // Set the active state of the orientation toggles. + changeOrientation(orientation, locked); // Set up switching between the vertical and horizontal presentation // of the toolbar trays based on a breakpoint. - if (options.breakpoints && typeof options.breakpoints['module.toolbar.wide'] !== 'undefined') { - mql = window.matchMedia(options.breakpoints['module.toolbar.wide']); - mql.addListener(Drupal.toolbar.mediaQueryChangeHandler); - if (mql.matches) { - Drupal.toolbar.mediaQueryChangeHandler(mql); - } + mql = window.matchMedia(options.breakpoints['module.toolbar.wide']); + mql.addListener(Drupal.toolbar.mediaQueryChangeHandler); + if (mql.matches) { + Drupal.toolbar.mediaQueryChangeHandler(mql); } - // Recalculate the offset top of the toolbar once on initialization. - Drupal.toolbar.setHeight(); // Call setHeight on screen resize. Wrap it in debounce to prevent // setHeight from being called too frequently. var setHeight = Drupal.debounce(Drupal.toolbar.setHeight, 250); + // Attach behavior to the window. $(window) .on('resize.toolbar', setHeight); // Attach behaviors to the toolbar. @@ -74,12 +72,22 @@ Drupal.behaviors.toolbar = { .on('click.toolbar', '.toggle-orientation button', Drupal.toolbar.orientationChangeHandler); // Decorate the main menu with an interactive menu. $toolbar.find('.administration.tray .interactive-menu > .menu').interactiveMenu(); - // Restore the toolbar to its saved state. - restoreState(); + // Restore the open tab. Only open the tab on wide screens. + if (activeTab && window.matchMedia(options.breakpoints['module.toolbar.narrow']).matches) { + $toolbar.find('[data-toolbar-tray="' + activeTab + '"].tab').trigger('click.toolbar'); + } + // Recalculate the offset top of the toolbar once on initialization. + else { + Drupal.toolbar.setHeight(); + } } }, + // Default options. options: { - breakpoints: null + breakpoints: { + 'module.toolbar.narrow': '', + 'module.toolbar.wide': '' + } } }; /** @@ -121,7 +129,6 @@ Drupal.toolbar.toggleTray = function (event) { */ Drupal.toolbar.setHeight = function () { // Set the top of the all the trays to the height of the bar. - var $trays = $toolbar.find('.tray'); var barHeight = $toolbar.find('.bar').outerHeight(); var height = barHeight; var bhpx = barHeight + 'px'; @@ -146,18 +153,18 @@ Drupal.toolbar.setHeight = function () { } }; /** - * + * Respond to configured media query applicability changes. */ Drupal.toolbar.mediaQueryChangeHandler = function (mql) { var orientation = (mql.matches) ? 'horizontal' : 'vertical'; - changeOrientation($toolbar.find('.tray'), orientation); + changeOrientation(orientation); // Adjust the body to accommodate trays. setBodyState(); // Adjust the height of the toolbar. Drupal.toolbar.setHeight(); }; /** - * + * Respond to the toggling of the tray orientation. */ Drupal.toolbar.orientationChangeHandler = function (event) { event.preventDefault(); @@ -165,73 +172,49 @@ Drupal.toolbar.orientationChangeHandler = function (event) { var $button = $(event.target); var orientation = event.target.value; var $tray = $button.closest('.tray'); - changeOrientation($tray, orientation, true); + changeOrientation(orientation, true); // Adjust the body to accommodate trays. setBodyState(); // Adjust the height of the toolbar. Drupal.toolbar.setHeight(); }; + /** + * Change the orientation of the tray between vertical and horizontal. * - */ -function restoreState () { - // Restore the open tab. - // Only open the tab on wide screens. - if (activeTab && mql.matches) { - $toolbar.find('[data-toolbar-tray="' + activeTab + '"].tab').trigger('click.toolbar'); - } - // Restore tray orientations. - if (trayOrientations.length) { - var $trays = $toolbar.find('.tray'); - var $tray; - for (var i = 0, il = trayOrientations.length; i < il; i++) { - $tray = $trays.filter('[data-toolbar-tray="' + trayOrientations[i].tray + '"]'); - changeOrientation($tray, trayOrientations[i].orientation, true); - } - } - // Adjust the body to accomodate trays. - setBodyState(); - // Adjust the height of the toolbar. - Drupal.toolbar.setHeight(); -} -/** + * @param {String} newOrientation + * Either 'vertical' or 'horizontal'. The orientation to change the tray to. * + * @param {Boolean} isLock + * Whether the orientation of the tray should be locked if it is being toggled + * to vertical. */ -function changeOrientation ($trays, orientation, isOverride) { - for (var i = 0, il = $trays.length; i < il; i++) { - var $tray = $trays.eq(i); - if (isOverride) { - var locked = orientation === 'vertical'; - $tray.attr('data-toolbar-orientation-locked', JSON.stringify(locked)); +function changeOrientation (newOrientation, isLock) { + var oldOrientation = orientation; + if (isLock) { + locked = (newOrientation === 'vertical'); + if (locked) { + localStorage.setItem('Drupal.toolbar.trayLocked', JSON.stringify(locked)); } - var currentOrientation = $tray.attr('data-toolbar-orientation'); - var isOrientationLocked = JSON.parse($tray.attr('data-toolbar-orientation-locked') || null); - if ((!isOrientationLocked && orientation === 'horizontal' && currentOrientation === 'vertical') - || (orientation === 'vertical' && currentOrientation === 'horizontal')) { - $tray.attr('data-toolbar-orientation', orientation) - .removeClass('horizontal vertical') - .addClass(orientation); - toggleOrientationToggle($tray, currentOrientation); + else { + localStorage.removeItem('Drupal.toolbar.trayLocked'); } } - // Save the state of overridden trays. - function getTrayOrientation (index, tray) { - var $tray = $(tray); - return { - 'tray': $tray.attr('data-toolbar-tray'), - 'orientation': $tray.attr('data-toolbar-orientation') || 'vertical' - }; + if ((!locked && newOrientation === 'horizontal') || newOrientation === 'vertical') { + $trays + .removeClass('horizontal vertical') + .addClass(newOrientation); + orientation = newOrientation; + toggleOrientationToggle((newOrientation === 'vertical') ? 'horizontal' : 'vertical'); } - - var traysState = $toolbar.find('[data-toolbar-orientation-locked="true"]').map(getTrayOrientation); - localStorage.setItem('Drupal.toolbar.trayOrientations', JSON.stringify(traysState.get())); + // Store the orientation to maintain it across page loads. + localStorage.setItem('Drupal.toolbar.trayOrientation', JSON.stringify(newOrientation)); } /** - * + * Mark up the body tag to reflect the current state of the toolbar. */ function setBodyState () { - var $activeTray = $toolbar.find('.tray.active'); - var orientation = $activeTray.attr('data-toolbar-orientation'); + var $activeTray = $trays.filter('.active'); $('body') .toggleClass('toolbar-tray-open', !!$activeTray.length) .toggleClass('toolbar-vertical', (!!$activeTray.length && orientation === 'vertical')) @@ -240,12 +223,9 @@ function setBodyState () { /** * Change the orientation toggle active state. */ -function toggleOrientationToggle ($trays, orientation) { - for (var i = 0, il = $trays.length; i < il; i++) { - var $tray = $trays.eq(i); - $tray.find('.toggle-orientation button').removeClass('active'); - $tray.find('.toggle-orientation button[value="' + orientation + '"]').addClass('active'); - } +function toggleOrientationToggle (orientation) { + $trays.find('.toggle-orientation button').removeClass('active'); + $trays.find('.toggle-orientation button[value="' + orientation + '"]').addClass('active'); } /** diff --git a/core/modules/toolbar/toolbar.install b/core/modules/toolbar/toolbar.install new file mode 100644 index 0000000..aa8c3d6 --- /dev/null +++ b/core/modules/toolbar/toolbar.install @@ -0,0 +1,28 @@ +mediaQuery;}, // Log a warning if the tab is already defined. if (array_key_exists($category, $toolbar_tabs)) { watchdog('toolbar', 'Toolbar tab %category is already defined.', - array('$category' => $category) + array('%category' => $category) ); } @@ -241,10 +243,15 @@ function($object) {return $object->mediaQuery;}, ); // Assign the trays to the build. - $build['toolbar_trays'] = array( - '#theme' => 'toolbar_tray', - '#trays' => $toolbar_trays, - ); + $build['toolbar_trays'] = array(); + foreach ($toolbar_trays as $key => $tray) { + if (!isset($tray['#theme_wrappers'])) { + $tray['#theme_wrappers'] = array(); + } + $tray['#theme_wrappers'][] = 'toolbar_tray'; + $tray['#name'] = $key; + $build['toolbar_trays'][$key] = $tray; + } return $build; } @@ -290,17 +297,37 @@ function toolbar_menu_navigation_links(&$tree) { } /** - * + * Preprocess variables for theme_toolbar_tray(). */ -function theme_toolbar_tray($trays) { - $output = ''; - - foreach ($trays['element']['#trays'] as $key => $tray) { - $output .= ''; - } +function template_preprocess_toolbar_tray(&$variables) { + $name = $variables['element']['#name']; + // Provide a content property to easily reference the rendered content + // of the tray. + $variables['content'] = $variables['element']['#children']; + $variables['attributes'] = array( + 'id' => 'toolbar-tray-' . $name, + 'class' => array( + 'tray', + $name, + ), + 'data-toolbar-tray' => $name, + ); + $variables['theme_hook_suggestions'][] = 'toolbar_tray__' . $name; +} +/** + * Returns HTML for wrapping content in a toolbar tray. + * + * @param array $variables + * An associative array containing: + * - attributes: Associative array of attributes to be placed in the nav tag. + * - content: The rendered content of the toolbar tray. + */ +function theme_toolbar_tray($variables) { + $output = ''; return $output; } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index ed421ca..2e4b5ed 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -3105,30 +3105,6 @@ function user_file_download_access($field, EntityInterface $entity, File $file) function user_toolbar() { global $user; - $items['user'] = array( - 'tab' => array( - 'title' => user_format_name($user), - 'href' => 'user', - 'html' => FALSE, - 'attributes' => array( - 'title' => t('My account'), - ), - ), - 'tray' => array( - '#pre_render' => array('user_toolbar_pre_render'), - ), - 'weight' => -5, - ); - - return $items; -} - -/** - * Pre-render function for adding user account actions to the toolbar. - */ -function user_toolbar_pre_render($toolbar) { - global $user; - // Add logout & user account links or login link. if ($user->uid) { $links = array( @@ -3155,7 +3131,7 @@ function user_toolbar_pre_render($toolbar) { ); } - $user_links = array( + $user_tray = array( '#theme' => 'links__toolbar_user', '#links' => $links, '#attributes' => array( @@ -3164,7 +3140,20 @@ function user_toolbar_pre_render($toolbar) { '#heading' => array('text' => t('User account actions'), 'level' => 'h2', 'class' => 'element-invisible'), ); - return $user_links; + $items['user'] = array( + 'tab' => array( + 'title' => user_format_name($user), + 'href' => 'user', + 'html' => FALSE, + 'attributes' => array( + 'title' => t('My account'), + ), + ), + 'tray' => $user_tray, + 'weight' => 100, + ); + + return $items; } /** diff --git a/core/profiles/standard/standard.info b/core/profiles/standard/standard.info index 4c812d0..4fb4d6c 100644 --- a/core/profiles/standard/standard.info +++ b/core/profiles/standard/standard.info @@ -4,6 +4,7 @@ version = VERSION core = 8.x dependencies[] = node dependencies[] = block +dependencies[] = breakpoint dependencies[] = color dependencies[] = config dependencies[] = comment