Ticket #24716: 24716.25.diff
File 24716.25.diff, 6.1 KB (added by , 10 years ago) |
---|
-
src/wp-admin/upload.php
24 24 wp_enqueue_media(); 25 25 wp_enqueue_script( 'media-grid' ); 26 26 wp_enqueue_script( 'media' ); 27 wp_localize_script( 'media-grid', 'mediaGridSettings', array( 'adminUrl' => parse_url( self_admin_url(), PHP_URL_PATH ) ) ); 27 28 28 29 require_once( ABSPATH . 'wp-admin/admin-header.php' ); 29 30 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*/ 2 2 (function($, _, Backbone, wp) { 3 3 var media = wp.media, l10n; 4 4 … … 120 120 * @global wp.Uploader 121 121 */ 122 122 initialize: function() { 123 var self = this; 123 124 _.defaults( this.options, { 124 125 title: l10n.mediaLibraryTitle, 125 126 modal: false, … … 168 169 this.createStates(); 169 170 this.bindHandlers(); 170 171 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 ) ); 171 191 }, 172 192 173 193 createSelection: function() { … … 210 230 bindHandlers: function() { 211 231 this.on( 'content:create:browse', this.browseContent, this ); 212 232 this.on( 'content:render:edit-image', this.editImageContent, this ); 233 this.on( 'input #media-search-input', this.search, this ); 213 234 214 235 // Handle a frame-level event for editing an attachment. 215 236 this.on( 'edit:attachment', this.editAttachment, this ); … … 247 268 hasNext = false; 248 269 } 249 270 250 new media.view.Frame.EditAttachment({271 wp.media.editAttachmentFrame = new media.view.Frame.EditAttachment({ 251 272 hasPrevious: hasPrevious, 252 273 hasNext: hasNext, 253 274 model: model, … … 324 345 }); 325 346 326 347 /** 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 /** 327 401 * A frame for editing the details of a specific media item. 328 402 * 329 403 * Opens in a modal by default. … … 340 414 'click': 'collapse', 341 415 'click .delete-media-item': 'deleteMediaItem', 342 416 'click .left': 'previousMediaItem', 343 'click .right': 'nextMediaItem' 344 }, 417 'click .right': 'nextMediaItem', 418 'keydown': 'keyEvent' 419 }, 345 420 346 421 initialize: function() { 347 422 var self = this; … … 373 448 // Completely destroy the modal DOM element when closing it. 374 449 this.modal.close = function() { 375 450 self.modal.remove(); 451 // Reset the browser URL 376 452 }; 377 453 378 454 this.modal.content( this ); 379 455 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 } ); 380 465 } 381 466 }, 382 467 … … 482 567 return; 483 568 this.modal.close(); 484 569 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; 485 597 } 486 598 487 599 });