Make WordPress Core

Changeset 59188


Ignore:
Timestamp:
10/07/2024 04:55:26 PM (2 years ago)
Author:
joedolson
Message:

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.

Location:
trunk/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/js/_enqueues/admin/post.js

    r59016 r59188  
    433433
    434434                $previewField.val('');
    435         });
    436 
    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                 }
    454435        });
    455436
  • trunk/src/js/_enqueues/wp/editor/base.js

    r57987 r59188  
    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];
     
    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 ) {
     
    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 ] );
     
    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' );
     
    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();
     
    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' );
     
    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
     
    546536                        }
    547537
    548                         if ( editor.getParam( 'wp_keep_scroll_position' ) ) {
    549                                 scrollVisualModeToStartElement( editor, startNode );
    550                         }
     538                        scrollVisualModeToStartElement( editor, startNode );
    551539
    552540                        removeSelectionMarker( startNode );
  • trunk/src/wp-admin/css/edit.css

    r59160 r59188  
    7474        padding: 10px;
    7575        pointer-events: none;
     76}
     77
     78#titlewrap .skiplink:focus {
     79        clip: inherit;
     80        clip-path: inherit;
     81        right: 4px;
     82        top: 4px;
     83        width: auto;
    7684}
    7785
     
    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
  • trunk/src/wp-admin/edit-form-advanced.php

    r59161 r59188  
    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
     
    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(
     
    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
  • trunk/src/wp-includes/class-wp-editor.php

    r58450 r59188  
    189189                                        $default_editor = 'tinymce';
    190190                                }
    191 
    192                                 $buttons .= '<button type="button" id="' . $editor_id_attr . '-tmce" class="wp-switch-editor switch-tmce"' .
     191                                $tmce_active = ( 'html' === $default_editor ) ? ' aria-pressed="true"' : '';
     192                                $html_active = ( 'html' === $default_editor ) ? '' : ' aria-pressed="true"';
     193
     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 {
     
    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                );
  • trunk/src/wp-includes/css/editor.css

    r58146 r59188  
    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;
Note: See TracChangeset for help on using the changeset viewer.