WordPress.org

Make WordPress Core

Ticket #24716: 24716.24.diff

File 24716.24.diff, 4.7 KB (added by adamsilverstein, 4 years ago)

add router - url mapping, history

  • src/wp-admin/upload.php

     
    2424        wp_enqueue_media();
    2525        wp_enqueue_script( 'media-grid' );
    2626        wp_enqueue_script( 'media' );
     27        wp_localize_script( 'media-grid', 'mediaGridSettings', array( 'adminUrl' => parse_url( self_admin_url(), PHP_URL_PATH )  ) );
    2728
    2829        require_once( ABSPATH . 'wp-admin/admin-header.php' );
    2930        include( ABSPATH . 'wp-admin/admin-footer.php' );
  • src/wp-includes/js/media-grid.js

     
    120120                 * @global wp.Uploader
    121121                 */
    122122                initialize: function() {
     123                        var self = this;
    123124                        _.defaults( this.options, {
    124125                                title:     l10n.mediaLibraryTitle,
    125126                                modal:     false,
     
    168169                        this.createStates();
    169170                        this.bindHandlers();
    170171                        this.render();
     172
     173                        _.defer( function(){
     174                                wp.media.mediarouter = new media.view.Frame.Router( self );
     175                                if ( window.history && window.history.pushState ) {
     176                                        Backbone.history.start({
     177                                                root: mediaGridSettings.adminUrl,
     178                                                pushState: true
     179                                        });
     180                                }
     181                        });
     182
     183                        $( '#media-search-input' ).on( 'input', _.debounce( function() {
     184                                wp.media.mediarouter.searchWith( this );
     185                        }, 250) )
     186
    171187                },
    172188
    173189                createSelection: function() {
     
    210226                bindHandlers: function() {
    211227                        this.on( 'content:create:browse', this.browseContent, this );
    212228                        this.on( 'content:render:edit-image', this.editImageContent, this );
     229                        this.on( 'input #media-search-input', this.search, this );
    213230
     231
    214232                        // Handle a frame-level event for editing an attachment.
    215233                        this.on( 'edit:attachment', this.editAttachment, this );
    216234                        this.on( 'edit:attachment:next', this.editNextAttachment, this );
     
    324342        });
    325343
    326344        /**
     345         * A router for handling the browser history and application state
     346         */
     347        media.view.Frame.Router = Backbone.Router.extend({
     348
     349                initialize: function( passedview ){
     350                        this.passedview = passedview;
     351                },
     352
     353                passedview: '',
     354
     355                routes: {
     356                        'upload.php?image=:slug': 'showimage',
     357                        'upload.php?search=:query': 'search'
     358                },
     359
     360                baseUrl: function( url ) {
     361                        return 'upload.php' + url;
     362                },
     363
     364                search: function( query ) {
     365                        $( '#media-search-input' ).val( query ).trigger( 'input' );
     366                },
     367
     368                searchWith: function( s ) {
     369                        this.navigate( this.baseUrl( '?search=' + $( s ).val() ), {trigger: false, replace: false} );
     370                },
     371
     372                showimage: function( query ) {
     373                        var library = this.passedview.state().get('library');
     374                        this.passedview.trigger( 'edit:attachment', library.findWhere( { id: parseInt( query ) } ) );
     375                },
     376
     377        });
     378
     379
     380        /**
    327381         * A frame for editing the details of a specific media item.
    328382         *
    329383         * Opens in a modal by default.
     
    340394                        'click':                    'collapse',
    341395                        'click .delete-media-item': 'deleteMediaItem',
    342396                        'click .left':              'previousMediaItem',
    343                         'click .right':             'nextMediaItem'
    344                 },
     397                        'click .right':             'nextMediaItem',
     398                        'keydown':                  'keyEvent'
     399                        },
    345400
    346401                initialize: function() {
    347402                        var self = this;
     
    373428                                // Completely destroy the modal DOM element when closing it.
    374429                                this.modal.close = function() {
    375430                                        self.modal.remove();
     431                                        // Reset the browser URL
    376432                                };
    377433
    378434                                this.modal.content( this );
    379435                                this.modal.open();
     436
     437                                // Update browser url when navigating media details
     438                                wp.media.mediarouter.navigate( wp.media.mediarouter.baseUrl( '?image=' + this.options.model.id ), {trigger: false, replace: false} );
     439
     440                                // Ensure modal gains focus, otherwise keyboard events lost
     441                                $( '.attachment-fields input:first' ).focus();
     442                                $( '.media-modal-backdrop, .media-modal-close' ).on( 'click', function() {
     443                                        self.resetRoute();
     444                                         } );
    380445                        }
    381446                },
    382447
     
    482547                                return;
    483548                        this.modal.close();
    484549                        this.options.gridController.trigger( 'edit:attachment:next', this.model );
     550                },
     551                /**
     552                 * Respond to the keyboard events: right arrow, left arrow, escape .
     553                 */
     554                keyEvent: function( event ) {
     555                        // The right arrow key
     556                        if ( event.keyCode === 39 ) {
     557                                if ( ! this.options.hasNext ) { return; }
     558                                _.once( this.nextMediaItem() );
     559                        }
     560
     561                        // The left arrow key
     562                        if ( event.keyCode === 37 ) {
     563                                if ( ! this.options.hasPrevious ) { return; }
     564                                _.once( this.previousMediaItem() );
     565                        }
     566                        // Pressing the escape key routes back to main url
     567                        if ( event.keyCode === 27 ) {
     568                                this.resetRoute();
     569                                return event;
     570                        }
     571                },
     572
     573                resetRoute: function() {
     574                        wp.media.mediarouter.navigate( wp.media.mediarouter.baseUrl( '' ), { trigger: false } );
     575                        return;
    485576                }
    486577
    487578        });