db backup prior to drupal security update
[yaffs-website] / web / core / modules / toolbar / js / toolbar.menu.js
1 /**
2  * @file
3  * Builds a nested accordion widget.
4  *
5  * Invoke on an HTML list element with the jQuery plugin pattern.
6  *
7  * @example
8  * $('.toolbar-menu').drupalToolbarMenu();
9  */
10
11 (function ($, Drupal, drupalSettings) {
12
13   'use strict';
14
15   /**
16    * Store the open menu tray.
17    */
18   var activeItem = Drupal.url(drupalSettings.path.currentPath);
19
20   $.fn.drupalToolbarMenu = function () {
21
22     var ui = {
23       handleOpen: Drupal.t('Extend'),
24       handleClose: Drupal.t('Collapse')
25     };
26
27     /**
28      * Handle clicks from the disclosure button on an item with sub-items.
29      *
30      * @param {Object} event
31      *   A jQuery Event object.
32      */
33     function toggleClickHandler(event) {
34       var $toggle = $(event.target);
35       var $item = $toggle.closest('li');
36       // Toggle the list item.
37       toggleList($item);
38       // Close open sibling menus.
39       var $openItems = $item.siblings().filter('.open');
40       toggleList($openItems, false);
41     }
42
43     /**
44      * Handle clicks from a menu item link.
45      *
46      * @param {Object} event
47      *   A jQuery Event object.
48      */
49     function linkClickHandler(event) {
50       // If the toolbar is positioned fixed (and therefore hiding content
51       // underneath), then users expect clicks in the administration menu tray
52       // to take them to that destination but for the menu tray to be closed
53       // after clicking: otherwise the toolbar itself is obstructing the view
54       // of the destination they chose.
55       if (!Drupal.toolbar.models.toolbarModel.get('isFixed')) {
56         Drupal.toolbar.models.toolbarModel.set('activeTab', null);
57       }
58       // Stopping propagation to make sure that once a toolbar-box is clicked
59       // (the whitespace part), the page is not redirected anymore.
60       event.stopPropagation();
61     }
62
63     /**
64      * Toggle the open/close state of a list is a menu.
65      *
66      * @param {jQuery} $item
67      *   The li item to be toggled.
68      *
69      * @param {Boolean} switcher
70      *   A flag that forces toggleClass to add or a remove a class, rather than
71      *   simply toggling its presence.
72      */
73     function toggleList($item, switcher) {
74       var $toggle = $item.children('.toolbar-box').children('.toolbar-handle');
75       switcher = (typeof switcher !== 'undefined') ? switcher : !$item.hasClass('open');
76       // Toggle the item open state.
77       $item.toggleClass('open', switcher);
78       // Twist the toggle.
79       $toggle.toggleClass('open', switcher);
80       // Adjust the toggle text.
81       $toggle
82         .find('.action')
83         // Expand Structure, Collapse Structure.
84         .text((switcher) ? ui.handleClose : ui.handleOpen);
85     }
86
87     /**
88      * Add markup to the menu elements.
89      *
90      * Items with sub-elements have a list toggle attached to them. Menu item
91      * links and the corresponding list toggle are wrapped with in a div
92      * classed with .toolbar-box. The .toolbar-box div provides a positioning
93      * context for the item list toggle.
94      *
95      * @param {jQuery} $menu
96      *   The root of the menu to be initialized.
97      */
98     function initItems($menu) {
99       var options = {
100         class: 'toolbar-icon toolbar-handle',
101         action: ui.handleOpen,
102         text: ''
103       };
104       // Initialize items and their links.
105       $menu.find('li > a').wrap('<div class="toolbar-box">');
106       // Add a handle to each list item if it has a menu.
107       $menu.find('li').each(function (index, element) {
108         var $item = $(element);
109         if ($item.children('ul.toolbar-menu').length) {
110           var $box = $item.children('.toolbar-box');
111           options.text = Drupal.t('@label', {'@label': $box.find('a').text()});
112           $item.children('.toolbar-box')
113             .append(Drupal.theme('toolbarMenuItemToggle', options));
114         }
115       });
116     }
117
118     /**
119      * Adds a level class to each list based on its depth in the menu.
120      *
121      * This function is called recursively on each sub level of lists elements
122      * until the depth of the menu is exhausted.
123      *
124      * @param {jQuery} $lists
125      *   A jQuery object of ul elements.
126      *
127      * @param {number} level
128      *   The current level number to be assigned to the list elements.
129      */
130     function markListLevels($lists, level) {
131       level = (!level) ? 1 : level;
132       var $lis = $lists.children('li').addClass('level-' + level);
133       $lists = $lis.children('ul');
134       if ($lists.length) {
135         markListLevels($lists, level + 1);
136       }
137     }
138
139     /**
140      * On page load, open the active menu item.
141      *
142      * Marks the trail of the active link in the menu back to the root of the
143      * menu with .menu-item--active-trail.
144      *
145      * @param {jQuery} $menu
146      *   The root of the menu.
147      */
148     function openActiveItem($menu) {
149       var pathItem = $menu.find('a[href="' + location.pathname + '"]');
150       if (pathItem.length && !activeItem) {
151         activeItem = location.pathname;
152       }
153       if (activeItem) {
154         var $activeItem = $menu.find('a[href="' + activeItem + '"]').addClass('menu-item--active');
155         var $activeTrail = $activeItem.parentsUntil('.root', 'li').addClass('menu-item--active-trail');
156         toggleList($activeTrail, true);
157       }
158     }
159
160     // Return the jQuery object.
161     return this.each(function (selector) {
162       var $menu = $(this).once('toolbar-menu');
163       if ($menu.length) {
164         // Bind event handlers.
165         $menu
166           .on('click.toolbar', '.toolbar-box', toggleClickHandler)
167           .on('click.toolbar', '.toolbar-box a', linkClickHandler);
168
169         $menu.addClass('root');
170         initItems($menu);
171         markListLevels($menu);
172         // Restore previous and active states.
173         openActiveItem($menu);
174       }
175     });
176   };
177
178   /**
179    * A toggle is an interactive element often bound to a click handler.
180    *
181    * @param {object} options
182    *   Options for the button.
183    * @param {string} options.class
184    *   Class to set on the button.
185    * @param {string} options.action
186    *   Action for the button.
187    * @param {string} options.text
188    *   Used as label for the button.
189    *
190    * @return {string}
191    *   A string representing a DOM fragment.
192    */
193   Drupal.theme.toolbarMenuItemToggle = function (options) {
194     return '<button class="' + options['class'] + '"><span class="action">' + options.action + '</span><span class="label">' + options.text + '</span></button>';
195   };
196
197 }(jQuery, Drupal, drupalSettings));