Make WordPress Core

Ticket #43169: 43169.diff

File 43169.diff, 27.7 KB (added by afercia, 7 years ago)
  • src/wp-admin/css/media.css

     
    697697        content: "\f345";
    698698}
    699699
    700 .edit-attachment-frame .edit-media-header .left.disabled,
    701 .edit-attachment-frame .edit-media-header .right.disabled,
    702 .edit-attachment-frame .edit-media-header .left.disabled:hover,
    703 .edit-attachment-frame .edit-media-header .right.disabled:hover {
     700.edit-attachment-frame .edit-media-header [disabled],
     701.edit-attachment-frame .edit-media-header [disabled]:hover {
    704702        color: #ccc;
    705703        background: inherit;
    706704        cursor: default;
    707         pointer-events: none;
    708705}
    709706
    710707.edit-attachment-frame .media-frame-content,
  • src/wp-includes/js/media/views/attachment/details.js

     
    4242                        rerenderOnModelChange: false
    4343                });
    4444
    45                 this.on( 'ready', this.initialFocus );
    4645                // Call 'initialize' directly on the parent class.
    4746                Attachment.prototype.initialize.apply( this, arguments );
    4847        },
    4948
    50         initialFocus: function() {
    51                 if ( ! wp.media.isTouchDevice ) {
    52                         /*
    53                         Previously focused the first ':input' (the readonly URL text field).
    54                         Since the first ':input' is now a button (delete/trash): when pressing
    55                         spacebar on an attachment, Firefox fires deleteAttachment/trashAttachment
    56                         as soon as focus is moved. Explicitly target the first text field for now.
    57                         @todo change initial focus logic, also for accessibility.
    58                         */
    59                         this.$( 'input[type="text"]' ).eq( 0 ).focus();
     49        /**
     50         * Get the previous and next attachments of the edited attachment.
     51         *
     52         * @since 5.0.0
     53         */
     54        getPreviousNextAttachments: function() {
     55                var editedAttachment = $( 'li[data-id="' + this.model.id + '"]' );
     56                this.previousAttachment = editedAttachment.prev();
     57                this.nextAttachment = editedAttachment.next();;
     58        },
     59
     60        /**
     61         * Move focus to the previous attachment in the grid, or to the next
     62         * one if the deleted attachment was the first one. Fallbacks to the grid
     63         * list when there are no attachments.
     64         *
     65         * @since 5.0.0
     66         */
     67        focusAttachment: function() {
     68                if ( this.previousAttachment.length ) {
     69                        this.previousAttachment.focus();
     70                } else if ( this.nextAttachment.length ) {
     71                        this.nextAttachment.focus();
     72                } else {
     73                        $( '.attachments-browser' ).find( '.attachments' ).focus();
    6074                }
    6175        },
    6276        /**
     
    6579        deleteAttachment: function( event ) {
    6680                event.preventDefault();
    6781
     82                this.getPreviousNextAttachments();
     83
    6884                if ( window.confirm( l10n.warnDelete ) ) {
    6985                        this.model.destroy();
    70                         // Keep focus inside media modal
    71                         // after image is deleted
    72                         this.controller.modal.focusManager.focus();
     86                        this.focusAttachment();
    7387                }
    7488        },
    7589        /**
     
    7993                var library = this.controller.library;
    8094                event.preventDefault();
    8195
     96                this.getPreviousNextAttachments();
     97
     98                // When in the Media Library.
    8299                if ( wp.media.view.settings.mediaTrash &&
    83100                        'edit-metadata' === this.controller.content.mode() ) {
    84101
     
    85102                        this.model.set( 'status', 'trash' );
    86103                        this.model.save().done( function() {
    87104                                library._requery( true );
     105                                /*
     106                                 * @todo we need to move focus back to the previous, next, or first
     107                                 * attachment but the librady gets re-queried and refreshed. Thus,
     108                                 * the references to the previous elements are lost, we need an
     109                                 * alternate method. Note: `this` is different within this callback.
     110                                 */
    88111                        } );
    89112                }  else {
    90113                        this.model.destroy();
     114                        this.focusAttachment();
    91115                }
    92116        },
    93117        /**
  • src/wp-includes/js/media/views/attachments/browser.js

     
    8383        },
    8484
    8585        editSelection: function( modal ) {
     86                // When editing a selection, move focus to the "Return to library" button.
    8687                modal.$( '.media-button-backToLibrary' ).focus();
    8788        },
    8889
  • src/wp-includes/js/media/views/attachments.js

     
    8282
    8383                this.collection.on( 'reset', this.render, this );
    8484
    85                 this.listenTo( this.controller, 'library:selection:add',    this.attachmentFocus );
     85                this.controller.on( 'library:selection:add', this.attachmentFocus, this );
    8686
    8787                // Throttle the scroll handler and bind this.
    8888                this.scroll = _.chain( this.scroll ).bind( this ).throttle( this.options.refreshSensitivity ).value();
     
    130130         * @returns {void}
    131131         */
    132132        attachmentFocus: function() {
    133                 this.$( 'li:first' ).focus();
     133                /*
     134                 * @todo when uploading new attachments, this tries to move focus to the
     135                 * first attachment in the grid. Actually, a progress bar gets initially
     136                 * displayed and then updated when uploading completes, so focus is lost.
     137                 * Additionally: this view is used for both the attachments list and the
     138                 * list of selected attachments in the bottom media toolbar. Thus, when
     139                 * uploading attachments, it runs twice returning two different `this`.
     140                 * To evaluate: move focus to the attachments list instead?
     141                 */
     142                if ( this.columns ) {
     143                        // Experimental: move focus to the grid list.
     144                        this.$el.focus();
     145                }
    134146        },
    135147
    136148        /**
    137149         * Restores focus to the selected item in the collection.
    138150         *
     151         * Moves focus back to the first selected attachment in the grid. Used when
     152         * tabbing backwards from the attachment details sidebar.
     153         *
    139154         * @since 4.0.0
    140155         *
    141156         * @returns {void}
  • src/wp-includes/js/media/views/edit-image.js

     
    2626        },
    2727
    2828        loadEditor: function() {
    29                 var dfd = this.editor.open( this.model.get('id'), this.model.get('nonces').edit, this );
    30                 dfd.done( _.bind( this.focus, this ) );
     29                this.editor.open( this.model.get('id'), this.model.get('nonces').edit, this );
    3130        },
    3231
    33         focus: function() {
    34                 this.$( '.imgedit-submit .button' ).eq( 0 ).focus();
    35         },
    36 
    3732        back: function() {
    3833                var lastState = this.controller.lastState();
    3934                this.controller.setState( lastState );
  • src/wp-includes/js/media/views/embed/url.js

     
    5555                return this;
    5656        },
    5757
    58         ready: function() {
    59                 if ( ! wp.media.isTouchDevice ) {
    60                         this.focus();
    61                 }
    62         },
    63 
    6458        url: function( event ) {
    6559                this.model.set( 'url', $.trim( event.target.value ) );
    66         },
    67 
    68         /**
    69          * If the input is visible, focus and select its contents.
    70          */
    71         focus: function() {
    72                 var $input = this.$input;
    73                 if ( $input.is(':visible') ) {
    74                         $input.focus()[0].select();
    75                 }
    7660        }
    7761});
    7862
  • src/wp-includes/js/media/views/focus-manager.js

     
    1414                'keydown': 'constrainTabbing'
    1515        },
    1616
    17         focus: function() { // Reset focus on first left menu item
     17        /**
     18         * Move focus to the first item in the modal menu.
     19         */
     20        focus: function() {
    1821                this.$('.media-menu-item').first().focus();
    1922        },
    2023        /**
  • src/wp-includes/js/media/views/frame/edit-attachments.js

     
    9191                        // Completely destroy the modal DOM element when closing it.
    9292                        this.modal.on( 'close', _.bind( function() {
    9393                                $( 'body' ).off( 'keydown.media-modal' ); /* remove the keydown event */
    94                                 // Restore the original focus item if possible
     94                                // Move focus back to the original item in the grid if possible.
    9595                                $( 'li.attachment[data-id="' + this.model.get( 'id' ) +'"]' ).focus();
    9696                                this.resetRoute();
    9797                        }, this ) );
     
    172172        },
    173173
    174174        toggleNav: function() {
    175                 this.$('.left').toggleClass( 'disabled', ! this.hasPrevious() );
    176                 this.$('.right').toggleClass( 'disabled', ! this.hasNext() );
     175                this.$( '.left' ).prop( 'disabled', ! this.hasPrevious() );
     176                this.$( '.right' ).prop( 'disabled', ! this.hasNext() );
    177177        },
    178178
    179179        /**
     
    200200         * Click handler to switch to the previous media item.
    201201         */
    202202        previousMediaItem: function() {
     203                var which = '';
     204
    203205                if ( ! this.hasPrevious() ) {
    204206                        return;
    205207                }
    206208                this.trigger( 'refresh', this.library.at( this.getCurrentIndex() - 1 ) );
    207                 this.$( '.left' ).focus();
     209                // When there are no previous items, the left button is disabled.
     210                this.focusNavButton( which = this.hasPrevious() ? '.left' : '.right' );
    208211        },
    209212
    210213        /**
     
    211214         * Click handler to switch to the next media item.
    212215         */
    213216        nextMediaItem: function() {
     217                var which = '';
     218
    214219                if ( ! this.hasNext() ) {
    215220                        return;
    216221                }
    217222                this.trigger( 'refresh', this.library.at( this.getCurrentIndex() + 1 ) );
    218                 this.$( '.right' ).focus();
     223                // When there are no next items, the right button is disabled.
     224                this.focusNavButton( which = this.hasNext() ? '.right' : '.left' );
    219225        },
    220226
     227        /**
     228         * Set focus to the navigation buttons depending on the browsing direction.
     229         *
     230         * @param {string} which A CSS selector to target the button to focus.
     231         */
     232        focusNavButton: function( which ) {
     233                this.$( which ).focus();
     234        },
     235
    221236        getCurrentIndex: function() {
    222237                return this.library.indexOf( this.model );
    223238        },
  • src/wp-includes/js/media/views/frame/post.js

     
    290290                                                frame.close();
    291291                                        }
    292292
    293                                         // Keep focus inside media modal
    294                                         // after canceling a gallery
     293                                        // Move focus to the modal first left menu item.
    295294                                        this.controller.modal.focusManager.focus();
    296295                                }
    297296                        },
     
    358357                }).render();
    359358
    360359                this.content.set( view );
    361 
    362                 if ( ! wp.media.isTouchDevice ) {
    363                         view.url.focus();
    364                 }
    365360        },
    366361
    367362        editSelectionContent: function() {
     
    483478                                        multiple: true
    484479                                }) );
    485480
    486                                 this.controller.setState('gallery-edit');
     481                                // Jump to gallery edit view.
     482                                this.controller.setState( 'gallery-edit' );
    487483
    488                                 // Keep focus inside media modal
    489                                 // after jumping to gallery view
     484                                // Move focus to the modal first left menu item.
    490485                                this.controller.modal.focusManager.focus();
    491486                        }
    492487                });
     
    513508                                        multiple: true
    514509                                }) );
    515510
    516                                 this.controller.setState('playlist-edit');
     511                                // Jump to audio playlist edit view.
     512                                this.controller.setState( 'playlist-edit' );
    517513
    518                                 // Keep focus inside media modal
    519                                 // after jumping to playlist view
     514                                // Move focus to the modal first left menu item.
    520515                                this.controller.modal.focusManager.focus();
    521516                        }
    522517                });
     
    543538                                        multiple: true
    544539                                }) );
    545540
    546                                 this.controller.setState('video-playlist-edit');
     541                                // Jump to video playlist edit view.
     542                                this.controller.setState( 'video-playlist-edit' );
    547543
    548                                 // Keep focus inside media modal
    549                                 // after jumping to video playlist view
     544                                // Move focus to the modal first left menu item.
    550545                                this.controller.modal.focusManager.focus();
    551546                        }
    552547                });
  • src/wp-includes/js/media/views/image-details.js

     
    7171        },
    7272
    7373        postRender: function() {
    74                 setTimeout( _.bind( this.resetFocus, this ), 10 );
     74                setTimeout( _.bind( this.scrollToTop, this ), 10 );
    7575                this.toggleLinkSettings();
    7676                if ( window.getUserSetting( 'advImgDetails' ) === 'show' ) {
    7777                        this.toggleAdvanced( true );
     
    7979                this.trigger( 'post-render' );
    8080        },
    8181
    82         resetFocus: function() {
    83                 this.$( '.link-to-custom' ).blur();
     82        scrollToTop: function() {
    8483                this.$( '.embed-media-settings' ).scrollTop( 0 );
    8584        },
    8685
  • src/wp-includes/js/media/views/media-details.js

     
    129129                AttachmentDisplay.prototype.render.apply( this, arguments );
    130130
    131131                setTimeout( _.bind( function() {
    132                         this.resetFocus();
     132                        this.scrollToTop();
    133133                }, this ), 10 );
    134134
    135135                this.settings = _.defaults( {
     
    139139                return this.setMedia();
    140140        },
    141141
    142         resetFocus: function() {
     142        scrollToTop: function() {
    143143                this.$( '.embed-media-settings' ).scrollTop( 0 );
    144144        }
    145145},/** @lends wp.media.view.MediaDetails */{
  • src/wp-includes/js/media/views/menu-item.js

     
    1 var $ = jQuery,
    2         MenuItem;
     1var MenuItem;
    32
    43/**
    54 * wp.media.view.MenuItem
     
    3736                } else {
    3837                        this.click();
    3938                }
    40 
    41                 // When selecting a tab along the left side,
    42                 // focus should be transferred into the main panel
    43                 if ( ! wp.media.isTouchDevice ) {
    44                         $('.media-frame-content input').first().focus();
    45                 }
    4639        },
    4740
    4841        click: function() {
  • src/wp-includes/js/media/views/modal.js

     
    125125                        }
    126126                }
    127127
     128                // Set initial focus on the media modal.
    128129                this.$el.focus();
    129130
    130131                return this.propagate('open');
  • src/wp-includes/js/media/views/selection.js

     
    7474                event.preventDefault();
    7575                this.collection.reset();
    7676
    77                 // Keep focus inside media modal
    78                 // after clear link is selected
     77                // Move focus to the modal first left menu item.
    7978                this.controller.modal.focusManager.focus();
    8079        }
    8180});
  • src/wp-includes/js/media/views/settings/attachment-display.js

     
    8383                }
    8484
    8585                $input.removeClass( 'hidden' );
    86 
    87                 // If the input is visible, focus and select its contents.
    88                 if ( ! wp.media.isTouchDevice && $input.is(':visible') ) {
    89                         $input.focus()[0].select();
    90                 }
    9186        }
    9287});
    9388
  • src/wp-includes/js/media-audiovideo.js

     
    969969                AttachmentDisplay.prototype.render.apply( this, arguments );
    970970
    971971                setTimeout( _.bind( function() {
    972                         this.resetFocus();
     972                        this.scrollToTop();
    973973                }, this ), 10 );
    974974
    975975                this.settings = _.defaults( {
     
    979979                return this.setMedia();
    980980        },
    981981
    982         resetFocus: function() {
     982        scrollToTop: function() {
    983983                this.$( '.embed-media-settings' ).scrollTop( 0 );
    984984        }
    985985},/** @lends wp.media.view.MediaDetails */{
  • src/wp-includes/js/media-grid.js

     
    685685                        // Completely destroy the modal DOM element when closing it.
    686686                        this.modal.on( 'close', _.bind( function() {
    687687                                $( 'body' ).off( 'keydown.media-modal' ); /* remove the keydown event */
    688                                 // Restore the original focus item if possible
     688                                // Move focus back to the original item in the grid if possible.
    689689                                $( 'li.attachment[data-id="' + this.model.get( 'id' ) +'"]' ).focus();
    690690                                this.resetRoute();
    691691                        }, this ) );
     
    766766        },
    767767
    768768        toggleNav: function() {
    769                 this.$('.left').toggleClass( 'disabled', ! this.hasPrevious() );
    770                 this.$('.right').toggleClass( 'disabled', ! this.hasNext() );
     769                this.$( '.left' ).prop( 'disabled', ! this.hasPrevious() );
     770                this.$( '.right' ).prop( 'disabled', ! this.hasNext() );
    771771        },
    772772
    773773        /**
     
    794794         * Click handler to switch to the previous media item.
    795795         */
    796796        previousMediaItem: function() {
     797                var which = '';
     798
    797799                if ( ! this.hasPrevious() ) {
    798800                        return;
    799801                }
    800802                this.trigger( 'refresh', this.library.at( this.getCurrentIndex() - 1 ) );
    801                 this.$( '.left' ).focus();
     803                // When there are no previous items, the left button is disabled.
     804                this.focusNavButton( which = this.hasPrevious() ? '.left' : '.right' );
    802805        },
    803806
    804807        /**
     
    805808         * Click handler to switch to the next media item.
    806809         */
    807810        nextMediaItem: function() {
     811                var which = '';
     812
    808813                if ( ! this.hasNext() ) {
    809814                        return;
    810815                }
    811816                this.trigger( 'refresh', this.library.at( this.getCurrentIndex() + 1 ) );
    812                 this.$( '.right' ).focus();
     817                // When there are no next items, the right button is disabled.
     818                this.focusNavButton( which = this.hasNext() ? '.right' : '.left' );
    813819        },
    814820
     821        /**
     822         * Set focus to the navigation buttons depending on the browsing direction.
     823         *
     824         * @param {string} which A CSS selector to target the button to focus.
     825         */
     826        focusNavButton: function( which ) {
     827                this.$( which ).focus();
     828        },
     829
    815830        getCurrentIndex: function() {
    816831                return this.library.indexOf( this.model );
    817832        },
  • src/wp-includes/js/media-views.js

     
    35943594                                                frame.close();
    35953595                                        }
    35963596
    3597                                         // Keep focus inside media modal
    3598                                         // after canceling a gallery
     3597                                        // Move focus to the modal first left menu item.
    35993598                                        this.controller.modal.focusManager.focus();
    36003599                                }
    36013600                        },
     
    36623661                }).render();
    36633662
    36643663                this.content.set( view );
    3665 
    3666                 if ( ! wp.media.isTouchDevice ) {
    3667                         view.url.focus();
    3668                 }
    36693664        },
    36703665
    36713666        editSelectionContent: function() {
     
    37873782                                        multiple: true
    37883783                                }) );
    37893784
    3790                                 this.controller.setState('gallery-edit');
     3785                                // Jump to gallery edit view.
     3786                                this.controller.setState( 'gallery-edit' );
    37913787
    3792                                 // Keep focus inside media modal
    3793                                 // after jumping to gallery view
     3788                                // Move focus to the modal first left menu item.
    37943789                                this.controller.modal.focusManager.focus();
    37953790                        }
    37963791                });
     
    38173812                                        multiple: true
    38183813                                }) );
    38193814
    3820                                 this.controller.setState('playlist-edit');
     3815                                // Jump to audio playlist edit view.
     3816                                this.controller.setState( 'playlist-edit' );
    38213817
    3822                                 // Keep focus inside media modal
    3823                                 // after jumping to playlist view
     3818                                // Move focus to the modal first left menu item.
    38243819                                this.controller.modal.focusManager.focus();
    38253820                        }
    38263821                });
     
    38473842                                        multiple: true
    38483843                                }) );
    38493844
    3850                                 this.controller.setState('video-playlist-edit');
     3845                                // Jump to video playlist edit view.
     3846                                this.controller.setState( 'video-playlist-edit' );
    38513847
    3852                                 // Keep focus inside media modal
    3853                                 // after jumping to video playlist view
     3848                                // Move focus to the modal first left menu item.
    38543849                                this.controller.modal.focusManager.focus();
    38553850                        }
    38563851                });
     
    43564351                        }
    43574352                }
    43584353
     4354                // Set initial focus on the media modal.
    43594355                this.$el.focus();
    43604356
    43614357                return this.propagate('open');
     
    44724468                'keydown': 'constrainTabbing'
    44734469        },
    44744470
    4475         focus: function() { // Reset focus on first left menu item
     4471        /**
     4472         * Move focus to the first item in the modal menu.
     4473         */
     4474        focus: function() {
    44764475                this.$('.media-menu-item').first().focus();
    44774476        },
    44784477        /**
     
    56995698/* 64 */
    57005699/***/ (function(module, exports) {
    57015700
    5702 var $ = jQuery,
    5703         MenuItem;
     5701var MenuItem;
    57045702
    57055703/**
    57065704 * wp.media.view.MenuItem
     
    57385736                } else {
    57395737                        this.click();
    57405738                }
    5741 
    5742                 // When selecting a tab along the left side,
    5743                 // focus should be transferred into the main panel
    5744                 if ( ! wp.media.isTouchDevice ) {
    5745                         $('.media-frame-content input').first().focus();
    5746                 }
    57475739        },
    57485740
    57495741        click: function() {
     
    67106702
    67116703                this.collection.on( 'reset', this.render, this );
    67126704
    6713                 this.listenTo( this.controller, 'library:selection:add',    this.attachmentFocus );
     6705                this.controller.on( 'library:selection:add', this.attachmentFocus, this );
    67146706
    67156707                // Throttle the scroll handler and bind this.
    67166708                this.scroll = _.chain( this.scroll ).bind( this ).throttle( this.options.refreshSensitivity ).value();
     
    67586750         * @returns {void}
    67596751         */
    67606752        attachmentFocus: function() {
    6761                 this.$( 'li:first' ).focus();
     6753                /*
     6754                 * @todo when uploading new attachments, this tries to move focus to the
     6755                 * first attachment in the grid. Actually, a progress bar gets initially
     6756                 * displayed and then updated when uploading completes, so focus is lost.
     6757                 * Additionally: this view is used for both the attachments list and the
     6758                 * list of selected attachments in the bottom media toolbar. Thus, when
     6759                 * uploading attachments, it runs twice returning two different `this`.
     6760                 * To evaluate: move focus to the attachments list instead?
     6761                 */
     6762                if ( this.columns ) {
     6763                        // Experimental: move focus to the grid list.
     6764                        this.$el.focus();
     6765                }
    67626766        },
    67636767
    67646768        /**
    67656769         * Restores focus to the selected item in the collection.
    67666770         *
     6771         * Moves focus back to the first selected attachment in the grid. Used when
     6772         * tabbing backwards from the attachment details sidebar.
     6773         *
    67676774         * @since 4.0.0
    67686775         *
    67696776         * @returns {void}
     
    74957502        },
    74967503
    74977504        editSelection: function( modal ) {
     7505                // When editing a selection, move focus to the "Return to library" button.
    74987506                modal.$( '.media-button-backToLibrary' ).focus();
    74997507        },
    75007508
     
    79687976                event.preventDefault();
    79697977                this.collection.reset();
    79707978
    7971                 // Keep focus inside media modal
    7972                 // after clear link is selected
     7979                // Move focus to the modal first left menu item.
    79737980                this.controller.modal.focusManager.focus();
    79747981        }
    79757982});
     
    82828289                }
    82838290
    82848291                $input.removeClass( 'hidden' );
    8285 
    8286                 // If the input is visible, focus and select its contents.
    8287                 if ( ! wp.media.isTouchDevice && $input.is(':visible') ) {
    8288                         $input.focus()[0].select();
    8289                 }
    82908292        }
    82918293});
    82928294
     
    83878389                        rerenderOnModelChange: false
    83888390                });
    83898391
    8390                 this.on( 'ready', this.initialFocus );
    83918392                // Call 'initialize' directly on the parent class.
    83928393                Attachment.prototype.initialize.apply( this, arguments );
    83938394        },
    83948395
    8395         initialFocus: function() {
    8396                 if ( ! wp.media.isTouchDevice ) {
    8397                         /*
    8398                         Previously focused the first ':input' (the readonly URL text field).
    8399                         Since the first ':input' is now a button (delete/trash): when pressing
    8400                         spacebar on an attachment, Firefox fires deleteAttachment/trashAttachment
    8401                         as soon as focus is moved. Explicitly target the first text field for now.
    8402                         @todo change initial focus logic, also for accessibility.
    8403                         */
    8404                         this.$( 'input[type="text"]' ).eq( 0 ).focus();
     8396        /**
     8397         * Get the previous and next attachments of the edited attachment.
     8398         *
     8399         * @since 5.0.0
     8400         */
     8401        getPreviousNextAttachments: function() {
     8402                var editedAttachment = $( 'li[data-id="' + this.model.id + '"]' );
     8403                this.previousAttachment = editedAttachment.prev();
     8404                this.nextAttachment = editedAttachment.next();;
     8405        },
     8406
     8407        /**
     8408         * Move focus to the previous attachment in the grid, or to the next
     8409         * one if the deleted attachment was the first one. Fallbacks to the grid
     8410         * list when there are no attachments.
     8411         *
     8412         * @since 5.0.0
     8413         */
     8414        focusAttachment: function() {
     8415                if ( this.previousAttachment.length ) {
     8416                        this.previousAttachment.focus();
     8417                } else if ( this.nextAttachment.length ) {
     8418                        this.nextAttachment.focus();
     8419                } else {
     8420                        $( '.attachments-browser' ).find( '.attachments' ).focus();
    84058421                }
    84068422        },
    84078423        /**
     
    84108426        deleteAttachment: function( event ) {
    84118427                event.preventDefault();
    84128428
     8429                this.getPreviousNextAttachments();
     8430
    84138431                if ( window.confirm( l10n.warnDelete ) ) {
    84148432                        this.model.destroy();
    8415                         // Keep focus inside media modal
    8416                         // after image is deleted
    8417                         this.controller.modal.focusManager.focus();
     8433                        this.focusAttachment();
    84188434                }
    84198435        },
    84208436        /**
     
    84248440                var library = this.controller.library;
    84258441                event.preventDefault();
    84268442
     8443                this.getPreviousNextAttachments();
     8444
     8445                // When in the Media Library.
    84278446                if ( wp.media.view.settings.mediaTrash &&
    84288447                        'edit-metadata' === this.controller.content.mode() ) {
    84298448
     
    84308449                        this.model.set( 'status', 'trash' );
    84318450                        this.model.save().done( function() {
    84328451                                library._requery( true );
     8452                                /*
     8453                                 * @todo we need to move focus back to the previous, next, or first
     8454                                 * attachment but the librady gets re-queried and refreshed. Thus,
     8455                                 * the references to the previous elements are lost, we need an
     8456                                 * alternate method. Note: `this` is different within this callback.
     8457                                 */
    84338458                        } );
    84348459                }  else {
    84358460                        this.model.destroy();
     8461                        this.focusAttachment();
    84368462                }
    84378463        },
    84388464        /**
     
    87678793                return this;
    87688794        },
    87698795
    8770         ready: function() {
    8771                 if ( ! wp.media.isTouchDevice ) {
    8772                         this.focus();
    8773                 }
    8774         },
    8775 
    87768796        url: function( event ) {
    87778797                this.model.set( 'url', $.trim( event.target.value ) );
    8778         },
    8779 
    8780         /**
    8781          * If the input is visible, focus and select its contents.
    8782          */
    8783         focus: function() {
    8784                 var $input = this.$input;
    8785                 if ( $input.is(':visible') ) {
    8786                         $input.focus()[0].select();
    8787                 }
    87888798        }
    87898799});
    87908800
     
    90109020        },
    90119021
    90129022        postRender: function() {
    9013                 setTimeout( _.bind( this.resetFocus, this ), 10 );
     9023                setTimeout( _.bind( this.scrollToTop, this ), 10 );
    90149024                this.toggleLinkSettings();
    90159025                if ( window.getUserSetting( 'advImgDetails' ) === 'show' ) {
    90169026                        this.toggleAdvanced( true );
     
    90189028                this.trigger( 'post-render' );
    90199029        },
    90209030
    9021         resetFocus: function() {
    9022                 this.$( '.link-to-custom' ).blur();
     9031        scrollToTop: function() {
    90239032                this.$( '.embed-media-settings' ).scrollTop( 0 );
    90249033        },
    90259034
     
    93519360        },
    93529361
    93539362        loadEditor: function() {
    9354                 var dfd = this.editor.open( this.model.get('id'), this.model.get('nonces').edit, this );
    9355                 dfd.done( _.bind( this.focus, this ) );
     9363                this.editor.open( this.model.get('id'), this.model.get('nonces').edit, this );
    93569364        },
    93579365
    9358         focus: function() {
    9359                 this.$( '.imgedit-submit .button' ).eq( 0 ).focus();
    9360         },
    9361 
    93629366        back: function() {
    93639367                var lastState = this.controller.lastState();
    93649368                this.controller.setState( lastState );
  • src/wp-includes/media-template.php

     
    305305
    306306        <script type="text/html" id="tmpl-edit-attachment-frame">
    307307                <div class="edit-media-header">
    308                         <button class="left dashicons <# if ( ! data.hasPrevious ) { #> disabled <# } #>"><span class="screen-reader-text"><?php _e( 'Edit previous media item' ); ?></span></button>
    309                         <button class="right dashicons <# if ( ! data.hasNext ) { #> disabled <# } #>"><span class="screen-reader-text"><?php _e( 'Edit next media item' ); ?></span></button>
     308                        <button class="left dashicons"<# if ( ! data.hasPrevious ) { #> disabled<# } #>><span class="screen-reader-text"><?php _e( 'Edit previous media item' ); ?></span></button>
     309                        <button class="right dashicons"<# if ( ! data.hasNext ) { #> disabled<# } #>><span class="screen-reader-text"><?php _e( 'Edit next media item' ); ?></span></button>
    310310                </div>
    311311                <div class="media-frame-title"></div>
    312312                <div class="media-frame-content"></div>