Make WordPress Core

Changeset 46363


Ignore:
Timestamp:
09/30/2019 07:36:42 PM (7 years ago)
Author:
afercia
Message:

Accessibility: Media: Use the ARIA tabs pattern for the media modal menus.

The ARIA tabs pattern improves interaction for keyboard and assistive technologies users.
It gives the menu items proper roles, and aria-selected allows users of assistive technologies to know which tab is currently selected.

Props audrasjb, afercia, joedolson, karmatosed, melchoyce.
See #47149.

Location:
trunk/src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/js/media/views/focus-manager.js

    r46239 r46363  
     1var $ = jQuery;
     2
    13/**
    24 * wp.media.view.FocusManager
     
    1214
    1315        events: {
    14                 'keydown': 'constrainTabbing'
     16                'keydown': 'focusManagementMode'
     17        },
     18
     19        /**
     20         * Initializes the Focus Manager.
     21         *
     22         * @param {object} options The Focus Manager options.
     23         *
     24         * @since 5.3.0
     25         *
     26         * @return {void}
     27         */
     28        initialize: function( options ) {
     29                this.mode                    = options.mode || 'constrainTabbing';
     30                this.tabsAutomaticActivation = options.tabsAutomaticActivation || false;
     31        },
     32
     33        /**
     34         * Determines which focus management mode to use.
     35         *
     36         * @since 5.3.0
     37         *
     38         * @param {object} event jQuery event object.
     39         *
     40         * @returns {void}
     41         */
     42        focusManagementMode: function( event ) {
     43                if ( this.mode === 'constrainTabbing' ) {
     44                        this.constrainTabbing( event );
     45                }
     46
     47                if ( this.mode === 'tabsNavigation' ) {
     48                        this.tabsNavigation( event );
     49                }
    1550        },
    1651
     
    68103
    69104        /**
    70          * Hides from assistive technologies all the body children except the
    71          * provided element and other elements that should not be hidden.
     105         * Hides from assistive technologies all the body children.
     106         *
     107         * Sets an `aria-hidden="true"` attribute on all the body children except
     108         * the provided element and other elements that should not be hidden.
    72109         *
    73110         * The reason why we use `aria-hidden` is that `aria-modal="true"` is buggy
     
    112149
    113150        /**
    114          * Makes visible again to assistive technologies all body children
     151         * Unhides from assistive technologies all the body children.
     152         *
     153         * Makes visible again to assistive technologies all the body children
    115154         * previously hidden and stored in this.ariaHiddenElements.
    116155         *
     
    166205         * @since 5.2.3
    167206         */
    168         ariaHiddenElements: []
     207        ariaHiddenElements: [],
     208
     209        /**
     210         * Holds the jQuery collection of ARIA tabs.
     211         *
     212         * @since 5.3.0
     213         */
     214        tabs: $(),
     215
     216        /**
     217         * Sets up tabs in an ARIA tabbed interface.
     218         *
     219         * @since 5.3.0
     220         *
     221         * @param {object} event jQuery event object.
     222         *
     223         * @returns {void}
     224         */
     225        setupAriaTabs: function() {
     226                this.tabs = this.$( '[role="tab"]' );
     227
     228                // Set up initial attributes.
     229                this.tabs.attr( {
     230                        'aria-selected': 'false',
     231                        tabIndex: '-1'
     232                } );
     233
     234                // Set up attributes on the initially active tab.
     235                this.tabs.filter( '.active' )
     236                        .removeAttr( 'tabindex' )
     237                        .attr( 'aria-selected', 'true' );
     238        },
     239
     240        /**
     241         * Enables arrows navigation within the ARIA tabbed interface.
     242         *
     243         * @since 5.3.0
     244         *
     245         * @param {object} event jQuery event object.
     246         *
     247         * @returns {void}
     248         */
     249        tabsNavigation: function( event ) {
     250                var orientation = 'horizontal',
     251                        keys = [ 32, 35, 36, 37, 38, 39, 40 ];
     252
     253                // Return if not Spacebar, End, Home, or Arrow keys.
     254                if ( keys.indexOf( event.which ) === -1 ) {
     255                        return;
     256                }
     257
     258                // Determine navigation direction.
     259                if ( this.$el.attr( 'aria-orientation' ) === 'vertical' ) {
     260                        orientation = 'vertical';
     261                }
     262
     263                // Make Up and Down arrow keys do nothing with horizontal tabs.
     264                if ( orientation === 'horizontal' && [ 38, 40 ].indexOf( event.which ) !== -1 ) {
     265                        return;
     266                }
     267
     268                // Make Left and Right arrow keys do nothing with vertical tabs.
     269                if ( orientation === 'vertical' && [ 37, 39 ].indexOf( event.which ) !== -1 ) {
     270                        return;
     271                }
     272
     273                this.switchTabs( event, this.tabs );
     274        },
     275
     276        /**
     277         * Switches tabs in the ARIA tabbed interface.
     278         *
     279         * @since 5.3.0
     280         *
     281         * @param {object} event jQuery event object.
     282         *
     283         * @returns {void}
     284         */
     285        switchTabs: function( event ) {
     286                var key   = event.which,
     287                        index = this.tabs.index( $( event.target ) ),
     288                        newIndex;
     289
     290                switch ( key ) {
     291                        // Space bar: Activate current targeted tab.
     292                        case 32: {
     293                                this.activateTab( this.tabs[ index ] );
     294                                break;
     295                        }
     296                        // End key: Activate last tab.
     297                        case 35: {
     298                                event.preventDefault();
     299                                this.activateTab( this.tabs[ this.tabs.length - 1 ] );
     300                                break;
     301                        }
     302                        // Home key: Activate first tab.
     303                        case 36: {
     304                                event.preventDefault();
     305                                this.activateTab( this.tabs[ 0 ] );
     306                                break;
     307                        }
     308                        // Left and up keys: Activate previous tab.
     309                        case 37:
     310                        case 38: {
     311                                event.preventDefault();
     312                                newIndex = ( index - 1 ) < 0 ? this.tabs.length - 1 : index - 1;
     313                                this.activateTab( this.tabs[ newIndex ] );
     314                                break;
     315                        }
     316                        // Right and down keys: Activate next tab.
     317                        case 39:
     318                        case 40: {
     319                                event.preventDefault();
     320                                newIndex = ( index + 1 ) === this.tabs.length ? 0 : index + 1;
     321                                this.activateTab( this.tabs[ newIndex ] );
     322                                break;
     323                        }
     324                }
     325        },
     326
     327        /**
     328         * Sets a single tab to be focusable and semantically selected.
     329         *
     330         * @since 5.3.0
     331         *
     332         * @param {object} tab The tab DOM element.
     333         *
     334         * @returns {void}
     335         */
     336        activateTab: function( tab ) {
     337                if ( ! tab ) {
     338                        return;
     339                }
     340
     341                // The tab is a DOM element: no need for jQuery methods.
     342                tab.focus();
     343
     344                // Handle automatic activation.
     345                if ( this.tabsAutomaticActivation ) {
     346                        tab.removeAttribute( 'tabindex' );
     347                        tab.setAttribute( 'aria-selected', 'true' );
     348                        tab.click();
     349
     350                        return;
     351                }
     352
     353                // Handle manual activation.
     354                $( tab ).on( 'click', function() {
     355                        tab.removeAttribute( 'tabindex' );
     356                        tab.setAttribute( 'aria-selected', 'true' );
     357                } );
     358        }
    169359});
    170360
  • trunk/src/js/media/views/frame/post.js

    r45531 r46363  
    258258                view.set({
    259259                        'library-separator': new wp.media.View({
    260                                 className: 'separator',
    261                                 priority: 100
     260                                className:  'separator',
     261                                priority:   100,
     262                                attributes: {
     263                                        role: 'presentation'
     264                                }
    262265                        })
    263266                });
  • trunk/src/js/media/views/media-frame.js

    r45925 r46363  
    2424
    2525        events: {
    26                 'click div.media-frame-title h1': 'toggleMenu'
     26                'click .media-frame-menu-toggle': 'toggleMenu'
    2727        },
    2828
     
    7676                this.title.mode('default');
    7777
    78                 this.on( 'title:render', function( view ) {
    79                         view.$el.append( '<span class="dashicons dashicons-arrow-down"></span>' );
    80                 });
    81 
    8278                // Bind default menu.
    8379                this.on( 'menu:create:default', this.createMenu, this );
    84         },
     80
     81                // Set the menu ARIA tab panel attributes when the modal opens.
     82                this.on( 'open', this.setMenuTabPanelAriaAttributes, this );
     83                // Set the router ARIA tab panel attributes when the modal opens.
     84                this.on( 'open', this.setRouterTabPanelAriaAttributes, this );
     85
     86                // Update the menu ARIA tab panel attributes when the content updates.
     87                this.on( 'content:render', this.setMenuTabPanelAriaAttributes, this );
     88                // Update the router ARIA tab panel attributes when the content updates.
     89                this.on( 'content:render', this.setRouterTabPanelAriaAttributes, this );
     90        },
     91
     92        /**
     93         * Sets the attributes to be used on the menu ARIA tab panel.
     94         *
     95         * @since 5.3.0
     96         *
     97         * @returns {void}
     98         */
     99        setMenuTabPanelAriaAttributes: function() {
     100                var stateId = this.state().get( 'id' ),
     101                        tabPanelEl = this.$el.find( '.media-frame-tab-panel' ),
     102                        ariaLabelledby;
     103
     104                tabPanelEl.removeAttr( 'role aria-labelledby tabindex' );
     105
     106                if ( this.menuView && this.menuView.isVisible ) {
     107                        ariaLabelledby = 'menu-item-' + stateId;
     108
     109                        // Set the tab panel attributes only if the tabs are visible.
     110                        tabPanelEl
     111                                .attr( {
     112                                        role: 'tabpanel',
     113                                        'aria-labelledby': ariaLabelledby,
     114                                        tabIndex: '0'
     115                                } );
     116                }
     117        },
     118
     119        /**
     120         * Sets the attributes to be used on the router ARIA tab panel.
     121         *
     122         * @since 5.3.0
     123         *
     124         * @returns {void}
     125         */
     126        setRouterTabPanelAriaAttributes: function() {
     127                var tabPanelEl = this.$el.find( '.media-frame-content' ),
     128                        ariaLabelledby;
     129
     130                tabPanelEl.removeAttr( 'role aria-labelledby tabindex' );
     131
     132                // On the Embed view the router menu is hidden.
     133                if ( 'embed' === this.content._mode ) {
     134                        return;
     135                }
     136
     137                // Set the tab panel attributes only if the tabs are visible.
     138                if ( this.routerView && this.routerView.isVisible && this.content._mode ) {
     139                        ariaLabelledby = 'menu-item-' + this.content._mode;
     140
     141                        tabPanelEl
     142                                .attr( {
     143                                        role: 'tabpanel',
     144                                        'aria-labelledby': ariaLabelledby,
     145                                        tabIndex: '0'
     146                                } );
     147                }
     148        },
     149
    85150        /**
    86151         * @returns {wp.media.view.MediaFrame} Returns itself to allow chaining
     
    112177        createMenu: function( menu ) {
    113178                menu.view = new wp.media.view.Menu({
    114                         controller: this
    115                 });
    116         },
    117 
    118         toggleMenu: function() {
    119                 this.$el.find( '.media-menu' ).toggleClass( 'visible' );
     179                        controller: this,
     180
     181                        attributes: {
     182                                role:               'tablist',
     183                                'aria-orientation': 'vertical'
     184                        }
     185                });
     186
     187                this.menuView = menu.view;
     188        },
     189
     190        toggleMenu: function( event ) {
     191                var menu = this.$el.find( '.media-menu' );
     192
     193                menu.toggleClass( 'visible' );
     194                $( event.target ).attr( 'aria-expanded', menu.hasClass( 'visible' ) );
    120195        },
    121196
     
    135210        createRouter: function( router ) {
    136211                router.view = new wp.media.view.Router({
    137                         controller: this
    138                 });
     212                        controller: this,
     213
     214                        attributes: {
     215                                role:               'tablist',
     216                                'aria-orientation': 'horizontal'
     217                        }
     218                });
     219
     220                this.routerView = router.view;
    139221        },
    140222        /**
  • trunk/src/js/media/views/menu-item.js

    r45524 r46363  
    1212 */
    1313MenuItem = wp.media.View.extend(/** @lends wp.media.view.MenuItem.prototype */{
    14         tagName:   'a',
     14        tagName:   'button',
    1515        className: 'media-menu-item',
    1616
    1717        attributes: {
    18                 href: '#'
     18                type: 'button',
     19                role: 'tab'
    1920        },
    2021
     
    2223                'click': '_click'
    2324        },
     25
    2426        /**
    25          * @param {Object} event
     27         * Allows to override the click event.
    2628         */
    27         _click: function( event ) {
     29        _click: function() {
    2830                var clickOverride = this.options.click;
    29 
    30                 if ( event ) {
    31                         event.preventDefault();
    32                 }
    3331
    3432                if ( clickOverride ) {
     
    4442                if ( state ) {
    4543                        this.controller.setState( state );
     44                        // Toggle the menu visibility in the responsive view.
    4645                        this.views.parent.$el.removeClass( 'visible' ); // TODO: or hide on any click, see below
    4746                }
    4847        },
     48
    4949        /**
    5050         * @returns {wp.media.view.MenuItem} returns itself to allow chaining
    5151         */
    5252        render: function() {
    53                 var options = this.options;
     53                var options = this.options,
     54                        menuProperty = options.state || options.contentMode;
    5455
    5556                if ( options.text ) {
     
    5960                }
    6061
     62                // Set the menu item ID based on the frame state associated to the menu item.
     63                this.$el.attr( 'id', 'menu-item-' + menuProperty );
     64
    6165                return this;
    6266        }
  • trunk/src/js/media/views/menu.js

    r43309 r46363  
    2121        region:    'menu',
    2222
    23         /* TODO: alternatively hide on any click anywhere
    24         events: {
    25                 'click': 'click'
     23        attributes: {
     24                role:               'tablist',
     25                'aria-orientation': 'horizontal'
    2626        },
    2727
    28         click: function() {
    29                 this.$el.removeClass( 'visible' );
     28        initialize: function() {
     29                this._views = {};
     30
     31                this.set( _.extend( {}, this._views, this.options.views ), { silent: true });
     32                delete this.options.views;
     33
     34                if ( ! this.options.silent ) {
     35                        this.render();
     36                }
     37
     38                // Initialize the Focus Manager.
     39                this.focusManager = new wp.media.view.FocusManager( {
     40                        el:   this.el,
     41                        mode: 'tabsNavigation'
     42                } );
     43
     44                // The menu is always rendered and can be visible or hidden on some frames.
     45                this.isVisible = true;
    3046        },
    31         */
    3247
    3348        /**
     
    4863                PriorityList.prototype.ready.apply( this, arguments );
    4964                this.visibility();
     65
     66                // Set up aria tabs initial attributes.
     67                this.focusManager.setupAriaTabs();
    5068        },
    5169
     
    7391
    7492                if ( this === view ) {
     93                        // Flag this menu as hidden or visible.
     94                        this.isVisible = ! hide;
     95                        // Set or remove a CSS class to hide the menu.
    7596                        this.controller.$el.toggleClass( 'hide-' + region, hide );
    7697                }
     
    88109                this.deselect();
    89110                view.$el.addClass('active');
     111
     112                // Set up again the aria tabs initial attributes after the menu updates.
     113                this.focusManager.setupAriaTabs();
    90114        },
    91115
  • trunk/src/js/media/views/router.js

    r43309 r46363  
    2121        region:    'router',
    2222
     23        attributes: {
     24                role:               'tablist',
     25                'aria-orientation': 'horizontal'
     26        },
     27
    2328        initialize: function() {
    2429                this.controller.on( 'content:render', this.update, this );
  • trunk/src/wp-includes/css/media-views.css

    r46362 r46363  
    581581}
    582582
    583 .media-menu > a {
    584         display: block;
     583.media-menu .media-menu-item {
     584        display: block;
     585        box-sizing: border-box;
     586        width: 100%;
    585587        position: relative;
     588        border: 0;
     589        margin: 0;
    586590        padding: 8px 20px;
    587         margin: 0;
     591        font-size: 14px;
    588592        line-height: 1.28571428;
    589         font-size: 14px;
     593        background: transparent;
    590594        color: #0073aa;
     595        text-align: left;
    591596        text-decoration: none;
    592 }
    593 
    594 .media-menu > a:hover {
     597        cursor: pointer;
     598}
     599
     600.media-menu .media-menu-item:hover {
     601        background: rgba(0, 0, 0, 0.04);
     602}
     603
     604.media-menu .media-menu-item:active {
    595605        color: #0073aa;
    596         background: rgba(0, 0, 0, 0.04);
    597 }
    598 
    599 .media-menu > a:active {
    600606        outline: none;
    601607}
     
    605611        color: #23282d;
    606612        font-weight: 600;
     613}
     614
     615.media-menu .media-menu-item:focus {
     616        box-shadow:
     617                0 0 0 1px #5b9dd9,
     618                0 0 2px 1px rgba(30, 140, 190, 0.8);
     619        color: #124964;
     620        /* Only visible in Windows High Contrast mode */
     621        outline: 1px solid transparent;
    607622}
    608623
     
    622637        margin: 0;
    623638        clear: both;
    624         -webkit-user-select: none;
    625         -moz-user-select: none;
    626         -ms-user-select: none;
    627         user-select: none;
    628 }
    629 
    630 .media-router a {
    631         transition: none;
    632 }
    633 
    634 .media-router > a {
     639}
     640
     641.media-router .media-menu-item {
    635642        position: relative;
    636643        float: left;
     644        border: 0;
     645        margin: 0;
    637646        padding: 8px 10px 9px;
    638         margin: 0;
    639647        height: 18px;
    640648        line-height: 1.28571428;
    641649        font-size: 14px;
    642650        text-decoration: none;
    643 }
    644 
    645 .media-router > a:last-child {
     651        background: transparent;
     652        cursor: pointer;
     653        transition: none;
     654}
     655
     656.media-router .media-menu-item:last-child {
    646657        border-right: 0;
    647658}
    648659
    649 .media-router > a:active {
    650         outline: none;
     660.media-router .media-menu-item:hover,
     661.media-router .media-menu-item:active {
     662        color: #0073aa;
    651663}
    652664
    653665.media-router .active,
    654666.media-router .active:hover {
    655         color: #32373c;
     667        color: #23282d;
     668}
     669
     670.media-router .media-menu-item:focus {
     671        box-shadow:
     672                0 0 0 1px #5b9dd9,
     673                0 0 2px 1px rgba(30, 140, 190, 0.8);
     674        color: #124964;
     675        /* Only visible in Windows High Contrast mode */
     676        outline: 1px solid transparent;
    656677}
    657678
    658679.media-router .active,
    659 .media-router > a.active:last-child {
     680.media-router .media-menu-item.active:last-child {
    660681        margin: -1px -1px 0;
    661682        background: #fff;
     
    753774}
    754775
    755 .media-frame.hide-router .media-frame-title {
    756         border-bottom: 1px solid #ddd;
    757         box-shadow: 0 4px 4px -4px rgba(0, 0, 0, 0.1);
    758 }
    759 
    760 .media-frame-title .dashicons {
    761         display: none;
    762 }
    763 
    764776.media-frame-title h1 {
    765777        padding: 0 16px;
     
    767779        line-height: 2.27272727;
    768780        margin: 0;
     781}
     782
     783.wp-core-ui .button.media-frame-menu-toggle {
     784        display: none;
    769785}
    770786
     
    22522268 */
    22532269@media only screen and (max-width: 900px) {
     2270        .media-modal .media-frame-title {
     2271                height: 40px;
     2272        }
     2273
     2274        .media-modal .media-frame-title h1 {
     2275                line-height: 2.22222222;
     2276                font-size: 18px;
     2277        }
     2278
     2279        .media-modal-close {
     2280                width: 42px;
     2281                height: 42px;
     2282        }
    22542283
    22552284        /* Drop-down menu */
    2256         .media-frame:not(.hide-menu) .media-frame-title,
     2285        .media-frame .media-frame-title {
     2286                position: static;
     2287                padding: 0 44px;
     2288                text-align: center;
     2289        }
     2290
    22572291        .media-frame:not(.hide-menu) .media-frame-router,
    22582292        .media-frame:not(.hide-menu) .media-frame-content,
     
    22612295        }
    22622296
     2297        .media-frame:not(.hide-menu) .media-frame-router {
     2298                /* 40 title + (40 - 6) menu toggle button + 6 spacing */
     2299                top: 80px;
     2300        }
     2301
     2302        .media-frame:not(.hide-menu) .media-frame-content {
     2303                /* 80 + room for the tabs */
     2304                top: 114px;
     2305        }
     2306
     2307        .media-frame.hide-router .media-frame-content {
     2308                top: 80px;
     2309        }
     2310
    22632311        .media-frame:not(.hide-menu) .media-frame-menu {
    22642312                position: static;
     
    22672315
    22682316        .media-frame:not(.hide-menu) .media-menu {
     2317                display: none;
    22692318                width: auto;
    22702319                max-width: 80%;
    22712320                overflow: auto;
    22722321                z-index: 2000;
    2273                 top: 50px;
    2274                 left: -300px;
     2322                top: 75px;
     2323                left: 0;
    22752324                right: auto;
    22762325                bottom: auto;
     
    22802329
    22812330        .media-frame:not(.hide-menu) .media-menu.visible {
    2282                 left: 0;
     2331                display: block;
    22832332        }
    22842333
     
    22882337        }
    22892338
    2290         .media-frame:not(.hide-menu) .media-menu > a.active {
    2291                 display: none;
    2292         }
    2293 
    22942339        .media-frame:not(.hide-menu) .media-menu .separator {
    22952340                margin: 5px 10px;
    22962341        }
    22972342
    2298         .media-frame:not(.hide-menu) .media-frame-title {
    2299                 left: 0;
    2300         }
    2301 
    2302         .media-frame:not(.hide-menu) .media-frame-title .dashicons {
    2303                 display: inline-block;
    2304                 line-height: 2.5;
    2305         }
    2306 
    2307         .media-frame:not(.hide-menu) .media-frame-title h1 {
    2308                 color: #0073aa;
    2309                 line-height: 3;
    2310                 font-size: 18px;
    2311                 float: left;
    2312                 cursor: pointer;
     2343        .wp-core-ui .media-frame:not(.hide-menu) .button.media-frame-menu-toggle {
     2344                display: inline-flex;
     2345                align-items: center;
     2346                vertical-align: top;
     2347                min-height: 40px;
     2348                margin: -6px 6px 0;
     2349                padding: 0 2px 0 12px;
     2350                font-size: 0.875rem;
     2351                font-weight: 600;
     2352                text-decoration: none;
     2353                background: transparent;
     2354        }
     2355
     2356        .wp-core-ui .button.media-frame-menu-toggle:hover,
     2357        .wp-core-ui .button.media-frame-menu-toggle:active {
     2358                background: transparent;
     2359                transform: none;
     2360        }
     2361
     2362        .wp-core-ui .button.media-frame-menu-toggle:focus {
     2363                /* Only visible in Windows High Contrast mode */
     2364                outline: 1px solid transparent;
    23132365        }
    23142366        /* End drop-down menu */
     
    25622614}
    25632615
    2564 /* Landscape specific header override */
    2565 @media screen and (max-height: 400px) {
    2566         .media-menu,
    2567         .media-frame:not(.hide-menu) .media-menu {
    2568                 top: 44px;
    2569         }
    2570 
    2571         .media-frame-router {
    2572                 top: 44px;
    2573         }
    2574 
    2575         .media-frame-content {
    2576                 top: 78px;
    2577         }
    2578 
    2579         .attachments-browser .attachments {
    2580                 top: 40px;
    2581         }
    2582 
    2583         /* Prevent unnecessary scrolling on title input */
    2584         .embed-link-settings {
    2585                 overflow: visible;
    2586         }
    2587 }
    2588 
    25892616@media only screen and (min-width: 901px) and (max-height: 400px) {
    25902617        .media-menu,
     
    25962623
    25972624@media only screen and (max-width: 480px) {
    2598         .media-modal-close {
    2599                 top: -5px;
    2600         }
    2601 
    2602         .media-modal .media-frame-title {
    2603                 height: 40px;
    2604         }
    2605 
    26062625        .wp-core-ui.wp-customizer .media-button {
    26072626                margin-top: 13px;
    2608         }
    2609 
    2610         .media-modal .media-frame-title h1,
    2611         .media-frame:not(.hide-menu) .media-frame-title h1 {
    2612                 font-size: 18px;
    2613                 line-height: 2.22222222;
    2614         }
    2615 
    2616         .media-frame:not(.hide-menu) .media-frame-title .dashicons {
    2617                 line-height: 2;
    2618         }
    2619 
    2620         .media-frame-router,
    2621         .media-frame:not(.hide-menu) .media-menu {
    2622                 top: 40px;
    2623                 padding-top: 0;
    2624         }
    2625 
    2626         .media-frame-content {
    2627                 top: 74px;
    26282627        }
    26292628
  • trunk/src/wp-includes/media-template.php

    r46239 r46363  
    179179        <script type="text/html" id="tmpl-media-frame">
    180180                <div class="media-frame-title" id="media-frame-title"></div>
     181                <button type="button" class="button button-link media-frame-menu-toggle" aria-expanded="false">
     182                        <?php _e( 'Media Types' ); ?>
     183                        <span class="dashicons dashicons-arrow-down" aria-hidden="true"></span>
     184                </button>
    181185                <div class="media-frame-menu"></div>
    182                 <div class="media-frame-router"></div>
    183                 <div class="media-frame-content"></div>
     186                <div class="media-frame-tab-panel">
     187                        <div class="media-frame-router"></div>
     188                        <div class="media-frame-content"></div>
     189                </div>
    184190                <div class="media-frame-toolbar"></div>
    185191                <div class="media-frame-uploader"></div>
Note: See TracChangeset for help on using the changeset viewer.