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


Generated: Thu Sep 23 01:00:04 2021 Cross-referenced by PHPXref 0.7.1