Changeset 57708
- Timestamp:
- 02/26/2024 12:50:22 AM (7 months ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/js/_enqueues/lib/admin-bar.js
r48650 r57708 32 32 topMenuItems = adminBar.querySelectorAll( 'li.menupop' ); 33 33 allMenuItems = adminBar.querySelectorAll( '.ab-item' ); 34 adminBarLogout = document. getElementById( 'wp-admin-bar-logout' );34 adminBarLogout = document.querySelector( '#wp-admin-bar-logout a' ); 35 35 adminBarSearchForm = document.getElementById( 'adminbarsearch' ); 36 36 shortlink = document.getElementById( 'wp-admin-bar-get-shortlink' ); … … 150 150 var wrapper; 151 151 152 if ( event.which !== 13 ) { 152 // Follow link if pressing Ctrl and/or Shift with Enter (opening in a new tab or window). 153 if ( event.which !== 13 || event.ctrlKey || event.shiftKey ) { 153 154 return; 154 155 } … … 337 338 element.className += className; 338 339 } 340 341 var menuItemToggle = element.querySelector( 'a' ); 342 if ( className === 'hover' && menuItemToggle && menuItemToggle.hasAttribute( 'aria-expanded' ) ) { 343 menuItemToggle.setAttribute( 'aria-expanded', 'true' ); 344 } 339 345 } 340 346 … … 366 372 367 373 element.className = classes.replace( /^[\s]+|[\s]+$/g, '' ); 374 } 375 376 var menuItemToggle = element.querySelector( 'a' ); 377 if ( className === 'hover' && menuItemToggle && menuItemToggle.hasAttribute( 'aria-expanded' ) ) { 378 menuItemToggle.setAttribute( 'aria-expanded', 'false' ); 368 379 } 369 380 } -
trunk/src/wp-includes/admin-bar.php
r57600 r57708 140 140 '</span>', 141 141 'href' => $about_url, 142 'meta' => array( 143 'menu_title' => __( 'About WordPress' ), 144 ), 142 145 ); 143 146 … … 283 286 'href' => $profile_url, 284 287 'meta' => array( 285 'class' => $class, 288 'class' => $class, 289 'menu_title' => sprintf( __( 'Howdy, %s' ), $current_user->display_name ), 286 290 ), 287 291 ) … … 326 330 } 327 331 332 $user_info .= "<span class='edit-profile'>" . __( 'Edit Profile' ) . '</span>'; 333 328 334 $wp_admin_bar->add_node( 329 335 array( … … 332 338 'title' => $user_info, 333 339 'href' => $profile_url, 334 'meta' => array( 335 'tabindex' => -1, 336 ), 337 ) 338 ); 339 340 if ( false !== $profile_url ) { 341 $wp_admin_bar->add_node( 342 array( 343 'parent' => 'user-actions', 344 'id' => 'edit-profile', 345 'title' => __( 'Edit Profile' ), 346 'href' => $profile_url, 347 ) 348 ); 349 } 340 ) 341 ); 350 342 351 343 $wp_admin_bar->add_node( … … 398 390 'title' => $title, 399 391 'href' => ( is_admin() || ! current_user_can( 'read' ) ) ? home_url( '/' ) : admin_url(), 392 'meta' => array( 393 'menu_title' => $title, 394 ), 400 395 ) 401 396 ); … … 995 990 'title' => $title, 996 991 'href' => admin_url( current( array_keys( $actions ) ) ), 992 'meta' => array( 993 'menu_title' => _x( 'New', 'admin bar menu group label' ), 994 ), 997 995 ) 998 996 ); -
trunk/src/wp-includes/class-wp-admin-bar.php
r56177 r57708 108 108 * @since 3.1.0 109 109 * @since 4.5.0 Added the ability to pass 'lang' and 'dir' meta data. 110 * @since 6.5.0 Added the ability to pass 'menu_title' for an ARIA menu name. 110 111 * 111 112 * @param array $args { … … 118 119 * @type bool $group Optional. Whether or not the node is a group. Default false. 119 120 * @type array $meta Meta data including the following keys: 'html', 'class', 'rel', 'lang', 'dir', 120 * 'onclick', 'target', 'title', 'tabindex' . Default empty.121 * 'onclick', 'target', 'title', 'tabindex', 'menu_title'. Default empty. 121 122 * } 122 123 */ … … 479 480 ?> 480 481 </div> 481 <?php if ( is_user_logged_in() ) : ?>482 <a class="screen-reader-shortcut" href="<?php echo esc_url( wp_logout_url() ); ?>"><?php _e( 'Log Out' ); ?></a>483 <?php endif; ?>484 482 </div> 485 483 … … 506 504 /** 507 505 * @since 3.3.0 506 * @since 6.5.0 Added `$menu_title` parameter to allow an ARIA menu name. 508 507 * 509 508 * @param object $node 510 */ 511 final protected function _render_group( $node ) { 509 * @param string|bool $menu_title The accessible name of this aria menu or false if not provided. 510 */ 511 final protected function _render_group( $node, $menu_title = false ) { 512 512 if ( 'container' === $node->type ) { 513 513 $this->_render_container( $node ); … … 524 524 } 525 525 526 echo "<ul id='" . esc_attr( 'wp-admin-bar-' . $node->id ) . "'$class>"; 526 if ( empty( $menu_title ) ) { 527 echo "<ul role='menu' id='" . esc_attr( 'wp-admin-bar-' . $node->id ) . "'$class>"; 528 } else { 529 echo "<ul role='menu' aria-label='" . esc_attr( $menu_title ) . "' id='" . esc_attr( 'wp-admin-bar-' . $node->id ) . "'$class>"; 530 } 527 531 foreach ( $node->children as $item ) { 528 532 $this->_render_item( $item ); … … 547 551 548 552 // Allow only numeric values, then casted to integers, and allow a tabindex value of `0` for a11y. 549 $tabindex = ( isset( $node->meta['tabindex'] ) && is_numeric( $node->meta['tabindex'] ) ) ? (int) $node->meta['tabindex'] : ''; 550 $aria_attributes = ( '' !== $tabindex ) ? ' tabindex="' . $tabindex . '"' : ''; 553 $tabindex = ( isset( $node->meta['tabindex'] ) && is_numeric( $node->meta['tabindex'] ) ) ? (int) $node->meta['tabindex'] : ''; 554 $aria_attributes = ( '' !== $tabindex ) ? ' tabindex="' . $tabindex . '"' : ''; 555 $aria_attributes .= ' role="menuitem"'; 551 556 552 557 $menuclass = ''; … … 555 560 if ( $is_parent ) { 556 561 $menuclass = 'menupop '; 557 $aria_attributes .= ' aria- haspopup="true"';562 $aria_attributes .= ' aria-expanded="false"'; 558 563 } 559 564 … … 604 609 echo '<div class="ab-sub-wrapper">'; 605 610 foreach ( $node->children as $group ) { 606 $this->_render_group( $group ); 611 if ( empty( $node->meta['menu_title'] ) ) { 612 $this->_render_group( $group, false ); 613 } else { 614 $this->_render_group( $group, $node->meta['menu_title'] ); 615 } 607 616 } 608 617 echo '</div>'; -
trunk/src/wp-includes/css/admin-bar.css
r56956 r57708 446 446 height: auto; 447 447 background: none; 448 } 449 450 #wpadminbar #wp-admin-bar-user-info a { 451 display: grid; 452 row-gap: 12px; 448 453 } 449 454 -
trunk/tests/phpunit/tests/adminbar.php
r56227 r57708 98 98 $node_my_account = $wp_admin_bar->get_node( 'my-account' ); 99 99 $node_user_info = $wp_admin_bar->get_node( 'user-info' ); 100 $node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' );101 100 102 101 // Site menu points to the home page instead of the admin URL. … … 106 105 $this->assertFalse( $node_my_account->href ); 107 106 $this->assertFalse( $node_user_info->href ); 108 $this->assertNull( $node_edit_profile );109 107 } 110 108 … … 117 115 118 116 wp_set_current_user( self::$editor_id ); 117 118 $wp_admin_bar = $this->get_standard_admin_bar(); 119 120 $node_site_name = $wp_admin_bar->get_node( 'site-name' ); 121 $node_my_account = $wp_admin_bar->get_node( 'my-account' ); 122 $node_user_info = $wp_admin_bar->get_node( 'user-info' ); 123 124 // Site menu points to the admin URL. 125 $this->assertSame( admin_url( '/' ), $node_site_name->href ); 126 127 $profile_url = admin_url( 'profile.php' ); 128 129 // Profile URLs point to profile.php. 130 $this->assertSame( $profile_url, $node_my_account->href ); 131 $this->assertSame( $profile_url, $node_user_info->href ); 132 } 133 134 /** 135 * @ticket 25162 136 * @group multisite 137 * @group ms-required 138 */ 139 public function test_admin_bar_contains_correct_links_for_users_with_no_role_on_blog() { 140 $blog_id = self::factory()->blog->create( 141 array( 142 'user_id' => self::$admin_id, 143 ) 144 ); 145 146 $this->assertTrue( user_can( self::$admin_id, 'read' ) ); 147 $this->assertTrue( user_can( self::$editor_id, 'read' ) ); 148 149 $this->assertTrue( is_user_member_of_blog( self::$admin_id, $blog_id ) ); 150 $this->assertFalse( is_user_member_of_blog( self::$editor_id, $blog_id ) ); 151 152 wp_set_current_user( self::$editor_id ); 153 154 switch_to_blog( $blog_id ); 119 155 120 156 $wp_admin_bar = $this->get_standard_admin_bar(); … … 123 159 $node_my_account = $wp_admin_bar->get_node( 'my-account' ); 124 160 $node_user_info = $wp_admin_bar->get_node( 'user-info' ); 125 $node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' ); 126 127 // Site menu points to the admin URL. 128 $this->assertSame( admin_url( '/' ), $node_site_name->href ); 129 130 $profile_url = admin_url( 'profile.php' ); 131 132 // Profile URLs point to profile.php. 133 $this->assertSame( $profile_url, $node_my_account->href ); 134 $this->assertSame( $profile_url, $node_user_info->href ); 135 $this->assertSame( $profile_url, $node_edit_profile->href ); 161 162 // Get primary blog. 163 $primary = get_active_blog_for_user( self::$editor_id ); 164 $this->assertIsObject( $primary ); 165 166 // No Site menu as the user isn't a member of this blog. 167 $this->assertNull( $node_site_name ); 168 169 $primary_profile_url = get_admin_url( $primary->blog_id, 'profile.php' ); 170 171 // Ensure the user's primary blog is not the same as the main site. 172 $this->assertNotEquals( $primary_profile_url, admin_url( 'profile.php' ) ); 173 174 // Profile URLs should go to the user's primary blog. 175 $this->assertSame( $primary_profile_url, $node_my_account->href ); 176 $this->assertSame( $primary_profile_url, $node_user_info->href ); 177 178 restore_current_blog(); 136 179 } 137 180 … … 141 184 * @group ms-required 142 185 */ 143 public function test_admin_bar_contains_correct_links_for_users_with_no_role_on_blog() { 186 public function test_admin_bar_contains_correct_links_for_users_with_no_role_on_network() { 187 $this->assertTrue( user_can( self::$admin_id, 'read' ) ); 188 $this->assertFalse( user_can( self::$no_role_id, 'read' ) ); 189 144 190 $blog_id = self::factory()->blog->create( 145 191 array( … … 148 194 ); 149 195 150 $this->assertTrue( user_can( self::$admin_id, 'read' ) );151 $this->assertTrue( user_can( self::$editor_id, 'read' ) );152 153 196 $this->assertTrue( is_user_member_of_blog( self::$admin_id, $blog_id ) ); 154 $this->assertFalse( is_user_member_of_blog( self::$editor_id, $blog_id ) ); 155 156 wp_set_current_user( self::$editor_id ); 197 $this->assertFalse( is_user_member_of_blog( self::$no_role_id, $blog_id ) ); 198 $this->assertTrue( is_user_member_of_blog( self::$no_role_id, get_current_blog_id() ) ); 199 200 // Remove `$nobody` from the current blog, so they're not a member of any blog. 201 $removed = remove_user_from_blog( self::$no_role_id, get_current_blog_id() ); 202 203 $this->assertTrue( $removed ); 204 $this->assertFalse( is_user_member_of_blog( self::$no_role_id, get_current_blog_id() ) ); 205 206 wp_set_current_user( self::$no_role_id ); 157 207 158 208 switch_to_blog( $blog_id ); … … 163 213 $node_my_account = $wp_admin_bar->get_node( 'my-account' ); 164 214 $node_user_info = $wp_admin_bar->get_node( 'user-info' ); 165 $node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' );166 167 // Get primary blog.168 $primary = get_active_blog_for_user( self::$editor_id );169 $this->assertIsObject( $primary );170 171 // No Site menu as the user isn't a member of this blog.172 $this->assertNull( $node_site_name );173 174 $primary_profile_url = get_admin_url( $primary->blog_id, 'profile.php' );175 176 // Ensure the user's primary blog is not the same as the main site.177 $this->assertNotEquals( $primary_profile_url, admin_url( 'profile.php' ) );178 179 // Profile URLs should go to the user's primary blog.180 $this->assertSame( $primary_profile_url, $node_my_account->href );181 $this->assertSame( $primary_profile_url, $node_user_info->href );182 $this->assertSame( $primary_profile_url, $node_edit_profile->href );183 184 restore_current_blog();185 }186 187 /**188 * @ticket 25162189 * @group multisite190 * @group ms-required191 */192 public function test_admin_bar_contains_correct_links_for_users_with_no_role_on_network() {193 $this->assertTrue( user_can( self::$admin_id, 'read' ) );194 $this->assertFalse( user_can( self::$no_role_id, 'read' ) );195 196 $blog_id = self::factory()->blog->create(197 array(198 'user_id' => self::$admin_id,199 )200 );201 202 $this->assertTrue( is_user_member_of_blog( self::$admin_id, $blog_id ) );203 $this->assertFalse( is_user_member_of_blog( self::$no_role_id, $blog_id ) );204 $this->assertTrue( is_user_member_of_blog( self::$no_role_id, get_current_blog_id() ) );205 206 // Remove `$nobody` from the current blog, so they're not a member of any blog.207 $removed = remove_user_from_blog( self::$no_role_id, get_current_blog_id() );208 209 $this->assertTrue( $removed );210 $this->assertFalse( is_user_member_of_blog( self::$no_role_id, get_current_blog_id() ) );211 212 wp_set_current_user( self::$no_role_id );213 214 switch_to_blog( $blog_id );215 216 $wp_admin_bar = $this->get_standard_admin_bar();217 218 $node_site_name = $wp_admin_bar->get_node( 'site-name' );219 $node_my_account = $wp_admin_bar->get_node( 'my-account' );220 $node_user_info = $wp_admin_bar->get_node( 'user-info' );221 $node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' );222 215 223 216 // Get primary blog. … … 235 228 $this->assertSame( $user_profile_url, $node_my_account->href ); 236 229 $this->assertSame( $user_profile_url, $node_user_info->href ); 237 $this->assertSame( $user_profile_url, $node_edit_profile->href );238 230 239 231 restore_current_blog(); … … 285 277 'id' => 'test-node', 286 278 ), 287 '<div class="ab-item ab-empty-item" >',279 '<div class="ab-item ab-empty-item" role="menuitem">', 288 280 ), 289 281 array( … … 293 285 'meta' => array( 'tabindex' => '' ), 294 286 ), 295 '<div class="ab-item ab-empty-item" >',287 '<div class="ab-item ab-empty-item" role="menuitem">', 296 288 ), 297 289 array( … … 301 293 'meta' => array( 'tabindex' => '1' ), 302 294 ), 303 '<div class="ab-item ab-empty-item" tabindex="1" >',295 '<div class="ab-item ab-empty-item" tabindex="1" role="menuitem">', 304 296 ), 305 297 array( … … 309 301 'meta' => array( 'tabindex' => '-1' ), 310 302 ), 311 '<div class="ab-item ab-empty-item" tabindex="-1" >',303 '<div class="ab-item ab-empty-item" tabindex="-1" role="menuitem">', 312 304 ), 313 305 array( … … 317 309 'meta' => array( 'tabindex' => '0' ), 318 310 ), 319 '<div class="ab-item ab-empty-item" tabindex="0" >',311 '<div class="ab-item ab-empty-item" tabindex="0" role="menuitem">', 320 312 ), 321 313 array( … … 325 317 'meta' => array( 'tabindex' => 0 ), 326 318 ), 327 '<div class="ab-item ab-empty-item" tabindex="0" >',319 '<div class="ab-item ab-empty-item" tabindex="0" role="menuitem">', 328 320 ), 329 321 array( … … 333 325 'meta' => array( 'tabindex' => 2 ), 334 326 ), 335 '<div class="ab-item ab-empty-item" tabindex="2" >',327 '<div class="ab-item ab-empty-item" tabindex="2" role="menuitem">', 336 328 ), 337 329 array( … … 341 333 'meta' => array( 'tabindex' => false ), 342 334 ), 343 '<div class="ab-item ab-empty-item" >',335 '<div class="ab-item ab-empty-item" role="menuitem">', 344 336 ), 345 337 );
Note: See TracChangeset
for help on using the changeset viewer.