| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /******/ (() => { // webpackBootstrap 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 659 5 (module) { 6 7 var l10n = wp.media.view.l10n, 8 EditAttachmentMetadata; 9 10 /** 11 * wp.media.controller.EditAttachmentMetadata 12 * 13 * A state for editing an attachment's metadata. 14 * 15 * @memberOf wp.media.controller 16 * 17 * @class 18 * @augments wp.media.controller.State 19 * @augments Backbone.Model 20 */ 21 EditAttachmentMetadata = wp.media.controller.State.extend(/** @lends wp.media.controller.EditAttachmentMetadata.prototype */{ 22 defaults: { 23 id: 'edit-attachment', 24 // Title string passed to the frame's title region view. 25 title: l10n.attachmentDetails, 26 // Region mode defaults. 27 content: 'edit-metadata', 28 menu: false, 29 toolbar: false, 30 router: false 31 } 32 }); 33 34 module.exports = EditAttachmentMetadata; 35 36 37 /***/ }, 38 39 /***/ 2429 40 (module) { 41 42 /** 43 * wp.media.view.MediaFrame.Manage.Router 44 * 45 * A router for handling the browser history and application state. 46 * 47 * @memberOf wp.media.view.MediaFrame.Manage 48 * 49 * @class 50 * @augments Backbone.Router 51 */ 52 var Router = Backbone.Router.extend(/** @lends wp.media.view.MediaFrame.Manage.Router.prototype */{ 53 routes: { 54 'upload.php?item=:slug&mode=edit': 'editItem', 55 'upload.php?item=:slug': 'showItem', 56 'upload.php?search=:query': 'search', 57 'upload.php': 'reset' 58 }, 59 60 // Map routes against the page URL. 61 baseUrl: function( url ) { 62 return 'upload.php' + url; 63 }, 64 65 reset: function() { 66 var frame = wp.media.frames.edit; 67 68 if ( frame ) { 69 frame.close(); 70 } 71 }, 72 73 // Respond to the search route by filling the search field and triggering the input event. 74 search: function( query ) { 75 jQuery( '#media-search-input' ).val( query ).trigger( 'input' ); 76 }, 77 78 // Show the modal with a specific item. 79 showItem: function( query ) { 80 var media = wp.media, 81 frame = media.frames.browse, 82 library = frame.state().get('library'), 83 item; 84 85 // Trigger the media frame to open the correct item. 86 item = library.findWhere( { id: parseInt( query, 10 ) } ); 87 88 if ( item ) { 89 item.set( 'skipHistory', true ); 90 frame.trigger( 'edit:attachment', item ); 91 } else { 92 item = media.attachment( query ); 93 frame.listenTo( item, 'change', function( model ) { 94 frame.stopListening( item ); 95 frame.trigger( 'edit:attachment', model ); 96 } ); 97 item.fetch(); 98 } 99 }, 100 101 // Show the modal in edit mode with a specific item. 102 editItem: function( query ) { 103 this.showItem( query ); 104 wp.media.frames.edit.content.mode( 'edit-details' ); 105 } 106 }); 107 108 module.exports = Router; 109 110 111 /***/ }, 112 113 /***/ 1312 114 (module) { 115 116 var Details = wp.media.view.Attachment.Details, 117 TwoColumn; 118 119 /** 120 * wp.media.view.Attachment.Details.TwoColumn 121 * 122 * A similar view to media.view.Attachment.Details 123 * for use in the Edit Attachment modal. 124 * 125 * @memberOf wp.media.view.Attachment.Details 126 * 127 * @class 128 * @augments wp.media.view.Attachment.Details 129 * @augments wp.media.view.Attachment 130 * @augments wp.media.View 131 * @augments wp.Backbone.View 132 * @augments Backbone.View 133 */ 134 TwoColumn = Details.extend(/** @lends wp.media.view.Attachment.Details.TwoColumn.prototype */{ 135 template: wp.template( 'attachment-details-two-column' ), 136 137 initialize: function() { 138 this.controller.on( 'content:activate:edit-details', _.bind( this.editAttachment, this ) ); 139 140 Details.prototype.initialize.apply( this, arguments ); 141 }, 142 143 editAttachment: function( event ) { 144 if ( event ) { 145 event.preventDefault(); 146 } 147 this.controller.content.mode( 'edit-image' ); 148 }, 149 150 /** 151 * Noop this from parent class, doesn't apply here. 152 */ 153 toggleSelectionHandler: function() {} 154 155 }); 156 157 module.exports = TwoColumn; 158 159 160 /***/ }, 161 162 /***/ 5806 163 (module) { 164 165 var Button = wp.media.view.Button, 166 DeleteSelected = wp.media.view.DeleteSelectedButton, 167 DeleteSelectedPermanently; 168 169 /** 170 * wp.media.view.DeleteSelectedPermanentlyButton 171 * 172 * When MEDIA_TRASH is true, a button that handles bulk Delete Permanently logic 173 * 174 * @memberOf wp.media.view 175 * 176 * @class 177 * @augments wp.media.view.DeleteSelectedButton 178 * @augments wp.media.view.Button 179 * @augments wp.media.View 180 * @augments wp.Backbone.View 181 * @augments Backbone.View 182 */ 183 DeleteSelectedPermanently = DeleteSelected.extend(/** @lends wp.media.view.DeleteSelectedPermanentlyButton.prototype */{ 184 initialize: function() { 185 DeleteSelected.prototype.initialize.apply( this, arguments ); 186 this.controller.on( 'select:activate', this.selectActivate, this ); 187 this.controller.on( 'select:deactivate', this.selectDeactivate, this ); 188 }, 189 190 filterChange: function( model ) { 191 this.canShow = ( 'trash' === model.get( 'status' ) ); 192 }, 193 194 selectActivate: function() { 195 this.toggleDisabled(); 196 this.$el.toggleClass( 'hidden', ! this.canShow ); 197 }, 198 199 selectDeactivate: function() { 200 this.toggleDisabled(); 201 this.$el.addClass( 'hidden' ); 202 }, 203 204 render: function() { 205 Button.prototype.render.apply( this, arguments ); 206 this.selectActivate(); 207 return this; 208 } 209 }); 210 211 module.exports = DeleteSelectedPermanently; 212 213 214 /***/ }, 215 216 /***/ 6606 217 (module) { 218 219 var Button = wp.media.view.Button, 220 l10n = wp.media.view.l10n, 221 DeleteSelected; 222 223 /** 224 * wp.media.view.DeleteSelectedButton 225 * 226 * A button that handles bulk Delete/Trash logic 227 * 228 * @memberOf wp.media.view 229 * 230 * @class 231 * @augments wp.media.view.Button 232 * @augments wp.media.View 233 * @augments wp.Backbone.View 234 * @augments Backbone.View 235 */ 236 DeleteSelected = Button.extend(/** @lends wp.media.view.DeleteSelectedButton.prototype */{ 237 initialize: function() { 238 Button.prototype.initialize.apply( this, arguments ); 239 if ( this.options.filters ) { 240 this.options.filters.model.on( 'change', this.filterChange, this ); 241 } 242 this.controller.on( 'selection:toggle', this.toggleDisabled, this ); 243 this.controller.on( 'select:activate', this.toggleDisabled, this ); 244 }, 245 246 filterChange: function( model ) { 247 if ( 'trash' === model.get( 'status' ) ) { 248 this.model.set( 'text', l10n.restoreSelected ); 249 } else if ( wp.media.view.settings.mediaTrash ) { 250 this.model.set( 'text', l10n.trashSelected ); 251 } else { 252 this.model.set( 'text', l10n.deletePermanently ); 253 } 254 }, 255 256 toggleDisabled: function() { 257 this.model.set( 'disabled', ! this.controller.state().get( 'selection' ).length ); 258 }, 259 260 render: function() { 261 // Set size silently before calling base render to avoid nested renders. 262 this.model.set( 'size', '', { silent: true } ); 263 Button.prototype.render.apply( this, arguments ); 264 265 if ( this.controller.isModeActive( 'select' ) ) { 266 this.$el.addClass( 'delete-selected-button' ); 267 } else { 268 this.$el.addClass( 'delete-selected-button hidden' ); 269 } 270 this.toggleDisabled(); 271 return this; 272 } 273 }); 274 275 module.exports = DeleteSelected; 276 277 278 /***/ }, 279 280 /***/ 682 281 (module) { 282 283 284 var Button = wp.media.view.Button, 285 l10n = wp.media.view.l10n, 286 SelectModeToggle; 287 288 /** 289 * wp.media.view.SelectModeToggleButton 290 * 291 * @memberOf wp.media.view 292 * 293 * @class 294 * @augments wp.media.view.Button 295 * @augments wp.media.View 296 * @augments wp.Backbone.View 297 * @augments Backbone.View 298 */ 299 SelectModeToggle = Button.extend(/** @lends wp.media.view.SelectModeToggle.prototype */{ 300 initialize: function() { 301 _.defaults( this.options, { 302 size : '' 303 } ); 304 305 Button.prototype.initialize.apply( this, arguments ); 306 this.controller.on( 'select:activate select:deactivate', this.toggleBulkEditHandler, this ); 307 this.controller.on( 'selection:action:done', this.back, this ); 308 }, 309 310 back: function () { 311 this.controller.deactivateMode( 'select' ).activateMode( 'edit' ); 312 }, 313 314 click: function() { 315 Button.prototype.click.apply( this, arguments ); 316 if ( this.controller.isModeActive( 'select' ) ) { 317 this.back(); 318 } else { 319 this.controller.deactivateMode( 'edit' ).activateMode( 'select' ); 320 } 321 }, 322 323 render: function() { 324 Button.prototype.render.apply( this, arguments ); 325 this.$el.addClass( 'select-mode-toggle-button' ); 326 return this; 327 }, 328 329 toggleBulkEditHandler: function() { 330 var toolbar = this.controller.content.get().toolbar, children; 331 332 children = toolbar.$( '.media-toolbar-secondary > *, .media-toolbar-primary > *' ); 333 334 // @todo The Frame should be doing all of this. 335 if ( this.controller.isModeActive( 'select' ) ) { 336 this.model.set( { 337 size: '', 338 text: l10n.cancel 339 } ); 340 children.not( '.spinner, .media-button' ).hide(); 341 this.$el.show(); 342 toolbar.$el.addClass( 'media-toolbar-mode-select' ); 343 toolbar.$( '.delete-selected-button' ).removeClass( 'hidden' ); 344 } else { 345 this.model.set( { 346 size: '', 347 text: l10n.bulkSelect 348 } ); 349 this.controller.content.get().$el.removeClass( 'fixed' ); 350 toolbar.$el.css( 'width', '' ); 351 toolbar.$el.removeClass( 'media-toolbar-mode-select' ); 352 toolbar.$( '.delete-selected-button' ).addClass( 'hidden' ); 353 children.not( '.media-button' ).show(); 354 this.controller.state().get( 'selection' ).reset(); 355 } 356 } 357 }); 358 359 module.exports = SelectModeToggle; 360 361 362 /***/ }, 363 364 /***/ 8521 365 (module) { 366 367 var View = wp.media.View, 368 EditImage = wp.media.view.EditImage, 369 Details; 370 371 /** 372 * wp.media.view.EditImage.Details 373 * 374 * @memberOf wp.media.view.EditImage 375 * 376 * @class 377 * @augments wp.media.view.EditImage 378 * @augments wp.media.View 379 * @augments wp.Backbone.View 380 * @augments Backbone.View 381 */ 382 Details = EditImage.extend(/** @lends wp.media.view.EditImage.Details.prototype */{ 383 initialize: function( options ) { 384 this.editor = window.imageEdit; 385 this.frame = options.frame; 386 this.controller = options.controller; 387 View.prototype.initialize.apply( this, arguments ); 388 }, 389 390 back: function() { 391 this.frame.content.mode( 'edit-metadata' ); 392 }, 393 394 save: function() { 395 this.model.fetch().done( _.bind( function() { 396 this.frame.content.mode( 'edit-metadata' ); 397 }, this ) ); 398 } 399 }); 400 401 module.exports = Details; 402 403 404 /***/ }, 405 406 /***/ 1003 407 (module) { 408 409 var Frame = wp.media.view.Frame, 410 MediaFrame = wp.media.view.MediaFrame, 411 l10n = wp.media.view.l10n, 412 413 $ = jQuery, 414 EditAttachments; 415 416 /** 417 * wp.media.view.MediaFrame.EditAttachments 418 * 419 * A frame for editing the details of a specific media item. 420 * 421 * Opens in a modal by default. 422 * 423 * Requires an attachment model to be passed in the options hash under `model`. 424 * 425 * @memberOf wp.media.view.MediaFrame 426 * 427 * @class 428 * @augments wp.media.view.Frame 429 * @augments wp.media.View 430 * @augments wp.Backbone.View 431 * @augments Backbone.View 432 * @mixes wp.media.controller.StateMachine 433 */ 434 EditAttachments = MediaFrame.extend(/** @lends wp.media.view.MediaFrame.EditAttachments.prototype */{ 435 436 className: 'edit-attachment-frame', 437 template: wp.template( 'edit-attachment-frame' ), 438 regions: [ 'title', 'content' ], 439 440 events: { 441 'click .left': 'previousMediaItem', 442 'click .right': 'nextMediaItem' 443 }, 444 445 /** 446 * Announces to screen readers the attachment shown after previous/next navigation. 447 * 448 * @since 7.1.0 449 * 450 * @param {Object} model The attachment model. 451 * @return {void} 452 */ 453 announceMediaItemDebounced: _.debounce( function( model ) { 454 var title; 455 456 if ( ! model ) { 457 return; 458 } 459 460 title = model.get( 'title' ) || model.get( 'filename' ) || model.get( 'id' ); 461 462 if ( ! title ) { 463 return; 464 } 465 466 wp.a11y.speak( l10n.mediaItemViewed.replace( '%s', title ) ); 467 }, 500 ), 468 469 initialize: function() { 470 Frame.prototype.initialize.apply( this, arguments ); 471 472 _.defaults( this.options, { 473 modal: true, 474 state: 'edit-attachment' 475 }); 476 477 this.controller = this.options.controller; 478 this.gridRouter = this.controller.gridRouter; 479 this.library = this.options.library; 480 481 if ( this.options.model ) { 482 this.model = this.options.model; 483 } 484 485 this.bindHandlers(); 486 this.createStates(); 487 this.createModal(); 488 489 this.title.mode( 'default' ); 490 this.toggleNav(); 491 }, 492 493 bindHandlers: function() { 494 // Bind default title creation. 495 this.on( 'title:create:default', this.createTitle, this ); 496 497 this.on( 'content:create:edit-metadata', this.editMetadataMode, this ); 498 this.on( 'content:create:edit-image', this.editImageMode, this ); 499 this.on( 'content:render:edit-image', this.editImageModeRender, this ); 500 this.on( 'refresh', this.rerender, this ); 501 this.on( 'close', this.detach ); 502 503 this.bindModelHandlers(); 504 this.listenTo( this.gridRouter, 'route:search', this.close, this ); 505 }, 506 507 bindModelHandlers: function() { 508 // Close the modal if the attachment is deleted. 509 this.listenTo( this.model, 'change:status destroy', this.close, this ); 510 }, 511 512 createModal: function() { 513 // Initialize modal container view. 514 if ( this.options.modal ) { 515 this.modal = new wp.media.view.Modal({ 516 controller: this, 517 title: this.options.title, 518 hasCloseButton: false 519 }); 520 521 this.modal.on( 'open', _.bind( function () { 522 $( 'body' ).on( 'keydown.media-modal', _.bind( this.keyEvent, this ) ); 523 }, this ) ); 524 525 // Completely destroy the modal DOM element when closing it. 526 this.modal.on( 'close', _.bind( function() { 527 // Remove the keydown event. 528 $( 'body' ).off( 'keydown.media-modal' ); 529 // Move focus back to the original item in the grid if possible. 530 $( 'li.attachment[data-id="' + this.model.get( 'id' ) +'"]' ).trigger( 'focus' ); 531 this.resetRoute(); 532 // Cancel any pending navigation announcement. 533 this.announceMediaItemDebounced.cancel(); 534 }, this ) ); 535 536 // Set this frame as the modal's content. 537 this.modal.content( this ); 538 this.modal.open(); 539 } 540 }, 541 542 /** 543 * Add the default states to the frame. 544 */ 545 createStates: function() { 546 this.states.add([ 547 new wp.media.controller.EditAttachmentMetadata({ 548 model: this.model, 549 library: this.library 550 }) 551 ]); 552 }, 553 554 /** 555 * Content region rendering callback for the `edit-metadata` mode. 556 * 557 * @param {Object} contentRegion Basic object with a `view` property, which 558 * should be set with the proper region view. 559 */ 560 editMetadataMode: function( contentRegion ) { 561 contentRegion.view = new wp.media.view.Attachment.Details.TwoColumn({ 562 controller: this, 563 model: this.model 564 }); 565 566 /** 567 * Attach a subview to display fields added via the 568 * `attachment_fields_to_edit` filter. 569 */ 570 contentRegion.view.views.set( '.attachment-compat', new wp.media.view.AttachmentCompat({ 571 controller: this, 572 model: this.model 573 }) ); 574 575 // Update browser url when navigating media details, except on load. 576 if ( this.model && ! this.model.get( 'skipHistory' ) ) { 577 this.gridRouter.navigate( this.gridRouter.baseUrl( '?item=' + this.model.id ) ); 578 } 579 }, 580 581 /** 582 * Render the EditImage view into the frame's content region. 583 * 584 * @param {Object} contentRegion Basic object with a `view` property, which 585 * should be set with the proper region view. 586 */ 587 editImageMode: function( contentRegion ) { 588 var editImageController = new wp.media.controller.EditImage( { 589 model: this.model, 590 frame: this 591 } ); 592 // Noop some methods. 593 editImageController._toolbar = function() {}; 594 editImageController._router = function() {}; 595 editImageController._menu = function() {}; 596 597 contentRegion.view = new wp.media.view.EditImage.Details( { 598 model: this.model, 599 frame: this, 600 controller: editImageController 601 } ); 602 603 this.gridRouter.navigate( this.gridRouter.baseUrl( '?item=' + this.model.id + '&mode=edit' ) ); 604 605 }, 606 607 editImageModeRender: function( view ) { 608 view.on( 'ready', view.loadEditor ); 609 }, 610 611 toggleNav: function() { 612 this.$( '.left' ).prop( 'disabled', ! this.hasPrevious() ); 613 this.$( '.right' ).prop( 'disabled', ! this.hasNext() ); 614 }, 615 616 /** 617 * Rerender the view. 618 * @param {wp.media.model.Attachment} model The attachment model to render. 619 */ 620 rerender: function( model ) { 621 this.stopListening( this.model ); 622 623 this.model = model; 624 625 this.bindModelHandlers(); 626 627 // Only rerender the `content` region. 628 if ( this.content.mode() !== 'edit-metadata' ) { 629 this.content.mode( 'edit-metadata' ); 630 } else { 631 this.content.render(); 632 } 633 634 this.toggleNav(); 635 }, 636 637 /** 638 * Click handler to switch to the previous media item. 639 */ 640 previousMediaItem: function() { 641 var model; 642 643 if ( ! this.hasPrevious() ) { 644 return; 645 } 646 647 model = this.library.at( this.getCurrentIndex() - 1 ); 648 this.trigger( 'refresh', model ); 649 // Move focus to the Previous button. When there are no more items, to the Next button. 650 this.focusNavButton( this.hasPrevious() ? '.left' : '.right' ); 651 this.announceMediaItemDebounced( model ); 652 }, 653 654 /** 655 * Click handler to switch to the next media item. 656 */ 657 nextMediaItem: function() { 658 var model; 659 660 if ( ! this.hasNext() ) { 661 return; 662 } 663 664 model = this.library.at( this.getCurrentIndex() + 1 ); 665 this.trigger( 'refresh', model ); 666 // Move focus to the Next button. When there are no more items, to the Previous button. 667 this.focusNavButton( this.hasNext() ? '.right' : '.left' ); 668 this.announceMediaItemDebounced( model ); 669 }, 670 671 /** 672 * Set focus to the navigation buttons depending on the browsing direction. 673 * 674 * @since 5.3.0 675 * 676 * @param {string} which A CSS selector to target the button to focus. 677 */ 678 focusNavButton: function( which ) { 679 $( which ).trigger( 'focus' ); 680 }, 681 682 getCurrentIndex: function() { 683 return this.library.indexOf( this.model ); 684 }, 685 686 hasNext: function() { 687 return ( this.getCurrentIndex() + 1 ) < this.library.length; 688 }, 689 690 hasPrevious: function() { 691 return ( this.getCurrentIndex() - 1 ) > -1; 692 }, 693 /** 694 * Respond to the keyboard events: Alt + right arrow, Alt + left arrow, 695 * except when focus is in a form field. Requires the Alt modifier key to 696 * avoid interfering with screen reader navigation. 697 * 698 * @param {Event} event The keyboard event. 699 */ 700 keyEvent: function( event ) { 701 if ( ( 'INPUT' === event.target.nodeName || 'TEXTAREA' === event.target.nodeName || 'SELECT' === event.target.nodeName ) && ! event.target.disabled ) { 702 return; 703 } 704 705 // Arrow key navigation requires Alt key to avoid interfering with screen reader navigation. 706 if ( ! event.altKey ) { 707 return; 708 } 709 710 // Alt + right arrow key. 711 if ( 39 === event.keyCode ) { 712 event.preventDefault(); 713 this.nextMediaItem(); 714 } 715 // Alt + left arrow key. 716 if ( 37 === event.keyCode ) { 717 event.preventDefault(); 718 this.previousMediaItem(); 719 } 720 }, 721 722 resetRoute: function() { 723 var searchTerm = this.controller.browserView.toolbar.get( 'search' ).$el.val(), 724 url = '' !== searchTerm ? '?search=' + searchTerm : ''; 725 this.gridRouter.navigate( this.gridRouter.baseUrl( url ), { replace: true } ); 726 } 727 }); 728 729 module.exports = EditAttachments; 730 731 732 /***/ }, 733 734 /***/ 8359 735 (module) { 736 737 var MediaFrame = wp.media.view.MediaFrame, 738 Library = wp.media.controller.Library, 739 740 $ = Backbone.$, 741 Manage; 742 743 /** 744 * wp.media.view.MediaFrame.Manage 745 * 746 * A generic management frame workflow. 747 * 748 * Used in the media grid view. 749 * 750 * @memberOf wp.media.view.MediaFrame 751 * 752 * @class 753 * @augments wp.media.view.MediaFrame 754 * @augments wp.media.view.Frame 755 * @augments wp.media.View 756 * @augments wp.Backbone.View 757 * @augments Backbone.View 758 * @mixes wp.media.controller.StateMachine 759 */ 760 Manage = MediaFrame.extend(/** @lends wp.media.view.MediaFrame.Manage.prototype */{ 761 /** 762 * Initializes the manage frame. 763 * 764 * @constructs 765 */ 766 initialize: function() { 767 _.defaults( this.options, { 768 title: '', 769 modal: false, 770 selection: [], 771 library: {}, // Options hash for the query to the media library. 772 multiple: 'add', 773 state: 'library', 774 uploader: true, 775 mode: [ 'grid', 'edit' ] 776 }); 777 778 this.$body = $( document.body ); 779 this.$window = $( window ); 780 this.$adminBar = $( '#wpadminbar' ); 781 // Store the Add New button for later reuse in wp.media.view.UploaderInline. 782 this.$uploaderToggler = $( '.page-title-action' ) 783 .attr( 'aria-expanded', 'false' ) 784 .on( 'click', _.bind( this.addNewClickHandler, this ) ); 785 786 this.$window.on( 'scroll resize', _.debounce( _.bind( this.fixPosition, this ), 15 ) ); 787 788 // Ensure core and media grid view UI is enabled. 789 this.$el.addClass('wp-core-ui'); 790 791 // Force the uploader off if the upload limit has been exceeded or 792 // if the browser isn't supported. 793 if ( wp.Uploader.limitExceeded || ! wp.Uploader.browser.supported ) { 794 this.options.uploader = false; 795 } 796 797 // Initialize a window-wide uploader. 798 if ( this.options.uploader ) { 799 this.uploader = new wp.media.view.UploaderWindow({ 800 controller: this, 801 uploader: { 802 dropzone: document.body, 803 container: document.body 804 } 805 }).render(); 806 this.uploader.ready(); 807 $('body').append( this.uploader.el ); 808 809 this.options.uploader = false; 810 } 811 812 this.gridRouter = new wp.media.view.MediaFrame.Manage.Router(); 813 814 // Call 'initialize' directly on the parent class. 815 MediaFrame.prototype.initialize.apply( this, arguments ); 816 817 // Append the frame view directly the supplied container. 818 this.$el.appendTo( this.options.container ); 819 820 this.createStates(); 821 this.bindRegionModeHandlers(); 822 this.render(); 823 this.bindSearchHandler(); 824 825 wp.media.frames.browse = this; 826 }, 827 828 /** 829 * Binds the search input to the grid router. 830 */ 831 bindSearchHandler: function() { 832 var search = this.$( '#media-search-input' ), 833 searchView = this.browserView.toolbar.get( 'search' ).$el, 834 listMode = this.$( '.view-list' ), 835 836 input = _.throttle( function (e) { 837 var val = $( e.currentTarget ).val(), 838 url = ''; 839 840 if ( val ) { 841 url += '?search=' + val; 842 } 843 844 this.gridRouter.navigate( this.gridRouter.baseUrl( url ), { replace: true } ); 845 }, 1000 ); 846 847 // Update the URL when entering search string (at most once per second). 848 search.on( 'input', _.bind( input, this ) ); 849 850 this.gridRouter 851 .on( 'route:search', function () { 852 var href = window.location.href; 853 if ( href.indexOf( 'mode=' ) > -1 ) { 854 href = href.replace( /mode=[^&]+/g, 'mode=list' ); 855 } else { 856 href += href.indexOf( '?' ) > -1 ? '&mode=list' : '?mode=list'; 857 } 858 href = href.replace( 'search=', 's=' ); 859 listMode.prop( 'href', href ); 860 }) 861 .on( 'route:reset', function() { 862 searchView.val( '' ).trigger( 'input' ); 863 }); 864 }, 865 866 /** 867 * Creates the default states for the frame. 868 */ 869 createStates: function() { 870 var options = this.options; 871 872 if ( this.options.states ) { 873 return; 874 } 875 876 // Add the default states. 877 this.states.add([ 878 new Library({ 879 library: wp.media.query( options.library ), 880 multiple: options.multiple, 881 title: options.title, 882 content: 'browse', 883 toolbar: 'select', 884 contentUserSetting: false, 885 filterable: 'all', 886 autoSelect: false 887 }) 888 ]); 889 }, 890 891 /** 892 * Binds region mode activation events to proper handlers. 893 */ 894 bindRegionModeHandlers: function() { 895 this.on( 'content:create:browse', this.browseContent, this ); 896 897 // Handle a frame-level event for editing an attachment. 898 this.on( 'edit:attachment', this.openEditAttachmentModal, this ); 899 900 this.on( 'select:activate', this.bindKeydown, this ); 901 this.on( 'select:deactivate', this.unbindKeydown, this ); 902 }, 903 904 /** 905 * Handles keydown events for the frame. 906 * 907 * @param {JQuery.Event} e The keydown event. 908 */ 909 handleKeydown: function( e ) { 910 if ( 27 === e.which ) { 911 e.preventDefault(); 912 this.deactivateMode( 'select' ).activateMode( 'edit' ); 913 } 914 }, 915 916 /** 917 * Binds the keydown event for the frame. 918 */ 919 bindKeydown: function() { 920 this.$body.on( 'keydown.select', _.bind( this.handleKeydown, this ) ); 921 }, 922 923 /** 924 * Unbinds the keydown event for the frame. 925 */ 926 unbindKeydown: function() { 927 this.$body.off( 'keydown.select' ); 928 }, 929 930 /** 931 * Fixes the position of the attachments browser when scrolling the page. 932 */ 933 fixPosition: function() { 934 var $browser, $toolbar; 935 if ( ! this.isModeActive( 'select' ) ) { 936 return; 937 } 938 939 $browser = this.$('.attachments-browser'); 940 $toolbar = $browser.find('.media-toolbar'); 941 942 // Offset doesn't appear to take top margin into account, hence +16. 943 if ( ( $browser.offset().top + 16 ) < this.$window.scrollTop() + this.$adminBar.height() ) { 944 $browser.addClass( 'fixed' ); 945 $toolbar.css('width', $browser.width() + 'px'); 946 } else { 947 $browser.removeClass( 'fixed' ); 948 $toolbar.css('width', ''); 949 } 950 }, 951 952 /** 953 * Click handler for the `Add New` button. 954 * 955 * @param {Event} event The click event. 956 */ 957 addNewClickHandler: function( event ) { 958 event.preventDefault(); 959 this.trigger( 'toggle:upload:attachment' ); 960 961 if ( this.uploader ) { 962 this.uploader.refresh(); 963 } 964 }, 965 966 /** 967 * Opens the Edit Attachment modal. 968 * 969 * @param {wp.media.model.Attachment} model The attachment model to edit. 970 */ 971 openEditAttachmentModal: function( model ) { 972 // Create a new EditAttachment frame, passing along the library and the attachment model. 973 if ( wp.media.frames.edit ) { 974 wp.media.frames.edit.open().trigger( 'refresh', model ); 975 } else { 976 wp.media.frames.edit = wp.media( { 977 frame: 'edit-attachments', 978 controller: this, 979 library: this.state().get('library'), 980 model: model 981 } ); 982 } 983 }, 984 985 /** 986 * Creates an attachments browser view within the content region. 987 * 988 * @param {Object} contentRegion Basic object with a `view` property, which 989 * should be set with the proper region view. 990 * @this wp.media.controller.Region 991 */ 992 browseContent: function( contentRegion ) { 993 var state = this.state(); 994 995 // Browse our library of attachments. 996 this.browserView = contentRegion.view = new wp.media.view.AttachmentsBrowser({ 997 controller: this, 998 collection: state.get('library'), 999 selection: state.get('selection'), 1000 model: state, 1001 sortable: state.get('sortable'), 1002 search: state.get('searchable'), 1003 filters: state.get('filterable'), 1004 date: state.get('date'), 1005 display: state.get('displaySettings'), 1006 dragInfo: state.get('dragInfo'), 1007 sidebar: 'errors', 1008 1009 suggestedWidth: state.get('suggestedWidth'), 1010 suggestedHeight: state.get('suggestedHeight'), 1011 1012 AttachmentView: state.get('AttachmentView'), 1013 1014 scrollElement: document 1015 }); 1016 this.browserView.on( 'ready', _.bind( this.bindDeferred, this ) ); 1017 1018 this.errors = wp.Uploader.errors; 1019 this.errors.on( 'add remove reset', this.sidebarVisibility, this ); 1020 }, 1021 1022 /** 1023 * Handles the visibility of the sidebar 1024 */ 1025 sidebarVisibility: function() { 1026 this.browserView.$( '.media-sidebar' ).toggle( !! this.errors.length ); 1027 }, 1028 1029 /** 1030 * Binds the deferred object of the browser view to the startHistory method. 1031 */ 1032 bindDeferred: function() { 1033 if ( ! this.browserView.dfd ) { 1034 return; 1035 } 1036 this.browserView.dfd.done( _.bind( this.startHistory, this ) ); 1037 }, 1038 1039 /** 1040 * Starts the history for the frame, if supported. 1041 */ 1042 startHistory: function() { 1043 // Verify pushState support and activate. 1044 if ( window.history && window.history.pushState ) { 1045 if ( Backbone.History.started ) { 1046 Backbone.history.stop(); 1047 } 1048 Backbone.history.start( { 1049 root: window._wpMediaGridSettings.adminUrl, 1050 pushState: true 1051 } ); 1052 } 1053 } 1054 }); 1055 1056 module.exports = Manage; 1057 1058 1059 /***/ } 1060 1061 /******/ }); 1062 /************************************************************************/ 1063 /******/ // The module cache 1064 /******/ const __webpack_module_cache__ = {}; 1065 /******/ 1066 /******/ // The require function 1067 /******/ function __webpack_require__(moduleId) { 1068 /******/ // Check if module is in cache 1069 /******/ const cachedModule = __webpack_module_cache__[moduleId]; 1070 /******/ if (cachedModule !== undefined) { 1071 /******/ return cachedModule.exports; 1072 /******/ } 1073 /******/ // Create a new module (and put it into the cache) 1074 /******/ const module = __webpack_module_cache__[moduleId] = { 1075 /******/ // no module.id needed 1076 /******/ // no module.loaded needed 1077 /******/ exports: {} 1078 /******/ }; 1079 /******/ 1080 /******/ // Execute the module function 1081 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 1082 /******/ 1083 /******/ // Return the exports of the module 1084 /******/ return module.exports; 1085 /******/ } 1086 /******/ 1087 /************************************************************************/ 1088 /** 1089 * @output wp-includes/js/media-grid.js 1090 */ 1091 1092 var media = wp.media; 1093 1094 media.controller.EditAttachmentMetadata = __webpack_require__( 659 ); 1095 media.view.MediaFrame.Manage = __webpack_require__( 8359 ); 1096 media.view.Attachment.Details.TwoColumn = __webpack_require__( 1312 ); 1097 media.view.MediaFrame.Manage.Router = __webpack_require__( 2429 ); 1098 media.view.EditImage.Details = __webpack_require__( 8521 ); 1099 media.view.MediaFrame.EditAttachments = __webpack_require__( 1003 ); 1100 media.view.SelectModeToggleButton = __webpack_require__( 682 ); 1101 media.view.DeleteSelectedButton = __webpack_require__( 6606 ); 1102 media.view.DeleteSelectedPermanentlyButton = __webpack_require__( 5806 ); 1103 1104 /******/ })() 1105 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Tue Sep 8 08:20:28 2026 | Cross-referenced by PHPXref |