[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/ -> media-grid.js (source)

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


Generated: Fri Apr 23 01:00:05 2021 Cross-referenced by PHPXref 0.7.1