Chris@0: /** Chris@0: * @file Chris@0: * Builds a nested accordion widget. Chris@0: * Chris@0: * Invoke on an HTML list element with the jQuery plugin pattern. Chris@0: * Chris@0: * @example Chris@0: * $('.toolbar-menu').drupalToolbarMenu(); Chris@0: */ Chris@0: Chris@17: (function($, Drupal, drupalSettings) { Chris@0: /** Chris@0: * Store the open menu tray. Chris@0: */ Chris@0: let activeItem = Drupal.url(drupalSettings.path.currentPath); Chris@0: Chris@17: $.fn.drupalToolbarMenu = function() { Chris@0: const ui = { Chris@0: handleOpen: Drupal.t('Extend'), Chris@0: handleClose: Drupal.t('Collapse'), Chris@0: }; Chris@0: Chris@0: /** Chris@17: * Toggle the open/close state of a list is a menu. Chris@17: * Chris@17: * @param {jQuery} $item Chris@17: * The li item to be toggled. Chris@17: * Chris@17: * @param {Boolean} switcher Chris@17: * A flag that forces toggleClass to add or a remove a class, rather than Chris@17: * simply toggling its presence. Chris@17: */ Chris@17: function toggleList($item, switcher) { Chris@17: const $toggle = $item Chris@17: .children('.toolbar-box') Chris@17: .children('.toolbar-handle'); Chris@17: switcher = Chris@17: typeof switcher !== 'undefined' ? switcher : !$item.hasClass('open'); Chris@17: // Toggle the item open state. Chris@17: $item.toggleClass('open', switcher); Chris@17: // Twist the toggle. Chris@17: $toggle.toggleClass('open', switcher); Chris@17: // Adjust the toggle text. Chris@17: $toggle Chris@17: .find('.action') Chris@17: // Expand Structure, Collapse Structure. Chris@17: .text(switcher ? ui.handleClose : ui.handleOpen); Chris@17: } Chris@17: Chris@17: /** Chris@0: * Handle clicks from the disclosure button on an item with sub-items. Chris@0: * Chris@0: * @param {Object} event Chris@0: * A jQuery Event object. Chris@0: */ Chris@0: function toggleClickHandler(event) { Chris@0: const $toggle = $(event.target); Chris@0: const $item = $toggle.closest('li'); Chris@0: // Toggle the list item. Chris@0: toggleList($item); Chris@0: // Close open sibling menus. Chris@0: const $openItems = $item.siblings().filter('.open'); Chris@0: toggleList($openItems, false); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Handle clicks from a menu item link. Chris@0: * Chris@0: * @param {Object} event Chris@0: * A jQuery Event object. Chris@0: */ Chris@0: function linkClickHandler(event) { Chris@0: // If the toolbar is positioned fixed (and therefore hiding content Chris@0: // underneath), then users expect clicks in the administration menu tray Chris@0: // to take them to that destination but for the menu tray to be closed Chris@0: // after clicking: otherwise the toolbar itself is obstructing the view Chris@0: // of the destination they chose. Chris@0: if (!Drupal.toolbar.models.toolbarModel.get('isFixed')) { Chris@0: Drupal.toolbar.models.toolbarModel.set('activeTab', null); Chris@0: } Chris@0: // Stopping propagation to make sure that once a toolbar-box is clicked Chris@0: // (the whitespace part), the page is not redirected anymore. Chris@0: event.stopPropagation(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Add markup to the menu elements. Chris@0: * Chris@0: * Items with sub-elements have a list toggle attached to them. Menu item Chris@0: * links and the corresponding list toggle are wrapped with in a div Chris@0: * classed with .toolbar-box. The .toolbar-box div provides a positioning Chris@0: * context for the item list toggle. Chris@0: * Chris@0: * @param {jQuery} $menu Chris@0: * The root of the menu to be initialized. Chris@0: */ Chris@0: function initItems($menu) { Chris@0: const options = { Chris@0: class: 'toolbar-icon toolbar-handle', Chris@0: action: ui.handleOpen, Chris@0: text: '', Chris@0: }; Chris@0: // Initialize items and their links. Chris@0: $menu.find('li > a').wrap('