Keyboard navigation friendliness for themes.php.
props matveb, azaozz, jorbin. see #26527. git-svn-id: https://develop.svn.wordpress.org/trunk@26922 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
5447a6ab72
commit
972b6ef466
@ -6465,6 +6465,24 @@ span.imgedit-scale-warn {
|
||||
-webkit-transition: opacity 0.1s ease-in-out;
|
||||
transition: opacity 0.1s ease-in-out;
|
||||
}
|
||||
.theme-browser .theme:focus {
|
||||
outline: 1px dotted #222;
|
||||
}
|
||||
/* Hide shortcut actions and hover feedback when using tab navigation */
|
||||
.theme-browser .theme:focus .theme-actions {
|
||||
display: none;
|
||||
}
|
||||
/* Restore display of theme controls if you hover a focused theme */
|
||||
.theme-browser .theme:focus:hover .theme-actions {
|
||||
display: block;
|
||||
}
|
||||
.theme-browser .theme:focus .more-details {
|
||||
opacity: 1;
|
||||
}
|
||||
/* Current theme needs to have its action always on view */
|
||||
.theme-browser .theme.active:focus .theme-actions {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.theme-browser.rendered .theme:hover .more-details {
|
||||
opacity: 1;
|
||||
@ -6690,10 +6708,13 @@ body.theme-overlay-open {
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
float: right;
|
||||
border: 0;
|
||||
border-left: 1px solid #ddd;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.theme-overlay .theme-header .close:hover:before {
|
||||
.theme-overlay .theme-header .close:hover:before,
|
||||
.theme-overlay .theme-header .close:focus:before {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@ -6710,20 +6731,21 @@ body.theme-overlay-open {
|
||||
.theme-overlay .theme-header .left {
|
||||
cursor: pointer;
|
||||
color: #777;
|
||||
background-color: transparent;
|
||||
height: 48px;
|
||||
width: 54px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
border-right: 1px solid #ddd;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.theme-overlay .theme-header .close:hover,
|
||||
.theme-overlay .theme-header .right:hover,
|
||||
.theme-overlay .theme-header .left:hover {
|
||||
.theme-overlay .theme-header .left:hover,
|
||||
.theme-overlay .theme-header .close:focus,
|
||||
.theme-overlay .theme-header .right:focus,
|
||||
.theme-overlay .theme-header .left:focus {
|
||||
background: #0074a2;
|
||||
color: #fff;
|
||||
}
|
||||
@ -6832,7 +6854,8 @@ body.folded .theme-overlay .theme-wrap {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.theme-overlay .theme-actions .delete-theme:hover {
|
||||
.theme-overlay .theme-actions .delete-theme:hover,
|
||||
.theme-overlay .theme-actions .delete-theme:focus {
|
||||
background: #d54e21;
|
||||
color: #fff;
|
||||
border-color: #d54e21;
|
||||
|
@ -188,6 +188,7 @@ themes.view.Theme = wp.Backbone.View.extend({
|
||||
|
||||
events: {
|
||||
'click': 'expand',
|
||||
'keydown': 'expand',
|
||||
'touchend': 'expand',
|
||||
'touchmove': 'preventExpand'
|
||||
},
|
||||
@ -197,7 +198,8 @@ themes.view.Theme = wp.Backbone.View.extend({
|
||||
render: function() {
|
||||
var data = this.model.toJSON();
|
||||
// Render themes using the html template
|
||||
this.$el.html( this.html( data ) );
|
||||
this.$el.html( this.html( data ) ).attr( 'tabindex', 0 );
|
||||
|
||||
// Renders active theme styles
|
||||
this.activeTheme();
|
||||
|
||||
@ -219,19 +221,27 @@ themes.view.Theme = wp.Backbone.View.extend({
|
||||
expand: function( event ) {
|
||||
var self = this;
|
||||
|
||||
event = event || window.event;
|
||||
|
||||
// 'enter' and 'space' keys expand the details view when a theme is :focused
|
||||
if ( event.type === 'keydown' && ( event.which !== 13 && event.which !== 32 ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bail if the user scrolled on a touch device
|
||||
if ( this.touchDrag === true ) {
|
||||
return this.touchDrag = false;
|
||||
}
|
||||
|
||||
event = event || window.event;
|
||||
|
||||
// Prevent the modal from showing when the user clicks
|
||||
// one of the direct action buttons
|
||||
if ( $( event.target ).is( '.theme-actions a' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set focused theme to current element
|
||||
themes.focusedTheme = this.$el;
|
||||
|
||||
this.trigger( 'theme:expand', self.model.cid );
|
||||
},
|
||||
|
||||
@ -266,6 +276,8 @@ themes.view.Details = wp.Backbone.View.extend({
|
||||
this.navigation();
|
||||
// Checks screenshot size
|
||||
this.screenshotCheck( this.$el );
|
||||
// Contain "tabbing" inside the overlay
|
||||
this.containFocus( this.$el );
|
||||
},
|
||||
|
||||
// Adds a class to the currently active theme
|
||||
@ -275,6 +287,34 @@ themes.view.Details = wp.Backbone.View.extend({
|
||||
this.$el.toggleClass( 'active', this.model.get( 'active' ) );
|
||||
},
|
||||
|
||||
// Keeps :focus within the theme details elements
|
||||
containFocus: function( $el ) {
|
||||
var $target;
|
||||
|
||||
// Move focus to the primary action
|
||||
_.delay( function() {
|
||||
$( '.theme-wrap a.button-primary:visible' ).focus();
|
||||
}, 500 );
|
||||
|
||||
$el.on( 'keydown.wp-themes', function( event ) {
|
||||
|
||||
// Tab key
|
||||
if ( event.which === 9 ) {
|
||||
$target = $( event.target );
|
||||
|
||||
// Keep focus within the overlay by making the last link on theme actions
|
||||
// switch focus to button.left on tabbing and vice versa
|
||||
if ( $target.is( 'button.left' ) && event.shiftKey ) {
|
||||
$el.find( '.theme-actions a:last-child' ).focus();
|
||||
event.preventDefault();
|
||||
} else if ( $target.is( '.theme-actions a:last-child' ) ) {
|
||||
$el.find( 'button.left' ).focus();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Single theme overlay screen
|
||||
// It's shown when clicking a theme
|
||||
collapse: function( event ) {
|
||||
@ -291,7 +331,7 @@ themes.view.Details = wp.Backbone.View.extend({
|
||||
// Detect if the click is inside the overlay
|
||||
// and don't close it unless the target was
|
||||
// the div.back button
|
||||
if ( $( event.target ).is( '.theme-backdrop' ) || $( event.target ).is( 'div.close' ) || event.keyCode === 27 ) {
|
||||
if ( $( event.target ).is( '.theme-backdrop' ) || $( event.target ).is( '.close' ) || event.keyCode === 27 ) {
|
||||
|
||||
// Add a temporary closing class while overlay fades out
|
||||
$( 'body' ).addClass( 'closing-overlay' );
|
||||
@ -311,6 +351,11 @@ themes.view.Details = wp.Backbone.View.extend({
|
||||
|
||||
// Restore scroll position
|
||||
document.body.scrollTop = scroll;
|
||||
|
||||
// Return focus to the theme div
|
||||
if ( themes.focusedTheme ) {
|
||||
themes.focusedTheme.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -192,7 +192,7 @@ if ( ! $ct->errors() || ( 1 == count( $ct->errors()->get_error_codes() )
|
||||
*/
|
||||
|
||||
foreach ( $themes as $theme ) : ?>
|
||||
<div class="theme<?php if ( $theme['active'] ) echo ' active'; ?>">
|
||||
<div class="theme<?php if ( $theme['active'] ) echo ' active'; ?>" tabindex="0">
|
||||
<?php if ( ! empty( $theme['screenshot'][0] ) ) { ?>
|
||||
<div class="theme-screenshot">
|
||||
<img src="<?php echo $theme['screenshot'][0]; ?>" alt="" />
|
||||
@ -309,9 +309,9 @@ if ( ! is_multisite() && current_user_can('edit_themes') && $broken_themes = wp_
|
||||
<div class="theme-backdrop"></div>
|
||||
<div class="theme-wrap">
|
||||
<div class="theme-header">
|
||||
<div alt="<?php _e( 'Close overlay' ); ?>" class="close dashicons dashicons-no"></div>
|
||||
<div alt="<?php _e( 'Show previous theme' ); ?>" class="left dashicons dashicons-no"></div>
|
||||
<div alt="<?php _e( 'Show next theme' ); ?>" class="right dashicons dashicons-no"></div>
|
||||
<button alt="<?php _e( 'Show previous theme' ); ?>" class="left dashicons dashicons-no"></button>
|
||||
<button alt="<?php _e( 'Show next theme' ); ?>" class="right dashicons dashicons-no"></button>
|
||||
<button alt="<?php _e( 'Close overlay' ); ?>" class="close dashicons dashicons-no"></button>
|
||||
</div>
|
||||
<div class="theme-about">
|
||||
<div class="theme-screenshots">
|
||||
|
Loading…
Reference in New Issue
Block a user