diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index f83d3e5830..561e610da9 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -274,11 +274,11 @@ a:active { a:focus, a:focus .media-icon img { color: #124964; - -webkit-box-shadow: - 0 0 0 1px #5b9dd9, + -webkit-box-shadow: + 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, .8); - box-shadow: - 0 0 0 1px #5b9dd9, + box-shadow: + 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, .8); } @@ -1670,7 +1670,7 @@ form.upgrade .hint { } .screen-options + .screen-options { - margin-top: 10px; + margin-top: 10px; } .metabox-prefs .submit { @@ -2952,10 +2952,10 @@ img { .js .postbox .handlediv:focus .toggle-indicator:before { -webkit-box-shadow: - 0 0 0 1px #5b9dd9, + 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, .8); - box-shadow: - 0 0 0 1px #5b9dd9, + box-shadow: + 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, .8); } diff --git a/src/wp-admin/css/media.css b/src/wp-admin/css/media.css index a11a0d3db9..13bec02558 100644 --- a/src/wp-admin/css/media.css +++ b/src/wp-admin/css/media.css @@ -640,7 +640,7 @@ border color while dragging a file over the uploader drop area */ .edit-attachment-frame .edit-media-header .left, .edit-attachment-frame .edit-media-header .right { cursor: pointer; - color: #777; + color: #72777c; background-color: transparent; height: 50px; width: 50px; @@ -650,7 +650,7 @@ border color while dragging a file over the uploader drop area */ border: 0; border-left: 1px solid #ddd; -webkit-transition: color .1s ease-in-out, background .1s ease-in-out; - transition: color .1s ease-in-out, background .1s ease-in-out; + transition: color .1s ease-in-out, background .1s ease-in-out; } .upload-php .media-modal-close { @@ -837,10 +837,16 @@ border color while dragging a file over the uploader drop area */ .imgedit-wrap { position: relative; + padding-top: 10px; } -.imgedit-settings p { - margin: 8px 0 0; +.imgedit-settings p, +.imgedit-settings fieldset { + margin: 8px 0; +} + +.imgedit-settings legend { + margin-bottom: 5px; } .describe .imgedit-wrap .imgedit-settings { @@ -853,13 +859,11 @@ border color while dragging a file over the uploader drop area */ .wp_attachment_holder .imgedit-wrap > div { height: auto; - overflow: hidden; } .wp_attachment_holder .imgedit-wrap .imgedit-panel-content { - padding-right: 16px; - width: auto; - overflow: hidden; + padding: 3px 16px 0 0; + float: left; } .wp_attachment_holder .imgedit-wrap .imgedit-settings { @@ -908,7 +912,6 @@ border color while dragging a file over the uploader drop area */ color: grey; } -.wp_attachment_image, .A1B1 { overflow: hidden; } @@ -928,41 +931,39 @@ border color while dragging a file over the uploader drop area */ } .imgedit-menu { - margin: 0 0 12px; min-width: 300px; + margin: 0 0 12px; } -.imgedit-menu div { +.imgedit-menu .note-no-rotate { + clear: both; + margin: 0; + padding: 1em 0 0; +} + +.image-editor .imgedit-menu .button { float: left; width: 32px; - border: 1px solid #d5d5d5; - background: #f1f1f1; - margin: 0 8px 0 0; height: 32px; + margin: 0 8px 0 0; + padding: 0; + background: #f1f1f1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - text-align: center; - line-height: 28px; - color: #777; - cursor: pointer; + line-height: 16px; + color: #72777c; } -.imgedit-menu div:before { +.imgedit-menu .button:before { font: normal 20px/1 dashicons; speak: none; vertical-align: middle; } -.imgedit-menu div:hover { - border-color: #c1c1c1; - background-color: #eaeaea; - color: #32373c; -} - -.imgedit-menu div.disabled { +.imgedit-menu .button.disabled { border-color: #ccc; background-color: #ddd; - color: #777; + color: #72777c; filter: alpha(opacity=50); opacity: 0.5; cursor: default; @@ -1028,12 +1029,17 @@ border color while dragging a file over the uploader drop area */ margin: 0 8px 0 3px; } -.imgedit-applyto img { - margin: 0 8px 0 0; +.imgedit-thumbnail-preview { + margin: 10px 8px 0 0; +} + +.imgedit-thumbnail-preview-caption { + display: block; } #poststuff .imgedit-group-top h3, /* Back-compat for pre-4.4 */ #poststuff .imgedit-group-top h2 { + display: inline-block; margin: 0; padding: 0; font-size: 14px; @@ -1046,8 +1052,8 @@ border color while dragging a file over the uploader drop area */ } .imgedit-applyto .imgedit-label { - padding: 2px 0 0; display: block; + padding: .5em 0 0; } .imgedit-help { @@ -1055,8 +1061,31 @@ border color while dragging a file over the uploader drop area */ font-style: italic; } -a.imgedit-help-toggle { - text-decoration: none; +/* higher specificity than buttons */ +.image-editor .imgedit-settings .imgedit-help-toggle, +.image-editor .imgedit-settings .imgedit-help-toggle:hover, +.image-editor .imgedit-settings .imgedit-help-toggle:active { + border: 1px solid transparent; + margin: -1px 0 0 -1px; + padding: 0; + background: transparent; + color: #0074a2; + font-size: 20px; + line-height: 1; + cursor: pointer; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-box-shadow: none; + box-shadow: none; +} + +.image-editor .imgedit-settings .imgedit-help-toggle:focus { + color: #0074a2; + border-color: #5b9dd9; + outline: none; + -webkit-box-shadow: 0 0 3px rgba( 0, 115, 170, .8 ); + box-shadow: 0 0 3px rgba( 0, 115, 170, .8 ); } .form-table td.imgedit-response { @@ -1073,6 +1102,8 @@ a.imgedit-help-toggle { .imgedit-wrap .nowrap { white-space: nowrap; + font-size: 12px; + line-height: inherit; } span.imgedit-scale-warn { @@ -1083,11 +1114,36 @@ span.imgedit-scale-warn { vertical-align: middle; } +.imgedit-save-target { + margin: 8px 0; +} + .imgedit-group { margin-bottom: 8px; padding: 10px; } +.imgedit-settings .imgedit-scale input[type="text"], +.imgedit-settings .imgedit-crop-ratio input[type="text"], +.imgedit-settings .imgedit-crop-sel input[type="text"] { + width: 50px; + font-size: 14px; + padding: 3px 5px; +} + +.imgedit-separator { + display: inline-block; + width: 7px; + text-align: center; + vertical-align: middle; + font-size: 13px; + color: #444; +} + +.imgedit-settings .imgedit-scale .button { + margin-bottom: 0; +} + audio, video { display: inline-block; max-width: 100%; @@ -1131,6 +1187,18 @@ audio, video { .media-upload-form .media-item .error { padding: 10px 0 10px 12px; } + + .imgedit-settings .imgedit-scale input[type="text"], + .imgedit-settings .imgedit-crop-ratio input[type="text"], + .imgedit-settings .imgedit-crop-sel input[type="text"] { + width: 60px; + font-size: 16px; + padding: 6px 10px; + } + + .imgedit-applyto .imgedit-label { + vertical-align: middle; + } } /** diff --git a/src/wp-admin/includes/image-edit.php b/src/wp-admin/includes/image-edit.php index 4015f30cf8..8947f537a8 100644 --- a/src/wp-admin/includes/image-edit.php +++ b/src/wp-admin/includes/image-edit.php @@ -40,13 +40,14 @@ function wp_image_editor($post_id, $msg = false) { } ?> -
+
-

+

+

@@ -54,9 +55,22 @@ function wp_image_editor($post_id, $msg = false) {

- × - ! - , 'scale')" class="button button-primary" value="" /> + +
+ +
+ + × + + ! + , 'scale')" class="button button-primary" value="" /> +
+
+
@@ -65,7 +79,7 @@ function wp_image_editor($post_id, $msg = false) {
-

+

-

+

+

@@ -97,23 +112,32 @@ function wp_image_editor($post_id, $msg = false) {
-

- - - - : - - -

+
+ +
+ + : + +
+
+ +
+ +
+ + × + +
+
-

- - - - × - - -

-

+

+

-

+

-
-

+
+
-

-
+

+
+
+
-
+
-
-
, this)" class="imgedit-crop disabled" title="">
+ get_post_mime_type( $post_id ), 'methods' => array( 'rotate' ) ) ) ) { ?> -
, this)" title="">
-
, this)" title="">
- get_post_mime_type( $post_id ), 'methods' => array( 'rotate' ) ) ) ) { + $note_no_rotate = ''; ?> -
-
+ + + ' . __( 'Image rotation is not supported by your web host.' ) . '

'; + ?> + + -
, this)" class="imgedit-flipv" title="">
-
, this)" class="imgedit-fliph" title="">
+ + -
, this)" class="imgedit-undo disabled" title="">
-
, this)" class="imgedit-redo disabled" title="">
-
+ + +
@@ -184,11 +213,11 @@ function wp_image_editor($post_id, $msg = false) {
- <?php esc_attr_e( 'Image preview' ); ?> +
- + )" disabled="disabled" class="button button-primary imgedit-submit-btn" value="" />
@@ -562,8 +591,9 @@ function stream_preview_image( $post_id ) { $img = wp_get_image_editor( _load_image_to_edit_path( $post_id ) ); - if ( is_wp_error( $img ) ) - return false; + if ( is_wp_error( $img ) ) { + return false; + } $changes = !empty($_REQUEST['history']) ? json_decode( wp_unslash($_REQUEST['history']) ) : null; if ( $changes ) diff --git a/src/wp-admin/includes/media.php b/src/wp-admin/includes/media.php index 316d06a92c..4acd094f67 100644 --- a/src/wp-admin/includes/media.php +++ b/src/wp-admin/includes/media.php @@ -2701,7 +2701,7 @@ function edit_form_image_editor( $post ) { $alt_text = get_post_meta( $post->ID, '_wp_attachment_image_alt', true ); $att_url = wp_get_attachment_url( $post->ID ); ?> -
+
ID ) ) : $image_edit_button = ''; @@ -2713,7 +2713,7 @@ function edit_form_image_editor( $post ) {
- class="wp_attachment_image" id="media-head-"> + class="wp_attachment_image wp-clearfix" id="media-head-">

diff --git a/src/wp-admin/js/image-edit.js b/src/wp-admin/js/image-edit.js index 17064cd926..ae75992301 100644 --- a/src/wp-admin/js/image-edit.js +++ b/src/wp-admin/js/image-edit.js @@ -11,13 +11,17 @@ var imageEdit = window.imageEdit = { return f | 0; }, - setDisabled : function(el, s) { + setDisabled : function( el, s ) { + /* + * `el` can be a single form element or a fieldset. Before #28864, the disabled state on + * some text fields was handled targeting $('input', el). Now we need to handle the + * disabled state on buttons too so we can just target `el` regardless if it's a single + * element or a fieldset because when a fieldset is disabled, its descendants are disabled too. + */ if ( s ) { - el.removeClass('disabled'); - $('input', el).removeAttr('disabled'); + el.removeClass( 'disabled' ).prop( 'disabled', false ); } else { - el.addClass('disabled'); - $('input', el).prop('disabled', true); + el.addClass( 'disabled' ).prop( 'disabled', true ); } }, @@ -63,7 +67,11 @@ var imageEdit = window.imageEdit = { }, toggleHelp : function(el) { - $( el ).parents( '.imgedit-group-top' ).toggleClass( 'imgedit-help-toggled' ).find( '.imgedit-help' ).slideToggle( 'fast' ); + var $el = $( el ); + $el + .attr( 'aria-expanded', 'false' === $el.attr( 'aria-expanded' ) ? 'true' : 'false' ) + .parents( '.imgedit-group-top' ).toggleClass( 'imgedit-help-toggled' ).find( '.imgedit-help' ).slideToggle( 'fast' ); + return false; }, @@ -166,8 +174,25 @@ var imageEdit = window.imageEdit = { }; img = $( '' ) - .on('load', function() { - var max1, max2, parent = $('#imgedit-crop-' + postid), t = imageEdit; + .on( 'load', { history: data.history }, function( event ) { + var max1, max2, + parent = $( '#imgedit-crop-' + postid ), + t = imageEdit, + historyObj; + + if ( '' !== event.data.history ) { + historyObj = JSON.parse( event.data.history ); + // If last executed action in history is a crop action. + if ( historyObj[historyObj.length - 1].hasOwnProperty( 'c' ) ) { + /* + * A crop action has completed and the crop button gets disabled + * ensure the undo button is enabled. + */ + t.setDisabled( $( '#image-undo-' + postid) , true ); + // Move focus to the undo button to avoid a focus loss. + $( '#image-undo-' + postid ).focus(); + } + } parent.empty().append(img); @@ -305,7 +330,14 @@ var imageEdit = window.imageEdit = { var dfd, data, elem = $('#image-editor-' + postid), head = $('#media-head-' + postid), btn = $('#imgedit-open-btn-' + postid), spin = btn.siblings('.spinner'); - btn.prop('disabled', true); + /* + * Instead of disabling the button, which causes a focus loss and makes screen + * readers announce "unavailable", return if the button was already clicked. + */ + if ( btn.hasClass( 'button-activated' ) ) { + return; + } + spin.addClass( 'is-active' ); data = { @@ -318,12 +350,15 @@ var imageEdit = window.imageEdit = { dfd = $.ajax({ url: ajaxurl, type: 'post', - data: data + data: data, + beforeSend: function() { + btn.addClass( 'button-activated' ); + } }).done(function( html ) { elem.html( html ); head.fadeOut('fast', function(){ elem.fadeIn('fast'); - btn.removeAttr('disabled'); + btn.removeClass( 'button-activated' ); spin.removeClass( 'is-active' ); }); }); @@ -337,6 +372,8 @@ var imageEdit = window.imageEdit = { this.initCrop(postid, img, parent); this.setCropSelection(postid, 0); this.toggleEditor(postid, 0); + // Editor is ready, move focus to the first focusable element. + $( '.imgedit-wrap .imgedit-help-toggle' ).eq( 0 ).focus(); }, initCrop : function(postid, image, parent) { @@ -429,7 +466,10 @@ var imageEdit = window.imageEdit = { // In case we are not accessing the image editor in the context of a View, close the editor the old-skool way else { $('#image-editor-' + postid).fadeOut('fast', function() { - $('#media-head-' + postid).fadeIn('fast'); + $( '#media-head-' + postid ).fadeIn( 'fast', function() { + // Move focus back to the Edit Image button. Runs also when saving. + $( '#imgedit-open-btn-' + postid ).focus(); + }); $(this).empty(); }); } @@ -453,9 +493,9 @@ var imageEdit = window.imageEdit = { addStep : function(op, postid, nonce) { var t = this, elem = $('#imgedit-history-' + postid), - history = ( elem.val() !== '' ) ? JSON.parse( elem.val() ) : [], - undone = $('#imgedit-undone-' + postid), - pop = t.intval(undone.val()); + history = ( elem.val() !== '' ) ? JSON.parse( elem.val() ) : [], + undone = $( '#imgedit-undone-' + postid ), + pop = t.intval( undone.val() ); while ( pop > 0 ) { history.pop(); @@ -516,10 +556,14 @@ var imageEdit = window.imageEdit = { elem.val(pop); t.refreshEditor(postid, nonce, function() { var elem = $('#imgedit-history-' + postid), - history = ( elem.val() !== '' ) ? JSON.parse( elem.val() ) : []; + history = ( elem.val() !== '' ) ? JSON.parse( elem.val() ) : []; t.setDisabled($('#image-redo-' + postid), true); t.setDisabled(button, pop < history.length); + // When undo gets disabled, move focus to the redo button to avoid a focus loss. + if ( history.length === pop ) { + $( '#image-redo-' + postid ).focus(); + } }); }, @@ -535,6 +579,10 @@ var imageEdit = window.imageEdit = { t.refreshEditor(postid, nonce, function() { t.setDisabled($('#image-undo-' + postid), true); t.setDisabled(button, pop > 0); + // When redo gets disabled, move focus to the undo button to avoid a focus loss. + if ( 0 === pop ) { + $( '#image-undo-' + postid ).focus(); + } }); }, diff --git a/src/wp-includes/css/media-views.css b/src/wp-includes/css/media-views.css index 2dcf0f1a4a..5120a204a5 100644 --- a/src/wp-includes/css/media-views.css +++ b/src/wp-includes/css/media-views.css @@ -22,6 +22,11 @@ -webkit-overflow-scrolling: touch; } +.media-modal legend, +.media-modal label { + font-size: 13px; +} + .media-frame input, .media-frame textarea { padding: 6px 8px; @@ -110,7 +115,7 @@ } .media-frame :-moz-placeholder { - color: #a9a9a9; + color: #a9a9a9; } .media-frame .hidden { @@ -394,7 +399,7 @@ color: #666; } -.compat-item label span { +.compat-item label span { text-align: right; } @@ -1734,7 +1739,7 @@ .media-modal .imgedit-wrap .imgedit-settings { background: #f3f3f3; border-left: 1px solid #ddd; - padding: 0 16px 16px; + padding: 20px 16px 16px; position: absolute; top: 0; right: 0; @@ -1762,33 +1767,73 @@ padding: 0; } +.media-modal .imgedit-group-top { + margin: 0; +} + .media-modal .imgedit-group-top h3, /* Back-compat for pre-4.4 */ -.media-modal .imgedit-group-top h2 { +.media-modal .imgedit-group-top h2, +.media-modal .imgedit-group-top h2 .button-link { + display: inline-block; text-transform: uppercase; font-size: 12px; color: #666; margin: 0; - margin-top: 24px; + margin-top: 3px; } .media-modal .imgedit-group-top h3 a, /* Back-compat for pre-4.4 */ -.media-modal .imgedit-group-top h2 a { +.media-modal .imgedit-group-top h2 a, +.media-modal .imgedit-group-top h2 .button-link { text-decoration: none; color: #666; } -.media-modal .imgedit-help-toggle { - margin-top: -2px; +/* higher specificity than media.css */ +.wp-core-ui.media-modal .image-editor .imgedit-help-toggle, +.wp-core-ui.media-modal .image-editor .imgedit-help-toggle:hover, +.wp-core-ui.media-modal .image-editor .imgedit-help-toggle:active { + border: 1px solid transparent; + margin: 0; + padding: 0; + background: transparent; + color: #0074a2; + font-size: 20px; + line-height: 1; cursor: pointer; - color: #666; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-box-shadow: none; + box-shadow: none; +} + +.wp-core-ui.media-modal .image-editor .imgedit-help-toggle:focus { + color: #0074a2; + border-color: #5b9dd9; + outline: none; + -webkit-box-shadow: 0 0 3px rgba( 0, 115, 170, .8 ); + box-shadow: 0 0 3px rgba( 0, 115, 170, .8 ); +} + +.wp-core-ui.media-modal .imgedit-group-top .dashicons-arrow-down.imgedit-help-toggle { + margin-top: -3px; +} + +.wp-core-ui.media-modal .image-editor h3 .imgedit-help-toggle { + margin-top: -2px; } .media-modal .imgedit-help-toggled span.dashicons:before { content: "\f142"; } -.media-modal .imgedit-group img { - margin-top: 5px; +.media-modal .imgedit-thumbnail-preview { + margin: 10px 8px 0 0; +} + +.imgedit-thumbnail-preview-caption { + display: block; } .media-modal .imgedit-wrap div.updated {