From 02355cbdb5cf5388eb288990e3c3ba01719f259c Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Sun, 4 Sep 2016 21:50:22 +0000 Subject: [PATCH] Accessibility: Improve the Customizer and Theme Installer initial focus. The Customizer and Theme Installer open in full overlays that need to receive focus. Also, keyboard navigation should be constrained within the overlays. Using CSS `visibility` to hide all the content except the overlays, makes them the only available and focusable content and allows browsers to handle focus natively. See #29158. Fixes #33228, #27705. git-svn-id: https://develop.svn.wordpress.org/trunk@38520 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/themes.css | 8 ++++++-- src/wp-admin/js/customize-controls.js | 10 +--------- src/wp-admin/js/theme.js | 12 ++++++++---- src/wp-includes/js/customize-loader.js | 18 ++++++++++-------- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index ab67ad0646..bfc7579abf 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -1182,6 +1182,8 @@ div#custom-background-image img { body.full-overlay-active { overflow: hidden; + /* Hide all the content, the Customizer overlay is then made visible to be the only available content. */ + visibility: hidden; } .wp-full-overlay { @@ -1613,8 +1615,10 @@ body.full-overlay-active { height: 100%; } -.customize-active #customize-container { - display: block; +/* Make the Customizer and Theme installer overlays the only available content. */ +#customize-container, +.theme-install-overlay { + visibility: visible; } .customize-loading #customize-container iframe { diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index 631df0b57c..7078cfd059 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -3620,7 +3620,7 @@ return; } - var parent, topFocus, + var parent, body = $( document.body ), overlay = body.children( '.wp-full-overlay' ), title = $( '#customize-info .panel-title.site-title' ), @@ -4234,14 +4234,6 @@ }); api.trigger( 'ready' ); - - // Make sure left column gets focus - topFocus = closeBtn; - topFocus.focus(); - setTimeout(function () { - topFocus.focus(); - }, 200); - }); })( wp, jQuery ); diff --git a/src/wp-admin/js/theme.js b/src/wp-admin/js/theme.js index 18596e824d..55706b3096 100644 --- a/src/wp-admin/js/theme.js +++ b/src/wp-admin/js/theme.js @@ -866,8 +866,12 @@ themes.view.Preview = themes.view.Details.extend({ html: themes.template( 'theme-preview' ), render: function() { - var self = this, currentPreviewDevice, - data = this.model.toJSON(); + var self = this, + currentPreviewDevice, + data = this.model.toJSON(), + $body = $( document.body ); + + $body.attr( 'aria-busy', 'true' ); this.$el.removeClass( 'iframe-ready' ).html( this.html( data ) ); @@ -879,8 +883,7 @@ themes.view.Preview = themes.view.Details.extend({ themes.router.navigate( themes.router.baseUrl( themes.router.themePath + this.model.get( 'id' ) ), { replace: true } ); this.$el.fadeIn( 200, function() { - $( 'body' ).addClass( 'theme-installer-active full-overlay-active' ); - $( '.close-full-overlay' ).focus(); + $body.addClass( 'theme-installer-active full-overlay-active' ); }); this.$el.find( 'iframe' ).one( 'load', function() { @@ -890,6 +893,7 @@ themes.view.Preview = themes.view.Details.extend({ iframeLoaded: function() { this.$el.addClass( 'iframe-ready' ); + $( document.body ).attr( 'aria-busy', 'false' ); }, close: function() { diff --git a/src/wp-includes/js/customize-loader.js b/src/wp-includes/js/customize-loader.js index e7b411df30..85ad7455be 100644 --- a/src/wp-includes/js/customize-loader.js +++ b/src/wp-includes/js/customize-loader.js @@ -183,11 +183,11 @@ window.wp = window.wp || {}; * Callback after the Customizer has been opened. */ opened: function() { - Loader.body.addClass( 'customize-active full-overlay-active' ); + Loader.body.addClass( 'customize-active full-overlay-active' ).attr( 'aria-busy', 'true' ); }, /** - * Close the Customizer overlay and return focus to the link that opened it. + * Close the Customizer overlay. */ close: function() { if ( ! this.active ) { @@ -209,11 +209,6 @@ window.wp = window.wp || {}; if ( this.originalDocumentTitle ) { document.title = this.originalDocumentTitle; } - - // Return focus to link that was originally clicked. - if ( this.link ) { - this.link.focus(); - } }, /** @@ -227,13 +222,20 @@ window.wp = window.wp || {}; Loader.saved = null; Loader.body.removeClass( 'customize-active full-overlay-active' ).removeClass( 'customize-loading' ); $( window ).off( 'beforeunload', Loader.beforeunload ); + /* + * Return focus to the link that opened the Customizer overlay after + * the body element visibility is restored. + */ + if ( Loader.link ) { + Loader.link.focus(); + } }, /** * Callback for the `load` event on the Customizer iframe. */ loaded: function() { - Loader.body.removeClass('customize-loading'); + Loader.body.removeClass( 'customize-loading' ).attr( 'aria-busy', 'false' ); }, /**