diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index c7a647d..42c049b 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -734,26 +734,25 @@ function shortcut_toolbar() { ); } - $links_tray = array( - '#heading' => t('User-defined shortcuts'), - 'shortcuts' => $links, - 'configure' => $configure_link, - ); - $items['shortcuts'] = array( - 'tab' => array( - '#title' => t('Shortcuts'), - '#href' => 'admin/config/user-interface/shortcut', - '#options' => array( - 'html' => FALSE, - 'attributes' => array( - 'title' => t('Shortcuts'), - 'class' => array('icon', 'icon-shortcut'), - ), + "#theme_wrappers" => array('toolbar_tab_wrapper'), + '#theme' => 'toolbar_tray_toggle', + '#text' => t('Shortcuts'), + '#path' => 'admin/config/user-interface/shortcut', + '#options' => array( + 'html' => FALSE, + 'attributes' => array( + 'title' => t('Shortcuts'), + 'class' => array('icon', 'icon-shortcut'), ), ), - 'tray' => $links_tray, - 'weight' => -10, + '#tray' => array( + '#theme_wrappers' => array('toolbar_tray_wrapper'), + '#heading' => t('User-defined shortcuts'), + 'shortcuts' => $links, + 'configure' => $configure_link, + ), + '#weight' => -10, ); return $items; } diff --git a/core/modules/toolbar/css/toolbar.base.css b/core/modules/toolbar/css/toolbar.base.css index cbdf153..1dc640b 100644 --- a/core/modules/toolbar/css/toolbar.base.css +++ b/core/modules/toolbar/css/toolbar.base.css @@ -43,8 +43,8 @@ html.js .toolbar { .js .toolbar .menu li { display: block; } -.js .toolbar .bar li, -.js .toolbar .horizontal li { +.js .toolbar .bar .tab, +.js .toolbar .horizontal .tab { float: left; /* LTR */ } .js .toolbar a { diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js index 08a68d2..cd97b1d 100644 --- a/core/modules/toolbar/js/toolbar.js +++ b/core/modules/toolbar/js/toolbar.js @@ -78,7 +78,7 @@ Drupal.behaviors.toolbar = { // query application decide the orientation. changeOrientation((locked) ? 'vertical' : ((mql.wide.matches) ? 'horizontal' : 'vertical'), locked); // Render the main menu as a nested, collapsible accordion. - $toolbar.find('.administration.tray .toolbar-menu > .menu').toolbarMenu(); + $toolbar.find('.tray-administration .toolbar-menu > .menu').toolbarMenu(); // Call setHeight on screen resize. Wrap it in debounce to prevent // setHeight from being called too frequently. var setHeight = Drupal.debounce(Drupal.toolbar.setHeight, 200); diff --git a/core/modules/toolbar/templates/toolbar.twig b/core/modules/toolbar/templates/toolbar.twig index e72bc97..2e52bd2 100644 --- a/core/modules/toolbar/templates/toolbar.twig +++ b/core/modules/toolbar/templates/toolbar.twig @@ -5,17 +5,15 @@ * * Available variables: * - * - tab_heading: Translated header for the Tabs section. - * - tabs: Themed links for the top level tabs. - * - trays: An array of trays. It contains: - * - content: The themed tray content. - * - attributes: HTML attributes for the surrounding element. It includes: - * - id: The unique id of the tray. This corresponds to the module name - * registered the tray. - * - class: A list of classes to target the trays for styling. * - attributes: HTML attributes for the surrounding element. It includes: * - id: The unique id of the toolbar. * - class: A list of classes to target the toolbar for styling. + * - bar: Administration bar meta data and renderable content. It includes: + * - attributes: HTML attributes for the surrounding element. It includes: + * - id: The unique id of the bar. + * - class: A list of classes to target the bar for styling. + * - items: An array of renderable content. + * - trays: An array of renderable content. * * @see template_preprocess() * @see template_preprocess_toolbar() @@ -25,17 +23,11 @@ #} diff --git a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module index fa09015..63497c5 100644 --- a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module +++ b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module @@ -9,33 +9,33 @@ * Implements hook_toolbar(). */ function toolbar_test_toolbar() { - $tray_items = array( - l(t('link 1'), ''), - l(t('link 2'), ''), - l(t('link 3'), ''), - ); $items['testing'] = array( - 'tab' => array( - '#title' => t('Test tab'), - '#href' => '', - '#options' => array( - 'html' => FALSE, - 'attributes' => array( - 'title' => t('Test tab'), - ), + "#theme_wrappers" => array('toolbar_tab_wrapper'), + '#theme' => 'toolbar_tray_toggle', + '#text' => t('Test tab'), + '#path' => '', + '#options' => array( + 'html' => FALSE, + 'attributes' => array( + 'title' => t('Test tab'), ), ), - 'tray' => array( + '#tray' => array( '#heading' => t('Test tray'), + '#theme_wrappers' => array('toolbar_tray_wrapper'), 'content' => array( '#theme' => 'item_list', - '#items' => $tray_items, + '#items' => array( + l(t('link 1'), ''), + l(t('link 2'), ''), + l(t('link 3'), ''), + ), '#attributes' => array( 'class' => array('menu'), ), ), ), - 'weight' => 50, + '#weight' => 50, ); return $items; diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module index 5e76400..4b4e0d8 100644 --- a/core/modules/toolbar/toolbar.module +++ b/core/modules/toolbar/toolbar.module @@ -41,9 +41,18 @@ function toolbar_permission() { */ function toolbar_theme($existing, $type, $theme, $path) { $items['toolbar'] = array( - 'render element' => 'toolbar', + 'render element' => 'elements', 'template' => 'toolbar', ); + $items['toolbar_tab_wrapper'] = array( + 'render element' => 'element', + ); + $items['toolbar_tray_toggle'] = array( + 'variables' => array('text' => NULL, 'path' => NULL, 'options' => array(), 'toolbar_identifier' => NULL), + ); + $items['toolbar_tray_wrapper'] = array( + 'render element' => 'element', + ); return $items; } @@ -145,10 +154,6 @@ function toolbar_page_build(&$page) { */ function toolbar_pre_render($toolbar) { $toolbar = array_merge($toolbar, toolbar_view()); - $toolbar['tab_heading'] = array( - '#type' => 'markup', - '#markup' => t('Toolbar'), - ); return $toolbar; } @@ -166,29 +171,114 @@ function template_preprocess_toolbar(&$variables) { 'class' => array('toolbar', 'overlay-displace-top'), 'role' => 'navigation', )); + // Provide a convenience variable for the bar. + $variables['bar'] = array( + 'items' => array(), + 'attributes' => new Attribute( + array( + 'id' => 'toolbar-bar', + 'class' => array('bar', 'overlay-displace-top', 'clearfix'), + ) + ), + ); + // Provide a convenience variable for the trays. + $variables['trays'] = array(); + // Loop through the items. Pull out trays if defined under the #tray key. + foreach($variables['elements']['#items'] as $key => $item) { + $id = drupal_html_class($key); + $variables['bar']['items'][$key] = $item; + $variables['bar']['items'][$key]['#toolbar_identifier'] = $id; + if (in_array('#tray', array_keys($item)) && isset($item['#tray'])) { + $variables['trays'][$key] = $item['#tray']; + $variables['trays'][$key]['#toolbar_identifier'] = $id; + } + } + unset($variables['elements']['#items']); +} - // Provide a convenience variable for the themed tabs. - $variables['toolbar']['tabs']['#attributes']['class'][] = 'overlay-displace-top'; - $variables['tabs'] = $variables['toolbar']['tabs']; - $variables['tab_heading'] = $variables['toolbar']['tab_heading']; - - // Place the tabs in a top-level variable so that attribute information - // can be associated with each one. - foreach ($variables['toolbar']['trays'] as $key => $tray) { - // Create tray heading text. Prefer the provided heading text if it exists. - $heading = isset($tray['#heading']) ? $tray['#heading'] : t('@group actions', array('@group' => $key)); - - $variables['trays'][$key] = array( - 'heading' => $heading, - 'content' => $variables['toolbar']['trays'][$key], - 'attributes' => new Attribute(array( - 'id' => 'toolbar-tray-' . $key, - 'class' => array('tray', 'overlay-displace-top', $key), - 'data-toolbar-tray' => $key, - 'aria-owned-by' => 'toolbar-tab-' . $key, - ) - ), - ); +/** + * Returns HTML for wrapping a toolbar tab. + * + * Toolbar tabs have a common styling and placement with the toolbar's bar area. + * + * @param array $variables + * An associative array containing: + * - element: An associative array containing the properties and children of + * the tray. Properties used: #children and #attributes. + */ +function theme_toolbar_tab_wrapper(&$variables) { + $element = $variables['element']; + if (!empty($element['#children'])) { + $element['#attributes']['class'][] = 'tab'; + return '' . $element['#children'] . ''; + } +} + +/** + * Implements template_preprocess_HOOK(). + */ +function template_preprocess_toolbar_tray_toggle(&$variables) { + // Provide an id, a data attribute linking each tab to the corresponding + // tray and ARIA information. + if (!isset($variables['options']['attributes'])) { + $variables['options']['attributes'] = array(); + } + $variables['options']['attributes']['id'] = 'toolbar-tab-' . $variables['toolbar_identifier']; + $variables['options']['attributes']['data-toolbar-tray'] = $variables['toolbar_identifier']; + $variables['options']['attributes']['aria-owns'] = 'toolbar-tray-' . $variables['toolbar_identifier']; + $variables['options']['attributes']['role'] = 'button'; + $variables['options']['attributes']['class'][] = 'trigger'; + $variables['options']['attributes']['aria-pressed'] = 'false'; +} + +/** + * Returns HTML for toolbar tab that opens and closes a tray. + * + * Use in combination with theme_toolbar_tray_wrapper to create an + * association between a link tag in the administration bar and a tray. + * + * @param $variables + * An associative array containing the keys 'text', 'path', and 'options'. See + * the l() function for information about these variables. + * + * @see l() + */ +function theme_toolbar_tray_toggle(&$variables) { + return l($variables['text'], $variables['path'], $variables['options']); +} + +/** + * Returns HTML for wrapping a toolbar tray. + * + * Used in combination with theme_toolbar_tray_toggle() to create an + * association between a link tag in the administration bar and a tray. + * + * @param array $variables + * An associative array containing: + * - element: An associative array containing the properties and children of + * the tray. Properties used: #children, #toolbar_identifier, #attributes + * and #heading. + */ +function theme_toolbar_tray_wrapper(&$variables) { + $element = $variables['element']; + if (!empty($element['#children'])) { + if (!empty($element['#toolbar_identifier'])) { + $group = $element['#toolbar_identifier']; + if (!isset($element['#attributes'])) { + $element['#attributes'] = array(); + } + $element['#attributes'] += array( + 'id' => 'toolbar-tray-' . $group, + 'data-toolbar-tray' => $group, + 'aria-owned-by' => 'toolbar-tab-' . $group, + ); + $element['#attributes']['class'][] = 'tray'; + $element['#attributes']['class'][] = 'tray-' . $group; + $element['#attributes']['class'][] = 'overlay-displace-top'; + } + // Print a heading in the tray if one exists. + $heading = (isset($element['#heading'])) ? '

' . $element['#heading'] . '

' : ''; + return '
' . $heading . $variables['element']['#children'] . '
'; } } @@ -216,18 +306,18 @@ function toolbar_toolbar() { // The 'Home' tab is a simple link, with no corresponding tray. $items['home'] = array( - 'tab' => array( - '#title' => t('Home'), - '#href' => '', - '#options' => array( - 'html' => FALSE, - 'attributes' => array( - 'title' => t('Home page'), - 'class' => array('icon', 'icon-home'), - ), + '#theme_wrappers' => array('toolbar_tab_wrapper'), + '#theme' => 'link', + '#text' => t('Home'), + '#path' => '', + '#options' => array( + 'html' => FALSE, + 'attributes' => array( + 'title' => t('Home page'), + 'class' => array('icon', 'icon-home'), ), ), - 'weight' => -20, + '#weight' => -20, ); // Retrieve the administration menu from the database. @@ -237,6 +327,8 @@ function toolbar_toolbar() { toolbar_menu_navigation_links($tree); $menu = array( + '#theme_wrappers' => array('toolbar_tray_wrapper'), + '#heading' => t('Administration menu'), 'toolbar_administration' => array( '#type' => 'container', '#attributes' => array( @@ -244,7 +336,6 @@ function toolbar_toolbar() { ), 'administration_menu' => menu_tree_output($tree), ), - '#heading' => t('Administration menu'), ); // To conserve bandwidth, we only include the top-level links in the HTML. @@ -254,20 +345,22 @@ function toolbar_toolbar() { // @see toolbar_subtrees_jsonp() $menu['toolbar_administration']['#attached']['js'][url('toolbar/subtrees/' . _toolbar_get_subtree_hash())] = array('type' => 'external'); + // The administration element has a link that is themed to correspond to + // a toolbar tray. The tray contains the full administrative menu of the site. $items['administration'] = array( - 'tab' => array( - '#title' => t('Menu'), - '#href' => 'admin', - '#options' => array( - 'html' => FALSE, - 'attributes' => array( - 'title' => t('Admin menu'), - 'class' => array('icon', 'icon-menu'), - ), + "#theme_wrappers" => array('toolbar_tab_wrapper'), + '#theme' => 'toolbar_tray_toggle', + '#text' => t('Menu'), + '#path' => 'admin', + '#options' => array( + 'html' => FALSE, + 'attributes' => array( + 'title' => t('Admin menu'), + 'class' => array('icon', 'icon-menu'), ), ), - 'tray' => $menu, - 'weight' => -15, + '#tray' => $menu, + '#weight' => -15, ); return $items; @@ -284,80 +377,7 @@ function toolbar_toolbar() { */ function toolbar_view() { - // Get toolbar items from all modules that implement hook_toolbar(). - $toolbar_groups = module_invoke_all('toolbar'); - - // @todo Maybe define a new type with these defaults using - // hook_element_info(). - $tab_defaults = array( - '#type' => 'link', - '#title' => '', - '#href' => '', - '#options' => array( - 'html' => FALSE, - 'attributes' => new Attribute(), - ), - ); - - // For each $group, $toolbar_groups[$group] is an array with keys 'tab' - // (required), 'tray', and 'weight'. Keep this structure until we invoke - // hook_toolbar_alter(), so that other modules can easily change the - // 'weight' values. If 'tray' is defined, then add attributes to the tab. - foreach ($toolbar_groups as $group => &$items) { - if (!array_key_exists('tab', $items)) { - continue; - } - $tab = &$items['tab']; - // Merge in the defaults. - // @todo Maybe merge in $tab_defaults['options'] separately. Or use - // array_merge_recursive(). - $tab += $tab_defaults; - // Register a tray if one is associated with this tab. - if (array_key_exists('tray', $items) && !empty($items['tray'])) { - // Provide an id, a data attribute linking each tab to the corresponding - // tray and aria information. If another module defines these in - // hook_toolbar(), it had better know what it is doing. - $tab['#options']['attributes']['id'] = 'toolbar-tab-' . $group; - $tab['#options']['attributes']['data-toolbar-tray'] = $group; - $tab['#options']['attributes']['aria-owns'] = 'toolbar-tray-' . $group; - $tab['#options']['attributes']['role'] = 'button'; - $tab['#options']['attributes']['aria-pressed'] = 'false'; - } - } - unset($items); - - // Modules can make changes using hook_toolbar_alter(). Note that - // $toolbar_groups has the same structure as before; the only change is that - // we have added some attributes. - drupal_alter('toolbar', $toolbar_groups); - uasort($toolbar_groups, 'drupal_sort_weight'); - - // Start to build the render array. $build = array('#theme' => 'toolbar'); - $build['trays'] = array(); - $build['tabs'] = array( - '#type' => 'ul', - '#items' => array(), - '#theme' => 'item_list', - '#attributes' => array( - 'class' => array('bar', 'clearfix'), - ), - ); - - // Add the tabs and trays from the toolbar groups. - foreach ($toolbar_groups as $group => $items) { - if (!array_key_exists('tab', $items)) { - continue; - } - // Assign the tabs to the build. - $build['tabs']['#items'][$group] = $items['tab']; - if (array_key_exists('tray', $items) && !empty($items['tray'])) { - // Assign the tray to the build. - $build['trays'][$group] = $items['tray']; - } - } - - // Attach the toolbar library. $build['#attached']['library'][] = array('toolbar', 'toolbar'); // Get the configured breakpoints to switch from vertical to horizontal @@ -366,20 +386,25 @@ function toolbar_view() { if (!empty($breakpoints)) { $media_queries = array(); $media_queries['toolbar']['breakpoints'] = array_map( - function($object) {return $object->mediaQuery;}, + function ($object) { + return $object->mediaQuery; + }, $breakpoints->breakpoints ); $build['#attached']['js'][] = array( - 'type' => 'setting', 'data' => $media_queries, + 'type' => 'setting', ); - // Load the breakpoints for toolbar. - // foreach ($breakpoints->breakpoints as $key => $breakpoint) { - // $build['#attached']['js'][0]['data']['toolbar']['breakpoints'][$key] = $breakpoint->mediaQuery; - // } } + // Get toolbar items from all modules that implement hook_toolbar(). + $toolbar_items = module_invoke_all('toolbar'); + // Allow for altering of hook_toolbar(). + drupal_alter('toolbar', $toolbar_items); + + $build['#items'] = $toolbar_items; + return $build; } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 7cc4bca..e1266a8 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -3027,31 +3027,30 @@ function user_toolbar() { ); } - $user_tray = array( - '#heading' => t('User account actions'), - 'content' => array( - '#theme' => 'links__toolbar_user', - '#links' => $links, - '#attributes' => array( - 'class' => array('menu',), + $items['user'] = array( + "#theme_wrappers" => array('toolbar_tab_wrapper'), + '#theme' => 'toolbar_tray_toggle', + '#text' => user_format_name($user), + '#path' => 'user', + '#options' => array( + 'html' => FALSE, + 'attributes' => array( + 'title' => t('My account'), + 'class' => array('icon', 'icon-user'), ), ), - ); - - $items['user'] = array( - 'tab' => array( - '#title' => user_format_name($user), - '#href' => 'user', - '#options' => array( - 'html' => FALSE, - 'attributes' => array( - 'title' => t('My account'), - 'class' => array('icon', 'icon-user'), + '#tray' => array( + '#theme_wrappers' => array('toolbar_tray_wrapper'), + '#heading' => t('User account actions'), + 'user_links' => array( + '#theme' => 'links__toolbar_user', + '#links' => $links, + '#attributes' => array( + 'class' => array('menu',), ), ), ), - 'tray' => $user_tray, - 'weight' => 100, + '#weight' => 100, ); return $items;