Make WordPress Core

Changeset 41876


Ignore:
Timestamp:
10/16/2017 05:58:07 PM (7 years ago)
Author:
afercia
Message:

Accessibility: Improve the File Editors interstitial warning.

The warning displayed upon first visit on the File Editors introduced in [41774]
needs to be the only perceivable content in the page for users of assistive
technologies. It looks like a modal but it's not exactly an ARIA dialog, not an
ARIA alert either, and needs some special treatment.

  • constrains tabbing within the modal
  • uses wp.a11y.speak() to make screen readers announce the modal message
  • hides all the other page content from assistive technologies using aria-hidden="true"

This way, even if users miss the speak message, the warning is actually the only
perceivable content in the page.

Fixes #42110.

Location:
trunk/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/js/theme-plugin-editor.js

    r41864 r41876  
    5252
    5353        if ( component.warning.length > 0 ) {
    54             $( 'body' ).addClass( 'modal-open' );
    55             component.warning.find( '.file-editor-warning-go-back' ).focus();
    56             component.warning.on( 'click', '.file-editor-warning-dismiss', component.dismissWarning );
     54            component.showWarning();
    5755        }
    5856
     
    7977
    8078    /**
     79     * Set up and display the warning modal.
     80     *
     81     * @since 4.9.0
     82     * @returns {void}
     83     */
     84    component.showWarning = function() {
     85        // Get the text within the modal.
     86        var rawMessage = component.warning.find( '.file-editor-warning-message' ).text();
     87        // Hide all the #wpwrap content from assistive technologies.
     88        $( '#wpwrap' ).attr( 'aria-hidden', 'true' );
     89        // Detach the warning modal from its position and append it to the body.
     90        $( document.body )
     91            .addClass( 'modal-open' )
     92            .append( component.warning.detach() );
     93        // Reveal the modal and set focus on the go back button.
     94        component.warning
     95            .removeClass( 'hidden' )
     96            .find( '.file-editor-warning-go-back' ).focus();
     97        // Get the links and buttons within the modal.
     98        component.warningTabbables = component.warning.find( 'a, button' );
     99        // Attach event handlers.
     100        component.warningTabbables.on( 'keydown', component.constrainTabbing );
     101        component.warning.on( 'click', '.file-editor-warning-dismiss', component.dismissWarning );
     102        // Make screen readers announce the warning message after a short delay (necessary for some screen readers).
     103        setTimeout( function() {
     104            wp.a11y.speak( wp.sanitize.stripTags( rawMessage.replace( /\s+/g, ' ' ) ), 'assertive' );
     105        }, 1000 );
     106    };
     107
     108    /**
     109     * Constrain tabbing within the warning modal.
     110     *
     111     * @since 4.9.0
     112     * @param {object} event jQuery event object.
     113     * @returns {void}
     114     */
     115    component.constrainTabbing = function( event ) {
     116        var firstTabbable, lastTabbable;
     117
     118        if ( 9 !== event.which ) {
     119            return;
     120        }
     121
     122        firstTabbable = component.warningTabbables.first()[0];
     123        lastTabbable = component.warningTabbables.last()[0];
     124
     125        if ( lastTabbable === event.target && ! event.shiftKey ) {
     126            firstTabbable.focus();
     127            event.preventDefault();
     128        } else if ( firstTabbable === event.target && event.shiftKey ) {
     129            lastTabbable.focus();
     130            event.preventDefault();
     131        }
     132    };
     133
     134    /**
    81135     * Dismiss the warning modal.
    82136     *
     
    92146        // Hide modal.
    93147        component.warning.remove();
     148        $( '#wpwrap' ).removeAttr( 'aria-hidden' );
    94149        $( 'body' ).removeClass( 'modal-open' );
    95 
    96         // Return focus - is this a trap?
    97         component.instance.codemirror.focus();
    98150    };
    99151
  • trunk/src/wp-admin/plugin-editor.php

    r41865 r41876  
    293293    }
    294294?>
    295 <div id="file-editor-warning" class="notification-dialog-wrap file-editor-warning hide-if-no-js">
     295<div id="file-editor-warning" class="notification-dialog-wrap file-editor-warning hide-if-no-js hidden">
    296296    <div class="notification-dialog-background"></div>
    297     <div class="notification-dialog" role="dialog" aria-labelledby="file-editor-warning-title" tabindex="0">
     297    <div class="notification-dialog">
    298298        <div class="file-editor-warning-content">
    299             <h1 id="file-editor-warning-title"><?php _e( 'Heads up!' ); ?></h1>
    300             <p><?php _e( 'You appear to be making direct edits to your plugin in the WordPress dashboard. We recommend that you don&#8217;t! Editing plugins directly may introduce incompatibilities that break your theme or other plugins, and can leave you unable to log back in to WordPress and undo changes.' ); ?></p>
    301             <p><?php _e( 'If you absolutely have to edit this plugin, create a copy with a new name and hang on to the original version, so you can re-enable a functional version if something goes wrong.' ); ?></p>
     299            <div class="file-editor-warning-message">
     300                <h1><?php _e( 'Heads up!' ); ?></h1>
     301                <p><?php _e( 'You appear to be making direct edits to your plugin in the WordPress dashboard. We recommend that you don&#8217;t! Editing plugins directly may introduce incompatibilities that break your theme or other plugins, and can leave you unable to log back in to WordPress and undo changes.' ); ?></p>
     302                <p><?php _e( 'If you absolutely have to edit this plugin, create a copy with a new name and hang on to the original version, so you can re-enable a functional version if something goes wrong.' ); ?></p>
     303            </div>
    302304            <p>
    303305                <a class="button file-editor-warning-go-back" href="<?php echo esc_url( $return_url ); ?>"><?php _e( 'Go back' ); ?></a>
  • trunk/src/wp-admin/theme-editor.php

    r41865 r41876  
    298298    }
    299299?>
    300 <div id="file-editor-warning" class="notification-dialog-wrap file-editor-warning hide-if-no-js">
     300<div id="file-editor-warning" class="notification-dialog-wrap file-editor-warning hide-if-no-js hidden">
    301301    <div class="notification-dialog-background"></div>
    302     <div class="notification-dialog" role="dialog" aria-labelledby="file-editor-warning-title" tabindex="0">
     302    <div class="notification-dialog">
    303303        <div class="file-editor-warning-content">
    304             <h1 id="file-editor-warning-title"><?php _e( 'Heads up!' ); ?></h1>
    305             <p>
    306                 <?php
    307                 echo sprintf(
    308                     /* translators: %s is a link to Custom CSS section in the Customizer. */
    309                     __( 'You appear to be making direct edits to your theme in the WordPress dashboard. We recommend that you don&#8217;t! Editing this code directly is dangerous, and can leave you unable to log back in to WordPress and undo changes. There&#8217;s no need to change your CSS here &mdash; you can edit and live preview CSS changes in WordPress&#8217;s <a href="%s">built in CSS editor</a>.' ),
    310                     esc_url( add_query_arg( 'autofocus[section]', 'custom_css', admin_url( 'customize.php' ) ) )
    311                 );
    312                 ?>
    313             </p>
    314             <p><?php _e( 'If you decide to go ahead with direct edits anyway, make sure to back up all your site&#8217;s files before making changes so you can restore a functional version if something goes wrong.' ); ?></p>
     304            <div class="file-editor-warning-message">
     305                <h1><?php _e( 'Heads up!' ); ?></h1>
     306                <p>
     307                    <?php
     308                    echo sprintf(
     309                        /* translators: %s is a link to Custom CSS section in the Customizer. */
     310                        __( 'You appear to be making direct edits to your theme in the WordPress dashboard. We recommend that you don&#8217;t! Editing this code directly is dangerous, and can leave you unable to log back in to WordPress and undo changes. There&#8217;s no need to change your CSS here &mdash; you can edit and live preview CSS changes in WordPress&#8217;s <a href="%s">built in CSS editor</a>.' ),
     311                        esc_url( add_query_arg( 'autofocus[section]', 'custom_css', admin_url( 'customize.php' ) ) )
     312                    );
     313                    ?>
     314                </p>
     315                <p><?php _e( 'If you decide to go ahead with direct edits anyway, make sure to back up all your site&#8217;s files before making changes so you can restore a functional version if something goes wrong.' ); ?></p>
     316            </div>
    315317            <p>
    316318                <a class="button file-editor-warning-go-back" href="<?php echo esc_url( $return_url ); ?>"><?php _e( 'Go back' ); ?></a>
  • trunk/src/wp-includes/script-loader.php

    r41844 r41876  
    470470    $scripts->add( 'htmlhint-kses', '/wp-includes/js/codemirror/htmlhint-kses.js', array( 'htmlhint' ) );
    471471    $scripts->add( 'code-editor', "/wp-admin/js/code-editor$suffix.js", array( 'jquery', 'wp-codemirror' ) );
    472     $scripts->add( 'wp-theme-plugin-editor', "/wp-admin/js/theme-plugin-editor$suffix.js", array( 'wp-util', 'jquery', 'jquery-ui-core', 'wp-a11y', 'underscore' ) );
     472    $scripts->add( 'wp-theme-plugin-editor', "/wp-admin/js/theme-plugin-editor$suffix.js", array( 'wp-util', 'wp-sanitize', 'jquery', 'jquery-ui-core', 'wp-a11y', 'underscore' ) );
    473473    did_action( 'init' ) && $scripts->add_inline_script( 'wp-theme-plugin-editor', sprintf( 'wp.themePluginEditor.l10n = %s;', wp_json_encode( array(
    474474        'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.' ),
Note: See TracChangeset for help on using the changeset viewer.