Media Grid/Modal Keyboard navigation improvements:

* Add focus to arrows on Next/Previous in the grid's modal on left/right keypress, and add the necessary CSS for `:focus`
* When in a disabled input in the grid modal, allow the left/right keys to work
* Make the image editor return a `$.Deferred` so that there isn't a race condition with UI loading. 
* Assign focus when the edit image mode is rendered so that the modal can be closed on Esc press

Props wonderboymusic, adamsilverstein (for the initial patch).
See #23560.


git-svn-id: https://develop.svn.wordpress.org/trunk@29560 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Scott Taylor 2014-08-21 02:34:23 +00:00
parent 5e838e6f4a
commit baf230c80f
4 changed files with 40 additions and 27 deletions

View File

@ -302,7 +302,7 @@ var imageEdit = window.imageEdit = {
open : function( postid, nonce, view ) { open : function( postid, nonce, view ) {
this._view = view; this._view = view;
var data, elem = $('#image-editor-' + postid), head = $('#media-head-' + postid), var dfd, data, elem = $('#image-editor-' + postid), head = $('#media-head-' + postid),
btn = $('#imgedit-open-btn-' + postid), spin = btn.siblings('.spinner'); btn = $('#imgedit-open-btn-' + postid), spin = btn.siblings('.spinner');
btn.prop('disabled', true); btn.prop('disabled', true);
@ -315,13 +315,20 @@ var imageEdit = window.imageEdit = {
'do': 'open' 'do': 'open'
}; };
elem.load(ajaxurl, data, function() { dfd = $.ajax({
url: ajaxurl,
type: 'post',
data: data
}).done(function( html ) {
elem.html( html );
head.fadeOut('fast', function(){ head.fadeOut('fast', function(){
elem.fadeIn('fast'); elem.fadeIn('fast');
btn.removeAttr('disabled'); btn.removeAttr('disabled');
spin.hide(); spin.hide();
}); });
}); });
return dfd;
}, },
imgLoaded : function(postid) { imgLoaded : function(postid) {

View File

@ -2717,6 +2717,12 @@
* *
* This should be OOCSS'd so both use a shared selector. * This should be OOCSS'd so both use a shared selector.
*/ */
.edit-attachment-frame {
display: block;
height: 100%;
width: 100%;
}
.edit-attachment-frame .edit-media-header { .edit-attachment-frame .edit-media-header {
overflow: hidden; overflow: hidden;
} }
@ -2773,8 +2779,10 @@
font-weight: 300; font-weight: 300;
} }
.edit-attachment-frame .edit-media-header .left:hover,
.edit-attachment-frame .edit-media-header .right:hover, .edit-attachment-frame .edit-media-header .right:hover,
.edit-attachment-frame .edit-media-header .left:hover { .edit-attachment-frame .edit-media-header .left:focus,
.edit-attachment-frame .edit-media-header .right:focus {
color: #2ea2cc; color: #2ea2cc;
} }

View File

@ -365,8 +365,9 @@
regions: [ 'title', 'content' ], regions: [ 'title', 'content' ],
events: { events: {
'click .left': 'previousMediaItem', 'click .left': 'previousMediaItem',
'click .right': 'nextMediaItem' 'click .right': 'nextMediaItem',
'keydown': 'keyEvent'
}, },
initialize: function() { initialize: function() {
@ -522,11 +523,12 @@
*/ */
previousMediaItem: function() { previousMediaItem: function() {
if ( ! this.hasPrevious() ) { if ( ! this.hasPrevious() ) {
this.$( '.left' ).blur();
return; return;
} }
this.model = this.library.at( this.getCurrentIndex() - 1 ); this.model = this.library.at( this.getCurrentIndex() - 1 );
this.rerender(); this.rerender();
this.$( '.left' ).focus();
}, },
/** /**
@ -534,11 +536,12 @@
*/ */
nextMediaItem: function() { nextMediaItem: function() {
if ( ! this.hasNext() ) { if ( ! this.hasNext() ) {
this.$( '.right' ).blur();
return; return;
} }
this.model = this.library.at( this.getCurrentIndex() + 1 ); this.model = this.library.at( this.getCurrentIndex() + 1 );
this.rerender(); this.rerender();
this.$( '.right' ).focus();
}, },
getCurrentIndex: function() { getCurrentIndex: function() {
@ -556,16 +559,8 @@
* Respond to the keyboard events: right arrow, left arrow, escape. * Respond to the keyboard events: right arrow, left arrow, escape.
*/ */
keyEvent: function( event ) { keyEvent: function( event ) {
var $target = $( event.target ); if ( 'INPUT' === event.target.tagName && ! ( event.target.readOnly || event.target.disabled ) ) {
return;
//Don't go left/right if we are in a textarea or input field
if ( $target.is( 'input' ) || $target.is( 'textarea' ) ) {
return event;
}
// Escape key, while in the Edit Image mode
if ( 27 === event.keyCode ) {
this.modal.close();
} }
// The right arrow key // The right arrow key

View File

@ -3256,7 +3256,7 @@
} }
} }
$el.find( '.media-modal-close' ).focus(); this.$( '.media-modal-close' ).focus();
return this.propagate('open'); return this.propagate('open');
}, },
@ -4809,7 +4809,7 @@
// Catch arrow events // Catch arrow events
if ( 37 === event.keyCode || 38 === event.keyCode || 39 === event.keyCode || 40 === event.keyCode ) { if ( 37 === event.keyCode || 38 === event.keyCode || 39 === event.keyCode || 40 === event.keyCode ) {
this.arrowEvent(event); this.controller.trigger( 'attachment:keydown:arrow', event );
return; return;
} }
@ -4849,13 +4849,6 @@
// Don't scroll the view and don't attempt to submit anything. // Don't scroll the view and don't attempt to submit anything.
event.stopPropagation(); event.stopPropagation();
}, },
/**
* @param {Object} event
*/
arrowEvent: function( event ) {
this.controller.trigger( 'attachment:keydown:arrow', event );
return false;
},
/** /**
* @param {Object} options * @param {Object} options
*/ */
@ -6579,6 +6572,11 @@
this.$( ':tabbable' ).eq( 0 ).blur(); this.$( ':tabbable' ).eq( 0 ).blur();
return false; return false;
} }
if ( 37 === event.keyCode || 38 === event.keyCode || 39 === event.keyCode || 40 === event.keyCode ) {
this.controller.trigger( 'attachment:keydown:arrow', event );
return;
}
} }
}); });
@ -7157,7 +7155,12 @@
}, },
loadEditor: function() { loadEditor: function() {
this.editor.open( this.model.get('id'), this.model.get('nonces').edit, this ); var dfd = this.editor.open( this.model.get('id'), this.model.get('nonces').edit, this );
dfd.done( _.bind( this.focus, this ) );
},
focus: function() {
this.$( '.imgedit-submit .button' ).eq( 0 ).focus();
}, },
back: function() { back: function() {