| @@ -278,10 +278,16 @@ | ||
| 278 | 278 | $is_list_open = false; |
| 279 | 279 | |
| 280 | 280 | foreach ( $inner_blocks as $inner_block ) { |
| 281 | 281 | $inner_block_markup = static::get_markup_for_inner_block( $inner_block ); |
| 282 | - $p = new WP_HTML_Tag_Processor( $inner_block_markup ); | |
| 283 | - $is_list_item = $p->next_tag( 'LI' ); | |
| 282 | + // Skip hidden blocks (e.g. hidden via block visibility) that render | |
| 283 | + // as an empty string. Without this check, empty markup is mistaken | |
| 284 | + // for a non-list-item and incorrectly closes the open <ul>. | |
| 285 | + if ( '' === $inner_block_markup ) { | |
| 286 | + continue; | |
| 287 | + } | |
| 288 | + $p = new WP_HTML_Tag_Processor( $inner_block_markup ); | |
| 289 | + $is_list_item = $p->next_tag( 'LI' ); | |
| 284 | 290 | |
| 285 | 291 | if ( $is_list_item && ! $is_list_open ) { |
| 286 | 292 | $is_list_open = true; |
| 287 | 293 | $inner_blocks_html .= sprintf( |
| @@ -410,9 +416,9 @@ | ||
| 410 | 416 | * |
| 411 | 417 | * @since 6.5.0 |
| 412 | 418 | * |
| 413 | 419 | * @param string $overlay_template_part_id The overlay template part ID in format "theme//slug". |
| 414 | - * @param array $attributes The block attributes. | |
| 420 | + * @param array $attributes The block attributes. | |
| 415 | 421 | * @return WP_Block_List Returns the inner blocks for the overlay template part. |
| 416 | 422 | */ |
| 417 | 423 | private static function get_overlay_blocks_from_template_part( $overlay_template_part_id, $attributes ) { |
| 418 | 424 | if ( empty( $overlay_template_part_id ) || ! is_string( $overlay_template_part_id ) ) { |
| @@ -511,9 +517,9 @@ | ||
| 511 | 517 | * |
| 512 | 518 | * @since 6.5.0 |
| 513 | 519 | * |
| 514 | 520 | * @param array $attributes The block attributes. |
| 515 | - * @param WP_Block $block The parsed block. | |
| 521 | + * @param WP_Block $block The parsed block. | |
| 516 | 522 | * @return WP_Block_List Returns the inner blocks for the navigation block. |
| 517 | 523 | */ |
| 518 | 524 | private static function get_inner_blocks( $attributes, $block ) { |
| 519 | 525 | $inner_blocks = $block->inner_blocks; |
| @@ -733,10 +739,10 @@ | ||
| 733 | 739 | * Get the responsive container markup |
| 734 | 740 | * |
| 735 | 741 | * @since 6.5.0 |
| 736 | 742 | * |
| 737 | - * @param array $attributes The block attributes. | |
| 738 | - * @param WP_Block_List $inner_blocks The list of inner blocks. | |
| 743 | + * @param array $attributes The block attributes. | |
| 744 | + * @param WP_Block_List $inner_blocks The list of inner blocks. | |
| 739 | 745 | * @param string $inner_blocks_html The markup for the inner blocks. |
| 740 | 746 | * @return string Returns the container markup. |
| 741 | 747 | */ |
| 742 | 748 | private static function get_responsive_container_markup( $attributes, $inner_blocks, $inner_blocks_html ) { |
| @@ -825,8 +831,16 @@ | ||
| 825 | 831 | '; |
| 826 | 832 | $responsive_container_content_directives = ' |
| 827 | 833 | data-wp-watch="callbacks.focusFirstElement" |
| 828 | 834 | '; |
| 835 | + | |
| 836 | + // The default overlay displays every submenu it contains; a custom overlay | |
| 837 | + // opts out through the `disable-default-overlay` class on this container. | |
| 838 | + // Submenus inherit this flag to tell the two apart, derived from the same | |
| 839 | + // value as that class so the markup and the styles cannot disagree. | |
| 840 | + if ( $has_custom_overlay ) { | |
| 841 | + $responsive_container_directives .= ' ' . wp_interactivity_data_wp_context( array( 'hasCustomOverlay' => true ) ); | |
| 842 | + } | |
| 829 | 843 | } |
| 830 | 844 | |
| 831 | 845 | // Don't apply overlay inline styles if using a custom overlay template part. |
| 832 | 846 | // The custom overlay is responsible for its own styling. |
| @@ -885,10 +899,10 @@ | ||
| 885 | 899 | * Get the wrapper attributes |
| 886 | 900 | * |
| 887 | 901 | * @since 6.5.0 |
| 888 | 902 | * |
| 889 | - * @param array $attributes The block attributes. | |
| 890 | - * @param WP_Block_List $inner_blocks A list of inner blocks. | |
| 903 | + * @param array $attributes The block attributes. | |
| 904 | + * @param WP_Block_List $inner_blocks A list of inner blocks. | |
| 891 | 905 | * @return string Returns the navigation block markup. |
| 892 | 906 | */ |
| 893 | 907 | private static function get_nav_attributes( $attributes, $inner_blocks ) { |
| 894 | 908 | $is_interactive = static::is_interactive( $attributes, $inner_blocks ); |
| @@ -972,9 +986,9 @@ | ||
| 972 | 986 | * Returns the markup for the navigation block. |
| 973 | 987 | * |
| 974 | 988 | * @since 6.5.0 |
| 975 | 989 | * |
| 976 | - * @param array $attributes The block attributes. | |
| 990 | + * @param array $attributes The block attributes. | |
| 977 | 991 | * @param WP_Block_List $inner_blocks The list of inner blocks. |
| 978 | 992 | * @return string Returns the navigation wrapper markup. |
| 979 | 993 | */ |
| 980 | 994 | private static function get_inner_block_markup( $attributes, $inner_blocks ) { |
| @@ -1041,8 +1055,12 @@ | ||
| 1041 | 1055 | } |
| 1042 | 1056 | |
| 1043 | 1057 | unset( $attributes['rgbTextColor'], $attributes['rgbBackgroundColor'] ); |
| 1044 | 1058 | |
| 1059 | + // Submenu detection is memoized while a navigation block renders. Reset it so | |
| 1060 | + // the result of a previously rendered navigation block is not reused for this one. | |
| 1061 | + static::$has_submenus = false; | |
| 1062 | + | |
| 1045 | 1063 | $inner_blocks = static::get_inner_blocks( $attributes, $block ); |
| 1046 | 1064 | // Prevent navigation blocks referencing themselves from rendering. |
| 1047 | 1065 | if ( gutenberg_block_core_navigation_block_tree_has_block_type( |
| 1048 | 1066 | $inner_blocks, |
| @@ -1779,14 +1797,14 @@ | ||
| 1779 | 1797 | * @since 5.9.0 |
| 1780 | 1798 | * |
| 1781 | 1799 | * @deprecated 6.3.0 Use WP_Navigation_Fallback::parse_blocks_from_menu_items() instead. |
| 1782 | 1800 | * |
| 1783 | - * @param array $menu_items An array of menu items that represent | |
| 1784 | - * an individual level of a menu. | |
| 1785 | - * @param array $menu_items_by_parent_id An array keyed by the id of the | |
| 1786 | - * parent menu where each element is an | |
| 1787 | - * array of menu items that belong to | |
| 1788 | - * that parent. | |
| 1801 | + * @param array $menu_items An array of menu items that represent | |
| 1802 | + * an individual level of a menu. | |
| 1803 | + * @param array $menu_items_by_parent_id An array keyed by the id of the | |
| 1804 | + * parent menu where each element is an | |
| 1805 | + * array of menu items that belong to | |
| 1806 | + * that parent. | |
| 1789 | 1807 | * @return array An array of parsed block data. |
| 1790 | 1808 | */ |
| 1791 | 1809 | function gutenberg_block_core_navigation_parse_blocks_from_menu_items( $menu_items, $menu_items_by_parent_id ) { |
| 1792 | 1810 | |
| @@ -1884,9 +1902,9 @@ | ||
| 1884 | 1902 | * @since 6.2.0 |
| 1885 | 1903 | * |
| 1886 | 1904 | * @deprecated 6.3.0 Use WP_Navigation_Fallback::get_classic_menu_fallback_blocks() instead. |
| 1887 | 1905 | * |
| 1888 | - * @param object $classic_nav_menu WP_Term The classic navigation object to convert. | |
| 1906 | + * @param object $classic_nav_menu WP_Term The classic navigation object to convert. | |
| 1889 | 1907 | * @return array the normalized parsed blocks. |
| 1890 | 1908 | */ |
| 1891 | 1909 | function gutenberg_block_core_navigation_get_classic_menu_fallback_blocks( $classic_nav_menu ) { |
| 1892 | 1910 | |