WordPress.org

Make WordPress Core

Ticket #47145: 47145.diff

File 47145.diff, 5.2 KB (added by afercia, 5 weeks ago)
  • src/js/media/views/modal.js

     
    117117                // Set initial focus on the content instead of this view element, to avoid page scrolling.
    118118                this.$( '.media-modal' ).focus();
    119119
     120                // Hide the page content from assistive technologies.
     121                this.hideBodyFromScreenReaders( $el );
     122
    120123                return this.propagate('open');
    121124        },
    122125
     
    135138                // Hide modal and remove restricted media modal tab focus once it's closed
    136139                this.$el.hide().undelegate( 'keydown' );
    137140
     141                /*
     142                 * Make all body children that have been made hidden when the modal opened
     143                 * visible again to assistive technologies.
     144                 */
     145                _.each( $( this.hiddenElements ), function( element ) {
     146                        element.removeAttribute( 'aria-hidden' );
     147                } );
     148
     149                this.hiddenElements = [];
     150                this.isBodyHidden   = false;
     151
    138152                // Move focus back in useful location once modal is closed.
    139153                if ( null !== this.clickedOpenerEl ) {
    140154                        // Move focus back to the element that opened the modal.
     
    202216                        this.escape();
    203217                        event.stopImmediatePropagation();
    204218                }
     219        },
     220
     221        /**
     222         * Stores elements that should be hidden from assistive technologies when
     223         * the modal opens.
     224         */
     225        hiddenElements: [],
     226
     227        /**
     228         * Hides from assistive technologies all elements in the body element except
     229         * the provided element and other elements that should not be hidden.
     230         *
     231         * The reason we do this is because `aria-modal="true"` is buggy in Safari 11.1
     232         * and support is spotty in other browsers overall. In the future we should
     233         * consider removing these helper functions in favor of `aria-modal="true"`.
     234         *
     235         * @param {object} dialogElement The jQuery object representing the element that should not be hidden.
     236         */
     237        hideBodyFromScreenReaders: function( dialogElement ) {
     238                var elements,
     239                        self = this;
     240
     241                if ( this.isBodyHidden ) {
     242                        return;
     243                }
     244
     245                // Get all the body children.
     246                elements = document.body.children;
     247
     248                // Loop through the body children and hide the ones that should be hidden.
     249                _.each( elements, function( element ) {
     250                        // Don't hide the modal element.
     251                        if ( element === dialogElement[0] ) {
     252                                return;
     253                        }
     254
     255                        // Determine the body children to hide.
     256                        if ( self.elementShouldBeHidden( element ) ) {
     257                                element.setAttribute( 'aria-hidden', 'true' );
     258                                // Store the hidden elements.
     259                                self.hiddenElements.push( element );
     260                        }
     261                } );
     262
     263                this.isBodyHidden = true;
     264        },
     265
     266        /**
     267         * Determines if the passed element should not be hidden from assistive technologies.
     268         *
     269         * @param {object} element The DOM element that should be checked.
     270         *
     271         * @return {boolean} Whether the element should not be hidden from assistive technologies.
     272         */
     273        elementShouldBeHidden: function( element ) {
     274                var role = element.getAttribute( 'role' ),
     275                        liveRegionsRoles = [ 'alert', 'status', 'log', 'marquee', 'timer' ];
     276
     277                /*
     278                 * Don't hide scripts, elements that already have `aria-hidden`, and
     279                 * ARIA live regions.
     280                 */
     281                return ! (
     282                        element.tagName === 'SCRIPT' ||
     283                        element.hasAttribute( 'aria-hidden' ) ||
     284                        element.hasAttribute( 'aria-live' ) ||
     285                        liveRegionsRoles.indexOf( role ) !== -1
     286                );
    205287        }
    206288});
    207289
  • src/wp-includes/css/media-views.css

     
    542542        right: 0;
    543543        bottom: 0;
    544544        margin: 0;
    545         padding: 10px 0;
     545        padding: 50px 0 10px;
    546546        background: #f3f3f3;
    547547        border-right-width: 1px;
    548548        border-right-style: solid;
     
    25302530
    25312531/* Landscape specific header override */
    25322532@media screen and (max-height: 400px) {
    2533         .media-menu {
    2534                 padding: 0;
     2533        .media-menu,
     2534        .media-frame:not(.hide-menu) .media-menu {
     2535                top: 44px;
    25352536        }
    25362537
    25372538        .media-frame-router {
  • src/wp-includes/media-template.php

     
    177177
    178178        <?php // Template for the media frame: used both in the media grid and in the media modal. ?>
    179179        <script type="text/html" id="tmpl-media-frame">
     180                <div class="media-frame-title" id="media-frame-title"></div>
    180181                <div class="media-frame-menu"></div>
    181                 <div class="media-frame-title"></div>
    182182                <div class="media-frame-router"></div>
    183183                <div class="media-frame-content"></div>
    184184                <div class="media-frame-toolbar"></div>
     
    187187
    188188        <?php // Template for the media modal. ?>
    189189        <script type="text/html" id="tmpl-media-modal">
    190                 <div tabindex="0" class="<?php echo $class; ?>">
     190                <div tabindex="0" class="<?php echo $class; ?>" role="dialog" aria-modal="true" aria-labelledby="media-frame-title">
    191191                        <# if ( data.hasCloseButton ) { #>
    192192                                <button type="button" class="media-modal-close"><span class="media-modal-icon"><span class="screen-reader-text"><?php _e( 'Close dialog' ); ?></span></span></button>
    193193                        <# } #>
    194                         <div class="media-modal-content"></div>
     194                        <div class="media-modal-content" role="document"></div>
    195195                </div>
    196196                <div class="media-modal-backdrop"></div>
    197197        </script>