Menus: Apply menu-item-has-children class in sub-menus.

Ensure the `menu-item-has-children` class is added to sub-menu items when `wp_nav_menu()` is called with the `depth` parameter specified to a non-zero value.

Follow up to [54478].

Props davidvongries, fpodhorsky, hellofromTonya, innovext, larsmqller, LeonidasMilossis, mattkeys, mukesh27, nuvoPoint, ocean90, outrankjames, petitphp, SergeyBiryukov, sippis, webmandesign, peterwilsoncc.
Merges [54801] to the 6.1 branch.
Fixes .
See .

git-svn-id: https://develop.svn.wordpress.org/branches/6.1@54809 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Jonathan Desrosiers 2022-11-11 02:40:54 +00:00
parent 1760eaa601
commit 88745395b8
2 changed files with 47 additions and 14 deletions
src/wp-includes
tests/phpunit/tests/menu

@ -204,14 +204,14 @@ function wp_nav_menu( $args = array() ) {
if ( $menu_item->menu_item_parent ) {
$menu_items_with_children[ $menu_item->menu_item_parent ] = 1;
}
}
// Calculate the depth of each menu item with children
foreach ( $menu_items_with_children as $menu_item_key => &$menu_item_depth ) {
$menu_item_parent = $menu_items_tree[ $menu_item_key ];
while ( $menu_item_parent ) {
$menu_item_depth = $menu_item_depth + 1;
$menu_item_parent = $menu_items_tree[ $menu_item_parent ];
}
// Calculate the depth of each menu item with children.
foreach ( $menu_items_with_children as $menu_item_key => &$menu_item_depth ) {
$menu_item_parent = $menu_items_tree[ $menu_item_key ];
while ( $menu_item_parent ) {
$menu_item_depth = $menu_item_depth + 1;
$menu_item_parent = $menu_items_tree[ $menu_item_parent ];
}
}

@ -11,6 +11,7 @@ class Tests_Menu_wpNavMenu extends WP_UnitTestCase {
static $lvl0_menu_item = 0;
static $lvl1_menu_item = 0;
static $lvl2_menu_item = 0;
static $lvl3_menu_item = 0;
public static function set_up_before_class() {
parent::set_up_before_class();
@ -53,6 +54,18 @@ class Tests_Menu_wpNavMenu extends WP_UnitTestCase {
)
);
// Create lvl3 menu item.
self::$lvl3_menu_item = wp_update_nav_menu_item(
self::$menu_id,
0,
array(
'menu-item-title' => 'Lvl3 menu item',
'menu-item-url' => '#',
'menu-item-parent-id' => self::$lvl2_menu_item,
'menu-item-status' => 'publish',
)
);
/*
* This filter is used to prevent reusing a menu item ID more that once.
* It caused the tests to fail after the first one since the IDs are missing
@ -81,6 +94,7 @@ class Tests_Menu_wpNavMenu extends WP_UnitTestCase {
* when displaying the menu without specifying a custom depth.
*
* @ticket 28620
* @ticket 56946
*/
public function test_wp_nav_menu_should_have_has_children_class_without_custom_depth() {
@ -112,11 +126,20 @@ class Tests_Menu_wpNavMenu extends WP_UnitTestCase {
$this->assertStringContainsString(
sprintf(
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-%1$d">',
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-%1$d">',
self::$lvl2_menu_item
),
$menu_html,
'Level 2 should be present in the HTML output and not have the `menu-item-has-children` class since it has no children.'
'Level 2 should be present in the HTML output and have the `menu-item-has-children` class.'
);
$this->assertStringContainsString(
sprintf(
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-%1$d">',
self::$lvl3_menu_item
),
$menu_html,
'Level 3 should be present in the HTML output and not have the `menu-item-has-children` class since it has no children.'
);
}
@ -125,6 +148,7 @@ class Tests_Menu_wpNavMenu extends WP_UnitTestCase {
* `menu-item-has-children` even if it's the case when displaying the full menu.
*
* @ticket 28620
* @ticket 56946
*/
public function test_wp_nav_menu_should_not_have_has_children_class_with_custom_depth() {
@ -132,7 +156,7 @@ class Tests_Menu_wpNavMenu extends WP_UnitTestCase {
$menu_html = wp_nav_menu(
array(
'menu' => self::$menu_id,
'depth' => 2,
'depth' => 3,
'echo' => false,
)
);
@ -148,20 +172,29 @@ class Tests_Menu_wpNavMenu extends WP_UnitTestCase {
$this->assertStringContainsString(
sprintf(
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-%1$d">',
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-%1$d">',
self::$lvl1_menu_item
),
$menu_html,
'Level 1 should be present in the HTML output and not have the `menu-item-has-children` class since it is the last item to be rendered.'
'Level 1 should be present in the HTML output and have the `menu-item-has-children` class.'
);
$this->assertStringContainsString(
sprintf(
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-%1$d">',
self::$lvl2_menu_item
),
$menu_html,
'Level 2 should be present in the HTML output and not have the `menu-item-has-children` class since it is the last item to be rendered.'
);
$this->assertStringNotContainsString(
sprintf(
'<li id="menu-item-%d"',
self::$lvl2_menu_item
self::$lvl3_menu_item
),
$menu_html,
'Level 2 should not be present in the HTML output.'
'Level 3 should not be present in the HTML output.'
);
}
}