WordPress.org

Make WordPress Core

Ticket #24716: 24716.25.diff

File 24716.25.diff, 6.1 KB (added by adamsilverstein, 4 years ago)

better routing,history; default route

  • 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

     
    1 /* global _wpMediaViewsL10n, setUserSetting, deleteUserSetting, MediaElementPlayer */
     1/* global _wpMediaViewsL10n, setUserSetting, deleteUserSetting, MediaElementPlayer, mediaGridSettings*/
    22(function($, _, Backbone, wp) {
    33        var media = wp.media, l10n;
    44
     
    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                        // Set up the Backbone router after a brief delay
     174                        _.delay( function(){
     175                                wp.media.mediarouter = new media.view.Frame.Router( self );
     176                                // Verify pushState support and activate
     177                                if ( window.history && window.history.pushState ) {
     178                                        Backbone.history.start({
     179                                                root: mediaGridSettings.adminUrl,
     180                                                pushState: true
     181                                        });
     182                                }
     183                        }, 150);
     184
     185                        // Update the URL when entering search string (at most once per second)
     186                        $( '#media-search-input' ).on( 'input', _.debounce( function() {
     187                                if ( '' !== $( this ).val() ) {
     188                                        wp.media.mediarouter.navigate( wp.media.mediarouter.baseUrl( '?search=' + $( this ).val() ), { trigger: false, replace: false } );
     189                                }
     190                        }, 1000 ) );
    171191                },
    172192
    173193                createSelection: function() {
     
    210230                bindHandlers: function() {
    211231                        this.on( 'content:create:browse', this.browseContent, this );
    212232                        this.on( 'content:render:edit-image', this.editImageContent, this );
     233                        this.on( 'input #media-search-input', this.search, this );
    213234
    214235                        // Handle a frame-level event for editing an attachment.
    215236                        this.on( 'edit:attachment', this.editAttachment, this );
     
    247268                                hasNext = false;
    248269                        }
    249270
    250                         new media.view.Frame.EditAttachment({
     271                        wp.media.editAttachmentFrame = new media.view.Frame.EditAttachment({
    251272                                hasPrevious:    hasPrevious,
    252273                                hasNext:        hasNext,
    253274                                model:          model,
     
    324345        });
    325346
    326347        /**
     348         * A router for handling the browser history and application state
     349         */
     350        media.view.Frame.Router = Backbone.Router.extend({
     351
     352                mediaFrame: '',
     353
     354                initialize: function( mediaFrame ){
     355                        this.mediaFrame = mediaFrame;
     356                },
     357
     358                routes: {
     359                        'upload.php?item=:slug':    'showitem',
     360                        'upload.php?search=:query': 'search',
     361                        ':default':                 'defaultRoute'
     362                },
     363
     364                // Map routes against the page URL
     365                baseUrl: function( url ) {
     366                        return 'upload.php' + url;
     367                },
     368
     369                // Respond to the search route by filling the search field and trigggering the input event
     370                search: function( query ) {
     371                        // Ensure modal closed, see back button
     372                        this.closeModal();
     373                        $( '#media-search-input' ).val( query ).trigger( 'input' );
     374                },
     375
     376                // Show the modal with a specific item
     377                showitem: function( query ) {
     378                        var library = this.mediaFrame.state().get('library');
     379
     380                        // Remove existing modal if present
     381                        this.closeModal();
     382                        // Trigger the media frame to open the correct item
     383                        this.mediaFrame.trigger( 'edit:attachment', library.findWhere( { id: parseInt( query, 10 ) } ) );
     384                },
     385
     386                // Close the modal if set up
     387                closeModal: function() {
     388                        if ( 'undefined' !== typeof wp.media.editAttachmentFrame ) {
     389                                wp.media.editAttachmentFrame.modal.remove();
     390                        }
     391                },
     392
     393                // Default route: make sure the modal and search are reset
     394                defaultRoute: function() {
     395                        this.closeModal();
     396                        $( '#media-search-input' ).val( '' ).trigger( 'input' );
     397                }
     398        });
     399
     400        /**
    327401         * A frame for editing the details of a specific media item.
    328402         *
    329403         * Opens in a modal by default.
     
    340414                        'click':                    'collapse',
    341415                        'click .delete-media-item': 'deleteMediaItem',
    342416                        'click .left':              'previousMediaItem',
    343                         'click .right':             'nextMediaItem'
    344                 },
     417                        'click .right':             'nextMediaItem',
     418                        'keydown':                  'keyEvent'
     419                        },
    345420
    346421                initialize: function() {
    347422                        var self = this;
     
    373448                                // Completely destroy the modal DOM element when closing it.
    374449                                this.modal.close = function() {
    375450                                        self.modal.remove();
     451                                        // Reset the browser URL
    376452                                };
    377453
    378454                                this.modal.content( this );
    379455                                this.modal.open();
     456
     457                                // Update browser url when navigating media details
     458                                wp.media.mediarouter.navigate( wp.media.mediarouter.baseUrl( '?item=' + this.options.model.id ), { trigger: false, replace: false } );
     459
     460                                // Ensure modal gains focus, otherwise keyboard events lost
     461                                $( '.attachment-fields input:first' ).focus();
     462                                $( '.media-modal-backdrop, .media-modal-close' ).on( 'click', function() {
     463                                        self.resetRoute();
     464                                } );
    380465                        }
    381466                },
    382467
     
    482567                                return;
    483568                        this.modal.close();
    484569                        this.options.gridController.trigger( 'edit:attachment:next', this.model );
     570                },
     571                /**
     572                 * Respond to the keyboard events: right arrow, left arrow, escape.
     573                 */
     574                keyEvent: function( event ) {
     575                        // The right arrow key
     576                        if ( event.keyCode === 39 ) {
     577                                if ( ! this.options.hasNext ) { return; }
     578                                _.once( this.nextMediaItem() );
     579                        }
     580
     581                        // The left arrow key
     582                        if ( event.keyCode === 37 ) {
     583                                if ( ! this.options.hasPrevious ) { return; }
     584                                _.once( this.previousMediaItem() );
     585                        }
     586
     587                        // Pressing the escape key routes back to main url
     588                        if ( event.keyCode === 27 ) {
     589                                this.resetRoute();
     590                                return event;
     591                        }
     592                },
     593
     594                resetRoute: function() {
     595                        wp.media.mediarouter.navigate( wp.media.mediarouter.baseUrl( '' ), { trigger: false, replace: false } );
     596                        return;
    485597                }
    486598
    487599        });