From 04b4a2aa50ee1f070a277dbb10a42343020670c2 Mon Sep 17 00:00:00 2001 From: Evan Herman Date: Fri, 12 Jun 2020 14:35:48 -0400 Subject: [PATCH 1/8] Proof of concept, main nav hover or click --- .../js/frontend/components/primary-menu.js | 2 +- .../js/frontend/vendor/responsive-nav.js | 31 ++++++++++++-- includes/core.php | 4 +- includes/customizer.php | 40 +++++++++++++++++++ 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/.dev/assets/shared/js/frontend/components/primary-menu.js b/.dev/assets/shared/js/frontend/components/primary-menu.js index c94d9cc9f..f9efe75f1 100644 --- a/.dev/assets/shared/js/frontend/components/primary-menu.js +++ b/.dev/assets/shared/js/frontend/components/primary-menu.js @@ -10,7 +10,7 @@ const init = () => { target: '#header__navigation', toggle: '#nav-toggle', // eslint-disable-next-line - sub_menu_open: 'click' + sub_menu_open: goFrontend.openMenuOnHover ? 'hover' : 'click' } ); } diff --git a/.dev/assets/shared/js/frontend/vendor/responsive-nav.js b/.dev/assets/shared/js/frontend/vendor/responsive-nav.js index 7a9447ec9..45f84aaef 100644 --- a/.dev/assets/shared/js/frontend/vendor/responsive-nav.js +++ b/.dev/assets/shared/js/frontend/vendor/responsive-nav.js @@ -220,10 +220,12 @@ }; // listener_close_open_menus() function menu_sub_close( open_item ) { - open_item.classList.remove('submenu-is-open'); - open_item.parentNode.classList.remove('child-has-focus'); + if ( open_item && open_item.classList ) { + open_item.classList.remove('submenu-is-open'); + open_item.parentNode.classList.remove('child-has-focus'); + } - if ( open_item.parentNode.querySelector( '.sub-menu' ) ) { + if ( open_item && open_item.parentNode && open_item.parentNode.querySelector( '.sub-menu' ) ) { open_item.parentNode.querySelector( '.sub-menu' ).setAttribute( 'aria-hidden', 'true' ); } }; // menu_sub_close() @@ -376,6 +378,29 @@ menu.classList.add( 'uses-click' ); } else if ( sub_menu_acion !== 'click' ) { if ( get_screen_size( 'has-full-nav' ) ) { + menu_items_with_children[i].addEventListener( 'mouseover', listener_submenu_focus ); + menu_items_with_children[i].addEventListener( 'mouseout', function() { + var closeParentMenu = setTimeout( function() { + var open_menus = menu.querySelectorAll('.submenu-is-open'); + var open_menus_count = open_menus.length; + var opn; + + // We were getting some errors, so let's add in a checkpoint + if ( open_menus_count ) { + + // Loop through all the open menus and close them + for ( opn = 0; opn < open_menus.length; opn = opn + 1 ) { + + var open_menus = menu.querySelectorAll('.submenu-is-open'); + + menu_sub_close( open_menus[opn] ); + + } // for + + } + + }, 200 ); + } ); menu_items_with_children[i].addEventListener( 'focusin', listener_submenu_focus ); } // if } // if diff --git a/includes/core.php b/includes/core.php index e10784e0a..7f48437ae 100755 --- a/includes/core.php +++ b/includes/core.php @@ -390,9 +390,9 @@ function scripts() { wp_localize_script( 'go-frontend', - 'GoText', + 'goFrontend', array( - 'searchLabel' => esc_html__( 'Expand search field', 'go' ), + 'openMenuOnHover' => (bool) get_theme_mod( 'open_menu_on_hover', false ), ) ); diff --git a/includes/customizer.php b/includes/customizer.php index 7c9d6919e..e5adb66d3 100644 --- a/includes/customizer.php +++ b/includes/customizer.php @@ -28,6 +28,7 @@ function setup() { add_action( 'customize_register', $n( 'register_header_controls' ) ); add_action( 'customize_register', $n( 'register_footer_controls' ) ); add_action( 'customize_register', $n( 'register_social_controls' ) ); + add_action( 'customize_register', $n( 'register_menu_controls' ) ); add_action( 'customize_register', $n( 'rename_panels' ) ); add_action( 'customize_preview_init', $n( 'customize_preview_init' ) ); add_action( 'customize_controls_enqueue_scripts', $n( 'customize_preview_init' ) ); @@ -937,6 +938,45 @@ function register_social_controls( \WP_Customize_Manager $wp_customize ) { ); } +/** + * Register the menu within Customize. + * + * @param \WP_Customize_Manager $wp_customize The customize manager object. + * + * @return void + */ +function register_menu_controls( \WP_Customize_Manager $wp_customize ) { + + $wp_customize->add_section( + 'menu_behavior', + array( + 'title' => __( 'Menu Behavior', 'go' ), + 'panel' => 'nav_menus', + ) + ); + + $wp_customize->add_setting( + 'open_menu_on_hover', + array( + 'capability' => 'edit_theme_options', + 'default' => false, + 'sanitize_callback' => 'absint', + ) + ); + + $wp_customize->add_control( + 'open_menu_on_hover', + array( + 'label' => __( 'Show sub menus on hover.', 'go' ), + 'description' => esc_html__( 'Show sub menu items on hover.', 'go' ), + 'section' => 'menu_behavior', + 'settings' => 'open_menu_on_hover', + 'type' => 'checkbox', + ) + ); + +} + /** * Rename customizer panels. * From e7daf455427f69314adb3d33af83c286d2f38076 Mon Sep 17 00:00:00 2001 From: Evan Herman Date: Fri, 28 Aug 2020 13:35:53 -0400 Subject: [PATCH 2/8] Fix PHPCS warnings --- includes/customizer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/customizer.php b/includes/customizer.php index e5adb66d3..ab0eb3b69 100644 --- a/includes/customizer.php +++ b/includes/customizer.php @@ -967,11 +967,11 @@ function register_menu_controls( \WP_Customize_Manager $wp_customize ) { $wp_customize->add_control( 'open_menu_on_hover', array( - 'label' => __( 'Show sub menus on hover.', 'go' ), + 'label' => __( 'Show sub menus on hover.', 'go' ), 'description' => esc_html__( 'Show sub menu items on hover.', 'go' ), - 'section' => 'menu_behavior', - 'settings' => 'open_menu_on_hover', - 'type' => 'checkbox', + 'section' => 'menu_behavior', + 'settings' => 'open_menu_on_hover', + 'type' => 'checkbox', ) ); From 7d76ea0657c8971f4c29e6b48b663906f61e0cea Mon Sep 17 00:00:00 2001 From: Evan Herman Date: Fri, 28 Aug 2020 13:40:15 -0400 Subject: [PATCH 3/8] Fix testScriptsLocalizedData unit test --- .dev/tests/php/test-core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.dev/tests/php/test-core.php b/.dev/tests/php/test-core.php index c6cdc85f3..3c01fac24 100644 --- a/.dev/tests/php/test-core.php +++ b/.dev/tests/php/test-core.php @@ -557,7 +557,7 @@ function testScriptsLocalizedData() { global $wp_scripts; - $this->assertEquals( 'var GoText = {"searchLabel":"Expand search field"};', $wp_scripts->registered['go-frontend']->extra['data'] ); + $this->assertEquals( 'var goFrontend = {"openMenuOnHover":false};', $wp_scripts->registered['go-frontend']->extra['data'] ); } From 893061a2563844595718e8a91f0a52c19a712e93 Mon Sep 17 00:00:00 2001 From: Evan Herman Date: Fri, 28 Aug 2020 13:44:06 -0400 Subject: [PATCH 4/8] Update unit tests. Change menu_behavior section to go_menu_behavior --- .dev/tests/php/test-customizer.php | 24 ++++++++++++++++++++++++ includes/customizer.php | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.dev/tests/php/test-customizer.php b/.dev/tests/php/test-customizer.php index 4cb65095a..d552ef45d 100644 --- a/.dev/tests/php/test-customizer.php +++ b/.dev/tests/php/test-customizer.php @@ -137,6 +137,19 @@ function test_hooked_register_social_controls() { } + /** + * Test register_menu_controls is hooked correctly + */ + function test_hooked_register_menu_controls() { + + $this->assertEquals( + 10, + has_action( 'customize_register', 'Go\Customizer\register_menu_controls' ), + 'customize_register is not attached to Go\Customizer\register_menu_controls. It might also have the wrong priority (validated priority: 10)' + ); + + } + /** * Test customize_preview_init is hooked correctly to customize_preview_init */ @@ -976,6 +989,17 @@ function test_register_social_controls_social_icon_x_setting_and_controls() { } + /** + * Test the register_menu_controls section is registered + */ + function test_register_menu_controls_menus_section() { + + Go\Customizer\register_social_controls( $GLOBALS['wp_customize'] ); + + $this->assertNotNull( $GLOBALS['wp_customize']->get_section( 'go_menu_behavior' ) ); + + } + /** * Test the viewport_basis setting is registered */ diff --git a/includes/customizer.php b/includes/customizer.php index ab0eb3b69..08ef22aba 100644 --- a/includes/customizer.php +++ b/includes/customizer.php @@ -948,7 +948,7 @@ function register_social_controls( \WP_Customize_Manager $wp_customize ) { function register_menu_controls( \WP_Customize_Manager $wp_customize ) { $wp_customize->add_section( - 'menu_behavior', + 'go_menu_behavior', array( 'title' => __( 'Menu Behavior', 'go' ), 'panel' => 'nav_menus', @@ -969,7 +969,7 @@ function register_menu_controls( \WP_Customize_Manager $wp_customize ) { array( 'label' => __( 'Show sub menus on hover.', 'go' ), 'description' => esc_html__( 'Show sub menu items on hover.', 'go' ), - 'section' => 'menu_behavior', + 'section' => 'go_menu_behavior', 'settings' => 'open_menu_on_hover', 'type' => 'checkbox', ) From 87971e53bc665c0b94eeb0450e41bc356d87d679 Mon Sep 17 00:00:00 2001 From: Evan Herman Date: Fri, 28 Aug 2020 13:51:39 -0400 Subject: [PATCH 5/8] Fix tests --- .dev/tests/php/test-core.php | 2 +- .dev/tests/php/test-customizer.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.dev/tests/php/test-core.php b/.dev/tests/php/test-core.php index 3c01fac24..03cd9b30d 100644 --- a/.dev/tests/php/test-core.php +++ b/.dev/tests/php/test-core.php @@ -557,7 +557,7 @@ function testScriptsLocalizedData() { global $wp_scripts; - $this->assertEquals( 'var goFrontend = {"openMenuOnHover":false};', $wp_scripts->registered['go-frontend']->extra['data'] ); + $this->assertEquals( 'var goFrontend = {"openMenuOnHover":""};', $wp_scripts->registered['go-frontend']->extra['data'] ); } diff --git a/.dev/tests/php/test-customizer.php b/.dev/tests/php/test-customizer.php index d552ef45d..90e85da6c 100644 --- a/.dev/tests/php/test-customizer.php +++ b/.dev/tests/php/test-customizer.php @@ -994,7 +994,7 @@ function test_register_social_controls_social_icon_x_setting_and_controls() { */ function test_register_menu_controls_menus_section() { - Go\Customizer\register_social_controls( $GLOBALS['wp_customize'] ); + Go\Customizer\register_menu_controls( $GLOBALS['wp_customize'] ); $this->assertNotNull( $GLOBALS['wp_customize']->get_section( 'go_menu_behavior' ) ); From 32ecf027fb91f5608e0f389f7d526f23248cf7f8 Mon Sep 17 00:00:00 2001 From: Evan Herman Date: Mon, 31 Aug 2020 13:35:07 -0400 Subject: [PATCH 6/8] Set open_menu_on_hover to true --- includes/core.php | 2 +- includes/customizer.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/core.php b/includes/core.php index 27b3aace9..a9c026058 100755 --- a/includes/core.php +++ b/includes/core.php @@ -395,7 +395,7 @@ function scripts() { 'go-frontend', 'goFrontend', array( - 'openMenuOnHover' => (bool) get_theme_mod( 'open_menu_on_hover', false ), + 'openMenuOnHover' => (bool) get_theme_mod( 'open_menu_on_hover', true ), ) ); diff --git a/includes/customizer.php b/includes/customizer.php index 08ef22aba..5f8a3dd3b 100644 --- a/includes/customizer.php +++ b/includes/customizer.php @@ -959,7 +959,7 @@ function register_menu_controls( \WP_Customize_Manager $wp_customize ) { 'open_menu_on_hover', array( 'capability' => 'edit_theme_options', - 'default' => false, + 'default' => true, 'sanitize_callback' => 'absint', ) ); From bc7cf94ea889a615a76fcec682981fa40a2936da Mon Sep 17 00:00:00 2001 From: Evan Herman Date: Mon, 31 Aug 2020 14:08:36 -0400 Subject: [PATCH 7/8] Update unit test --- .dev/tests/php/test-core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.dev/tests/php/test-core.php b/.dev/tests/php/test-core.php index 03cd9b30d..2e45a96a5 100644 --- a/.dev/tests/php/test-core.php +++ b/.dev/tests/php/test-core.php @@ -557,7 +557,7 @@ function testScriptsLocalizedData() { global $wp_scripts; - $this->assertEquals( 'var goFrontend = {"openMenuOnHover":""};', $wp_scripts->registered['go-frontend']->extra['data'] ); + $this->assertEquals( 'var goFrontend = {"openMenuOnHover":"1"};', $wp_scripts->registered['go-frontend']->extra['data'] ); } From 32cf5b780e2d2ca7d1425944ef581e36af8102d8 Mon Sep 17 00:00:00 2001 From: Evan Herman Date: Wed, 2 Sep 2020 18:55:52 -0400 Subject: [PATCH 8/8] Tweak the functionality of the menu on click --- .dev/assets/shared/css/header/sub-menu.css | 12 +++++ .../js/frontend/vendor/responsive-nav.js | 54 +++++++++++-------- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/.dev/assets/shared/css/header/sub-menu.css b/.dev/assets/shared/css/header/sub-menu.css index 35d4673d6..a45724d8b 100644 --- a/.dev/assets/shared/css/header/sub-menu.css +++ b/.dev/assets/shared/css/header/sub-menu.css @@ -50,6 +50,17 @@ left: 50%; } } + + /* Spacer to fix menu hovers */ + &::after { + bottom: 100%; + content: ""; + height: 1.75rem; + left: 0; + position: absolute; + right: 0; + width: 100%; + } } /* All other submenus */ @@ -126,6 +137,7 @@ & svg { transform: rotate(180deg); + z-index: 9999; } } diff --git a/.dev/assets/shared/js/frontend/vendor/responsive-nav.js b/.dev/assets/shared/js/frontend/vendor/responsive-nav.js index 45f84aaef..71b3db1ec 100644 --- a/.dev/assets/shared/js/frontend/vendor/responsive-nav.js +++ b/.dev/assets/shared/js/frontend/vendor/responsive-nav.js @@ -7,7 +7,7 @@ 'target' : '#primary-nav', // the selector of the nav menu
    'toggle' : '#js-menu-toggle', // the ID of the link you're using to open/close the small screen menu - 'sub_menu_open' : 'hover' // "click" is the other option + 'sub_menu_open' : 'hover' }, function() { @@ -98,10 +98,21 @@ currentTarget = e.currentTarget; target = e.target; + console.log( 'Before' ); + console.log( currentTarget ); + console.log( target ); + console.log( '----------' ); + if ( target.tagName === 'svg' || target.tagName === 'path' ) { + console.log( 'Yes, the target is an SVG' ); target = currentTarget.closest( '.menu-item > a' ); } + console.log( 'After' ); + console.log( currentTarget ); + console.log( target ); + console.log( '----------' ); + if ( target.getAttribute( 'aria-haspopup' ) ) { // Stop links from firing e.preventDefault(); @@ -267,11 +278,11 @@ // Loop through all submenus and bind events when needed for ( i = 0; i < menu_items_with_children_count; i = i + 1 ) { - if ( sub_menu_acion !== 'click' ) { - menu_items_with_children[i].addEventListener( 'click', listener_submenu_click ); - menu_items_with_children[i].removeEventListener( 'focusin', listener_submenu_focus ); - menu.classList.add( 'uses-click' ); + var svgElements = menu_items_with_children[i].querySelectorAll( 'svg' ); + for ( var q = 0; q < svgElements.length; q = q + 1 ) { + svgElements[q].addEventListener( 'click', listener_submenu_click ); } + menu_items_with_children[i].removeEventListener( 'focusin', listener_submenu_focus ); } // for // Bind the event @@ -375,33 +386,34 @@ } - menu.classList.add( 'uses-click' ); + menu.classList.add( sub_menu_acion === 'click' ? 'uses-click' : 'uses-hover' ); } else if ( sub_menu_acion !== 'click' ) { if ( get_screen_size( 'has-full-nav' ) ) { menu_items_with_children[i].addEventListener( 'mouseover', listener_submenu_focus ); menu_items_with_children[i].addEventListener( 'mouseout', function() { - var closeParentMenu = setTimeout( function() { - var open_menus = menu.querySelectorAll('.submenu-is-open'); - var open_menus_count = open_menus.length; - var opn; - - // We were getting some errors, so let's add in a checkpoint - if ( open_menus_count ) { + var open_menus = menu.querySelectorAll( '.submenu-is-open' ); + var open_menus_count = open_menus.length; + var opn; - // Loop through all the open menus and close them - for ( opn = 0; opn < open_menus.length; opn = opn + 1 ) { + // We were getting some errors, so let's add in a checkpoint + if ( open_menus_count ) { - var open_menus = menu.querySelectorAll('.submenu-is-open'); + // Loop through all the open menus and close them + for ( opn = 0; opn < open_menus_count; opn = opn + 1 ) { - menu_sub_close( open_menus[opn] ); + menu_sub_close( open_menus[opn] ); - } // for + } // for - } - - }, 200 ); + } } ); menu_items_with_children[i].addEventListener( 'focusin', listener_submenu_focus ); + menu_items_with_children[i].querySelectorAll( '.sub-menu' ).forEach( submenu => { + submenu.addEventListener( 'mouseover', event => { + submenu.parentElement.classList.add( 'child-has-focus' ); + submenu.previousElementSibling.classList.add( 'submenu-is-open' ); + }, false ); + } ); } // if } // if } // for