Ticket #24716: 24716.38.diff
File 24716.38.diff, 7.5 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 … … 91 91 * @global wp.Uploader 92 92 */ 93 93 initialize: function() { 94 var self = this; 94 95 _.defaults( this.options, { 95 96 title: l10n.mediaLibraryTitle, 96 97 modal: false, … … 140 141 this.createStates(); 141 142 this.bindHandlers(); 142 143 this.render(); 144 145 // Set up the Backbone router after a brief delay 146 _.delay( function(){ 147 wp.media.mediarouter = new media.view.Frame.Router( self ); 148 // Verify pushState support and activate 149 if ( window.history && window.history.pushState ) { 150 Backbone.history.start({ 151 root: mediaGridSettings.adminUrl, 152 pushState: true 153 }); 154 } 155 }, 250); 156 157 // Update the URL when entering search string (at most once per second) 158 $( '#media-search-input' ).on( 'input', _.debounce( function() { 159 var $val = $( this ).val(); 160 wp.media.mediarouter.navigate( wp.media.mediarouter.baseUrl( ( '' == $val ) ? '' : ( '?search=' + $val ) ) ); 161 }, 1000 ) ); 143 162 }, 144 163 145 164 createSelection: function() { … … 218 237 * Open the Edit Attachment modal. 219 238 */ 220 239 editAttachment: function( model ) { 221 var library = this.state().get('library'); 240 var self = this, 241 library = this.state().get('library'); 222 242 223 243 // Create a new EditAttachment frame, passing along the library and the attachment model. 224 this.editAttachmentFrame = new media.view.Frame.EditAttachment ({244 this.editAttachmentFrame = new media.view.Frame.EditAttachments({ 225 245 library: library, 226 246 model: model 227 247 }); … … 229 249 // Listen to events on the edit attachment frame for triggering pagination callback handlers. 230 250 this.listenTo( this.editAttachmentFrame, 'edit:attachment:next', this.editNextAttachment ); 231 251 this.listenTo( this.editAttachmentFrame, 'edit:attachment:previous', this.editPreviousAttachment ); 252 // Listen to keyboard events on the modal 253 $( 'body' ).on( 'keydown.media-modal', function( e ) { 254 self.editAttachmentFrame.keyEvent( e ); 255 } ); 232 256 }, 233 257 234 258 /** … … 300 324 }); 301 325 302 326 /** 327 * A router for handling the browser history and application state 328 */ 329 media.view.Frame.Router = Backbone.Router.extend({ 330 331 mediaFrame: '', 332 333 initialize: function( mediaFrame ){ 334 this.mediaFrame = mediaFrame; 335 }, 336 337 routes: { 338 'upload.php?item=:slug': 'showitem', 339 'upload.php?search=:query': 'search', 340 ':default': 'defaultRoute' 341 }, 342 343 // Map routes against the page URL 344 baseUrl: function( url ) { 345 return 'upload.php' + url; 346 }, 347 348 // Respond to the search route by filling the search field and trigggering the input event 349 search: function( query ) { 350 // Ensure modal closed, see back button 351 this.closeModal(); 352 $( '#media-search-input' ).val( query ).trigger( 'input' ); 353 }, 354 355 // Show the modal with a specific item 356 showitem: function( query ) { 357 var library = this.mediaFrame.state().get('library'); 358 359 // Remove existing modal if present 360 this.closeModal(); 361 // Trigger the media frame to open the correct item 362 this.mediaFrame.trigger( 'edit:attachment', library.findWhere( { id: parseInt( query, 10 ) } ) ); 363 }, 364 365 // Close the modal if set up 366 closeModal: function() { 367 if ( 'undefined' !== typeof this.mediaFrame.editAttachmentFrame ) { 368 this.mediaFrame.editAttachmentFrame.modal.close(); 369 } 370 }, 371 372 // Default route: make sure the modal and search are reset 373 defaultRoute: function() { 374 this.closeModal(); 375 $( '#media-search-input' ).val( '' ).trigger( 'input' ); 376 } 377 }); 378 379 /** 303 380 * A frame for editing the details of a specific media item. 304 381 * 305 382 * Opens in a modal by default. … … 306 383 * 307 384 * Requires an attachment model to be passed in the options hash under `model`. 308 385 */ 309 media.view.Frame.EditAttachment = media.view.Frame.extend({386 media.view.Frame.EditAttachments = media.view.Frame.extend({ 310 387 311 388 className: 'edit-attachment-frame', 312 389 template: media.template( 'edit-attachment-frame' ), … … 328 405 state: 'edit-attachment' 329 406 }); 330 407 408 this.library = this.options.library; 409 if ( this.options.model ) { 410 this.model = this.options.model; 411 } else { 412 this.model = this.library.at( 0 ); 413 } 414 331 415 this.createStates(); 332 416 333 417 this.on( 'content:render:edit-metadata', this.editMetadataContent, this ); … … 334 418 this.on( 'content:render:edit-image', this.editImageContentUgh, this ); 335 419 336 420 // Only need a tab to Edit Image for images. 337 if ( this.model.get( 'type' ) === 'image' ) {421 if ( 'undefined' !== typeof this.model && this.model.get( 'type' ) === 'image' ) { 338 422 this.on( 'router:create', this.createRouter, this ); 339 423 this.on( 'router:render', this.browseRouter, this ); 340 424 } … … 352 436 // Completely destroy the modal DOM element when closing it. 353 437 this.modal.close = function() { 354 438 self.modal.remove(); 439 $( 'body' ).off( 'keydown.media-modal' ); /* remove the keydown event */ 440 // Reset the browser URL 441 self.resetRoute(); 355 442 }; 356 443 357 444 this.modal.content( this ); … … 391 478 model: this.model 392 479 }); 393 480 this.content.set( view ); 481 // Update browser url when navigating media details 482 wp.media.mediarouter.navigate( wp.media.mediarouter.baseUrl( '?item=' + this.model.id ) ); 394 483 }, 395 484 396 485 /** … … 461 550 return; 462 551 this.modal.close(); 463 552 this.trigger( 'edit:attachment:next', this.model ); 553 }, 554 555 getCurrentIndex: function() { 556 return this.library.indexOf( this.model ); 557 }, 558 559 hasNext: function() { 560 return ( this.getCurrentIndex() + 1 ) < this.library.length; 561 }, 562 563 hasPrevious: function() { 564 return ( this.getCurrentIndex() - 1 ) > -1; 565 }, 566 /** 567 * Respond to the keyboard events: right arrow, left arrow, escape. 568 */ 569 keyEvent: function( event ) { 570 var $target = $( event.target ); 571 // Pressing the escape key routes back to main url 572 if ( event.keyCode === 27 ) { 573 this.resetRoute(); 574 return event; 575 } 576 //Don't go left/right if we are in a textarea or input field 577 if ( $target.is( 'input' ) || $target.is( 'textarea' ) ) { 578 return event; 579 } 580 // The right arrow key 581 if ( event.keyCode === 39 ) { 582 if ( ! this.hasNext ) { return; } 583 _.debounce( this.nextMediaItem(), 250 ); 584 } 585 // The left arrow key 586 if ( event.keyCode === 37 ) { 587 if ( ! this.hasPrevious ) { return; } 588 _.debounce( this.previousMediaItem(), 250 ); 589 } 590 }, 591 592 resetRoute: function() { 593 wp.media.mediarouter.navigate( wp.media.mediarouter.baseUrl( '' ) ); 594 return; 464 595 } 465 596 }); 466 597