Make WordPress Core

Changeset 28607


Ignore:
Timestamp:
05/29/2014 03:38:31 AM (12 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.