Changeset 60818
- Timestamp:
- 09/30/2025 04:59:02 PM (2 months ago)
- Location:
- branches/6.8
- Files:
-
- 7 edited
-
. (modified) (1 prop)
-
src/js/_enqueues/lib/nav-menu.js (modified) (11 diffs)
-
src/js/_enqueues/wp/customize/nav-menus.js (modified) (2 diffs)
-
src/wp-includes/class-wp-customize-nav-menus.php (modified) (3 diffs)
-
src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php (modified) (12 diffs)
-
tests/phpunit/tests/customize/nav-menu-item-setting.php (modified) (2 diffs)
-
tests/phpunit/tests/customize/nav-menus.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/6.8
- Property svn:mergeinfo changed
/trunk merged: 60815-60816
- Property svn:mergeinfo changed
-
branches/6.8/src/js/_enqueues/lib/nav-menu.js
r59950 r60818 299 299 $.each( parentDropdowns, function() { 300 300 var parentDropdown = $( this ), 301 $html = '', 302 $selected = '', 303 currentItemID = parentDropdown.closest( 'li.menu-item' ).find( '.menu-item-data-db-id' ).val(), 304 currentparentID = parentDropdown.closest( 'li.menu-item' ).find( '.menu-item-data-parent-id' ).val(), 301 currentItemID = parseInt( parentDropdown.closest( 'li.menu-item' ).find( '.menu-item-data-db-id' ).val() ), 302 currentParentID = parseInt( parentDropdown.closest( 'li.menu-item' ).find( '.menu-item-data-parent-id' ).val() ), 305 303 currentItem = parentDropdown.closest( 'li.menu-item' ), 306 304 currentMenuItemChild = currentItem.childMenuItems(), 307 excludeMenuItem = [ currentItemID ]; 305 excludeMenuItem = /** @type {number[]} */ [ currentItemID ]; 306 307 parentDropdown.empty(); 308 308 309 309 if ( currentMenuItemChild.length > 0 ) { 310 310 $.each( currentMenuItemChild, function(){ 311 311 var childItem = $(this), 312 childID = childItem.find( '.menu-item-data-db-id' ).val();312 childID = parseInt( childItem.find( '.menu-item-data-db-id' ).val() ); 313 313 314 314 excludeMenuItem.push( childID ); … … 316 316 } 317 317 318 if ( currentparentID == 0 ) { 319 $selected = 'selected'; 320 } 321 322 $html += '<option ' + $selected + ' value="0">' + wp.i18n._x( 'No Parent', 'menu item without a parent in navigation menu' ) + '</option>'; 318 parentDropdown.append( 319 $( '<option>', { 320 value: '0', 321 selected: currentParentID === 0, 322 text: wp.i18n._x( 'No Parent', 'menu item without a parent in navigation menu' ), 323 } ) 324 ); 323 325 324 326 $.each( menuItems, function() { 325 327 var menuItem = $(this), 326 $selected = '', 327 menuID = menuItem.find( '.menu-item-data-db-id' ).val(), 328 menuID = parseInt( menuItem.find( '.menu-item-data-db-id' ).val() ), 328 329 menuTitle = menuItem.find( '.edit-menu-item-title' ).val(); 329 330 330 331 if ( ! excludeMenuItem.includes( menuID ) ) { 331 if ( currentparentID == menuID ) { 332 $selected = 'selected'; 333 } 334 $html += '<option ' + $selected + ' value="' + menuID + '">' + menuTitle + '</option>'; 332 parentDropdown.append( 333 $( '<option>', { 334 value: menuID.toString(), 335 selected: currentParentID === menuID, 336 text: menuTitle, 337 } ) 338 ); 335 339 } 336 340 }); 337 338 parentDropdown.html( $html );339 341 }); 340 342 … … 350 352 menuItem = orderDropdown.closest( 'li.menu-item' ).first(), 351 353 depth = menuItem.menuItemDepth(), 352 isPrimaryMenuItem = ( 0 === depth ) ,353 $html = '', 354 $selected = '';354 isPrimaryMenuItem = ( 0 === depth ); 355 356 orderDropdown.empty(); 355 357 356 358 if ( isPrimaryMenuItem ) { … … 361 363 362 364 for ( let i = 1; i < totalMenuItems + 1; i++ ) { 363 $selected = ''; 364 if ( i == itemPosition ) { 365 $selected = 'selected'; 366 } 367 var itemString = wp.i18n.sprintf( 365 var itemString = wp.i18n.sprintf( 368 366 /* translators: 1: The current menu item number, 2: The total number of menu items. */ 369 367 wp.i18n._x( '%1$s of %2$s', 'part of a total number of menu items' ), … … 371 369 totalMenuItems 372 370 ); 373 $html += '<option ' + $selected + ' value="' + i + '">' + itemString + '</option>'; 371 orderDropdown.append( 372 $( '<option>', { 373 selected: i === itemPosition, 374 value: i.toString(), 375 text: itemString, 376 } ) 377 ); 374 378 } 375 379 … … 383 387 384 388 for ( let i = 1; i < totalSubMenuItems + 1; i++ ) { 385 $selected = ''; 386 if ( i == itemPosition ) { 387 $selected = 'selected'; 388 } 389 var submenuString = wp.i18n.sprintf( 389 var submenuString = wp.i18n.sprintf( 390 390 /* translators: 1: The current submenu item number, 2: The total number of submenu items. */ 391 391 wp.i18n._x( '%1$s of %2$s', 'part of a total number of menu items' ), … … 393 393 totalSubMenuItems 394 394 ); 395 $html += '<option ' + $selected + ' value="' + i + '">' + submenuString + '</option>'; 395 orderDropdown.append( 396 $( '<option>', { 397 selected: i === itemPosition, 398 value: i.toString(), 399 text: submenuString, 400 } ) 401 ); 396 402 } 397 403 398 404 } 399 400 orderDropdown.html( $html );401 405 }); 402 406 … … 1291 1295 1292 1296 if ( this.checked === true ) { 1293 $( '#pending-menu-items-to-delete ul' ).append( 1294 '<li data-menu-item-id="' + menuItemID + '">' + 1295 '<span class="pending-menu-item-name">' + menuItemName + '</span> ' + 1296 '<span class="pending-menu-item-type">(' + menuItemType + ')</span>' + 1297 '<span class="separator"></span>' + 1298 '</li>' 1299 ); 1297 const $li = $( '<li>', { 'data-menu-item-id': menuItemID } ); 1298 $li.append( $( '<span>', { 1299 'class': 'pending-menu-item-name', 1300 text: menuItemName 1301 } ) ); 1302 $li.append( ' ' ); 1303 $li.append( $( '<span>', { 1304 'class': 'pending-menu-item-type', 1305 text: '(' + menuItemType + ')', 1306 } ) ); 1307 $li.append( $( '<span>', { 'class': 'separator' } ) ); 1308 $( '#pending-menu-items-to-delete ul' ).append( $li ); 1300 1309 } 1301 1310 … … 1700 1709 1701 1710 eventOnClickMenuSave : function() { 1702 var locs = '', 1703 menuName = $('#menu-name'), 1704 menuNameVal = menuName.val(); 1711 var menuName = $('#menu-name'), 1712 menuNameVal = menuName.val(); 1705 1713 1706 1714 // Cancel and warn if invalid menu name. … … 1710 1718 } 1711 1719 // Copy menu theme locations. 1720 // Note: This appears to be dead code since #nav-menu-theme-locations no longer exists, perhaps removed in r32842. 1721 var $updateNavMenu = $('#update-nav-menu'); 1712 1722 $('#nav-menu-theme-locations select').each(function() { 1713 locs += '<input type="hidden" name="' + this.name + '" value="' + $(this).val() + '" />'; 1714 }); 1715 $('#update-nav-menu').append( locs ); 1723 $updateNavMenu.append( 1724 $( '<input>', { 1725 type: 'hidden', 1726 name: this.name, 1727 value: $( this ).val(), 1728 } ) 1729 ); 1730 }); 1716 1731 // Update menu item position data. 1717 1732 api.menuList.find('.menu-item-data-position').val( function(index) { return index + 1; } ); … … 1756 1771 1757 1772 if( ! $items.length ) { 1758 $('.categorychecklist', panel).html( '<li><p>' + wp.i18n.__( 'No results found.' ) + '</p></li>' ); 1773 const li = $( '<li>' ); 1774 const p = $( '<p>', { text: wp.i18n.__( 'No results found.' ) } ); 1775 li.append( p ); 1776 $('.categorychecklist', panel).empty().append( li ); 1759 1777 $( '.spinner', panel ).removeClass( 'is-active' ); 1760 1778 wrapper.addClass( 'has-no-menu-item' ); -
branches/6.8/src/js/_enqueues/wp/customize/nav-menus.js
r59948 r60818 530 530 } 531 531 532 this.currentMenuControl.addItemToMenu( menu_item.attributes ); 532 // Leave the title as empty to reuse the original title as a placeholder if set. 533 var nav_menu_item = Object.assign( {}, menu_item.attributes ); 534 if ( nav_menu_item.title === nav_menu_item.original_title ) { 535 nav_menu_item.title = ''; 536 } 537 538 this.currentMenuControl.addItemToMenu( nav_menu_item ); 533 539 534 540 $( menuitemTpl ).find( '.menu-item-handle' ).addClass( 'item-added' ); … … 3137 3143 { 3138 3144 nav_menu_term_id: menuControl.params.menu_id, 3139 original_title: item.title,3140 3145 position: position 3141 3146 } -
branches/6.8/src/wp-includes/class-wp-customize-nav-menus.php
r59948 r60818 192 192 } elseif ( 'post' !== $object_name && 0 === $page && $post_type->has_archive ) { 193 193 // Add a post type archive link. 194 $title = $post_type->labels->archives; 194 195 $items[] = array( 195 'id' => $object_name . '-archive', 196 'title' => $post_type->labels->archives, 197 'type' => 'post_type_archive', 198 'type_label' => __( 'Post Type Archive' ), 199 'object' => $object_name, 200 'url' => get_post_type_archive_link( $object_name ), 196 'id' => $object_name . '-archive', 197 'title' => $title, 198 'original_title' => $title, 199 'type' => 'post_type_archive', 200 'type_label' => __( 'Post Type Archive' ), 201 'object' => $object_name, 202 'url' => get_post_type_archive_link( $object_name ), 201 203 ); 202 204 } … … 245 247 } 246 248 249 $title = html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ); 247 250 $items[] = array( 248 'id' => "post-{$post->ID}", 249 'title' => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ), 250 'type' => 'post_type', 251 'type_label' => $post_type_label, 252 'object' => $post->post_type, 253 'object_id' => (int) $post->ID, 254 'url' => get_permalink( (int) $post->ID ), 251 'id' => "post-{$post->ID}", 252 'title' => $title, 253 'original_title' => $title, 254 'type' => 'post_type', 255 'type_label' => $post_type_label, 256 'object' => $post->post_type, 257 'object_id' => (int) $post->ID, 258 'url' => get_permalink( (int) $post->ID ), 255 259 ); 256 260 } … … 277 281 278 282 foreach ( $terms as $term ) { 283 $title = html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ); 279 284 $items[] = array( 280 'id' => "term-{$term->term_id}", 281 'title' => html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ), 282 'type' => 'taxonomy', 283 'type_label' => get_taxonomy( $term->taxonomy )->labels->singular_name, 284 'object' => $term->taxonomy, 285 'object_id' => (int) $term->term_id, 286 'url' => get_term_link( (int) $term->term_id, $term->taxonomy ), 285 'id' => "term-{$term->term_id}", 286 'title' => $title, 287 'original_title' => $title, 288 'type' => 'taxonomy', 289 'type_label' => get_taxonomy( $term->taxonomy )->labels->singular_name, 290 'object' => $term->taxonomy, 291 'object_id' => (int) $term->term_id, 292 'url' => get_term_link( (int) $term->term_id, $term->taxonomy ), 287 293 ); 288 294 } -
branches/6.8/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php
r56548 r60818 57 57 'xfn' => '', 58 58 'status' => 'publish', 59 'original_title' => '',60 59 'nav_menu_term_id' => 0, // This will be supplied as the $menu_id arg for wp_update_nav_menu_item(). 61 60 '_invalid' => false, … … 211 210 */ 212 211 public function value() { 212 $type_label = null; 213 213 if ( $this->is_previewed && get_current_blog_id() === $this->_previewed_blog_id ) { 214 214 $undefined = new stdClass(); // Symbol. … … 219 219 } else { 220 220 $value = $post_value; 221 }222 if ( ! empty( $value ) && empty( $value['original_title'] ) ) {223 $value['original_title'] = $this->get_original_title( (object) $value );224 221 } 225 222 } elseif ( isset( $this->value ) ) { … … 234 231 $is_title_empty = empty( $post->post_title ); 235 232 $value = (array) wp_setup_nav_menu_item( $post ); 233 if ( isset( $value['type_label'] ) ) { 234 $type_label = $value['type_label']; 235 } 236 236 if ( $is_title_empty ) { 237 237 $value['title'] = ''; … … 250 250 } 251 251 252 if ( ! empty( $value ) && empty( $value['type_label'] ) ) { 253 $value['type_label'] = $this->get_type_label( (object) $value ); 252 // These properties are read-only and are part of the setting for use in the Customizer UI. 253 if ( is_array( $value ) ) { 254 $value_obj = (object) $value; 255 $value['type_label'] = isset( $type_label ) ? $type_label : $this->get_type_label( $value_obj ); 256 $value['original_title'] = $this->get_original_title( $value_obj ); 254 257 } 255 258 … … 258 261 259 262 /** 263 * Prepares the value for editing on the client. 264 * 265 * @since 6.8.3 266 * 267 * @return array|false Value prepared for the client. 268 */ 269 public function js_value() { 270 $value = parent::js_value(); 271 if ( is_array( $value ) && isset( $value['original_title'] ) ) { 272 // Decode entities for the sake of displaying the original title as a placeholder. 273 $value['original_title'] = html_entity_decode( $value['original_title'], ENT_QUOTES, get_bloginfo( 'charset' ) ); 274 } 275 return $value; 276 } 277 278 /** 260 279 * Get original title. 261 280 * … … 263 282 * 264 283 * @param object $item Nav menu item. 265 * @return string The original title .284 * @return string The original title, without entity decoding. 266 285 */ 267 286 protected function get_original_title( $item ) { … … 289 308 } 290 309 } 291 $original_title = html_entity_decode( $original_title, ENT_QUOTES, get_bloginfo( 'charset' ) );292 310 return $original_title; 293 311 } … … 345 363 $this->value['status'] = $this->value['post_status']; 346 364 unset( $this->value['post_status'] ); 347 }348 349 if ( ! isset( $this->value['original_title'] ) ) {350 $this->value['original_title'] = $this->get_original_title( (object) $this->value );351 365 } 352 366 … … 595 609 unset( $item->position ); 596 610 597 if ( empty( $item->original_title ) ) {598 $item->original_title = $this->get_original_title( $item );599 }600 611 if ( empty( $item->title ) && ! empty( $item->original_title ) ) { 601 $item->title = $item->original_title; 612 $item->title = $item->original_title; // This is NOT entity-decoded. It comes from self::get_original_title(). 602 613 } 603 614 if ( $item->title ) { … … 655 666 * @since 5.9.0 Renamed `$menu_item_value` to `$value` for PHP 8 named parameter support. 656 667 * 657 * @param array $value The menu item value to sanitize.668 * @param array|false $value The menu item value to sanitize. 658 669 * @return array|false|null|WP_Error Null or WP_Error if an input isn't valid. False if it is marked for deletion. 659 670 * Otherwise the sanitized value. … … 712 723 } 713 724 714 $menu_item_value['original_title'] = sanitize_text_field( $menu_item_value['original_title'] );715 716 725 // Apply the same filters as when calling wp_insert_post(). 717 726 -
branches/6.8/tests/phpunit/tests/customize/nav-menu-item-setting.php
r56421 r60818 90 90 'xfn' => '', 91 91 'status' => 'publish', 92 'original_title' => '',93 92 'nav_menu_term_id' => 0, 94 93 '_invalid' => false, … … 582 581 'xfn' => 'hello inject', 583 582 'status' => 'draft', 584 'original_title' => 'Hi ',583 'original_title' => 'Hi<script>unfilteredHtml()</script>', 585 584 'nav_menu_term_id' => 0, 586 585 ); -
branches/6.8/tests/phpunit/tests/customize/nav-menus.php
r59224 r60818 169 169 // Expected menu item array. 170 170 $expected = array( 171 'id' => "post-{$post_id}", 172 'title' => 'Post Title', 173 'type' => 'post_type', 174 'type_label' => 'Post', 175 'object' => 'post', 176 'object_id' => (int) $post_id, 177 'url' => get_permalink( (int) $post_id ), 171 'id' => "post-{$post_id}", 172 'title' => 'Post Title', 173 'original_title' => 'Post Title', 174 'type' => 'post_type', 175 'type_label' => 'Post', 176 'object' => 'post', 177 'object_id' => (int) $post_id, 178 'url' => get_permalink( (int) $post_id ), 178 179 ); 179 180 … … 201 202 // Expected menu item array. 202 203 $expected = array( 203 'id' => "post-{$page_id}", 204 'title' => 'Page Title', 205 'type' => 'post_type', 206 'type_label' => 'Page', 207 'object' => 'page', 208 'object_id' => (int) $page_id, 209 'url' => get_permalink( (int) $page_id ), 204 'id' => "post-{$page_id}", 205 'title' => 'Page Title', 206 'original_title' => 'Page Title', 207 'type' => 'post_type', 208 'type_label' => 'Page', 209 'object' => 'page', 210 'object_id' => (int) $page_id, 211 'url' => get_permalink( (int) $page_id ), 210 212 ); 211 213 … … 227 229 // Expected menu item array. 228 230 $expected = array( 229 'id' => "post-{$post_id}", 230 'title' => 'Post Title', 231 'type' => 'post_type', 232 'type_label' => 'Post', 233 'object' => 'post', 234 'object_id' => (int) $post_id, 235 'url' => get_permalink( (int) $post_id ), 231 'id' => "post-{$post_id}", 232 'title' => 'Post Title', 233 'original_title' => 'Post Title', 234 'type' => 'post_type', 235 'type_label' => 'Post', 236 'object' => 'post', 237 'object_id' => (int) $post_id, 238 'url' => get_permalink( (int) $post_id ), 236 239 ); 237 240 … … 253 256 // Expected menu item array. 254 257 $expected = array( 255 'id' => "term-{$term_id}", 256 'title' => 'Term Title', 257 'type' => 'taxonomy', 258 'type_label' => 'Category', 259 'object' => 'category', 260 'object_id' => (int) $term_id, 261 'url' => get_term_link( (int) $term_id, 'category' ), 258 'id' => "term-{$term_id}", 259 'title' => 'Term Title', 260 'original_title' => 'Term Title', 261 'type' => 'taxonomy', 262 'type_label' => 'Category', 263 'object' => 'category', 264 'object_id' => (int) $term_id, 265 'url' => get_term_link( (int) $term_id, 'category' ), 262 266 ); 263 267
Note: See TracChangeset
for help on using the changeset viewer.