From f9fd563ec7237ba5da473c2e5bd2188690e0a4f3 Mon Sep 17 00:00:00 2001 From: Scott Taylor Date: Sat, 9 May 2015 05:41:01 +0000 Subject: [PATCH] Media Grid: clean up our flawed `Backbone.Router` implementation so that the browser forward/back buttons work the same way as the left/right keys when the Edit Attachment frame is open. Fixes #31846. git-svn-id: https://develop.svn.wordpress.org/trunk@32466 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/js/media-grid.js | 62 ++++++++++++++----- src/wp-includes/js/media/routers/manage.js | 39 +++++++++--- .../js/media/views/frame/manage.js | 23 +++++-- 3 files changed, 94 insertions(+), 30 deletions(-) diff --git a/src/wp-includes/js/media-grid.js b/src/wp-includes/js/media-grid.js index 6c8faa5a82..7dbc8f92c3 100644 --- a/src/wp-includes/js/media-grid.js +++ b/src/wp-includes/js/media-grid.js @@ -55,9 +55,29 @@ media.view.DeleteSelectedPermanentlyButton = require( './views/button/delete-sel * @augments Backbone.Router */ var Router = Backbone.Router.extend({ + initialize: function ( options ) { + this.controller = options.controller; + this.library = options.library; + this.on( 'route', this.checkRoute ); + }, + routes: { 'upload.php?item=:slug': 'showItem', - 'upload.php?search=:query': 'search' + 'upload.php?search=:query': 'search', + 'upload.php': 'defaultRoute' + }, + + checkRoute: function ( event ) { + if ( 'defaultRoute' !== event ) { + this.modal = true; + } + }, + + defaultRoute: function () { + if ( this.modal ) { + wp.media.frame.close(); + this.modal = false; + } }, // Map routes against the page URL @@ -72,19 +92,18 @@ var Router = Backbone.Router.extend({ // Show the modal with a specific item showItem: function( query ) { - var media = wp.media, - library = media.frame.state().get('library'), + var frame = this.controller, item; - + // Trigger the media frame to open the correct item - item = library.findWhere( { id: parseInt( query, 10 ) } ); + item = this.library.findWhere( { id: parseInt( query, 10 ) } ); if ( item ) { - media.frame.trigger( 'edit:attachment', item ); + frame.trigger( 'edit:attachment', item ); } else { - item = media.attachment( query ); - media.frame.listenTo( item, 'change', function( model ) { - media.frame.stopListening( item ); - media.frame.trigger( 'edit:attachment', model ); + item = wp.media.attachment( query ); + frame.listenTo( item, 'change', function( model ) { + frame.stopListening( item ); + frame.trigger( 'edit:attachment', model ); } ); item.fetch(); } @@ -655,25 +674,36 @@ Manage = MediaFrame.extend({ } }).render(); this.uploader.ready(); - $('body').append( this.uploader.el ); + this.$body.append( this.uploader.el ); this.options.uploader = false; } - this.gridRouter = new wp.media.view.MediaFrame.Manage.Router(); - // Call 'initialize' directly on the parent class. MediaFrame.prototype.initialize.apply( this, arguments ); // Append the frame view directly the supplied container. this.$el.appendTo( this.options.container ); + this.setLibrary( this.options ); + this.setRouter(); this.createStates(); this.bindRegionModeHandlers(); this.render(); this.bindSearchHandler(); }, + setLibrary: function ( options ) { + this.library = wp.media.query( options.library ); + }, + + setRouter: function () { + this.gridRouter = new wp.media.view.MediaFrame.Manage.Router({ + controller: this, + library: this.library + }); + }, + bindSearchHandler: function() { var search = this.$( '#media-search-input' ), currentSearch = this.options.container.data( 'search' ), @@ -692,7 +722,9 @@ Manage = MediaFrame.extend({ // Update the URL when entering search string (at most once per second) search.on( 'input', _.bind( input, this ) ); - searchView.val( currentSearch ).trigger( 'input' ); + if ( currentSearch ) { + searchView.val( currentSearch ).trigger( 'input' ); + } this.gridRouter.on( 'route:search', function () { var href = window.location.href; @@ -719,7 +751,7 @@ Manage = MediaFrame.extend({ // Add the default states. this.states.add([ new Library({ - library: wp.media.query( options.library ), + library: this.library, multiple: options.multiple, title: options.title, content: 'browse', diff --git a/src/wp-includes/js/media/routers/manage.js b/src/wp-includes/js/media/routers/manage.js index 61b784a2c8..3a008eac50 100644 --- a/src/wp-includes/js/media/routers/manage.js +++ b/src/wp-includes/js/media/routers/manage.js @@ -9,9 +9,29 @@ * @augments Backbone.Router */ var Router = Backbone.Router.extend({ + initialize: function ( options ) { + this.controller = options.controller; + this.library = options.library; + this.on( 'route', this.checkRoute ); + }, + routes: { 'upload.php?item=:slug': 'showItem', - 'upload.php?search=:query': 'search' + 'upload.php?search=:query': 'search', + 'upload.php': 'defaultRoute' + }, + + checkRoute: function ( event ) { + if ( 'defaultRoute' !== event ) { + this.modal = true; + } + }, + + defaultRoute: function () { + if ( this.modal ) { + wp.media.frame.close(); + this.modal = false; + } }, // Map routes against the page URL @@ -26,19 +46,18 @@ var Router = Backbone.Router.extend({ // Show the modal with a specific item showItem: function( query ) { - var media = wp.media, - library = media.frame.state().get('library'), + var frame = this.controller, item; - + // Trigger the media frame to open the correct item - item = library.findWhere( { id: parseInt( query, 10 ) } ); + item = this.library.findWhere( { id: parseInt( query, 10 ) } ); if ( item ) { - media.frame.trigger( 'edit:attachment', item ); + frame.trigger( 'edit:attachment', item ); } else { - item = media.attachment( query ); - media.frame.listenTo( item, 'change', function( model ) { - media.frame.stopListening( item ); - media.frame.trigger( 'edit:attachment', model ); + item = wp.media.attachment( query ); + frame.listenTo( item, 'change', function( model ) { + frame.stopListening( item ); + frame.trigger( 'edit:attachment', model ); } ); item.fetch(); } diff --git a/src/wp-includes/js/media/views/frame/manage.js b/src/wp-includes/js/media/views/frame/manage.js index 330c877468..9a9dd18fae 100644 --- a/src/wp-includes/js/media/views/frame/manage.js +++ b/src/wp-includes/js/media/views/frame/manage.js @@ -62,25 +62,36 @@ Manage = MediaFrame.extend({ } }).render(); this.uploader.ready(); - $('body').append( this.uploader.el ); + this.$body.append( this.uploader.el ); this.options.uploader = false; } - this.gridRouter = new wp.media.view.MediaFrame.Manage.Router(); - // Call 'initialize' directly on the parent class. MediaFrame.prototype.initialize.apply( this, arguments ); // Append the frame view directly the supplied container. this.$el.appendTo( this.options.container ); + this.setLibrary( this.options ); + this.setRouter(); this.createStates(); this.bindRegionModeHandlers(); this.render(); this.bindSearchHandler(); }, + setLibrary: function ( options ) { + this.library = wp.media.query( options.library ); + }, + + setRouter: function () { + this.gridRouter = new wp.media.view.MediaFrame.Manage.Router({ + controller: this, + library: this.library + }); + }, + bindSearchHandler: function() { var search = this.$( '#media-search-input' ), currentSearch = this.options.container.data( 'search' ), @@ -99,7 +110,9 @@ Manage = MediaFrame.extend({ // Update the URL when entering search string (at most once per second) search.on( 'input', _.bind( input, this ) ); - searchView.val( currentSearch ).trigger( 'input' ); + if ( currentSearch ) { + searchView.val( currentSearch ).trigger( 'input' ); + } this.gridRouter.on( 'route:search', function () { var href = window.location.href; @@ -126,7 +139,7 @@ Manage = MediaFrame.extend({ // Add the default states. this.states.add([ new Library({ - library: wp.media.query( options.library ), + library: this.library, multiple: options.multiple, title: options.title, content: 'browse',