Skip to content

Commit 9dfb758

Browse files
committed
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. git-svn-id: https://develop.svn.wordpress.org/trunk@41876 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 0bfa2d7 commit 9dfb758

4 files changed

Lines changed: 81 additions & 25 deletions

File tree

src/wp-admin/js/theme-plugin-editor.js

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ wp.themePluginEditor = (function( $ ) {
5151
component.warning = $( '.file-editor-warning' );
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

5957
if ( false !== component.codeEditor ) {
@@ -77,6 +75,62 @@ wp.themePluginEditor = (function( $ ) {
7775
} );
7876
};
7977

78+
/**
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+
80134
/**
81135
* Dismiss the warning modal.
82136
*
@@ -91,10 +145,8 @@ wp.themePluginEditor = (function( $ ) {
91145

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

100152
/**

src/wp-admin/plugin-editor.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,13 +292,15 @@
292292
$return_url = admin_url( '/' );
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>
304306
<button type="button" class="file-editor-warning-dismiss button button-primary"><?php _e( 'I understand' ); ?></button>

src/wp-admin/theme-editor.php

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -297,21 +297,23 @@
297297
$return_url = admin_url( '/' );
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>
317319
<button type="button" class="file-editor-warning-dismiss button button-primary"><?php _e( 'I understand' ); ?></button>

src/wp-includes/script-loader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ function wp_default_scripts( &$scripts ) {
469469
$scripts->add( 'htmlhint', '/wp-includes/js/codemirror/htmlhint.js', array(), '0.9.14-xwp' );
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.' ),
475475
'saveError' => __( 'Something went wrong. Your change may not have been saved. Please try again. There is also a chance that you may need to manually fix and upload the file over FTP.' ),

0 commit comments

Comments
 (0)