Customize: Constrain focus when overlay notification is displayed.

* Restore previously-focused element when overlay notifications are dismissed.
* Allow notifications to be dismissed via keyboard.

Amends [41667].
See #42110, #35210, #39896.

Built from https://develop.svn.wordpress.org/trunk@41803


git-svn-id: http://core.svn.wordpress.org/trunk@41637 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Weston Ruter 2017-10-10 03:34:53 +00:00
parent f462387431
commit ef1c95ff91
5 changed files with 56 additions and 13 deletions

View File

@ -78,6 +78,8 @@
api.Values.prototype.initialize.call( collection, options );
_.bindAll( collection, 'constrainFocus' );
// Keep track of the order in which the notifications were added for sorting purposes.
collection._addedIncrement = 0;
collection._addedOrder = {};
@ -188,9 +190,9 @@
*/
render: function() {
var collection = this,
notifications, hadOverlayNotification = false, hasOverlayNotification,
notifications, hadOverlayNotification = false, hasOverlayNotification, overlayNotifications = [],
previousNotificationsByCode = {},
listElement;
listElement, focusableElements;
// Short-circuit if there are no container to render into.
if ( ! collection.container || ! collection.container.length ) {
@ -226,14 +228,15 @@
wp.a11y.speak( notification.message, 'assertive' );
}
notificationContainer = $( notification.render() );
notification.container = notificationContainer;
listElement.append( notificationContainer ); // @todo Consider slideDown() as enhancement.
// @todo Constraing focus in notificationContainer if notification.extended( api.OverlayNotification ).
if ( notification.extended( api.OverlayNotification ) ) {
overlayNotifications.push( notification );
}
});
hasOverlayNotification = Boolean( overlayNotifications.length );
hasOverlayNotification = Boolean( _.find( notifications, function( notification ) {
return notification.extended( api.OverlayNotification );
} ) );
if ( collection.previousNotifications ) {
hadOverlayNotification = Boolean( _.find( collection.previousNotifications, function( notification ) {
return notification.extended( api.OverlayNotification );
@ -243,11 +246,47 @@
if ( hasOverlayNotification !== hadOverlayNotification ) {
$( document.body ).toggleClass( 'customize-loading', hasOverlayNotification );
collection.container.toggleClass( 'has-overlay-notifications', hasOverlayNotification );
if ( hasOverlayNotification ) {
collection.previousActiveElement = document.activeElement;
$( document ).on( 'keydown', collection.constrainFocus );
} else {
$( document ).off( 'keydown', collection.constrainFocus );
}
}
if ( hasOverlayNotification ) {
collection.focusContainer = overlayNotifications[ overlayNotifications.length - 1 ].container;
collection.focusContainer.prop( 'tabIndex', -1 );
focusableElements = collection.focusContainer.find( ':focusable' );
if ( focusableElements.length ) {
focusableElements.first().focus();
} else {
collection.focusContainer.focus();
}
} else if ( collection.previousActiveElement ) {
$( collection.previousActiveElement ).focus();
collection.previousActiveElement = null;
}
collection.previousNotifications = notifications;
collection.previousContainer = collection.container;
collection.trigger( 'rendered' );
},
/**
* Constrain focus on focus container.
*
* @since 4.9.0
*
* @param {jQuery.Event} event - Event.
* @returns {void}
*/
constrainFocus: function constrainFocus( event ) {
var collection = this;
if ( ! collection.focusContainer || collection.focusContainer.is( event.target ) || $.contains( collection.focusContainer[0], event.target[0] ) ) {
return;
}
collection.focusContainer.focus();
}
});

File diff suppressed because one or more lines are too long

View File

@ -885,7 +885,11 @@ window.wp = window.wp || {};
container = $( notification.template( data ) );
if ( notification.dismissible ) {
container.find( '.notice-dismiss' ).on( 'click', function() {
container.find( '.notice-dismiss' ).on( 'click keydown', function( event ) {
if ( 'keydown' === event.type && 13 !== event.which ) {
return;
}
if ( notification.parent ) {
notification.parent.remove( notification.code );
} else {

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.9-beta1-41802';
$wp_version = '4.9-beta1-41803';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.