WordPress.org

Make WordPress Core

Changeset 28607


Ignore:
Timestamp:
05/29/2014 03:38:31 AM (6 years ago)
Author:
helen
Message:

At long last, improved keyboard accessibility for the media modal.

props lessbloat, grahamarmfield, sharonaustin, bramd.
see #23560.

Location:
trunk/src/wp-includes
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/css/media-views.css

    r28581 r28607  
    479479}
    480480
    481 .media-router > a:active,
    482 .media-router > a:focus {
     481.media-router > a:active {
    483482    outline: none;
    484483}
     
    695694    -ms-user-select: none;
    696695    user-select: none;
     696}
     697
     698.attachment:focus {
     699    -webkit-box-shadow:
     700        0 0 0 1px #5b9dd9,
     701        0 0 2px 2px #5b9dd9;
     702    box-shadow:
     703        0 0 0 1px #5b9dd9,
     704        0 0 2px 2px #5b9dd9;
     705    outline: none;
    697706}
    698707
     
    926935    bottom: 0;
    927936    overflow: auto;
     937    outline: none;
    928938}
    929939
  • trunk/src/wp-includes/js/media-views.js

    r28581 r28607  
    23142314                            frame.close();
    23152315                        }
     2316
     2317                        // Keep focus inside media modal
     2318                        // after canceling a gallery
     2319                        new media.view.FocusManager({
     2320                            el: this.el
     2321                        }).focus();
    23162322                    }
    23172323                },
     
    24962502
    24972503                    this.controller.setState('gallery-edit');
     2504
     2505                    // Keep focus inside media modal
     2506                    // after jumping to gallery view
     2507                    new media.view.FocusManager({
     2508                        el: this.el
     2509                    }).focus();
    24982510                }
    24992511            });
     
    25222534
    25232535                    this.controller.setState('playlist-edit');
     2536
     2537                    // Keep focus inside media modal
     2538                    // after jumping to playlist view
     2539                    new media.view.FocusManager({
     2540                        el: this.el
     2541                    }).focus();
    25242542                }
    25252543            });
     
    25482566
    25492567                    this.controller.setState('video-playlist-edit');
     2568
     2569                    // Keep focus inside media modal
     2570                    // after jumping to video playlist view
     2571                    new media.view.FocusManager({
     2572                        el: this.el
     2573                    }).focus();
    25502574                }
    25512575            });
     
    29572981                freeze:    true
    29582982            });
     2983
     2984            this.focusManager = new media.view.FocusManager({
     2985                el: this.el
     2986            });
    29592987        },
    29602988        /**
     
    30383066            }
    30393067
    3040             this.$el.hide();
     3068            // Hide modal and remove restricted media modal tab focus once it's closed
     3069            this.$el.hide().undelegate( 'keydown' );
     3070
     3071            // Put focus back in useful location once modal is closed
     3072            $('#wpbody-content').focus();
     3073
    30413074            this.propagate('close');
    30423075
     
    30993132                this.escape();
    31003133                event.stopImmediatePropagation();
     3134            } else {
     3135                // Keep focus inside the media modal
     3136                this.focusManager;
    31013137            }
    31023138        }
     
    31183154
    31193155        focus: function() {
    3120             if ( _.isUndefined( this.index ) ) {
    3121                 return;
    3122             }
    3123 
    3124             // Update our collection of `$tabbables`.
    3125             this.$tabbables = this.$(':tabbable');
    3126 
    3127             // If tab is saved, focus it.
    3128             this.$tabbables.eq( this.index ).focus();
     3156            // Reset focus on first left menu item
     3157            $('.media-menu-item').first().focus();
    31293158        },
    31303159        /**
     
    31373166            }
    31383167
    3139             // First try to update the index.
    3140             if ( _.isUndefined( this.index ) ) {
    3141                 this.updateIndex( event );
    3142             }
    3143 
    3144             // If we still don't have an index, bail.
    3145             if ( _.isUndefined( this.index ) ) {
    3146                 return;
    3147             }
    3148 
    3149             var index = this.index + ( event.shiftKey ? -1 : 1 );
    3150 
    3151             if ( index >= 0 && index < this.$tabbables.length ) {
    3152                 this.index = index;
    3153             } else {
    3154                 delete this.index;
     3168            // Keep tab focus within media modal while it's open
     3169            if ( event.target === this.tabbableLast[0] && !event.shiftKey ) {
     3170                this.tabbableFirst.focus();
     3171                return false;
     3172            } else if ( event.target === this.tabbableFirst[0] && event.shiftKey ) {
     3173                this.tabbableLast.focus();
     3174                return false;
    31553175            }
    31563176        },
     
    31593179         */
    31603180        updateIndex: function( event ) {
    3161             this.$tabbables = this.$(':tabbable');
    3162 
    3163             var index = this.$tabbables.index( event.target );
    3164 
    3165             if ( -1 === index ) {
    3166                 delete this.index;
    3167             } else {
    3168                 this.index = index;
    3169             }
     3181            // Resets tabbable elements
     3182            this.tabbables = $( ':tabbable', this.$el );
     3183            this.tabbableFirst = this.tabbables.filter( ':first' );
     3184            this.tabbableLast = this.tabbables.filter( ':last' );
    31703185        }
    31713186    });
     
    43984413        template:  media.template('attachment'),
    43994414
     4415        attributes: {
     4416            tabIndex: 0,
     4417            role: 'checkbox'
     4418        },
     4419
    44004420        events: {
    44014421            'click .attachment-preview':      'toggleSelectionHandler',
     
    44064426            'click .close':                   'removeFromLibrary',
    44074427            'click .check':                   'removeFromSelection',
    4408             'click a':                        'preventDefault'
     4428            'click a':                        'preventDefault',
     4429            'keydown':                        'toggleSelectionHandler'
    44094430        },
    44104431
     
    44144435            var selection = this.options.selection;
    44154436
     4437            this.$el.attr('aria-label', this.model.attributes.title).attr('aria-checked', false);
    44164438            this.model.on( 'change:sizes change:uploading', this.render, this );
    44174439            this.model.on( 'change:title', this._syncTitle, this );
     
    45184540            var method;
    45194541
     4542            // Catch enter and space events
     4543            if ( 'keydown' === event.type && 13 !== event.keyCode && 32 !== event.keyCode ) {
     4544                return;
     4545            }
    45204546            if ( event.shiftKey ) {
    45214547                method = 'between';
     
    45744600            }
    45754601
     4602            // Fixes bug that loses focus when selecting a featured image
     4603            if ( !method ) {
     4604                method = 'add';
     4605            }
    45764606            if ( method !== 'add' ) {
    45774607                method = 'reset';
     
    46184648            }
    46194649
    4620             this.$el.addClass('selected');
     4650            this.$el.addClass('selected').attr('aria-checked', true);
    46214651        },
    46224652        /**
     
    46334663                return;
    46344664            }
    4635             this.$el.removeClass('selected');
     4665            this.$el.removeClass('selected').attr('aria-checked', false);
    46364666        },
    46374667        /**
     
    48654895        tagName:   'ul',
    48664896        className: 'attachments',
     4897
     4898        attributes: {
     4899            tabIndex: -1
     4900        },
    48674901
    48684902        cssTemplate: media.template('attachments-css'),
     
    55805614            event.preventDefault();
    55815615            this.collection.reset();
     5616
     5617            // Keep focus inside media modal
     5618            // after clear link is selected
     5619            new media.view.FocusManager({
     5620                el: this.el
     5621            }).focus();
    55825622        }
    55835623    });
     
    59055945        initialize: function() {
    59065946            /**
    5907              * @member {wp.media.view.FocusManager}
    5908              */
    5909             this.focusManager = new media.view.FocusManager({
    5910                 el: this.el
    5911             });
    5912             /**
    59135947             * call 'initialize' directly on the parent class
    59145948             */
     
    59235957             */
    59245958            media.view.Attachment.prototype.render.apply( this, arguments );
    5925             this.focusManager.focus();
    59265959            return this;
    59275960        },
     
    59345967            if ( confirm( l10n.warnDelete ) ) {
    59355968                this.model.destroy();
     5969                // Keep focus inside media modal
     5970                // after image is deleted
     5971                new media.view.FocusManager({
     5972                    el: this.el
     5973                }).focus();
    59365974            }
    59375975        },
     
    59896027
    59906028        initialize: function() {
    5991             /**
    5992              * @member {wp.media.view.FocusManager}
    5993              */
    5994             this.focusManager = new media.view.FocusManager({
    5995                 el: this.el
    5996             });
    5997 
    59986029            this.model.on( 'change:compat', this.render, this );
    59996030        },
     
    60226053            this.$el.html( compat.item );
    60236054            this.views.render();
    6024 
    6025             this.focusManager.focus();
    60266055            return this;
    60276056        },
  • trunk/src/wp-includes/media-template.php

    r28581 r28607  
    120120        $class .= ' ie7';
    121121    ?>
     122    <!--[if lte IE 8]>
     123    <style>
     124        .attachment:focus {
     125            outline: #1e8cbe solid;
     126        }
     127        .selected.attachment {
     128            outline: #1e8cbe solid;
     129        }
     130    </style>
     131    <![endif]-->
    122132    <script type="text/html" id="tmpl-media-frame">
    123133        <div class="media-frame-menu"></div>
     
    239249                <div class="thumbnail">
    240250                    <div class="centered">
    241                         <img src="{{ data.size.url }}" draggable="false" />
     251                        <img src="{{ data.size.url }}" draggable="false" alt="" />
    242252                    </div>
    243253                </div>
     
    254264
    255265            <# if ( data.buttons.check ) { #>
    256                 <a class="check" href="#" title="<?php esc_attr_e('Deselect'); ?>"><div class="media-modal-icon"></div></a>
     266                <a class="check" href="#" title="<?php esc_attr_e('Deselect'); ?>" tabindex="-1"><div class="media-modal-icon"></div></a>
    257267            <# } #>
    258268        </div>
Note: See TracChangeset for help on using the changeset viewer.