Skip to content

Commit 4c1898d

Browse files
committed
Editor: A11y: Fix tab order, state, and focus in classic editor.
Remove code that forced focus to skip from the title field to the editor. Add link to skip to editor to give the user control over their path. Set `aria-pressed` on editor selector buttons to communicate which editor is enabled. Make focus state visible on unselected editor button. Remove `wp_keep_scroll_position` flag used for IE compatibility. Add `role="presentation"` to table used as status info bar. This addresses a long-standing accessibility problem in the classic editor which created a confusing keyboard navigation path by skipping all content between the title field and the content editor. Props afercia, rcreators, benjamin_zekavica, sharonaustin, joedolson. Fixes #29838. git-svn-id: https://develop.svn.wordpress.org/trunk@59188 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 90d2429 commit 4c1898d

File tree

6 files changed

+33
-54
lines changed

6 files changed

+33
-54
lines changed

src/js/_enqueues/admin/post.js

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -434,25 +434,6 @@ jQuery( function($) {
434434
$previewField.val('');
435435
});
436436

437-
// This code is meant to allow tabbing from Title to Post content.
438-
$('#title').on( 'keydown.editor-focus', function( event ) {
439-
var editor;
440-
441-
if ( event.keyCode === 9 && ! event.ctrlKey && ! event.altKey && ! event.shiftKey ) {
442-
editor = typeof tinymce != 'undefined' && tinymce.get('content');
443-
444-
if ( editor && ! editor.isHidden() ) {
445-
editor.focus();
446-
} else if ( $textarea.length ) {
447-
$textarea.trigger( 'focus' );
448-
} else {
449-
return;
450-
}
451-
452-
event.preventDefault();
453-
}
454-
});
455-
456437
// Auto save new posts after a title is typed.
457438
if ( $( '#auto_draft' ).val() ) {
458439
$( '#title' ).on( 'blur', function() {

src/js/_enqueues/wp/editor/base.js

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ window.wp = window.wp || {};
7979
var editorHeight, toolbarHeight, iframe,
8080
editor = tinymce.get( id ),
8181
wrap = $$( '#wp-' + id + '-wrap' ),
82+
htmlSwitch = wrap.find( '.switch-tmce' ),
83+
tmceSwitch = wrap.find( '.switch-html' ),
8284
$textarea = $$( '#' + id ),
8385
textarea = $textarea[0];
8486

@@ -103,18 +105,7 @@ window.wp = window.wp || {};
103105

104106
editorHeight = parseInt( textarea.style.height, 10 ) || 0;
105107

106-
var keepSelection = false;
107-
if ( editor ) {
108-
keepSelection = editor.getParam( 'wp_keep_scroll_position' );
109-
} else {
110-
keepSelection = window.tinyMCEPreInit.mceInit[ id ] &&
111-
window.tinyMCEPreInit.mceInit[ id ].wp_keep_scroll_position;
112-
}
113-
114-
if ( keepSelection ) {
115-
// Save the selection.
116-
addHTMLBookmarkInTextAreaContent( $textarea );
117-
}
108+
addHTMLBookmarkInTextAreaContent( $textarea );
118109

119110
if ( editor ) {
120111
editor.show();
@@ -130,15 +121,14 @@ window.wp = window.wp || {};
130121
}
131122
}
132123

133-
if ( editor.getParam( 'wp_keep_scroll_position' ) ) {
134-
// Restore the selection.
135-
focusHTMLBookmarkInVisualEditor( editor );
136-
}
124+
focusHTMLBookmarkInVisualEditor( editor );
137125
} else {
138126
tinymce.init( window.tinyMCEPreInit.mceInit[ id ] );
139127
}
140128

141129
wrap.removeClass( 'html-active' ).addClass( 'tmce-active' );
130+
tmceSwitch.attr( 'aria-pressed', false );
131+
htmlSwitch.attr( 'aria-pressed', true );
142132
$textarea.attr( 'aria-hidden', true );
143133
window.setUserSetting( 'editor', 'tinymce' );
144134

@@ -168,9 +158,7 @@ window.wp = window.wp || {};
168158

169159
var selectionRange = null;
170160

171-
if ( editor.getParam( 'wp_keep_scroll_position' ) ) {
172-
selectionRange = findBookmarkedPosition( editor );
173-
}
161+
selectionRange = findBookmarkedPosition( editor );
174162

175163
editor.hide();
176164

@@ -184,6 +172,8 @@ window.wp = window.wp || {};
184172
}
185173

186174
wrap.removeClass( 'tmce-active' ).addClass( 'html-active' );
175+
tmceSwitch.attr( 'aria-pressed', true );
176+
htmlSwitch.attr( 'aria-pressed', false );
187177
$textarea.attr( 'aria-hidden', false );
188178
window.setUserSetting( 'editor', 'html' );
189179
}
@@ -520,7 +510,7 @@ window.wp = window.wp || {};
520510
* Focuses the selection markers in Visual mode.
521511
*
522512
* The method checks for existing selection markers inside the editor DOM (Visual mode)
523-
* and create a selection between the two nodes using the DOM `createRange` selection API
513+
* and create a selection between the two nodes using the DOM `createRange` selection API.
524514
*
525515
* If there is only a single node, select only the single node through TinyMCE's selection API
526516
*
@@ -545,9 +535,7 @@ window.wp = window.wp || {};
545535
}
546536
}
547537

548-
if ( editor.getParam( 'wp_keep_scroll_position' ) ) {
549-
scrollVisualModeToStartElement( editor, startNode );
550-
}
538+
scrollVisualModeToStartElement( editor, startNode );
551539

552540
removeSelectionMarker( startNode );
553541
removeSelectionMarker( endNode );

src/wp-admin/css/edit.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@
7575
pointer-events: none;
7676
}
7777

78+
#titlewrap .skiplink:focus {
79+
clip: inherit;
80+
clip-path: inherit;
81+
right: 4px;
82+
top: 4px;
83+
width: auto;
84+
}
85+
7886
input#link_description,
7987
input#link_url {
8088
width: 100%;
@@ -1038,6 +1046,14 @@ form#tags-filter {
10381046
white-space: normal;
10391047
line-height: 1.8;
10401048
}
1049+
1050+
#edit-slug-box {
1051+
padding: 0;
1052+
}
1053+
1054+
#titlewrap .skiplink:focus {
1055+
top: 5px;
1056+
}
10411057
}
10421058

10431059
@media only screen and (max-width: 1004px) {

src/wp-admin/edit-form-advanced.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@
546546
?>
547547
<label class="screen-reader-text" id="title-prompt-text" for="title"><?php echo $title_placeholder; ?></label>
548548
<input type="text" name="post_title" size="30" value="<?php echo esc_attr( $post->post_title ); ?>" id="title" spellcheck="true" autocomplete="off" />
549+
<a href="#content" class="button-secondary screen-reader-text skiplink" onclick="if (tinymce) { tinymce.execCommand( 'mceFocus', false, 'content' ); }"><?php esc_html_e( 'Skip to Editor' ); ?></a>
549550
</div>
550551
<?php
551552
/**
@@ -621,18 +622,16 @@
621622
array(
622623
'_content_editor_dfw' => $_content_editor_dfw,
623624
'drag_drop_upload' => true,
624-
'tabfocus_elements' => 'content-html,save-post',
625625
'editor_height' => 300,
626626
'tinymce' => array(
627627
'resize' => false,
628628
'wp_autoresize_on' => $_wp_editor_expand,
629629
'add_unload_trigger' => false,
630-
'wp_keep_scroll_position' => ! $is_IE,
631630
),
632631
)
633632
);
634633
?>
635-
<table id="post-status-info"><tbody><tr>
634+
<table id="post-status-info" role="presentation"><tbody><tr>
636635
<td id="wp-word-count" class="hide-if-no-js">
637636
<?php
638637
printf(

src/wp-includes/class-wp-editor.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,12 @@ public static function editor( $content, $editor_id, $settings = array() ) {
188188
if ( 'html' !== $default_editor ) {
189189
$default_editor = 'tinymce';
190190
}
191+
$tmce_active = ( 'html' === $default_editor ) ? ' aria-pressed="true"' : '';
192+
$html_active = ( 'html' === $default_editor ) ? '' : ' aria-pressed="true"';
191193

192-
$buttons .= '<button type="button" id="' . $editor_id_attr . '-tmce" class="wp-switch-editor switch-tmce"' .
194+
$buttons .= '<button type="button" id="' . $editor_id_attr . '-tmce"' . $html_active . ' class="wp-switch-editor switch-tmce"' .
193195
' data-wp-editor-id="' . $editor_id_attr . '">' . _x( 'Visual', 'Name for the Visual editor tab' ) . "</button>\n";
194-
$buttons .= '<button type="button" id="' . $editor_id_attr . '-html" class="wp-switch-editor switch-html"' .
196+
$buttons .= '<button type="button" id="' . $editor_id_attr . '-html"' . $tmce_active . ' class="wp-switch-editor switch-html"' .
195197
' data-wp-editor-id="' . $editor_id_attr . '">' . _x( 'Text', 'Name for the Text editor tab (formerly HTML)' ) . "</button>\n";
196198
} else {
197199
$default_editor = 'tinymce';
@@ -1113,7 +1115,6 @@ private static function default_settings() {
11131115
'end_container_on_empty_block' => true,
11141116
'wpeditimage_html5_captions' => true,
11151117
'wp_lang_attr' => get_bloginfo( 'language' ),
1116-
'wp_keep_scroll_position' => false,
11171118
'wp_shortcut_labels' => wp_json_encode( $shortcut_labels ),
11181119
);
11191120

src/wp-includes/css/editor.css

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,12 +1140,6 @@ i.mce-i-wp_code:before {
11401140
color: #1d2327;
11411141
}
11421142

1143-
.wp-switch-editor:active,
1144-
.html-active .switch-html:focus,
1145-
.tmce-active .switch-tmce:focus {
1146-
box-shadow: none;
1147-
}
1148-
11491143
.wp-switch-editor:active {
11501144
background-color: #f6f7f7;
11511145
box-shadow: none;

0 commit comments

Comments
 (0)