diff --git a/src/wp-admin/css/nav-menus.css b/src/wp-admin/css/nav-menus.css index 2b2ad55a86..d58d566ee7 100644 --- a/src/wp-admin/css/nav-menus.css +++ b/src/wp-admin/css/nav-menus.css @@ -61,10 +61,6 @@ ul.add-menu-item-tabs li { position: relative; } -.blank-slate .menu-name { - height: 2em; -} - .blank-slate .menu-settings { border: none; margin-top: 0; @@ -179,7 +175,10 @@ ul.add-menu-item-tabs li { } #nav-menu-header .menu-name-label { - margin-top: 4px; + display: inline-block; + vertical-align: middle; + margin-right: 7px; + font-style: italic; } .nav-menus-php #post-body div.updated, @@ -248,27 +247,13 @@ ul.add-menu-item-tabs li { border-right: 1px solid #ccc; } -#wpbody .open-label { - display: block; - float:left; -} - -#wpbody .open-label span { - padding-right: 10px; -} - -.js .input-with-default-title { - color: #a0a5aa; - font-style: italic; -} - #menu-management .inside { padding: 0 10px; } /* Add Menu Item Boxes */ .postbox .howto input, -.accordion-container .howto input { +.customlinkdiv .menu-item-textbox { width: 180px; float: right; } @@ -277,10 +262,6 @@ ul.add-menu-item-tabs li { margin: 0; } -.customlinkdiv .howto input { - width: 180px; -} - .customlinkdiv p { margin-top: 0 } @@ -355,6 +336,7 @@ ul.add-menu-item-tabs li { /* Create Menu */ #menu-name { width: 270px; + vertical-align: middle; } #manage-menu .inside { @@ -381,10 +363,10 @@ ul.add-menu-item-tabs li { width: 180px; } +.customlinkdiv label, .nav-menus-php .howto span { - margin-top: 6px; - display: block; float: left; + margin-top: 6px; } /* Menu item types */ @@ -731,14 +713,12 @@ body.menu-max-depth-11 { min-width: 1280px !important; } /* Major/minor publishing actions (classes) */ .nav-menus-php .major-publishing-actions { clear: both; - padding: 3px 0 6px; + padding: 7px 0 6px; } .nav-menus-php .major-publishing-actions .publishing-action { text-align: right; float: right; - line-height: 23px; - margin: 4px 0 1px; } .nav-menus-php .blank-slate .menu-settings { diff --git a/src/wp-admin/includes/nav-menu.php b/src/wp-admin/includes/nav-menu.php index f66c079b7b..cb94fe2dc7 100644 --- a/src/wp-admin/includes/nav-menu.php +++ b/src/wp-admin/includes/nav-menu.php @@ -264,17 +264,13 @@ function wp_nav_menu_item_link_meta_box() {
- + + 'submit-quick-search-posttype-' . $post_type_name ) ); ?>
@@ -714,7 +711,8 @@ function wp_nav_menu_item_taxonomy_meta_box( $object, $taxonomy ) { } ?>- + + 'submit-quick-search-taxonomy-' . $taxonomy_name ) ); ?>
diff --git a/src/wp-admin/js/common.js b/src/wp-admin/js/common.js index 9fa67e5b65..9cd1fff910 100644 --- a/src/wp-admin/js/common.js +++ b/src/wp-admin/js/common.js @@ -913,6 +913,9 @@ $document.ready( function() { aria_button_if_js(); $document.on( 'wp-pin-menu wp-window-resized.pin-menu postboxes-columnchange.pin-menu postbox-toggled.pin-menu wp-collapse-menu.pin-menu wp-scroll-start.pin-menu', setPinMenu ); + + // Set initial focus on a specific element. + $( '.wp-initial-focus' ).focus(); }); // Fire a custom jQuery event at the end of window resize diff --git a/src/wp-admin/js/nav-menu.js b/src/wp-admin/js/nav-menu.js index c23fc69683..569c27a977 100644 --- a/src/wp-admin/js/nav-menu.js +++ b/src/wp-admin/js/nav-menu.js @@ -30,6 +30,7 @@ var wpNavMenu; menusChanged : false, isRTL: !! ( 'undefined' != typeof isRtl && isRtl ), negateIfRTL: ( 'undefined' != typeof isRtl && isRtl ) ? -1 : 1, + lastSearch: '', // Functions that run on init. init : function() { @@ -40,7 +41,6 @@ var wpNavMenu; this.attachMenuEditListeners(); - this.setupInputWithDefaultTitle(); this.attachQuickSearchListeners(); this.attachThemeLocationsListeners(); @@ -444,35 +444,35 @@ var wpNavMenu; // Where can they move this menu item? if ( 0 !== position ) { thisLink = menuItem.find( '.menus-move-up' ); - thisLink.prop( 'title', menus.moveUp ).css( 'display', 'inline' ); + thisLink.attr( 'aria-label', menus.moveUp ).css( 'display', 'inline' ); } if ( 0 !== position && isPrimaryMenuItem ) { thisLink = menuItem.find( '.menus-move-top' ); - thisLink.prop( 'title', menus.moveToTop ).css( 'display', 'inline' ); + thisLink.attr( 'aria-label', menus.moveToTop ).css( 'display', 'inline' ); } if ( position + 1 !== totalMenuItems && 0 !== position ) { thisLink = menuItem.find( '.menus-move-down' ); - thisLink.prop( 'title', menus.moveDown ).css( 'display', 'inline' ); + thisLink.attr( 'aria-label', menus.moveDown ).css( 'display', 'inline' ); } if ( 0 === position && 0 !== hasSameDepthSibling ) { thisLink = menuItem.find( '.menus-move-down' ); - thisLink.prop( 'title', menus.moveDown ).css( 'display', 'inline' ); + thisLink.attr( 'aria-label', menus.moveDown ).css( 'display', 'inline' ); } if ( ! isPrimaryMenuItem ) { thisLink = menuItem.find( '.menus-move-left' ), thisLinkText = menus.outFrom.replace( '%s', prevItemNameLeft ); - thisLink.prop( 'title', menus.moveOutFrom.replace( '%s', prevItemNameLeft ) ).text( thisLinkText ).css( 'display', 'inline' ); + thisLink.attr( 'aria-label', menus.moveOutFrom.replace( '%s', prevItemNameLeft ) ).text( thisLinkText ).css( 'display', 'inline' ); } if ( 0 !== position ) { if ( menuItem.find( '.menu-item-data-parent-id' ).val() !== menuItem.prev().find( '.menu-item-data-db-id' ).val() ) { thisLink = menuItem.find( '.menus-move-right' ), thisLinkText = menus.under.replace( '%s', prevItemNameRight ); - thisLink.prop( 'title', menus.moveUnder.replace( '%s', prevItemNameRight ) ).text( thisLinkText ).css( 'display', 'inline' ); + thisLink.attr( 'aria-label', menus.moveUnder.replace( '%s', prevItemNameRight ) ).text( thisLinkText ).css( 'display', 'inline' ); } } @@ -494,7 +494,8 @@ var wpNavMenu; title = menus.subMenuFocus.replace( '%1$s', itemName ).replace( '%2$d', itemPosition ).replace( '%3$s', parentItemName ); } - $this.prop('title', title).text( title ); + // @todo Consider to update just the `aria-label` attribute. + $this.attr( 'aria-label', title ).text( title ); // Mark this item's accessibility as refreshed $this.data( 'needs_accessibility_refresh', false ); @@ -833,36 +834,6 @@ var wpNavMenu; }); }, - /** - * An interface for managing default values for input elements - * that is both JS and accessibility-friendly. - * - * Input elements that add the class 'input-with-default-title' - * will have their values set to the provided HTML title when empty. - */ - setupInputWithDefaultTitle : function() { - var name = 'input-with-default-title'; - - $('.' + name).each( function(){ - var $t = $(this), title = $t.attr('title'), val = $t.val(); - $t.data( name, title ); - - if( '' === val ) $t.val( title ); - else if ( title == val ) return; - else $t.removeClass( name ); - }).focus( function(){ - var $t = $(this); - if( $t.val() == $t.data(name) ) - $t.val('').removeClass( name ); - }).blur( function(){ - var $t = $(this); - if( '' === $t.val() ) - $t.addClass( name ).val( $t.data(name) ); - }); - - $( '.blank-slate .input-with-default-title' ).focus(); - }, - attachThemeLocationsListeners : function() { var loc = $('#nav-menu-theme-locations'), params = {}; params.action = 'menu-locations-save'; @@ -880,9 +851,21 @@ var wpNavMenu; }, attachQuickSearchListeners : function() { - var searchTimer; + var searchTimer, + inputEvent; - $('.quick-search').keypress(function(e){ + /* + * Use feature detection to determine whether password inputs should use + * the `keyup` or `input` event. Input is preferred but lacks support + * in legacy browsers. See changeset 34078, see also ticket #26600#comment:59 + */ + if ( 'oninput' in document.createElement( 'input' ) ) { + inputEvent = 'input'; + } else { + inputEvent = 'keyup'; + } + + $( '.quick-search' ).on( inputEvent, function( e ) { var t = $(this); if( 13 == e.which ) { @@ -894,16 +877,26 @@ var wpNavMenu; searchTimer = setTimeout(function(){ api.updateQuickSearchResults( t ); - }, 400); + }, 500 ); + }).on( 'blur', function() { + api.lastSearch = ''; }).attr('autocomplete','off'); }, updateQuickSearchResults : function(input) { var panel, params, - minSearchLength = 2, - q = input.val(); + minSearchLength = 2, + q = input.val(); - if( q.length < minSearchLength ) return; + /* + * Minimum characters for a search. Also avoid a new AJAX search when + * the pressed key (e.g. arrows) doesn't change the searched term. + */ + if ( q.length < minSearchLength || api.lastSearch == q ) { + return; + } + + api.lastSearch = q; panel = input.parents('.tabs-panel'); params = { diff --git a/src/wp-admin/nav-menus.php b/src/wp-admin/nav-menus.php index 132bc9b3b6..89aa6d8edb 100644 --- a/src/wp-admin/nav-menus.php +++ b/src/wp-admin/nav-menus.php @@ -736,17 +736,21 @@ require_once( ABSPATH . 'wp-admin/admin-header.php' ); wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' ); - if ( $one_theme_location_no_menus ) { ?> + $menu_name_aria_desc = $add_new_screen ? ' aria-describedby="menu-name-desc"' : ''; + + if ( $one_theme_location_no_menus ) { + $menu_name_val = 'value="' . esc_attr( 'Menu 1' ) . '"'; + ?> - +