From 37cdffd3ccce82065e52e75244e525b52602d910 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Thu, 3 Oct 2019 12:09:31 +0000 Subject: [PATCH] Accessibility: Media: Add more headings in the Media Modal. Headings are the predominant mechanism for screen reader users to find information in a page. They also help all users to better identify the main sections of user interfaces. - adds three new headings within the media modal - improves plural form translation for "item selected" by using `wp.i18n` - horizontally centers the media modal menu in the responsive view Props kjellr, karmatosed, melchoyce, afercia. See #47149. Fixes #47610. git-svn-id: https://develop.svn.wordpress.org/trunk@46375 602fd350-edb4-49c9-b593-d223f7449a82 --- src/js/media/views/attachments/browser.js | 27 +++++-- src/js/media/views/selection.js | 8 +- src/wp-includes/css/media-views.css | 96 ++++++++++++++++++----- src/wp-includes/media-template.php | 2 + src/wp-includes/media.php | 3 +- src/wp-includes/script-loader.php | 2 +- tests/qunit/index.html | 3 +- 7 files changed, 111 insertions(+), 30 deletions(-) diff --git a/src/js/media/views/attachments/browser.js b/src/js/media/views/attachments/browser.js index 0ab18afe24..c6d3b8c841 100644 --- a/src/js/media/views/attachments/browser.js +++ b/src/js/media/views/attachments/browser.js @@ -132,7 +132,8 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro }, createToolbar: function() { - var LibraryViewSwitcher, Filters, toolbarOptions; + var LibraryViewSwitcher, Filters, toolbarOptions, + showFilterByType = -1 !== $.inArray( this.options.filters, [ 'uploaded', 'all' ] ); toolbarOptions = { controller: this.controller @@ -153,9 +154,21 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro priority: -60 }) ); - if ( -1 !== $.inArray( this.options.filters, [ 'uploaded', 'all' ] ) ) { - // "Filters" will return a , a visually hidden label element needs to be rendered before. this.toolbar.set( 'filtersLabel', new wp.media.view.Label({ value: l10n.filterByType, attributes: { @@ -195,7 +208,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro priority: -90 }).render() ); - // DateFilter is a , a visually hidden label element needs to be rendered before. this.toolbar.set( 'dateFilterLabel', new wp.media.view.Label({ value: l10n.filterByDate, attributes: { @@ -317,7 +330,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro } } else if ( this.options.date ) { - // DateFilter is a , a visually hidden label element needs to be rendered before. this.toolbar.set( 'dateFilterLabel', new wp.media.view.Label({ value: l10n.filterByDate, attributes: { @@ -333,7 +346,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro } if ( this.options.search ) { - // Search is an input, screen reader text needs to be rendered before + // Search is an input, a visually hidden label element needs to be rendered before. this.toolbar.set( 'searchLabel', new wp.media.view.Label({ value: l10n.searchMediaLabel, attributes: { diff --git a/src/js/media/views/selection.js b/src/js/media/views/selection.js index e71965e23c..a872aa7340 100644 --- a/src/js/media/views/selection.js +++ b/src/js/media/views/selection.js @@ -1,4 +1,5 @@ -var l10n = wp.media.view.l10n, +var _n = wp.i18n._n, + sprintf = wp.i18n.sprintf, Selection; /** @@ -60,7 +61,10 @@ Selection = wp.media.View.extend(/** @lends wp.media.view.Selection.prototype */ this.$el.toggleClass( 'one', 1 === collection.length ); this.$el.toggleClass( 'editing', editing ); - this.$('.count').text( l10n.selected.replace('%d', collection.length) ); + this.$( '.count' ).text( + /* translators: %s: Number of selected media attachments. */ + sprintf( _n( '%s item selected', '%s items selected', collection.length ), collection.length ) + ); }, edit: function( event ) { diff --git a/src/wp-includes/css/media-views.css b/src/wp-includes/css/media-views.css index e65148df91..6bf88653da 100644 --- a/src/wp-includes/css/media-views.css +++ b/src/wp-includes/css/media-views.css @@ -268,7 +268,7 @@ } .media-modal-content .media-frame select.attachment-filters { - margin-top: 11px; + margin-top: 32px; margin-right: 2%; width: 42%; width: calc(48% - 12px); @@ -307,12 +307,6 @@ border-top: 1px solid #ddd; } -@media screen and (max-width: 782px) { - .media-frame-toolbar .media-toolbar { - bottom: -48px; - } -} - .media-toolbar-primary { float: right; height: 100%; @@ -768,6 +762,7 @@ } .media-frame.hide-menu .media-frame-menu, +.media-frame.hide-menu .media-frame-menu-heading, .media-frame.hide-router .media-frame-router, .media-frame.hide-toolbar .media-frame-toolbar { display: none; @@ -780,6 +775,32 @@ margin: 0; } +.media-frame-menu-heading, +.media-attachments-filter-heading { + position: absolute; + left: 20px; + top: 22px; + margin: 0; + font-size: 13px; + line-height: 1; + /* Above the media-frame-menu. */ + z-index: 151; +} + +.media-attachments-filter-heading { + top: 10px; + left: 16px; +} + +.mode-grid .media-attachments-filter-heading { + top: 0; + left: -9999px; +} + +.mode-grid .media-frame-actions-heading { + display: none; +} + .wp-core-ui .button.media-frame-menu-toggle { display: none; } @@ -849,7 +870,7 @@ * Search */ .media-frame .search { - margin-top: 10px; + margin-top: 32px; padding: 4px; font-size: 13px; color: #444; @@ -1106,7 +1127,8 @@ .attachments-browser .media-toolbar { right: 300px; - height: 50px; + height: 72px; + background: #fff; } .attachments-browser.hide-sidebar .media-toolbar { @@ -1127,7 +1149,7 @@ .attachments-browser .attachments, .attachments-browser .uploader-inline { position: absolute; - top: 50px; + top: 72px; left: 0; right: 300px; bottom: 0; @@ -2330,7 +2352,8 @@ overflow: auto; z-index: 2000; top: 75px; - left: 0; + left: 50%; + transform: translateX(-50%); right: auto; bottom: auto; padding: 5px 0; @@ -2350,17 +2373,35 @@ margin: 5px 10px; } + /* Visually hide the menu heading keeping it available to assistive technologies. */ + .media-frame-menu-heading { + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + padding: 0; + width: 1px; + word-wrap: normal !important; + } + + /* Reveal the menu toggle button. */ .wp-core-ui .media-frame:not(.hide-menu) .button.media-frame-menu-toggle { display: inline-flex; align-items: center; - vertical-align: top; - min-height: 40px; - margin: -6px 6px 0; + position: absolute; + left: 50%; + transform: translateX(-50%); + margin: -6px 0 0; padding: 0 2px 0 12px; font-size: 0.875rem; font-weight: 600; text-decoration: none; background: transparent; + /* Only for IE11 to vertically align text within the inline-flex button */ + height: 0.1%; + /* Modern browsers */ + min-height: 40px; } .wp-core-ui .button.media-frame-menu-toggle:hover, @@ -2564,6 +2605,29 @@ .media-frame select { font-size: 16px; } + + .media-frame .media-toolbar input[type="search"] { + line-height: 1.625; /* 26px */ + } +} + +@media screen and (max-width: 782px) { + .attachments-browser .media-toolbar { + height: 82px; + } + + .attachments-browser .attachments, + .attachments-browser .uploader-inline { + top: 82px; + } + + .media-frame .media-toolbar input[type="search"] { + line-height: 2.25; /* 36px */ + } + + .media-frame-toolbar .media-toolbar { + bottom: -48px; + } } /* Responsive on portrait and landscape */ @@ -2635,10 +2699,6 @@ .wp-core-ui.wp-customizer .media-button { margin-top: 13px; } - - .media-frame.hide-router .media-frame-content { - top: 40px; - } } /** diff --git a/src/wp-includes/media-template.php b/src/wp-includes/media-template.php index 8a4691851c..ddac75d5e0 100644 --- a/src/wp-includes/media-template.php +++ b/src/wp-includes/media-template.php @@ -178,6 +178,7 @@ function wp_print_media_templates() { diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index d1afad5d3e..71bfed3a42 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -3931,7 +3931,8 @@ function wp_enqueue_media( $args = array() ) { 'addToVideoPlaylistTitle' => __( 'Add to Video Playlist' ), // Headings - 'attachmentsList' => __( 'Attachments list' ), + 'filterAttachments' => __( 'Filter Media' ), + 'attachmentsList' => __( 'Media list' ), ); /** diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 7a4f8d4dec..0fc16cfc7e 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -1617,7 +1617,7 @@ function wp_default_scripts( &$scripts ) { // To enqueue media-views or media-editor, call wp_enqueue_media(). // Both rely on numerous settings, styles, and templates to operate correctly. - $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement', 'wp-api-request', 'wp-a11y' ), false, 1 ); + $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement', 'wp-api-request', 'wp-a11y', 'wp-i18n' ), false, 1 ); $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 ); $scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' ), false, 1 ); $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'jquery', 'media-views', 'media-audiovideo' ), false, 1 ); diff --git a/tests/qunit/index.html b/tests/qunit/index.html index 32ce3ab435..81244c51a7 100644 --- a/tests/qunit/index.html +++ b/tests/qunit/index.html @@ -44,8 +44,9 @@ +