mirror of
https://github.com/WordPress/WordPress.git
synced 2025-03-02 11:21:57 +01:00
Accessibility: Widgets: Make the "Available Widgets" section operable with a keyboard.
For a number of years, the "Available Widgets" section has been off-limits for keyboard users. Now it can be used also with the keyboard. This change introduces also some improvements for assistive technologies. - makes the widget toggles focusable and adds an `aria-expanded` attribute to indicate their state - improves the toggles labelling to clarify context (add/edit) - changes the controls to choose a sidebar from list items to buttons - adds an `aria-label` attribute to the buttons to clarify their purpose - adds an `aria-pressed` attribute to the buttons to indicate which one is selected - improves color contrast of the selected button - uses a `wp.a11y.speak()` message to announce to screen reader users when a widget has been added to a sidebar - moves focus back to the toggle button when closing a widget See #40677. Built from https://develop.svn.wordpress.org/trunk@42794 git-svn-id: http://core.svn.wordpress.org/trunk@42624 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
e34999f4aa
commit
ffedf3d752
@ -3368,7 +3368,8 @@ img {
|
||||
.control-section.open .accordion-section-title:after,
|
||||
#customize-info.open .accordion-section-title:after,
|
||||
.nav-menus-php .menu-item-edit-active .item-edit:before,
|
||||
.widget.open .widget-top .widget-action .toggle-indicator:before {
|
||||
.widget.open .widget-top .widget-action .toggle-indicator:before,
|
||||
.widget.widget-in-question .widget-top .widget-action .toggle-indicator:before {
|
||||
content: "\f142";
|
||||
}
|
||||
|
||||
|
2
wp-admin/css/common-rtl.min.css
vendored
2
wp-admin/css/common-rtl.min.css
vendored
File diff suppressed because one or more lines are too long
@ -3368,7 +3368,8 @@ img {
|
||||
.control-section.open .accordion-section-title:after,
|
||||
#customize-info.open .accordion-section-title:after,
|
||||
.nav-menus-php .menu-item-edit-active .item-edit:before,
|
||||
.widget.open .widget-top .widget-action .toggle-indicator:before {
|
||||
.widget.open .widget-top .widget-action .toggle-indicator:before,
|
||||
.widget.widget-in-question .widget-top .widget-action .toggle-indicator:before {
|
||||
content: "\f142";
|
||||
}
|
||||
|
||||
|
2
wp-admin/css/common.min.css
vendored
2
wp-admin/css/common.min.css
vendored
File diff suppressed because one or more lines are too long
@ -381,10 +381,6 @@ div#widgets-left .widget-holder {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#available-widgets .widget-action {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#available-widgets .widget {
|
||||
margin: 0;
|
||||
}
|
||||
@ -516,8 +512,11 @@ div#widgets-right .closed .widgets-sortables {
|
||||
}
|
||||
|
||||
#available-widgets .widget-control-edit .edit,
|
||||
#available-widgets .widget-action .edit,
|
||||
#widgets-left .inactive-sidebar .widget-control-edit .add,
|
||||
#widgets-right .widget-control-edit .add {
|
||||
#widgets-left .inactive-sidebar .widget-action .add,
|
||||
#widgets-right .widget-control-edit .add,
|
||||
#widgets-right .widget-action .add {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -664,44 +663,40 @@ div#widgets-right .widget-top:hover,
|
||||
}
|
||||
|
||||
.widgets-chooser li {
|
||||
padding: 10px 35px 10px 15px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fff;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.widgets-chooser .widgets-chooser-button {
|
||||
width: 100%;
|
||||
padding: 10px 35px 10px 15px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
box-sizing: border-box;
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
/* @todo looks like these hover/focus states are overridden by .widgets-chooser-selected */
|
||||
.widgets-chooser li:hover,
|
||||
.widgets-chooser li:focus {
|
||||
background: rgba(255,255,255,0.7);
|
||||
}
|
||||
|
||||
.widgets-chooser li:focus:before {
|
||||
content: "\f147";
|
||||
display: block;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font: normal 26px/1 dashicons;
|
||||
color: #555d66;
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 5px;
|
||||
/* @todo looks like these hover/focus states are overridden by .widgets-chooser-selected */
|
||||
.widgets-chooser .widgets-chooser-button:hover,
|
||||
.widgets-chooser .widgets-chooser-button:focus {
|
||||
outline: none;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.widgets-chooser li:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.widgets-chooser li.widgets-chooser-selected {
|
||||
background: #00a0d2;
|
||||
.widgets-chooser .widgets-chooser-selected .widgets-chooser-button {
|
||||
background: #0073aa;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.widgets-chooser li.widgets-chooser-selected:before,
|
||||
.widgets-chooser li.widgets-chooser-selected:focus:before {
|
||||
.widgets-chooser .widgets-chooser-selected:before {
|
||||
content: "\f147";
|
||||
display: block;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
@ -717,10 +712,6 @@ div#widgets-right .widget-top:hover,
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.widgets-chooser button {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
#available-widgets .widget .widget-top {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
2
wp-admin/css/widgets-rtl.min.css
vendored
2
wp-admin/css/widgets-rtl.min.css
vendored
File diff suppressed because one or more lines are too long
@ -381,10 +381,6 @@ div#widgets-left .widget-holder {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#available-widgets .widget-action {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#available-widgets .widget {
|
||||
margin: 0;
|
||||
}
|
||||
@ -516,8 +512,11 @@ div#widgets-right .closed .widgets-sortables {
|
||||
}
|
||||
|
||||
#available-widgets .widget-control-edit .edit,
|
||||
#available-widgets .widget-action .edit,
|
||||
#widgets-left .inactive-sidebar .widget-control-edit .add,
|
||||
#widgets-right .widget-control-edit .add {
|
||||
#widgets-left .inactive-sidebar .widget-action .add,
|
||||
#widgets-right .widget-control-edit .add,
|
||||
#widgets-right .widget-action .add {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -664,44 +663,40 @@ div#widgets-right .widget-top:hover,
|
||||
}
|
||||
|
||||
.widgets-chooser li {
|
||||
padding: 10px 15px 10px 35px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fff;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.widgets-chooser .widgets-chooser-button {
|
||||
width: 100%;
|
||||
padding: 10px 15px 10px 35px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
box-sizing: border-box;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
/* @todo looks like these hover/focus states are overridden by .widgets-chooser-selected */
|
||||
.widgets-chooser li:hover,
|
||||
.widgets-chooser li:focus {
|
||||
background: rgba(255,255,255,0.7);
|
||||
}
|
||||
|
||||
.widgets-chooser li:focus:before {
|
||||
content: "\f147";
|
||||
display: block;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font: normal 26px/1 dashicons;
|
||||
color: #555d66;
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: 5px;
|
||||
/* @todo looks like these hover/focus states are overridden by .widgets-chooser-selected */
|
||||
.widgets-chooser .widgets-chooser-button:hover,
|
||||
.widgets-chooser .widgets-chooser-button:focus {
|
||||
outline: none;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.widgets-chooser li:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.widgets-chooser li.widgets-chooser-selected {
|
||||
background: #00a0d2;
|
||||
.widgets-chooser .widgets-chooser-selected .widgets-chooser-button {
|
||||
background: #0073aa;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.widgets-chooser li.widgets-chooser-selected:before,
|
||||
.widgets-chooser li.widgets-chooser-selected:focus:before {
|
||||
.widgets-chooser .widgets-chooser-selected:before {
|
||||
content: "\f147";
|
||||
display: block;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
@ -717,10 +712,6 @@ div#widgets-right .widget-top:hover,
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.widgets-chooser button {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#available-widgets .widget .widget-top {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
2
wp-admin/css/widgets.min.css
vendored
2
wp-admin/css/widgets.min.css
vendored
File diff suppressed because one or more lines are too long
@ -90,8 +90,13 @@ function wp_list_widget_controls( $sidebar, $sidebar_name = '' ) {
|
||||
echo '<div id="' . esc_attr( $sidebar ) . '" class="widgets-sortables">';
|
||||
|
||||
if ( $sidebar_name ) {
|
||||
$add_to = sprintf(
|
||||
/* translators: %s: widgets sidebar name. */
|
||||
__( 'Add to: %s' ),
|
||||
$sidebar_name
|
||||
);
|
||||
?>
|
||||
<div class="sidebar-name">
|
||||
<div class="sidebar-name" data-add-to="<?php echo esc_attr( $add_to ); ?>">
|
||||
<button type="button" class="handlediv hide-if-no-js" aria-expanded="true">
|
||||
<span class="screen-reader-text"><?php echo esc_html( $sidebar_name ); ?></span>
|
||||
<span class="toggle-indicator" aria-hidden="true"></span>
|
||||
@ -239,7 +244,8 @@ function wp_widget_control( $sidebar_args ) {
|
||||
<div class="widget-top">
|
||||
<div class="widget-title-action">
|
||||
<button type="button" class="widget-action hide-if-no-js" aria-expanded="false">
|
||||
<span class="screen-reader-text"><?php printf( __( 'Edit widget: %s' ), $widget_title ); ?></span>
|
||||
<span class="screen-reader-text edit"><?php printf( __( 'Edit widget: %s' ), $widget_title ); ?></span>
|
||||
<span class="screen-reader-text add"><?php printf( __( 'Add widget: %s' ), $widget_title ); ?></span>
|
||||
<span class="toggle-indicator" aria-hidden="true"></span>
|
||||
</button>
|
||||
<a class="widget-control-edit hide-if-js" href="<?php echo esc_url( add_query_arg( $query_arg ) ); ?>">
|
||||
|
@ -21,7 +21,8 @@ wpWidgets = {
|
||||
l10n: {
|
||||
save: '{save}',
|
||||
saved: '{saved}',
|
||||
saveAlert: '{saveAlert}'
|
||||
saveAlert: '{saveAlert}',
|
||||
widgetAdded: '{widgetAdded}'
|
||||
},
|
||||
|
||||
/**
|
||||
@ -176,19 +177,16 @@ wpWidgets = {
|
||||
widget.removeClass( 'open' );
|
||||
});
|
||||
}
|
||||
e.preventDefault();
|
||||
} else if ( target.hasClass('widget-control-save') ) {
|
||||
wpWidgets.save( target.closest('div.widget'), 0, 1, 0 );
|
||||
e.preventDefault();
|
||||
} else if ( target.hasClass('widget-control-remove') ) {
|
||||
wpWidgets.save( target.closest('div.widget'), 1, 1, 0 );
|
||||
e.preventDefault();
|
||||
} else if ( target.hasClass('widget-control-close') ) {
|
||||
widget = target.closest('div.widget');
|
||||
widget.removeClass( 'open' );
|
||||
toggleBtn.attr( 'aria-expanded', 'false' );
|
||||
wpWidgets.close( widget );
|
||||
e.preventDefault();
|
||||
} else if ( target.attr( 'id' ) === 'inactive-widgets-control-remove' ) {
|
||||
wpWidgets.removeInactiveWidgets();
|
||||
e.preventDefault();
|
||||
@ -433,35 +431,53 @@ wpWidgets = {
|
||||
$( '#widgets-right .widgets-holder-wrap' ).each( function( index, element ) {
|
||||
var $element = $( element ),
|
||||
name = $element.find( '.sidebar-name h2' ).text(),
|
||||
ariaLabel = $element.find( '.sidebar-name' ).data( 'add-to' ),
|
||||
id = $element.find( '.widgets-sortables' ).attr( 'id' ),
|
||||
li = $('<li tabindex="0">').text( $.trim( name ) );
|
||||
li = $( '<li>' ),
|
||||
button = $( '<button>', {
|
||||
type: 'button',
|
||||
'aria-pressed': 'false',
|
||||
'class': 'widgets-chooser-button',
|
||||
'aria-label': ariaLabel
|
||||
} ).text( $.trim( name ) );
|
||||
|
||||
li.append( button );
|
||||
|
||||
if ( index === 0 ) {
|
||||
li.addClass( 'widgets-chooser-selected' );
|
||||
button.attr( 'aria-pressed', 'true' );
|
||||
}
|
||||
|
||||
selectSidebar.append( li );
|
||||
li.data( 'sidebarId', id );
|
||||
});
|
||||
|
||||
$( '#available-widgets .widget .widget-title' ).on( 'click.widgets-chooser', function() {
|
||||
var $widget = $(this).closest( '.widget' );
|
||||
$( '#available-widgets .widget .widget-top' ).on( 'click.widgets-chooser', function() {
|
||||
var $widget = $( this ).closest( '.widget' ),
|
||||
toggleButton = $( this ).find( '.widget-action' ),
|
||||
chooserButtons = selectSidebar.find( '.widgets-chooser-button' );
|
||||
|
||||
if ( $widget.hasClass( 'widget-in-question' ) || $( '#widgets-left' ).hasClass( 'chooser' ) ) {
|
||||
toggleButton.attr( 'aria-expanded', 'false' );
|
||||
self.closeChooser();
|
||||
} else {
|
||||
// Open the chooser
|
||||
self.clearWidgetSelection();
|
||||
$( '#widgets-left' ).addClass( 'chooser' );
|
||||
// Add CSS class and insert the chooser after the widget description.
|
||||
$widget.addClass( 'widget-in-question' ).children( '.widget-description' ).after( chooser );
|
||||
|
||||
// Open the chooser with a slide down animation.
|
||||
chooser.slideDown( 300, function() {
|
||||
selectSidebar.find('.widgets-chooser-selected').focus();
|
||||
// Update the toggle button aria-expanded attribute after previous DOM manipulations.
|
||||
toggleButton.attr( 'aria-expanded', 'true' );
|
||||
});
|
||||
|
||||
selectSidebar.find( 'li' ).on( 'focusin.widgets-chooser', function() {
|
||||
selectSidebar.find('.widgets-chooser-selected').removeClass( 'widgets-chooser-selected' );
|
||||
$(this).addClass( 'widgets-chooser-selected' );
|
||||
chooserButtons.on( 'click.widgets-chooser', function() {
|
||||
selectSidebar.find( '.widgets-chooser-selected' ).removeClass( 'widgets-chooser-selected' );
|
||||
chooserButtons.attr( 'aria-pressed', 'false' );
|
||||
$( this )
|
||||
.attr( 'aria-pressed', 'true' )
|
||||
.closest( 'li' ).addClass( 'widgets-chooser-selected' );
|
||||
} );
|
||||
}
|
||||
});
|
||||
@ -477,15 +493,7 @@ wpWidgets = {
|
||||
self.closeChooser();
|
||||
}
|
||||
}).on( 'keyup.widgets-chooser', function( event ) {
|
||||
if ( event.which === $.ui.keyCode.ENTER ) {
|
||||
if ( $( event.target ).hasClass( 'widgets-chooser-cancel' ) ) {
|
||||
// Close instead of adding when pressing Enter on the Cancel button
|
||||
self.closeChooser();
|
||||
} else {
|
||||
self.addWidget( chooser );
|
||||
self.closeChooser();
|
||||
}
|
||||
} else if ( event.which === $.ui.keyCode.ESCAPE ) {
|
||||
if ( event.which === $.ui.keyCode.ESCAPE ) {
|
||||
self.closeChooser();
|
||||
}
|
||||
});
|
||||
@ -705,15 +713,20 @@ wpWidgets = {
|
||||
// Cannot use a callback in the animation above as it fires twice,
|
||||
// have to queue this "by hand".
|
||||
widget.find( '.widget-title' ).trigger('click');
|
||||
// At the end of the animation, announce the widget has been added.
|
||||
window.wp.a11y.speak( wpWidgets.l10n.widgetAdded, 'assertive' );
|
||||
}, 250 );
|
||||
},
|
||||
|
||||
closeChooser: function() {
|
||||
var self = this;
|
||||
var self = this,
|
||||
widgetInQuestion = $( '#available-widgets .widget-in-question' );
|
||||
|
||||
$( '.widgets-chooser' ).slideUp( 200, function() {
|
||||
$( '#wpbody-content' ).append( this );
|
||||
self.clearWidgetSelection();
|
||||
// Move focus back to the toggle button.
|
||||
widgetInQuestion.find( '.widget-action' ).attr( 'aria-expanded', 'false' ).focus();
|
||||
});
|
||||
},
|
||||
|
||||
|
2
wp-admin/js/widgets.min.js
vendored
2
wp-admin/js/widgets.min.js
vendored
File diff suppressed because one or more lines are too long
@ -786,14 +786,15 @@ function wp_default_scripts( &$scripts ) {
|
||||
|
||||
$scripts->add( 'admin-gallery', "/wp-admin/js/gallery$suffix.js", array( 'jquery-ui-sortable' ) );
|
||||
|
||||
$scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), false, 1 );
|
||||
$scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'wp-a11y' ), false, 1 );
|
||||
did_action( 'init' ) && $scripts->add_inline_script(
|
||||
'admin-widgets', sprintf(
|
||||
'wpWidgets.l10n = %s;', wp_json_encode(
|
||||
array(
|
||||
'save' => __( 'Save' ),
|
||||
'saved' => __( 'Saved' ),
|
||||
'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.' ),
|
||||
'save' => __( 'Save' ),
|
||||
'saved' => __( 'Saved' ),
|
||||
'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.' ),
|
||||
'widgetAdded' => __( 'Widget has been added to the selected sidebar' ),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '5.0-alpha-42793';
|
||||
$wp_version = '5.0-alpha-42794';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
Loading…
Reference in New Issue
Block a user