@@ -3438,26 +3438,67 @@ function wp_enqueue_command_palette_assets() {
34383438 'is_network_admin ' => is_network_admin (),
34393439 );
34403440
3441+ /**
3442+ * Extracts root-level text nodes from HTML string.
3443+ *
3444+ * @ignore
3445+ * @param string $label HTML string to extract text from.
3446+ * @return string Extracted text content, trimmed.
3447+ */
3448+ $ extract_root_text = static function ( string $ label ): string {
3449+ if ( '' === $ label ) {
3450+ return '' ;
3451+ }
3452+
3453+ $ processor = new WP_HTML_Tag_Processor ( $ label );
3454+ $ text_parts = array ();
3455+ $ depth = 0 ;
3456+
3457+ while ( $ processor ->next_token () ) {
3458+ $ token_type = $ processor ->get_token_type ();
3459+
3460+ if ( '#text ' === $ token_type ) {
3461+ if ( 0 === $ depth ) {
3462+ $ text_parts [] = $ processor ->get_modifiable_text ();
3463+ }
3464+ continue ;
3465+ }
3466+
3467+ if ( '#tag ' !== $ token_type ) {
3468+ continue ;
3469+ }
3470+
3471+ if ( $ processor ->is_tag_closer () ) {
3472+ if ( $ depth > 0 ) {
3473+ --$ depth ;
3474+ }
3475+ continue ;
3476+ }
3477+
3478+ $ token_name = $ processor ->get_tag ();
3479+ if ( $ token_name && ! WP_HTML_Processor::is_void ( $ token_name ) ) {
3480+ ++$ depth ;
3481+ }
3482+ }
3483+
3484+ return trim ( implode ( '' , $ text_parts ) );
3485+ };
3486+
34413487 if ( $ menu ) {
34423488 $ menu_commands = array ();
34433489 foreach ( $ menu as $ menu_item ) {
3444- if ( empty ( $ menu_item [0 ] ) || ! empty ( $ menu_item [1 ] ) && ! current_user_can ( $ menu_item [1 ] ) ) {
3490+ if ( empty ( $ menu_item [0 ] ) || ! is_string ( $ menu_item [ 0 ] ) || ! empty ( $ menu_item [1 ] ) && ! current_user_can ( $ menu_item [1 ] ) ) {
34453491 continue ;
34463492 }
34473493
3448- // Remove all HTML tags and their contents.
3449- $ menu_label = $ menu_item [0 ];
3450- while ( preg_match ( '/<[^>]*>/ ' , $ menu_label ) ) {
3451- $ menu_label = preg_replace ( '/<[^>]*>.*?<\/[^>]*>|<[^>]*\/>|<[^>]*>/s ' , '' , $ menu_label );
3452- }
3453- $ menu_label = trim ( $ menu_label );
3494+ $ menu_label = $ extract_root_text ( $ menu_item [0 ] );
34543495 $ menu_url = '' ;
34553496 $ menu_slug = $ menu_item [2 ];
34563497
34573498 if ( preg_match ( '/\.php($|\?)/ ' , $ menu_slug ) || wp_http_validate_url ( $ menu_slug ) ) {
34583499 $ menu_url = $ menu_slug ;
34593500 } elseif ( ! empty ( menu_page_url ( $ menu_slug , false ) ) ) {
3460- $ menu_url = html_entity_decode ( menu_page_url ( $ menu_slug , false ), ENT_QUOTES , get_bloginfo ( ' charset ' ) );
3501+ $ menu_url = WP_HTML_Decoder:: decode_attribute ( menu_page_url ( $ menu_slug , false ) );
34613502 }
34623503
34633504 if ( $ menu_url ) {
@@ -3474,21 +3515,15 @@ function wp_enqueue_command_palette_assets() {
34743515 continue ;
34753516 }
34763517
3477- // Remove all HTML tags and their contents.
3478- $ submenu_label = $ submenu_item [0 ];
3479- while ( preg_match ( '/<[^>]*>/ ' , $ submenu_label ) ) {
3480- $ submenu_label = preg_replace ( '/<[^>]*>.*?<\/[^>]*>|<[^>]*\/>|<[^>]*>/s ' , '' , $ submenu_label );
3481- }
3482- $ submenu_label = trim ( $ submenu_label );
3518+ $ submenu_label = $ extract_root_text ( $ submenu_item [0 ] );
34833519 $ submenu_url = '' ;
34843520 $ submenu_slug = $ submenu_item [2 ];
34853521
34863522 if ( preg_match ( '/\.php($|\?)/ ' , $ submenu_slug ) || wp_http_validate_url ( $ submenu_slug ) ) {
34873523 $ submenu_url = $ submenu_slug ;
34883524 } elseif ( ! empty ( menu_page_url ( $ submenu_slug , false ) ) ) {
3489- $ submenu_url = html_entity_decode ( menu_page_url ( $ submenu_slug , false ), ENT_QUOTES , get_bloginfo ( ' charset ' ) );
3525+ $ submenu_url = WP_HTML_Decoder:: decode_attribute ( menu_page_url ( $ submenu_slug , false ) );
34903526 }
3491-
34923527 if ( $ submenu_url ) {
34933528 $ menu_commands [] = array (
34943529 'label ' => sprintf (
0 commit comments