123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- /**
- * This script adds the accessibility-ready responsive menus Genesis Framework child themes.
- *
- * @author StudioPress
- * @link https://github.com/copyblogger/responsive-menus
- * @version 1.1.2
- * @license GPL-2.0+
- */
- var genesisMenuParams = typeof genesis_responsive_menu === 'undefined' ? '' : genesis_responsive_menu,
- genesisMenusUnchecked = genesisMenuParams.menuClasses,
- genesisMenus = {},
- menusToCombine = [];
- ( function ( document, $, undefined ) {
- 'use strict';
- // Make our menus unique if there's more than one instance on the page.
- /**
- * Validate the menus passed by the theme with what's being loaded on the page,
- * and pass the new and accurate information to our new data.
- * @param {genesisMenusUnchecked} Raw data from the localized script in the theme.
- * @return {array} genesisMenus array gets populated with updated data.
- * @return {array} menusToCombine array gets populated with relevant data.
- */
- $.each( genesisMenusUnchecked, function( group ) {
- // Mirror our group object to populate.
- genesisMenus[group] = [];
- // Loop through each instance of the specified menu on the page.
- $.each( this, function( key, value ) {
- var menuString = value,
- $menu = $(value);
- // If there is more than one instance, append the index and update array.
- if ( $menu.length > 1 ) {
- $.each( $menu, function( key, value ) {
- var newString = menuString + '-' + key;
- $(this).addClass( newString.replace('.','') );
- genesisMenus[group].push( newString );
- if ( 'combine' === group ) {
- menusToCombine.push( newString );
- }
- });
- } else if ( $menu.length == 1 ) {
- genesisMenus[group].push( menuString );
- if ( 'combine' === group ) {
- menusToCombine.push( menuString );
- }
- }
- });
- });
- // Make sure there is something to use for the 'others' array.
- if ( typeof genesisMenus.others == 'undefined' ) {
- genesisMenus.others = [];
- }
- // If there's only one menu on the page for combining, push it to the 'others' array and nullify our 'combine' variable.
- if ( menusToCombine.length == 1 ) {
- genesisMenus.others.push( menusToCombine[0] );
- genesisMenus.combine = null;
- menusToCombine = null;
- }
- var genesisMenu = {},
- mainMenuButtonClass = 'menu-toggle',
- subMenuButtonClass = 'sub-menu-toggle',
- responsiveMenuClass = 'genesis-responsive-menu';
- // Initialize.
- genesisMenu.init = function() {
- // Exit early if there are no menus to do anything.
- if ( $( _getAllMenusArray() ).length == 0 ) {
- return;
- }
- var menuIconClass = typeof genesisMenuParams.menuIconClass !== 'undefined' ? genesisMenuParams.menuIconClass : 'dashicons-before dashicons-menu',
- subMenuIconClass = typeof genesisMenuParams.subMenuIconClass !== 'undefined' ? genesisMenuParams.subMenuIconClass : 'dashicons-before dashicons-arrow-down-alt2',
- toggleButtons = {
- menu : $( '<button />', {
- 'class' : mainMenuButtonClass,
- 'aria-expanded' : false,
- 'aria-pressed' : false,
- 'role' : 'button'
- } )
- .append( genesisMenuParams.mainMenu ),
- submenu : $( '<button />', {
- 'class' : subMenuButtonClass,
- 'aria-expanded' : false,
- 'aria-pressed' : false,
- 'role' : 'button'
- } )
- .append( $( '<span />', {
- 'class' : 'screen-reader-text',
- 'text' : genesisMenuParams.subMenu
- } ) )
- };
- // Add the responsive menu class to the active menus.
- _addResponsiveMenuClass();
- // Add the main nav button to the primary menu, or exit the plugin.
- _addMenuButtons( toggleButtons );
-
- // Setup additional classes.
- $( '.' + mainMenuButtonClass ).addClass( menuIconClass );
- $( '.' + subMenuButtonClass ).addClass( subMenuIconClass );
- $( '.' + mainMenuButtonClass ).on( 'click.genesisMenu-mainbutton', _mainmenuToggle ).each( _addClassID );
- $( '.' + subMenuButtonClass ).on( 'click.genesisMenu-subbutton', _submenuToggle );
- $( window ).on( 'resize.genesisMenu', _doResize ).triggerHandler( 'resize.genesisMenu' );
- };
- /**
- * Add menu toggle button to appropriate menus.
- * @param {toggleButtons} Object of menu buttons to use for toggles.
- */
- function _addMenuButtons( toggleButtons ) {
- // Apply sub menu toggle to each sub-menu found in the menuList.
- $( _getMenuSelectorString( genesisMenus ) ).find( '.sub-menu' ).before( toggleButtons.submenu );
-
- if ( menusToCombine !== null ) {
- var menusToToggle = genesisMenus.others.concat( menusToCombine[0] );
-
- // Only add menu button the primary menu and navs NOT in the combine variable.
- $( _getMenuSelectorString( menusToToggle ) ).before( toggleButtons.menu );
- } else {
- // Apply the main menu toggle to all menus in the list.
- $( _getMenuSelectorString( genesisMenus.others ) ).before( toggleButtons.menu );
- }
- }
- /**
- * Add the responsive menu class.
- */
- function _addResponsiveMenuClass() {
- $( _getMenuSelectorString( genesisMenus ) ).addClass( responsiveMenuClass );
- }
- /**
- * Execute our responsive menu functions on window resizing.
- */
- function _doResize() {
- var buttons = $( 'button[id^="genesis-mobile-"]' ).attr( 'id' );
- if ( typeof buttons === 'undefined' ) {
- return;
- }
- _maybeClose( buttons );
- _superfishToggle( buttons );
- _changeSkipLink( buttons );
- _combineMenus( buttons );
- }
- /**
- * Add the nav- class of the related navigation menu as
- * an ID to associated button (helps target specific buttons outside of context).
- */
- function _addClassID() {
- var $this = $( this ),
- nav = $this.next( 'nav' ),
- id = 'class';
- $this.attr( 'id', 'genesis-mobile-' + $( nav ).attr( id ).match( /nav-\w*\b/ ) );
- }
-
- /**
- * Combine our menus if the mobile menu is visible.
- * @params buttons
- */
- function _combineMenus( buttons ){
-
- // Exit early if there are no menus to combine.
- if ( menusToCombine == null ) {
- return;
- }
- // Split up the menus to combine based on order of appearance in the array.
- var primaryMenu = menusToCombine[0],
- combinedMenus = $( menusToCombine ).filter( function(index) { if ( index > 0 ) { return index; } });
-
- // If the responsive menu is active, append items in 'combinedMenus' object to the 'primaryMenu' object.
- if ( 'none' !== _getDisplayValue( buttons ) ) {
- $.each( combinedMenus, function( key, value ) {
- $(value).find( '.menu > li' ).addClass( 'moved-item-' + value.replace( '.','' ) ).appendTo( primaryMenu + ' ul.genesis-nav-menu' );
- });
- $( _getMenuSelectorString( combinedMenus ) ).hide();
- } else {
- $( _getMenuSelectorString( combinedMenus ) ).show();
- $.each( combinedMenus, function( key, value ) {
- $( '.moved-item-' + value.replace( '.','' ) ).appendTo( value + ' ul.genesis-nav-menu' ).removeClass( 'moved-item-' + value.replace( '.','' ) );
- });
-
- }
- }
- /**
- * Action to happen when the main menu button is clicked.
- */
- function _mainmenuToggle() {
- var $this = $( this );
- _toggleAria( $this, 'aria-pressed' );
- _toggleAria( $this, 'aria-expanded' );
- $this.toggleClass( 'activated' );
- $this.next( 'nav' ).slideToggle( 'fast' );
- }
- /**
- * Action for submenu toggles.
- */
- function _submenuToggle() {
- var $this = $( this ),
- others = $this.closest( '.menu-item' ).siblings();
- _toggleAria( $this, 'aria-pressed' );
- _toggleAria( $this, 'aria-expanded' );
- $this.toggleClass( 'activated' );
- $this.next( '.sub-menu' ).slideToggle( 'fast' );
- others.find( '.' + subMenuButtonClass ).removeClass( 'activated' ).attr( 'aria-pressed', 'false' );
- others.find( '.sub-menu' ).slideUp( 'fast' );
- }
- /**
- * Activate/deactivate superfish.
- * @params buttons
- */
- function _superfishToggle( buttons ) {
- var _superfish = $( '.' + responsiveMenuClass + ' .js-superfish' ),
- $args = 'destroy';
- if ( typeof _superfish.superfish !== 'function' ) {
- return;
- }
- if ( 'none' === _getDisplayValue( buttons ) ) {
- $args = {
- 'delay': 100,
- 'animation': {'opacity': 'show', 'height': 'show'},
- 'dropShadows': false,
- 'speed': 'fast'
- };
- }
- _superfish.superfish( $args );
- }
- /**
- * Modify skip link to match mobile buttons.
- * @param buttons
- */
- function _changeSkipLink( buttons ) {
- // Start with an empty array.
- var menuToggleList = _getAllMenusArray();
- // Exit out if there are no menu items to update.
- if ( ! $( menuToggleList ).length > 0 ) {
- return;
- }
- $.each( menuToggleList, function ( key, value ) {
-
- var newValue = value.replace( '.', '' ),
- startLink = 'genesis-' + newValue,
- endLink = 'genesis-mobile-' + newValue;
- if ( 'none' == _getDisplayValue( buttons ) ) {
- startLink = 'genesis-mobile-' + newValue;
- endLink = 'genesis-' + newValue;
- }
- var $item = $( '.genesis-skip-link a[href="#' + startLink + '"]' );
- if ( menusToCombine !== null && value !== menusToCombine[0] ) {
- $item.toggleClass( 'skip-link-hidden' );
- }
- if ( $item.length > 0 ) {
- var link = $item.attr( 'href' );
- link = link.replace( startLink, endLink );
- $item.attr( 'href', link );
- } else {
- return;
- }
- });
- }
- /**
- * Close all the menu toggles if buttons are hidden.
- * @param buttons
- */
- function _maybeClose( buttons ) {
- if ( 'none' !== _getDisplayValue( buttons ) ) {
- return true;
- }
- $( '.' + mainMenuButtonClass + ', .' + responsiveMenuClass + ' .sub-menu-toggle' )
- .removeClass( 'activated' )
- .attr( 'aria-expanded', false )
- .attr( 'aria-pressed', false );
-
- $( '.' + responsiveMenuClass + ', ' + responsiveMenuClass + ' .sub-menu' )
- .attr( 'style', '' );
- }
- /**
- * Generic function to get the display value of an element.
- * @param {id} $id ID to check
- * @return {string} CSS value of display property
- */
- function _getDisplayValue( $id ) {
- var element = document.getElementById( $id ),
- style = window.getComputedStyle( element );
- return style.getPropertyValue( 'display' );
- }
- /**
- * Toggle aria attributes.
- * @param {button} $this passed through
- * @param {aria-xx} attribute aria attribute to toggle
- * @return {bool} from _ariaReturn
- */
- function _toggleAria( $this, attribute ) {
- $this.attr( attribute, function( index, value ) {
- return 'false' === value;
- });
- }
- /**
- * Helper function to return a comma separated string of menu selectors.
- * @param {itemArray} Array of menu items to loop through.
- * @param {ignoreSecondary} boolean of whether to ignore the 'secondary' menu item.
- * @return {string} Comma-separated string.
- */
- function _getMenuSelectorString( itemArray ) {
- var itemString = $.map( itemArray, function( value, key ) {
- return value;
- });
- return itemString.join( ',' );
- }
- /**
- * Helper function to return a group array of all the menus in
- * both the 'others' and 'combine' arrays.
- * @return {array} Array of all menu items as class selectors.
- */
- function _getAllMenusArray() {
- // Start with an empty array.
- var menuList = [];
- // If there are menus in the 'menusToCombine' array, add them to 'menuList'.
- if ( menusToCombine !== null ) {
- $.each( menusToCombine, function( key, value ) {
- menuList.push( value.valueOf() );
- });
- }
- // Add menus in the 'others' array to 'menuList'.
- $.each( genesisMenus.others, function( key, value ) {
- menuList.push( value.valueOf() );
- });
- if ( menuList.length > 0 ) {
- return menuList;
- } else {
- return null;
- }
- }
- $(document).ready(function () {
- if ( _getAllMenusArray() !== null ) {
- genesisMenu.init();
-
- }
- });
- })( document, jQuery );
|