Changeset 59775 for trunk/src/wp-includes/blocks/navigation.php
- Timestamp:
- 02/07/2025 03:44:07 PM (10 months ago)
- File:
-
- 1 edited
-
trunk/src/wp-includes/blocks/navigation.php (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/blocks/navigation.php
r59119 r59775 344 344 345 345 $navigation_name = $attributes['ariaLabel'] ?? ''; 346 347 if ( ! empty( $navigation_name ) ) { 348 return $navigation_name; 349 } 346 350 347 351 // Load the navigation post. … … 536 540 $toggle_aria_label_open, 537 541 $toggle_aria_label_close, 538 esc_attr( implode( ' ', $responsive_container_classes) ),539 esc_attr( implode( ' ', $open_button_classes) ),542 esc_attr( trim( implode( ' ', $responsive_container_classes ) ) ), 543 esc_attr( trim( implode( ' ', $open_button_classes ) ) ), 540 544 ( ! empty( $overlay_inline_styles ) ) ? "style=\"$overlay_inline_styles\"" : '', 541 545 $toggle_button_content, … … 564 568 $style = static::get_styles( $attributes ); 565 569 $class = static::get_classes( $attributes ); 566 $wrapper_attributes = get_block_wrapper_attributes( 567 array( 568 'class' => $class, 569 'style' => $style, 570 'aria-label' => $nav_menu_name, 571 ) 570 $extra_attributes = array( 571 'class' => $class, 572 'style' => $style, 572 573 ); 574 if ( ! empty( $nav_menu_name ) ) { 575 $extra_attributes['aria-label'] = $nav_menu_name; 576 } 577 $wrapper_attributes = get_block_wrapper_attributes( $extra_attributes ); 573 578 574 579 if ( $is_responsive_menu ) { … … 814 819 // Add directives to the parent `<li>`. 815 820 $tags->set_attribute( 'data-wp-interactive', 'core/navigation' ); 816 $tags->set_attribute( 'data-wp-context', '{ "submenuOpenedBy": { "click": false, "hover": false, "focus": false }, "type": "submenu" }' );821 $tags->set_attribute( 'data-wp-context', '{ "submenuOpenedBy": { "click": false, "hover": false, "focus": false }, "type": "submenu", "modal": null }' ); 817 822 $tags->set_attribute( 'data-wp-watch', 'callbacks.initMenu' ); 818 823 $tags->set_attribute( 'data-wp-on--focusout', 'actions.handleMenuFocusout' ); … … 1434 1439 1435 1440 /** 1436 * Accepts the serialized markup of a block and its inner blocks, and returns serialized markup of the inner blocks.1437 *1438 * @since 6.5.01439 *1440 * @param string $serialized_block The serialized markup of a block and its inner blocks.1441 * @return string1442 */1443 function block_core_navigation_remove_serialized_parent_block( $serialized_block ) {1444 $start = strpos( $serialized_block, '-->' ) + strlen( '-->' );1445 $end = strrpos( $serialized_block, '<!--' );1446 return substr( $serialized_block, $start, $end - $start );1447 }1448 1449 /**1450 1441 * Mock a parsed block for the Navigation block given its inner blocks and the `wp_navigation` post object. 1451 1442 * The `wp_navigation` post's `_wp_ignored_hooked_blocks` meta is queried to add the `metadata.ignoredHookedBlocks` attribute. … … 1501 1492 $mock_navigation_block = block_core_navigation_mock_parsed_block( $inner_blocks, $post ); 1502 1493 1503 if ( function_exists( 'apply_block_hooks_to_content' ) ) { 1504 $mock_navigation_block_markup = serialize_block( $mock_navigation_block ); 1505 return apply_block_hooks_to_content( $mock_navigation_block_markup, $post, 'insert_hooked_blocks' ); 1506 } 1507 1508 $hooked_blocks = get_hooked_blocks(); 1509 $before_block_visitor = null; 1510 $after_block_visitor = null; 1511 1512 if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) { 1513 $before_block_visitor = make_before_block_visitor( $hooked_blocks, $post, 'insert_hooked_blocks' ); 1514 $after_block_visitor = make_after_block_visitor( $hooked_blocks, $post, 'insert_hooked_blocks' ); 1515 } 1516 1517 return traverse_and_serialize_block( $mock_navigation_block, $before_block_visitor, $after_block_visitor ); 1518 } 1519 1520 /** 1521 * Insert ignoredHookedBlocks meta into the Navigation block and its inner blocks. 1522 * 1523 * Given a Navigation block's inner blocks and its corresponding `wp_navigation` post object, 1524 * this function inserts ignoredHookedBlocks meta into it, and returns the serialized inner blocks in a 1525 * mock Navigation block wrapper. 1526 * 1527 * @since 6.5.0 1528 * 1529 * @param array $inner_blocks Parsed inner blocks of a Navigation block. 1530 * @param WP_Post $post `wp_navigation` post object corresponding to the block. 1531 * @return string Serialized inner blocks in mock Navigation block wrapper, with hooked blocks inserted, if any. 1532 */ 1533 function block_core_navigation_set_ignored_hooked_blocks_metadata( $inner_blocks, $post ) { 1534 $mock_navigation_block = block_core_navigation_mock_parsed_block( $inner_blocks, $post ); 1535 $hooked_blocks = get_hooked_blocks(); 1536 $before_block_visitor = null; 1537 $after_block_visitor = null; 1538 1539 if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) { 1540 $before_block_visitor = make_before_block_visitor( $hooked_blocks, $post, 'set_ignored_hooked_blocks_metadata' ); 1541 $after_block_visitor = make_after_block_visitor( $hooked_blocks, $post, 'set_ignored_hooked_blocks_metadata' ); 1542 } 1543 1544 return traverse_and_serialize_block( $mock_navigation_block, $before_block_visitor, $after_block_visitor ); 1545 } 1546 1547 /** 1548 * Updates the post meta with the list of ignored hooked blocks when the navigation is created or updated via the REST API. 1549 * 1550 * @access private 1551 * @since 6.5.0 1552 * 1553 * @param stdClass $post Post object. 1554 * @return stdClass The updated post object. 1555 */ 1556 function block_core_navigation_update_ignore_hooked_blocks_meta( $post ) { 1557 /* 1558 * In this scenario the user has likely tried to create a navigation via the REST API. 1559 * In which case we won't have a post ID to work with and store meta against. 1560 */ 1561 if ( empty( $post->ID ) ) { 1562 return $post; 1563 } 1564 1565 /** 1566 * Skip meta generation when consumers intentionally update specific Navigation fields 1567 * and omit the content update. 1568 */ 1569 if ( ! isset( $post->post_content ) ) { 1570 return $post; 1571 } 1572 1573 /* 1574 * We run the Block Hooks mechanism to inject the `metadata.ignoredHookedBlocks` attribute into 1575 * all anchor blocks. For the root level, we create a mock Navigation and extract them from there. 1576 */ 1577 $blocks = parse_blocks( $post->post_content ); 1578 1579 /* 1580 * Block Hooks logic requires a `WP_Post` object (rather than the `stdClass` with the updates that 1581 * we're getting from the `rest_pre_insert_wp_navigation` filter) as its second argument (to be 1582 * used as context for hooked blocks insertion). 1583 * We thus have to look it up from the DB,based on `$post->ID`. 1584 */ 1585 $markup = block_core_navigation_set_ignored_hooked_blocks_metadata( $blocks, get_post( $post->ID ) ); 1586 1587 $root_nav_block = parse_blocks( $markup )[0]; 1588 $ignored_hooked_blocks = isset( $root_nav_block['attrs']['metadata']['ignoredHookedBlocks'] ) 1589 ? $root_nav_block['attrs']['metadata']['ignoredHookedBlocks'] 1590 : array(); 1591 1592 if ( ! empty( $ignored_hooked_blocks ) ) { 1593 $existing_ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ); 1594 if ( ! empty( $existing_ignored_hooked_blocks ) ) { 1595 $existing_ignored_hooked_blocks = json_decode( $existing_ignored_hooked_blocks, true ); 1596 $ignored_hooked_blocks = array_unique( array_merge( $ignored_hooked_blocks, $existing_ignored_hooked_blocks ) ); 1597 } 1598 update_post_meta( $post->ID, '_wp_ignored_hooked_blocks', json_encode( $ignored_hooked_blocks ) ); 1599 } 1600 1601 $post->post_content = block_core_navigation_remove_serialized_parent_block( $markup ); 1602 return $post; 1603 } 1604 1605 /* 1606 * Before adding our filter, we verify if it's already added in Core. 1607 * However, during the build process, Gutenberg automatically prefixes our functions with "gutenberg_". 1608 * Therefore, we concatenate the Core's function name to circumvent this prefix for our check. 1609 */ 1610 $rest_insert_wp_navigation_core_callback = 'block_core_navigation_' . 'update_ignore_hooked_blocks_meta'; // phpcs:ignore Generic.Strings.UnnecessaryStringConcat.Found 1611 1612 /* 1613 * Do not add the `block_core_navigation_update_ignore_hooked_blocks_meta` filter in the following cases: 1614 * - If Core has added the `update_ignored_hooked_blocks_postmeta` filter already (WP >= 6.6); 1615 * - or if the `$rest_insert_wp_navigation_core_callback` filter has already been added. 1616 */ 1617 if ( 1618 ! has_filter( 'rest_pre_insert_wp_navigation', 'update_ignored_hooked_blocks_postmeta' ) && 1619 ! has_filter( 'rest_pre_insert_wp_navigation', $rest_insert_wp_navigation_core_callback ) 1620 ) { 1621 add_filter( 'rest_pre_insert_wp_navigation', 'block_core_navigation_update_ignore_hooked_blocks_meta' ); 1622 } 1623 1624 /** 1625 * Hooks into the REST API response for the core/navigation block and adds the first and last inner blocks. 1626 * 1627 * @since 6.5.0 1628 * 1629 * @param WP_REST_Response $response The response object. 1630 * @param WP_Post $post Post object. 1631 * @return WP_REST_Response The response object. 1632 */ 1633 function block_core_navigation_insert_hooked_blocks_into_rest_response( $response, $post ) { 1634 if ( ! isset( $response->data['content']['raw'] ) || ! isset( $response->data['content']['rendered'] ) ) { 1635 return $response; 1636 } 1637 $parsed_blocks = parse_blocks( $response->data['content']['raw'] ); 1638 $content = block_core_navigation_insert_hooked_blocks( $parsed_blocks, $post ); 1639 1640 // Remove mock Navigation block wrapper. 1641 $content = block_core_navigation_remove_serialized_parent_block( $content ); 1642 1643 $response->data['content']['raw'] = $content; 1644 1645 /** This filter is documented in wp-includes/post-template.php */ 1646 $response->data['content']['rendered'] = apply_filters( 'the_content', $content ); 1647 1648 return $response; 1649 } 1650 1651 /* 1652 * Before adding our filter, we verify if it's already added in Core. 1653 * However, during the build process, Gutenberg automatically prefixes our functions with "gutenberg_". 1654 * Therefore, we concatenate the Core's function name to circumvent this prefix for our check. 1655 */ 1656 $rest_prepare_wp_navigation_core_callback = 'block_core_navigation_' . 'insert_hooked_blocks_into_rest_response'; 1657 1658 /* 1659 * Do not add the `block_core_navigation_insert_hooked_blocks_into_rest_response` filter in the following cases: 1660 * - If Core has added the `insert_hooked_blocks_into_rest_response` filter already (WP >= 6.6); 1661 * - or if the `$rest_prepare_wp_navigation_core_callback` filter has already been added. 1662 */ 1663 if ( 1664 ! has_filter( 'rest_prepare_wp_navigation', 'insert_hooked_blocks_into_rest_response' ) && 1665 ! has_filter( 'rest_prepare_wp_navigation', $rest_prepare_wp_navigation_core_callback ) 1666 ) { 1667 add_filter( 'rest_prepare_wp_navigation', 'block_core_navigation_insert_hooked_blocks_into_rest_response', 10, 3 ); 1668 } 1494 $mock_navigation_block_markup = serialize_block( $mock_navigation_block ); 1495 return apply_block_hooks_to_content( $mock_navigation_block_markup, $post, 'insert_hooked_blocks' ); 1496 }
Note: See TracChangeset
for help on using the changeset viewer.