1/** 2 * @file 3 * JavaScript to create a menu accessible through keyboard navigation. 4 */ 5 6/** 7 * Create an accessible menu. 8 * 9 * @param object options 10 * The options can take the following key/value pairs: 11 * - buttonClass: The class(es) to add to the button markup. 12 * - hasItemsSelector: The selector used to test whether a specific menu node. 13 * has menu items below it and should have a button added. Defaults to 14 * '.menu-item--expanded > a'. 15 * - itemCloseText: The button close text. Can include a '%s' string which is 16 * replaced with the text of the tree's anchor link. Defaults to the 17 * [data-item-close-text] attribute on the calling element. 18 * - itemOpenText: The button open text. Can include a '%s' string which is 19 * replaced with the text of the tree's anchor link. Defaults to the 20 * [data-item-open-text] attribute on the calling element. 21 * - itemOpenClass: Open class to add to the <li> when the menu is opened. 22 * Defaults to 'menu-item--open'. 23 * - itemRegex: Replacement regex pattern used in itemCloseText and 24 * itemOpenText. Defaults to '/%s/'. 25 * 26 * Emits events: 27 * - 'toggled', when a menu item accessible button is toggled. Provides two 28 * variables, the button jQuery object which triggered the event and the 29 * current state of the button, either 'open' or 'closed'. 30 */ 31(function($, Drupal){ 32 Drupal.behaviors.accessibleMenu = { 33 attach: function (context) { 34 $.fn.ohoAccessibleMenu = function(options) { 35 // Alias the calling element. 36 var $menu = $(this); 37 38 // Menu defaults. 39 var defaults = { 40 buttonClass: 'menu-item__button', 41 hasItemsSelector: '.menu-item--expanded > a, .menu-item--expanded > span', 42 itemCloseText: $menu.attr('data-item-close-text'), 43 itemOpenText: $menu.attr('data-item-open-text'), 44 itemOpenClass: 'menu-item--open', 45 itemRegex: /%s/, 46 }; 47 48 // Create options. 49 var options = $.extend({}, defaults, options); 50 // Add accessibile buttons to the menu links. 51 $menu.find(options.hasItemsSelector).each(function() { 52 // Save the link and get the link text. 53 var $link = $(this), 54 linkText = $link.text(); 55 56 // Create the button markup. 57 var $button = $('<button class="' + options.buttonClass + ' element-invisible element-focusable">' + options.itemOpenText.replace(options.itemRegex, linkText) + '</button>'); 58 59 // Insert the button after the link. 60 $link.after($button); 61 }); 62 // Add the button click behaviors. Toggle the class and switch button text. 63 $('.' + options.buttonClass).click(function(event) { 64 // Don't do the link. 65 event.preventDefault(); 66 67 var linkText = $(this).prev('a').text(); 68 69 // Get the parent. 70 var $parent = $(this).parent(); 71 72 // Switch the class. 73 $parent.toggleClass(options.itemOpenClass); 74 75 // Record the state. 76 var state = $parent.hasClass(options.itemOpenClass) ? 'open' : 'closed'; 77 78 // Switch the text. 79 $(this).html(function(i, v) { 80 var openText = options.itemOpenText.replace(options.itemRegex, linkText), 81 closeText = options.itemCloseText.replace(options.itemRegex, linkText); 82 return v === openText ? closeText : openText; 83 }); 84 85 // Emit the event. 86 $menu.trigger('toggled', [$(this), state]); 87 }); 88 } 89 } 90 } 91})(jQuery, Drupal);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.