Accessibility: Media: Fix the Image Editor mismatching keyboard focus order and visual reading order.

Swaps the DOM order of the two main columns within the admin Image Editor.

When the sequence in which content is presented affects its meaning and the navigation sequences affect meaning or operation, visual order and DOM order must match. See WCAG 2.1 Success Criterion 1.3.2 Meaningful Sequence and Success Criterion 2.4.3 Focus Order.

Props sabernhardt, anevins, audrasjb, afercia.
Fixes #47136.


git-svn-id: https://develop.svn.wordpress.org/trunk@48265 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrea Fercia 2020-07-01 14:27:18 +00:00
parent 28cb0c2049
commit f3f7b77522
4 changed files with 75 additions and 54 deletions

View File

@ -136,6 +136,8 @@
return false; return false;
} }
}); });
$( document ).on( 'image-editor-image-loaded', this.focusManager );
}, },
/** /**
@ -621,8 +623,26 @@
this.setCropSelection( postid, { 'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0, 'width': img.innerWidth(), 'height': img.innerHeight() } ); this.setCropSelection( postid, { 'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0, 'width': img.innerWidth(), 'height': img.innerHeight() } );
this.toggleEditor(postid, 0); this.toggleEditor(postid, 0);
// Editor is ready, move focus to the first focusable element.
$( '.imgedit-wrap .imgedit-help-toggle' ).eq( 0 ).focus(); $( document ).trigger( 'image-editor-image-loaded' );
},
/**
* Manages keyboard focus in the Image Editor user interface.
*
* @since 5.5.0
*
* @return {void}
*/
focusManager: function() {
/*
* Editor is ready, move focus to the first focusable element. Since the
* DOM update is pretty large, the timeout helps browsers update their
* accessibility tree to better support assistive technologies.
*/
setTimeout( function() {
$( '.imgedit-wrap' ).find( ':tabbable:first' ).focus();
}, 100 );
}, },
/** /**

View File

@ -1224,6 +1224,7 @@ audio, video {
float: none; float: none;
width: auto; width: auto;
max-width: none; max-width: none;
padding-bottom: 16px;
} }
.copy-to-clipboard-container .success { .copy-to-clipboard-container .success {

View File

@ -48,6 +48,57 @@ function wp_image_editor( $post_id, $msg = false ) {
<div class="imgedit-wrap wp-clearfix"> <div class="imgedit-wrap wp-clearfix">
<div id="imgedit-panel-<?php echo $post_id; ?>"> <div id="imgedit-panel-<?php echo $post_id; ?>">
<div class="imgedit-panel-content wp-clearfix">
<?php echo $note; ?>
<div class="imgedit-menu wp-clearfix">
<button type="button" onclick="imageEdit.handleCropToolClick( <?php echo "$post_id, '$nonce'"; ?>, this )" class="imgedit-crop button disabled" disabled><?php esc_html_e( 'Crop' ); ?></button>
<?php
// On some setups GD library does not provide imagerotate() - Ticket #11536.
if ( wp_image_editor_supports(
array(
'mime_type' => get_post_mime_type( $post_id ),
'methods' => array( 'rotate' ),
)
) ) {
$note_no_rotate = '';
?>
<button type="button" class="imgedit-rleft button" onclick="imageEdit.rotate( 90, <?php echo "$post_id, '$nonce'"; ?>, this)"><?php esc_html_e( 'Rotate left' ); ?></button>
<button type="button" class="imgedit-rright button" onclick="imageEdit.rotate(-90, <?php echo "$post_id, '$nonce'"; ?>, this)"><?php esc_html_e( 'Rotate right' ); ?></button>
<?php
} else {
$note_no_rotate = '<p class="note-no-rotate"><em>' . __( 'Image rotation is not supported by your web host.' ) . '</em></p>';
?>
<button type="button" class="imgedit-rleft button disabled" disabled></button>
<button type="button" class="imgedit-rright button disabled" disabled></button>
<?php } ?>
<button type="button" onclick="imageEdit.flip(1, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-flipv button"><?php esc_html_e( 'Flip vertical' ); ?></button>
<button type="button" onclick="imageEdit.flip(2, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-fliph button"><?php esc_html_e( 'Flip horizontal' ); ?></button>
<br class="imgedit-undo-redo-separator" />
<button type="button" id="image-undo-<?php echo $post_id; ?>" onclick="imageEdit.undo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-undo button disabled" disabled><?php esc_html_e( 'Undo' ); ?></button>
<button type="button" id="image-redo-<?php echo $post_id; ?>" onclick="imageEdit.redo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-redo button disabled" disabled><?php esc_html_e( 'Redo' ); ?></button>
<?php echo $note_no_rotate; ?>
</div>
<input type="hidden" id="imgedit-sizer-<?php echo $post_id; ?>" value="<?php echo $sizer; ?>" />
<input type="hidden" id="imgedit-history-<?php echo $post_id; ?>" value="" />
<input type="hidden" id="imgedit-undone-<?php echo $post_id; ?>" value="0" />
<input type="hidden" id="imgedit-selection-<?php echo $post_id; ?>" value="" />
<input type="hidden" id="imgedit-x-<?php echo $post_id; ?>" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
<input type="hidden" id="imgedit-y-<?php echo $post_id; ?>" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
<div id="imgedit-crop-<?php echo $post_id; ?>" class="imgedit-crop-wrap">
<img id="image-preview-<?php echo $post_id; ?>" onload="imageEdit.imgLoaded('<?php echo $post_id; ?>')" src="<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>?action=imgedit-preview&amp;_ajax_nonce=<?php echo $nonce; ?>&amp;postid=<?php echo $post_id; ?>&amp;rand=<?php echo rand( 1, 99999 ); ?>" alt="" />
</div>
<div class="imgedit-submit">
<input type="button" onclick="imageEdit.close(<?php echo $post_id; ?>, 1)" class="button imgedit-cancel-btn" value="<?php esc_attr_e( 'Cancel' ); ?>" />
<input type="button" onclick="imageEdit.save(<?php echo "$post_id, '$nonce'"; ?>)" disabled="disabled" class="button button-primary imgedit-submit-btn" value="<?php esc_attr_e( 'Save' ); ?>" />
</div>
</div>
<div class="imgedit-settings"> <div class="imgedit-settings">
<div class="imgedit-group"> <div class="imgedit-group">
<div class="imgedit-group-top"> <div class="imgedit-group-top">
@ -195,57 +246,6 @@ function wp_image_editor( $post_id, $msg = false ) {
</div> </div>
<div class="imgedit-panel-content wp-clearfix">
<?php echo $note; ?>
<div class="imgedit-menu wp-clearfix">
<button type="button" onclick="imageEdit.handleCropToolClick( <?php echo "$post_id, '$nonce'"; ?>, this )" class="imgedit-crop button disabled" disabled><?php esc_html_e( 'Crop' ); ?></button>
<?php
// On some setups GD library does not provide imagerotate() - Ticket #11536.
if ( wp_image_editor_supports(
array(
'mime_type' => get_post_mime_type( $post_id ),
'methods' => array( 'rotate' ),
)
) ) {
$note_no_rotate = '';
?>
<button type="button" class="imgedit-rleft button" onclick="imageEdit.rotate( 90, <?php echo "$post_id, '$nonce'"; ?>, this)"><?php esc_html_e( 'Rotate left' ); ?></button>
<button type="button" class="imgedit-rright button" onclick="imageEdit.rotate(-90, <?php echo "$post_id, '$nonce'"; ?>, this)"><?php esc_html_e( 'Rotate right' ); ?></button>
<?php
} else {
$note_no_rotate = '<p class="note-no-rotate"><em>' . __( 'Image rotation is not supported by your web host.' ) . '</em></p>';
?>
<button type="button" class="imgedit-rleft button disabled" disabled></button>
<button type="button" class="imgedit-rright button disabled" disabled></button>
<?php } ?>
<button type="button" onclick="imageEdit.flip(1, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-flipv button"><?php esc_html_e( 'Flip vertical' ); ?></button>
<button type="button" onclick="imageEdit.flip(2, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-fliph button"><?php esc_html_e( 'Flip horizontal' ); ?></button>
<br class="imgedit-undo-redo-separator" />
<button type="button" id="image-undo-<?php echo $post_id; ?>" onclick="imageEdit.undo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-undo button disabled" disabled><?php esc_html_e( 'Undo' ); ?></button>
<button type="button" id="image-redo-<?php echo $post_id; ?>" onclick="imageEdit.redo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-redo button disabled" disabled><?php esc_html_e( 'Redo' ); ?></button>
<?php echo $note_no_rotate; ?>
</div>
<input type="hidden" id="imgedit-sizer-<?php echo $post_id; ?>" value="<?php echo $sizer; ?>" />
<input type="hidden" id="imgedit-history-<?php echo $post_id; ?>" value="" />
<input type="hidden" id="imgedit-undone-<?php echo $post_id; ?>" value="0" />
<input type="hidden" id="imgedit-selection-<?php echo $post_id; ?>" value="" />
<input type="hidden" id="imgedit-x-<?php echo $post_id; ?>" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
<input type="hidden" id="imgedit-y-<?php echo $post_id; ?>" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
<div id="imgedit-crop-<?php echo $post_id; ?>" class="imgedit-crop-wrap">
<img id="image-preview-<?php echo $post_id; ?>" onload="imageEdit.imgLoaded('<?php echo $post_id; ?>')" src="<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>?action=imgedit-preview&amp;_ajax_nonce=<?php echo $nonce; ?>&amp;postid=<?php echo $post_id; ?>&amp;rand=<?php echo rand( 1, 99999 ); ?>" alt="" />
</div>
<div class="imgedit-submit">
<input type="button" onclick="imageEdit.close(<?php echo $post_id; ?>, 1)" class="button imgedit-cancel-btn" value="<?php esc_attr_e( 'Cancel' ); ?>" />
<input type="button" onclick="imageEdit.save(<?php echo "$post_id, '$nonce'"; ?>)" disabled="disabled" class="button button-primary imgedit-submit-btn" value="<?php esc_attr_e( 'Save' ); ?>" />
</div>
</div>
</div> </div>
<div class="imgedit-wait" id="imgedit-wait-<?php echo $post_id; ?>"></div> <div class="imgedit-wait" id="imgedit-wait-<?php echo $post_id; ?>"></div>
<div class="hidden" id="imgedit-leaving-<?php echo $post_id; ?>"><?php _e( "There are unsaved changes that will be lost. 'OK' to continue, 'Cancel' to return to the Image Editor." ); ?></div> <div class="hidden" id="imgedit-leaving-<?php echo $post_id; ?>"><?php _e( "There are unsaved changes that will be lost. 'OK' to continue, 'Cancel' to return to the Image Editor." ); ?></div>

View File

@ -1465,7 +1465,7 @@ function wp_default_scripts( $scripts ) {
) )
); );
$scripts->add( 'image-edit', "/wp-admin/js/image-edit$suffix.js", array( 'jquery', 'json2', 'imgareaselect' ), false, 1 ); $scripts->add( 'image-edit', "/wp-admin/js/image-edit$suffix.js", array( 'jquery', 'jquery-ui-core', 'json2', 'imgareaselect' ), false, 1 );
did_action( 'init' ) && $scripts->localize( did_action( 'init' ) && $scripts->localize(
'image-edit', 'image-edit',
'imageEditL10n', 'imageEditL10n',