[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 /******/ (function() { // webpackBootstrap 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 7727: 5 /***/ (function(module) { 6 7 var $ = Backbone.$, 8 Attachment; 9 10 /** 11 * wp.media.model.Attachment 12 * 13 * @memberOf wp.media.model 14 * 15 * @class 16 * @augments Backbone.Model 17 */ 18 Attachment = Backbone.Model.extend(/** @lends wp.media.model.Attachment.prototype */{ 19 /** 20 * Triggered when attachment details change 21 * Overrides Backbone.Model.sync 22 * 23 * @param {string} method 24 * @param {wp.media.model.Attachment} model 25 * @param {Object} [options={}] 26 * 27 * @return {Promise} 28 */ 29 sync: function( method, model, options ) { 30 // If the attachment does not yet have an `id`, return an instantly 31 // rejected promise. Otherwise, all of our requests will fail. 32 if ( _.isUndefined( this.id ) ) { 33 return $.Deferred().rejectWith( this ).promise(); 34 } 35 36 // Overload the `read` request so Attachment.fetch() functions correctly. 37 if ( 'read' === method ) { 38 options = options || {}; 39 options.context = this; 40 options.data = _.extend( options.data || {}, { 41 action: 'get-attachment', 42 id: this.id 43 }); 44 return wp.media.ajax( options ); 45 46 // Overload the `update` request so properties can be saved. 47 } else if ( 'update' === method ) { 48 // If we do not have the necessary nonce, fail immediately. 49 if ( ! this.get('nonces') || ! this.get('nonces').update ) { 50 return $.Deferred().rejectWith( this ).promise(); 51 } 52 53 options = options || {}; 54 options.context = this; 55 56 // Set the action and ID. 57 options.data = _.extend( options.data || {}, { 58 action: 'save-attachment', 59 id: this.id, 60 nonce: this.get('nonces').update, 61 post_id: wp.media.model.settings.post.id 62 }); 63 64 // Record the values of the changed attributes. 65 if ( model.hasChanged() ) { 66 options.data.changes = {}; 67 68 _.each( model.changed, function( value, key ) { 69 options.data.changes[ key ] = this.get( key ); 70 }, this ); 71 } 72 73 return wp.media.ajax( options ); 74 75 // Overload the `delete` request so attachments can be removed. 76 // This will permanently delete an attachment. 77 } else if ( 'delete' === method ) { 78 options = options || {}; 79 80 if ( ! options.wait ) { 81 this.destroyed = true; 82 } 83 84 options.context = this; 85 options.data = _.extend( options.data || {}, { 86 action: 'delete-post', 87 id: this.id, 88 _wpnonce: this.get('nonces')['delete'] 89 }); 90 91 return wp.media.ajax( options ).done( function() { 92 this.destroyed = true; 93 }).fail( function() { 94 this.destroyed = false; 95 }); 96 97 // Otherwise, fall back to `Backbone.sync()`. 98 } else { 99 /** 100 * Call `sync` directly on Backbone.Model 101 */ 102 return Backbone.Model.prototype.sync.apply( this, arguments ); 103 } 104 }, 105 /** 106 * Convert date strings into Date objects. 107 * 108 * @param {Object} resp The raw response object, typically returned by fetch() 109 * @return {Object} The modified response object, which is the attributes hash 110 * to be set on the model. 111 */ 112 parse: function( resp ) { 113 if ( ! resp ) { 114 return resp; 115 } 116 117 resp.date = new Date( resp.date ); 118 resp.modified = new Date( resp.modified ); 119 return resp; 120 }, 121 /** 122 * @param {Object} data The properties to be saved. 123 * @param {Object} options Sync options. e.g. patch, wait, success, error. 124 * 125 * @this Backbone.Model 126 * 127 * @return {Promise} 128 */ 129 saveCompat: function( data, options ) { 130 var model = this; 131 132 // If we do not have the necessary nonce, fail immediately. 133 if ( ! this.get('nonces') || ! this.get('nonces').update ) { 134 return $.Deferred().rejectWith( this ).promise(); 135 } 136 137 return wp.media.post( 'save-attachment-compat', _.defaults({ 138 id: this.id, 139 nonce: this.get('nonces').update, 140 post_id: wp.media.model.settings.post.id 141 }, data ) ).done( function( resp, status, xhr ) { 142 model.set( model.parse( resp, xhr ), options ); 143 }); 144 } 145 },/** @lends wp.media.model.Attachment */{ 146 /** 147 * Create a new model on the static 'all' attachments collection and return it. 148 * 149 * @static 150 * 151 * @param {Object} attrs 152 * @return {wp.media.model.Attachment} 153 */ 154 create: function( attrs ) { 155 var Attachments = wp.media.model.Attachments; 156 return Attachments.all.push( attrs ); 157 }, 158 /** 159 * Create a new model on the static 'all' attachments collection and return it. 160 * 161 * If this function has already been called for the id, 162 * it returns the specified attachment. 163 * 164 * @static 165 * @param {string} id A string used to identify a model. 166 * @param {Backbone.Model|undefined} attachment 167 * @return {wp.media.model.Attachment} 168 */ 169 get: _.memoize( function( id, attachment ) { 170 var Attachments = wp.media.model.Attachments; 171 return Attachments.all.push( attachment || { id: id } ); 172 }) 173 }); 174 175 module.exports = Attachment; 176 177 178 /***/ }), 179 180 /***/ 6940: 181 /***/ (function(module) { 182 183 /** 184 * wp.media.model.Attachments 185 * 186 * A collection of attachments. 187 * 188 * This collection has no persistence with the server without supplying 189 * 'options.props.query = true', which will mirror the collection 190 * to an Attachments Query collection - @see wp.media.model.Attachments.mirror(). 191 * 192 * @memberOf wp.media.model 193 * 194 * @class 195 * @augments Backbone.Collection 196 * 197 * @param {array} [models] Models to initialize with the collection. 198 * @param {object} [options] Options hash for the collection. 199 * @param {string} [options.props] Options hash for the initial query properties. 200 * @param {string} [options.props.order] Initial order (ASC or DESC) for the collection. 201 * @param {string} [options.props.orderby] Initial attribute key to order the collection by. 202 * @param {string} [options.props.query] Whether the collection is linked to an attachments query. 203 * @param {string} [options.observe] 204 * @param {string} [options.filters] 205 * 206 */ 207 var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachments.prototype */{ 208 /** 209 * @type {wp.media.model.Attachment} 210 */ 211 model: wp.media.model.Attachment, 212 /** 213 * @param {Array} [models=[]] Array of models used to populate the collection. 214 * @param {Object} [options={}] 215 */ 216 initialize: function( models, options ) { 217 options = options || {}; 218 219 this.props = new Backbone.Model(); 220 this.filters = options.filters || {}; 221 222 // Bind default `change` events to the `props` model. 223 this.props.on( 'change', this._changeFilteredProps, this ); 224 225 this.props.on( 'change:order', this._changeOrder, this ); 226 this.props.on( 'change:orderby', this._changeOrderby, this ); 227 this.props.on( 'change:query', this._changeQuery, this ); 228 229 this.props.set( _.defaults( options.props || {} ) ); 230 231 if ( options.observe ) { 232 this.observe( options.observe ); 233 } 234 }, 235 /** 236 * Sort the collection when the order attribute changes. 237 * 238 * @access private 239 */ 240 _changeOrder: function() { 241 if ( this.comparator ) { 242 this.sort(); 243 } 244 }, 245 /** 246 * Set the default comparator only when the `orderby` property is set. 247 * 248 * @access private 249 * 250 * @param {Backbone.Model} model 251 * @param {string} orderby 252 */ 253 _changeOrderby: function( model, orderby ) { 254 // If a different comparator is defined, bail. 255 if ( this.comparator && this.comparator !== Attachments.comparator ) { 256 return; 257 } 258 259 if ( orderby && 'post__in' !== orderby ) { 260 this.comparator = Attachments.comparator; 261 } else { 262 delete this.comparator; 263 } 264 }, 265 /** 266 * If the `query` property is set to true, query the server using 267 * the `props` values, and sync the results to this collection. 268 * 269 * @access private 270 * 271 * @param {Backbone.Model} model 272 * @param {boolean} query 273 */ 274 _changeQuery: function( model, query ) { 275 if ( query ) { 276 this.props.on( 'change', this._requery, this ); 277 this._requery(); 278 } else { 279 this.props.off( 'change', this._requery, this ); 280 } 281 }, 282 /** 283 * @access private 284 * 285 * @param {Backbone.Model} model 286 */ 287 _changeFilteredProps: function( model ) { 288 // If this is a query, updating the collection will be handled by 289 // `this._requery()`. 290 if ( this.props.get('query') ) { 291 return; 292 } 293 294 var changed = _.chain( model.changed ).map( function( t, prop ) { 295 var filter = Attachments.filters[ prop ], 296 term = model.get( prop ); 297 298 if ( ! filter ) { 299 return; 300 } 301 302 if ( term && ! this.filters[ prop ] ) { 303 this.filters[ prop ] = filter; 304 } else if ( ! term && this.filters[ prop ] === filter ) { 305 delete this.filters[ prop ]; 306 } else { 307 return; 308 } 309 310 // Record the change. 311 return true; 312 }, this ).any().value(); 313 314 if ( ! changed ) { 315 return; 316 } 317 318 // If no `Attachments` model is provided to source the searches from, 319 // then automatically generate a source from the existing models. 320 if ( ! this._source ) { 321 this._source = new Attachments( this.models ); 322 } 323 324 this.reset( this._source.filter( this.validator, this ) ); 325 }, 326 327 validateDestroyed: false, 328 /** 329 * Checks whether an attachment is valid. 330 * 331 * @param {wp.media.model.Attachment} attachment 332 * @return {boolean} 333 */ 334 validator: function( attachment ) { 335 336 if ( ! this.validateDestroyed && attachment.destroyed ) { 337 return false; 338 } 339 return _.all( this.filters, function( filter ) { 340 return !! filter.call( this, attachment ); 341 }, this ); 342 }, 343 /** 344 * Add or remove an attachment to the collection depending on its validity. 345 * 346 * @param {wp.media.model.Attachment} attachment 347 * @param {Object} options 348 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 349 */ 350 validate: function( attachment, options ) { 351 var valid = this.validator( attachment ), 352 hasAttachment = !! this.get( attachment.cid ); 353 354 if ( ! valid && hasAttachment ) { 355 this.remove( attachment, options ); 356 } else if ( valid && ! hasAttachment ) { 357 this.add( attachment, options ); 358 } 359 360 return this; 361 }, 362 363 /** 364 * Add or remove all attachments from another collection depending on each one's validity. 365 * 366 * @param {wp.media.model.Attachments} attachments 367 * @param {Object} [options={}] 368 * 369 * @fires wp.media.model.Attachments#reset 370 * 371 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 372 */ 373 validateAll: function( attachments, options ) { 374 options = options || {}; 375 376 _.each( attachments.models, function( attachment ) { 377 this.validate( attachment, { silent: true }); 378 }, this ); 379 380 if ( ! options.silent ) { 381 this.trigger( 'reset', this, options ); 382 } 383 return this; 384 }, 385 /** 386 * Start observing another attachments collection change events 387 * and replicate them on this collection. 388 * 389 * @param {wp.media.model.Attachments} The attachments collection to observe. 390 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 391 */ 392 observe: function( attachments ) { 393 this.observers = this.observers || []; 394 this.observers.push( attachments ); 395 396 attachments.on( 'add change remove', this._validateHandler, this ); 397 attachments.on( 'add', this._addToTotalAttachments, this ); 398 attachments.on( 'remove', this._removeFromTotalAttachments, this ); 399 attachments.on( 'reset', this._validateAllHandler, this ); 400 this.validateAll( attachments ); 401 return this; 402 }, 403 /** 404 * Stop replicating collection change events from another attachments collection. 405 * 406 * @param {wp.media.model.Attachments} The attachments collection to stop observing. 407 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 408 */ 409 unobserve: function( attachments ) { 410 if ( attachments ) { 411 attachments.off( null, null, this ); 412 this.observers = _.without( this.observers, attachments ); 413 414 } else { 415 _.each( this.observers, function( attachments ) { 416 attachments.off( null, null, this ); 417 }, this ); 418 delete this.observers; 419 } 420 421 return this; 422 }, 423 /** 424 * Update total attachment count when items are added to a collection. 425 * 426 * @access private 427 * 428 * @since 5.8.0 429 */ 430 _removeFromTotalAttachments: function() { 431 if ( this.mirroring ) { 432 this.mirroring.totalAttachments = this.mirroring.totalAttachments - 1; 433 } 434 }, 435 /** 436 * Update total attachment count when items are added to a collection. 437 * 438 * @access private 439 * 440 * @since 5.8.0 441 */ 442 _addToTotalAttachments: function() { 443 if ( this.mirroring ) { 444 this.mirroring.totalAttachments = this.mirroring.totalAttachments + 1; 445 } 446 }, 447 /** 448 * @access private 449 * 450 * @param {wp.media.model.Attachments} attachment 451 * @param {wp.media.model.Attachments} attachments 452 * @param {Object} options 453 * 454 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 455 */ 456 _validateHandler: function( attachment, attachments, options ) { 457 // If we're not mirroring this `attachments` collection, 458 // only retain the `silent` option. 459 options = attachments === this.mirroring ? options : { 460 silent: options && options.silent 461 }; 462 463 return this.validate( attachment, options ); 464 }, 465 /** 466 * @access private 467 * 468 * @param {wp.media.model.Attachments} attachments 469 * @param {Object} options 470 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 471 */ 472 _validateAllHandler: function( attachments, options ) { 473 return this.validateAll( attachments, options ); 474 }, 475 /** 476 * Start mirroring another attachments collection, clearing out any models already 477 * in the collection. 478 * 479 * @param {wp.media.model.Attachments} The attachments collection to mirror. 480 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 481 */ 482 mirror: function( attachments ) { 483 if ( this.mirroring && this.mirroring === attachments ) { 484 return this; 485 } 486 487 this.unmirror(); 488 this.mirroring = attachments; 489 490 // Clear the collection silently. A `reset` event will be fired 491 // when `observe()` calls `validateAll()`. 492 this.reset( [], { silent: true } ); 493 this.observe( attachments ); 494 495 // Used for the search results. 496 this.trigger( 'attachments:received', this ); 497 return this; 498 }, 499 /** 500 * Stop mirroring another attachments collection. 501 */ 502 unmirror: function() { 503 if ( ! this.mirroring ) { 504 return; 505 } 506 507 this.unobserve( this.mirroring ); 508 delete this.mirroring; 509 }, 510 /** 511 * Retrieve more attachments from the server for the collection. 512 * 513 * Only works if the collection is mirroring a Query Attachments collection, 514 * and forwards to its `more` method. This collection class doesn't have 515 * server persistence by itself. 516 * 517 * @param {Object} options 518 * @return {Promise} 519 */ 520 more: function( options ) { 521 var deferred = jQuery.Deferred(), 522 mirroring = this.mirroring, 523 attachments = this; 524 525 if ( ! mirroring || ! mirroring.more ) { 526 return deferred.resolveWith( this ).promise(); 527 } 528 /* 529 * If we're mirroring another collection, forward `more` to 530 * the mirrored collection. Account for a race condition by 531 * checking if we're still mirroring that collection when 532 * the request resolves. 533 */ 534 mirroring.more( options ).done( function() { 535 if ( this === attachments.mirroring ) { 536 deferred.resolveWith( this ); 537 } 538 539 // Used for the search results. 540 attachments.trigger( 'attachments:received', this ); 541 }); 542 543 return deferred.promise(); 544 }, 545 /** 546 * Whether there are more attachments that haven't been sync'd from the server 547 * that match the collection's query. 548 * 549 * Only works if the collection is mirroring a Query Attachments collection, 550 * and forwards to its `hasMore` method. This collection class doesn't have 551 * server persistence by itself. 552 * 553 * @return {boolean} 554 */ 555 hasMore: function() { 556 return this.mirroring ? this.mirroring.hasMore() : false; 557 }, 558 /** 559 * Holds the total number of attachments. 560 * 561 * @since 5.8.0 562 */ 563 totalAttachments: 0, 564 565 /** 566 * Gets the total number of attachments. 567 * 568 * @since 5.8.0 569 * 570 * @return {number} The total number of attachments. 571 */ 572 getTotalAttachments: function() { 573 return this.mirroring ? this.mirroring.totalAttachments : 0; 574 }, 575 576 /** 577 * A custom Ajax-response parser. 578 * 579 * See trac ticket #24753. 580 * 581 * Called automatically by Backbone whenever a collection's models are returned 582 * by the server, in fetch. The default implementation is a no-op, simply 583 * passing through the JSON response. We override this to add attributes to 584 * the collection items. 585 * 586 * @param {Object|Array} response The raw response Object/Array. 587 * @param {Object} xhr 588 * @return {Array} The array of model attributes to be added to the collection 589 */ 590 parse: function( response, xhr ) { 591 if ( ! _.isArray( response ) ) { 592 response = [response]; 593 } 594 return _.map( response, function( attrs ) { 595 var id, attachment, newAttributes; 596 597 if ( attrs instanceof Backbone.Model ) { 598 id = attrs.get( 'id' ); 599 attrs = attrs.attributes; 600 } else { 601 id = attrs.id; 602 } 603 604 attachment = wp.media.model.Attachment.get( id ); 605 newAttributes = attachment.parse( attrs, xhr ); 606 607 if ( ! _.isEqual( attachment.attributes, newAttributes ) ) { 608 attachment.set( newAttributes ); 609 } 610 611 return attachment; 612 }); 613 }, 614 615 /** 616 * If the collection is a query, create and mirror an Attachments Query collection. 617 * 618 * @access private 619 * @param {Boolean} refresh Deprecated, refresh parameter no longer used. 620 */ 621 _requery: function() { 622 var props; 623 if ( this.props.get('query') ) { 624 props = this.props.toJSON(); 625 this.mirror( wp.media.model.Query.get( props ) ); 626 } 627 }, 628 /** 629 * If this collection is sorted by `menuOrder`, recalculates and saves 630 * the menu order to the database. 631 * 632 * @return {undefined|Promise} 633 */ 634 saveMenuOrder: function() { 635 if ( 'menuOrder' !== this.props.get('orderby') ) { 636 return; 637 } 638 639 /* 640 * Removes any uploading attachments, updates each attachment's 641 * menu order, and returns an object with an { id: menuOrder } 642 * mapping to pass to the request. 643 */ 644 var attachments = this.chain().filter( function( attachment ) { 645 return ! _.isUndefined( attachment.id ); 646 }).map( function( attachment, index ) { 647 // Indices start at 1. 648 index = index + 1; 649 attachment.set( 'menuOrder', index ); 650 return [ attachment.id, index ]; 651 }).object().value(); 652 653 if ( _.isEmpty( attachments ) ) { 654 return; 655 } 656 657 return wp.media.post( 'save-attachment-order', { 658 nonce: wp.media.model.settings.post.nonce, 659 post_id: wp.media.model.settings.post.id, 660 attachments: attachments 661 }); 662 } 663 },/** @lends wp.media.model.Attachments */{ 664 /** 665 * A function to compare two attachment models in an attachments collection. 666 * 667 * Used as the default comparator for instances of wp.media.model.Attachments 668 * and its subclasses. @see wp.media.model.Attachments._changeOrderby(). 669 * 670 * @param {Backbone.Model} a 671 * @param {Backbone.Model} b 672 * @param {Object} options 673 * @return {number} -1 if the first model should come before the second, 674 * 0 if they are of the same rank and 675 * 1 if the first model should come after. 676 */ 677 comparator: function( a, b, options ) { 678 var key = this.props.get('orderby'), 679 order = this.props.get('order') || 'DESC', 680 ac = a.cid, 681 bc = b.cid; 682 683 a = a.get( key ); 684 b = b.get( key ); 685 686 if ( 'date' === key || 'modified' === key ) { 687 a = a || new Date(); 688 b = b || new Date(); 689 } 690 691 // If `options.ties` is set, don't enforce the `cid` tiebreaker. 692 if ( options && options.ties ) { 693 ac = bc = null; 694 } 695 696 return ( 'DESC' === order ) ? wp.media.compare( a, b, ac, bc ) : wp.media.compare( b, a, bc, ac ); 697 }, 698 /** @namespace wp.media.model.Attachments.filters */ 699 filters: { 700 /** 701 * @static 702 * Note that this client-side searching is *not* equivalent 703 * to our server-side searching. 704 * 705 * @param {wp.media.model.Attachment} attachment 706 * 707 * @this wp.media.model.Attachments 708 * 709 * @return {Boolean} 710 */ 711 search: function( attachment ) { 712 if ( ! this.props.get('search') ) { 713 return true; 714 } 715 716 return _.any(['title','filename','description','caption','name'], function( key ) { 717 var value = attachment.get( key ); 718 return value && -1 !== value.search( this.props.get('search') ); 719 }, this ); 720 }, 721 /** 722 * @static 723 * @param {wp.media.model.Attachment} attachment 724 * 725 * @this wp.media.model.Attachments 726 * 727 * @return {boolean} 728 */ 729 type: function( attachment ) { 730 var type = this.props.get('type'), atts = attachment.toJSON(), mime, found; 731 732 if ( ! type || ( _.isArray( type ) && ! type.length ) ) { 733 return true; 734 } 735 736 mime = atts.mime || ( atts.file && atts.file.type ) || ''; 737 738 if ( _.isArray( type ) ) { 739 found = _.find( type, function (t) { 740 return -1 !== mime.indexOf( t ); 741 } ); 742 } else { 743 found = -1 !== mime.indexOf( type ); 744 } 745 746 return found; 747 }, 748 /** 749 * @static 750 * @param {wp.media.model.Attachment} attachment 751 * 752 * @this wp.media.model.Attachments 753 * 754 * @return {boolean} 755 */ 756 uploadedTo: function( attachment ) { 757 var uploadedTo = this.props.get('uploadedTo'); 758 if ( _.isUndefined( uploadedTo ) ) { 759 return true; 760 } 761 762 return uploadedTo === attachment.get('uploadedTo'); 763 }, 764 /** 765 * @static 766 * @param {wp.media.model.Attachment} attachment 767 * 768 * @this wp.media.model.Attachments 769 * 770 * @return {boolean} 771 */ 772 status: function( attachment ) { 773 var status = this.props.get('status'); 774 if ( _.isUndefined( status ) ) { 775 return true; 776 } 777 778 return status === attachment.get('status'); 779 } 780 } 781 }); 782 783 module.exports = Attachments; 784 785 786 /***/ }), 787 788 /***/ 5927: 789 /***/ (function(module) { 790 791 /** 792 * wp.media.model.PostImage 793 * 794 * An instance of an image that's been embedded into a post. 795 * 796 * Used in the embedded image attachment display settings modal - @see wp.media.view.MediaFrame.ImageDetails. 797 * 798 * @memberOf wp.media.model 799 * 800 * @class 801 * @augments Backbone.Model 802 * 803 * @param {int} [attributes] Initial model attributes. 804 * @param {int} [attributes.attachment_id] ID of the attachment. 805 **/ 806 var PostImage = Backbone.Model.extend(/** @lends wp.media.model.PostImage.prototype */{ 807 808 initialize: function( attributes ) { 809 var Attachment = wp.media.model.Attachment; 810 this.attachment = false; 811 812 if ( attributes.attachment_id ) { 813 this.attachment = Attachment.get( attributes.attachment_id ); 814 if ( this.attachment.get( 'url' ) ) { 815 this.dfd = jQuery.Deferred(); 816 this.dfd.resolve(); 817 } else { 818 this.dfd = this.attachment.fetch(); 819 } 820 this.bindAttachmentListeners(); 821 } 822 823 // Keep URL in sync with changes to the type of link. 824 this.on( 'change:link', this.updateLinkUrl, this ); 825 this.on( 'change:size', this.updateSize, this ); 826 827 this.setLinkTypeFromUrl(); 828 this.setAspectRatio(); 829 830 this.set( 'originalUrl', attributes.url ); 831 }, 832 833 bindAttachmentListeners: function() { 834 this.listenTo( this.attachment, 'sync', this.setLinkTypeFromUrl ); 835 this.listenTo( this.attachment, 'sync', this.setAspectRatio ); 836 this.listenTo( this.attachment, 'change', this.updateSize ); 837 }, 838 839 changeAttachment: function( attachment, props ) { 840 this.stopListening( this.attachment ); 841 this.attachment = attachment; 842 this.bindAttachmentListeners(); 843 844 this.set( 'attachment_id', this.attachment.get( 'id' ) ); 845 this.set( 'caption', this.attachment.get( 'caption' ) ); 846 this.set( 'alt', this.attachment.get( 'alt' ) ); 847 this.set( 'size', props.get( 'size' ) ); 848 this.set( 'align', props.get( 'align' ) ); 849 this.set( 'link', props.get( 'link' ) ); 850 this.updateLinkUrl(); 851 this.updateSize(); 852 }, 853 854 setLinkTypeFromUrl: function() { 855 var linkUrl = this.get( 'linkUrl' ), 856 type; 857 858 if ( ! linkUrl ) { 859 this.set( 'link', 'none' ); 860 return; 861 } 862 863 // Default to custom if there is a linkUrl. 864 type = 'custom'; 865 866 if ( this.attachment ) { 867 if ( this.attachment.get( 'url' ) === linkUrl ) { 868 type = 'file'; 869 } else if ( this.attachment.get( 'link' ) === linkUrl ) { 870 type = 'post'; 871 } 872 } else { 873 if ( this.get( 'url' ) === linkUrl ) { 874 type = 'file'; 875 } 876 } 877 878 this.set( 'link', type ); 879 }, 880 881 updateLinkUrl: function() { 882 var link = this.get( 'link' ), 883 url; 884 885 switch( link ) { 886 case 'file': 887 if ( this.attachment ) { 888 url = this.attachment.get( 'url' ); 889 } else { 890 url = this.get( 'url' ); 891 } 892 this.set( 'linkUrl', url ); 893 break; 894 case 'post': 895 this.set( 'linkUrl', this.attachment.get( 'link' ) ); 896 break; 897 case 'none': 898 this.set( 'linkUrl', '' ); 899 break; 900 } 901 }, 902 903 updateSize: function() { 904 var size; 905 906 if ( ! this.attachment ) { 907 return; 908 } 909 910 if ( this.get( 'size' ) === 'custom' ) { 911 this.set( 'width', this.get( 'customWidth' ) ); 912 this.set( 'height', this.get( 'customHeight' ) ); 913 this.set( 'url', this.get( 'originalUrl' ) ); 914 return; 915 } 916 917 size = this.attachment.get( 'sizes' )[ this.get( 'size' ) ]; 918 919 if ( ! size ) { 920 return; 921 } 922 923 this.set( 'url', size.url ); 924 this.set( 'width', size.width ); 925 this.set( 'height', size.height ); 926 }, 927 928 setAspectRatio: function() { 929 var full; 930 931 if ( this.attachment && this.attachment.get( 'sizes' ) ) { 932 full = this.attachment.get( 'sizes' ).full; 933 934 if ( full ) { 935 this.set( 'aspectRatio', full.width / full.height ); 936 return; 937 } 938 } 939 940 this.set( 'aspectRatio', this.get( 'customWidth' ) / this.get( 'customHeight' ) ); 941 } 942 }); 943 944 module.exports = PostImage; 945 946 947 /***/ }), 948 949 /***/ 4009: 950 /***/ (function(module) { 951 952 var Attachments = wp.media.model.Attachments, 953 Query; 954 955 /** 956 * wp.media.model.Query 957 * 958 * A collection of attachments that match the supplied query arguments. 959 * 960 * Note: Do NOT change this.args after the query has been initialized. 961 * Things will break. 962 * 963 * @memberOf wp.media.model 964 * 965 * @class 966 * @augments wp.media.model.Attachments 967 * @augments Backbone.Collection 968 * 969 * @param {array} [models] Models to initialize with the collection. 970 * @param {object} [options] Options hash. 971 * @param {object} [options.args] Attachments query arguments. 972 * @param {object} [options.args.posts_per_page] 973 */ 974 Query = Attachments.extend(/** @lends wp.media.model.Query.prototype */{ 975 /** 976 * @param {Array} [models=[]] Array of initial models to populate the collection. 977 * @param {Object} [options={}] 978 */ 979 initialize: function( models, options ) { 980 var allowed; 981 982 options = options || {}; 983 Attachments.prototype.initialize.apply( this, arguments ); 984 985 this.args = options.args; 986 this._hasMore = true; 987 this.created = new Date(); 988 989 this.filters.order = function( attachment ) { 990 var orderby = this.props.get('orderby'), 991 order = this.props.get('order'); 992 993 if ( ! this.comparator ) { 994 return true; 995 } 996 997 /* 998 * We want any items that can be placed before the last 999 * item in the set. If we add any items after the last 1000 * item, then we can't guarantee the set is complete. 1001 */ 1002 if ( this.length ) { 1003 return 1 !== this.comparator( attachment, this.last(), { ties: true }); 1004 1005 /* 1006 * Handle the case where there are no items yet and 1007 * we're sorting for recent items. In that case, we want 1008 * changes that occurred after we created the query. 1009 */ 1010 } else if ( 'DESC' === order && ( 'date' === orderby || 'modified' === orderby ) ) { 1011 return attachment.get( orderby ) >= this.created; 1012 1013 // If we're sorting by menu order and we have no items, 1014 // accept any items that have the default menu order (0). 1015 } else if ( 'ASC' === order && 'menuOrder' === orderby ) { 1016 return attachment.get( orderby ) === 0; 1017 } 1018 1019 // Otherwise, we don't want any items yet. 1020 return false; 1021 }; 1022 1023 /* 1024 * Observe the central `wp.Uploader.queue` collection to watch for 1025 * new matches for the query. 1026 * 1027 * Only observe when a limited number of query args are set. There 1028 * are no filters for other properties, so observing will result in 1029 * false positives in those queries. 1030 */ 1031 allowed = [ 's', 'order', 'orderby', 'posts_per_page', 'post_mime_type', 'post_parent', 'author' ]; 1032 if ( wp.Uploader && _( this.args ).chain().keys().difference( allowed ).isEmpty().value() ) { 1033 this.observe( wp.Uploader.queue ); 1034 } 1035 }, 1036 /** 1037 * Whether there are more attachments that haven't been sync'd from the server 1038 * that match the collection's query. 1039 * 1040 * @return {boolean} 1041 */ 1042 hasMore: function() { 1043 return this._hasMore; 1044 }, 1045 /** 1046 * Fetch more attachments from the server for the collection. 1047 * 1048 * @param {Object} [options={}] 1049 * @return {Promise} 1050 */ 1051 more: function( options ) { 1052 var query = this; 1053 1054 // If there is already a request pending, return early with the Deferred object. 1055 if ( this._more && 'pending' === this._more.state() ) { 1056 return this._more; 1057 } 1058 1059 if ( ! this.hasMore() ) { 1060 return jQuery.Deferred().resolveWith( this ).promise(); 1061 } 1062 1063 options = options || {}; 1064 options.remove = false; 1065 1066 return this._more = this.fetch( options ).done( function( response ) { 1067 if ( _.isEmpty( response ) || -1 === query.args.posts_per_page || response.length < query.args.posts_per_page ) { 1068 query._hasMore = false; 1069 } 1070 }); 1071 }, 1072 /** 1073 * Overrides Backbone.Collection.sync 1074 * Overrides wp.media.model.Attachments.sync 1075 * 1076 * @param {string} method 1077 * @param {Backbone.Model} model 1078 * @param {Object} [options={}] 1079 * @return {Promise} 1080 */ 1081 sync: function( method, model, options ) { 1082 var args, fallback; 1083 1084 // Overload the read method so Attachment.fetch() functions correctly. 1085 if ( 'read' === method ) { 1086 options = options || {}; 1087 options.context = this; 1088 options.data = _.extend( options.data || {}, { 1089 action: 'query-attachments', 1090 post_id: wp.media.model.settings.post.id 1091 }); 1092 1093 // Clone the args so manipulation is non-destructive. 1094 args = _.clone( this.args ); 1095 1096 // Determine which page to query. 1097 if ( -1 !== args.posts_per_page ) { 1098 args.paged = Math.round( this.length / args.posts_per_page ) + 1; 1099 } 1100 1101 options.data.query = args; 1102 return wp.media.ajax( options ); 1103 1104 // Otherwise, fall back to `Backbone.sync()`. 1105 } else { 1106 /** 1107 * Call wp.media.model.Attachments.sync or Backbone.sync 1108 */ 1109 fallback = Attachments.prototype.sync ? Attachments.prototype : Backbone; 1110 return fallback.sync.apply( this, arguments ); 1111 } 1112 } 1113 }, /** @lends wp.media.model.Query */{ 1114 /** 1115 * @readonly 1116 */ 1117 defaultProps: { 1118 orderby: 'date', 1119 order: 'DESC' 1120 }, 1121 /** 1122 * @readonly 1123 */ 1124 defaultArgs: { 1125 posts_per_page: 80 1126 }, 1127 /** 1128 * @readonly 1129 */ 1130 orderby: { 1131 allowed: [ 'name', 'author', 'date', 'title', 'modified', 'uploadedTo', 'id', 'post__in', 'menuOrder' ], 1132 /** 1133 * A map of JavaScript orderby values to their WP_Query equivalents. 1134 * @type {Object} 1135 */ 1136 valuemap: { 1137 'id': 'ID', 1138 'uploadedTo': 'parent', 1139 'menuOrder': 'menu_order ID' 1140 } 1141 }, 1142 /** 1143 * A map of JavaScript query properties to their WP_Query equivalents. 1144 * 1145 * @readonly 1146 */ 1147 propmap: { 1148 'search': 's', 1149 'type': 'post_mime_type', 1150 'perPage': 'posts_per_page', 1151 'menuOrder': 'menu_order', 1152 'uploadedTo': 'post_parent', 1153 'status': 'post_status', 1154 'include': 'post__in', 1155 'exclude': 'post__not_in', 1156 'author': 'author' 1157 }, 1158 /** 1159 * Creates and returns an Attachments Query collection given the properties. 1160 * 1161 * Caches query objects and reuses where possible. 1162 * 1163 * @static 1164 * @method 1165 * 1166 * @param {object} [props] 1167 * @param {Object} [props.order] 1168 * @param {Object} [props.orderby] 1169 * @param {Object} [props.include] 1170 * @param {Object} [props.exclude] 1171 * @param {Object} [props.s] 1172 * @param {Object} [props.post_mime_type] 1173 * @param {Object} [props.posts_per_page] 1174 * @param {Object} [props.menu_order] 1175 * @param {Object} [props.post_parent] 1176 * @param {Object} [props.post_status] 1177 * @param {Object} [props.author] 1178 * @param {Object} [options] 1179 * 1180 * @return {wp.media.model.Query} A new Attachments Query collection. 1181 */ 1182 get: (function(){ 1183 /** 1184 * @static 1185 * @type Array 1186 */ 1187 var queries = []; 1188 1189 /** 1190 * @return {Query} 1191 */ 1192 return function( props, options ) { 1193 var args = {}, 1194 orderby = Query.orderby, 1195 defaults = Query.defaultProps, 1196 query; 1197 1198 // Remove the `query` property. This isn't linked to a query, 1199 // this *is* the query. 1200 delete props.query; 1201 1202 // Fill default args. 1203 _.defaults( props, defaults ); 1204 1205 // Normalize the order. 1206 props.order = props.order.toUpperCase(); 1207 if ( 'DESC' !== props.order && 'ASC' !== props.order ) { 1208 props.order = defaults.order.toUpperCase(); 1209 } 1210 1211 // Ensure we have a valid orderby value. 1212 if ( ! _.contains( orderby.allowed, props.orderby ) ) { 1213 props.orderby = defaults.orderby; 1214 } 1215 1216 _.each( [ 'include', 'exclude' ], function( prop ) { 1217 if ( props[ prop ] && ! _.isArray( props[ prop ] ) ) { 1218 props[ prop ] = [ props[ prop ] ]; 1219 } 1220 } ); 1221 1222 // Generate the query `args` object. 1223 // Correct any differing property names. 1224 _.each( props, function( value, prop ) { 1225 if ( _.isNull( value ) ) { 1226 return; 1227 } 1228 1229 args[ Query.propmap[ prop ] || prop ] = value; 1230 }); 1231 1232 // Fill any other default query args. 1233 _.defaults( args, Query.defaultArgs ); 1234 1235 // `props.orderby` does not always map directly to `args.orderby`. 1236 // Substitute exceptions specified in orderby.keymap. 1237 args.orderby = orderby.valuemap[ props.orderby ] || props.orderby; 1238 1239 queries = []; 1240 1241 // Otherwise, create a new query and add it to the cache. 1242 if ( ! query ) { 1243 query = new Query( [], _.extend( options || {}, { 1244 props: props, 1245 args: args 1246 } ) ); 1247 queries.push( query ); 1248 } 1249 1250 return query; 1251 }; 1252 }()) 1253 }); 1254 1255 module.exports = Query; 1256 1257 1258 /***/ }), 1259 1260 /***/ 6584: 1261 /***/ (function(module) { 1262 1263 var Attachments = wp.media.model.Attachments, 1264 Selection; 1265 1266 /** 1267 * wp.media.model.Selection 1268 * 1269 * A selection of attachments. 1270 * 1271 * @memberOf wp.media.model 1272 * 1273 * @class 1274 * @augments wp.media.model.Attachments 1275 * @augments Backbone.Collection 1276 */ 1277 Selection = Attachments.extend(/** @lends wp.media.model.Selection.prototype */{ 1278 /** 1279 * Refresh the `single` model whenever the selection changes. 1280 * Binds `single` instead of using the context argument to ensure 1281 * it receives no parameters. 1282 * 1283 * @param {Array} [models=[]] Array of models used to populate the collection. 1284 * @param {Object} [options={}] 1285 */ 1286 initialize: function( models, options ) { 1287 /** 1288 * call 'initialize' directly on the parent class 1289 */ 1290 Attachments.prototype.initialize.apply( this, arguments ); 1291 this.multiple = options && options.multiple; 1292 1293 this.on( 'add remove reset', _.bind( this.single, this, false ) ); 1294 }, 1295 1296 /** 1297 * If the workflow does not support multi-select, clear out the selection 1298 * before adding a new attachment to it. 1299 * 1300 * @param {Array} models 1301 * @param {Object} options 1302 * @return {wp.media.model.Attachment[]} 1303 */ 1304 add: function( models, options ) { 1305 if ( ! this.multiple ) { 1306 this.remove( this.models ); 1307 } 1308 /** 1309 * call 'add' directly on the parent class 1310 */ 1311 return Attachments.prototype.add.call( this, models, options ); 1312 }, 1313 1314 /** 1315 * Fired when toggling (clicking on) an attachment in the modal. 1316 * 1317 * @param {undefined|boolean|wp.media.model.Attachment} model 1318 * 1319 * @fires wp.media.model.Selection#selection:single 1320 * @fires wp.media.model.Selection#selection:unsingle 1321 * 1322 * @return {Backbone.Model} 1323 */ 1324 single: function( model ) { 1325 var previous = this._single; 1326 1327 // If a `model` is provided, use it as the single model. 1328 if ( model ) { 1329 this._single = model; 1330 } 1331 // If the single model isn't in the selection, remove it. 1332 if ( this._single && ! this.get( this._single.cid ) ) { 1333 delete this._single; 1334 } 1335 1336 this._single = this._single || this.last(); 1337 1338 // If single has changed, fire an event. 1339 if ( this._single !== previous ) { 1340 if ( previous ) { 1341 previous.trigger( 'selection:unsingle', previous, this ); 1342 1343 // If the model was already removed, trigger the collection 1344 // event manually. 1345 if ( ! this.get( previous.cid ) ) { 1346 this.trigger( 'selection:unsingle', previous, this ); 1347 } 1348 } 1349 if ( this._single ) { 1350 this._single.trigger( 'selection:single', this._single, this ); 1351 } 1352 } 1353 1354 // Return the single model, or the last model as a fallback. 1355 return this._single; 1356 } 1357 }); 1358 1359 module.exports = Selection; 1360 1361 1362 /***/ }) 1363 1364 /******/ }); 1365 /************************************************************************/ 1366 /******/ // The module cache 1367 /******/ var __webpack_module_cache__ = {}; 1368 /******/ 1369 /******/ // The require function 1370 /******/ function __webpack_require__(moduleId) { 1371 /******/ // Check if module is in cache 1372 /******/ var cachedModule = __webpack_module_cache__[moduleId]; 1373 /******/ if (cachedModule !== undefined) { 1374 /******/ return cachedModule.exports; 1375 /******/ } 1376 /******/ // Create a new module (and put it into the cache) 1377 /******/ var module = __webpack_module_cache__[moduleId] = { 1378 /******/ // no module.id needed 1379 /******/ // no module.loaded needed 1380 /******/ exports: {} 1381 /******/ }; 1382 /******/ 1383 /******/ // Execute the module function 1384 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 1385 /******/ 1386 /******/ // Return the exports of the module 1387 /******/ return module.exports; 1388 /******/ } 1389 /******/ 1390 /************************************************************************/ 1391 var __webpack_exports__ = {}; 1392 // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. 1393 !function() { 1394 /** 1395 * @output wp-includes/js/media-models.js 1396 */ 1397 1398 var $ = jQuery, 1399 Attachment, Attachments, l10n, media; 1400 1401 /** @namespace wp */ 1402 window.wp = window.wp || {}; 1403 1404 /** 1405 * Create and return a media frame. 1406 * 1407 * Handles the default media experience. 1408 * 1409 * @alias wp.media 1410 * @memberOf wp 1411 * @namespace 1412 * 1413 * @param {Object} attributes The properties passed to the main media controller. 1414 * @return {wp.media.view.MediaFrame} A media workflow. 1415 */ 1416 media = wp.media = function( attributes ) { 1417 var MediaFrame = media.view.MediaFrame, 1418 frame; 1419 1420 if ( ! MediaFrame ) { 1421 return; 1422 } 1423 1424 attributes = _.defaults( attributes || {}, { 1425 frame: 'select' 1426 }); 1427 1428 if ( 'select' === attributes.frame && MediaFrame.Select ) { 1429 frame = new MediaFrame.Select( attributes ); 1430 } else if ( 'post' === attributes.frame && MediaFrame.Post ) { 1431 frame = new MediaFrame.Post( attributes ); 1432 } else if ( 'manage' === attributes.frame && MediaFrame.Manage ) { 1433 frame = new MediaFrame.Manage( attributes ); 1434 } else if ( 'image' === attributes.frame && MediaFrame.ImageDetails ) { 1435 frame = new MediaFrame.ImageDetails( attributes ); 1436 } else if ( 'audio' === attributes.frame && MediaFrame.AudioDetails ) { 1437 frame = new MediaFrame.AudioDetails( attributes ); 1438 } else if ( 'video' === attributes.frame && MediaFrame.VideoDetails ) { 1439 frame = new MediaFrame.VideoDetails( attributes ); 1440 } else if ( 'edit-attachments' === attributes.frame && MediaFrame.EditAttachments ) { 1441 frame = new MediaFrame.EditAttachments( attributes ); 1442 } 1443 1444 delete attributes.frame; 1445 1446 media.frame = frame; 1447 1448 return frame; 1449 }; 1450 1451 /** @namespace wp.media.model */ 1452 /** @namespace wp.media.view */ 1453 /** @namespace wp.media.controller */ 1454 /** @namespace wp.media.frames */ 1455 _.extend( media, { model: {}, view: {}, controller: {}, frames: {} }); 1456 1457 // Link any localized strings. 1458 l10n = media.model.l10n = window._wpMediaModelsL10n || {}; 1459 1460 // Link any settings. 1461 media.model.settings = l10n.settings || {}; 1462 delete l10n.settings; 1463 1464 Attachment = media.model.Attachment = __webpack_require__( 7727 ); 1465 Attachments = media.model.Attachments = __webpack_require__( 6940 ); 1466 1467 media.model.Query = __webpack_require__( 4009 ); 1468 media.model.PostImage = __webpack_require__( 5927 ); 1469 media.model.Selection = __webpack_require__( 6584 ); 1470 1471 /** 1472 * ======================================================================== 1473 * UTILITIES 1474 * ======================================================================== 1475 */ 1476 1477 /** 1478 * A basic equality comparator for Backbone models. 1479 * 1480 * Used to order models within a collection - @see wp.media.model.Attachments.comparator(). 1481 * 1482 * @param {mixed} a The primary parameter to compare. 1483 * @param {mixed} b The primary parameter to compare. 1484 * @param {string} ac The fallback parameter to compare, a's cid. 1485 * @param {string} bc The fallback parameter to compare, b's cid. 1486 * @return {number} -1: a should come before b. 1487 * 0: a and b are of the same rank. 1488 * 1: b should come before a. 1489 */ 1490 media.compare = function( a, b, ac, bc ) { 1491 if ( _.isEqual( a, b ) ) { 1492 return ac === bc ? 0 : (ac > bc ? -1 : 1); 1493 } else { 1494 return a > b ? -1 : 1; 1495 } 1496 }; 1497 1498 _.extend( media, /** @lends wp.media */{ 1499 /** 1500 * media.template( id ) 1501 * 1502 * Fetch a JavaScript template for an id, and return a templating function for it. 1503 * 1504 * See wp.template() in `wp-includes/js/wp-util.js`. 1505 * 1506 * @borrows wp.template as template 1507 */ 1508 template: wp.template, 1509 1510 /** 1511 * media.post( [action], [data] ) 1512 * 1513 * Sends a POST request to WordPress. 1514 * See wp.ajax.post() in `wp-includes/js/wp-util.js`. 1515 * 1516 * @borrows wp.ajax.post as post 1517 */ 1518 post: wp.ajax.post, 1519 1520 /** 1521 * media.ajax( [action], [options] ) 1522 * 1523 * Sends an XHR request to WordPress. 1524 * See wp.ajax.send() in `wp-includes/js/wp-util.js`. 1525 * 1526 * @borrows wp.ajax.send as ajax 1527 */ 1528 ajax: wp.ajax.send, 1529 1530 /** 1531 * Scales a set of dimensions to fit within bounding dimensions. 1532 * 1533 * @param {Object} dimensions 1534 * @return {Object} 1535 */ 1536 fit: function( dimensions ) { 1537 var width = dimensions.width, 1538 height = dimensions.height, 1539 maxWidth = dimensions.maxWidth, 1540 maxHeight = dimensions.maxHeight, 1541 constraint; 1542 1543 /* 1544 * Compare ratios between the two values to determine 1545 * which max to constrain by. If a max value doesn't exist, 1546 * then the opposite side is the constraint. 1547 */ 1548 if ( ! _.isUndefined( maxWidth ) && ! _.isUndefined( maxHeight ) ) { 1549 constraint = ( width / height > maxWidth / maxHeight ) ? 'width' : 'height'; 1550 } else if ( _.isUndefined( maxHeight ) ) { 1551 constraint = 'width'; 1552 } else if ( _.isUndefined( maxWidth ) && height > maxHeight ) { 1553 constraint = 'height'; 1554 } 1555 1556 // If the value of the constrained side is larger than the max, 1557 // then scale the values. Otherwise return the originals; they fit. 1558 if ( 'width' === constraint && width > maxWidth ) { 1559 return { 1560 width : maxWidth, 1561 height: Math.round( maxWidth * height / width ) 1562 }; 1563 } else if ( 'height' === constraint && height > maxHeight ) { 1564 return { 1565 width : Math.round( maxHeight * width / height ), 1566 height: maxHeight 1567 }; 1568 } else { 1569 return { 1570 width : width, 1571 height: height 1572 }; 1573 } 1574 }, 1575 /** 1576 * Truncates a string by injecting an ellipsis into the middle. 1577 * Useful for filenames. 1578 * 1579 * @param {string} string 1580 * @param {number} [length=30] 1581 * @param {string} [replacement=…] 1582 * @return {string} The string, unless length is greater than string.length. 1583 */ 1584 truncate: function( string, length, replacement ) { 1585 length = length || 30; 1586 replacement = replacement || '…'; 1587 1588 if ( string.length <= length ) { 1589 return string; 1590 } 1591 1592 return string.substr( 0, length / 2 ) + replacement + string.substr( -1 * length / 2 ); 1593 } 1594 }); 1595 1596 /** 1597 * ======================================================================== 1598 * MODELS 1599 * ======================================================================== 1600 */ 1601 /** 1602 * wp.media.attachment 1603 * 1604 * @static 1605 * @param {string} id A string used to identify a model. 1606 * @return {wp.media.model.Attachment} 1607 */ 1608 media.attachment = function( id ) { 1609 return Attachment.get( id ); 1610 }; 1611 1612 /** 1613 * A collection of all attachments that have been fetched from the server. 1614 * 1615 * @static 1616 * @member {wp.media.model.Attachments} 1617 */ 1618 Attachments.all = new Attachments(); 1619 1620 /** 1621 * wp.media.query 1622 * 1623 * Shorthand for creating a new Attachments Query. 1624 * 1625 * @param {Object} [props] 1626 * @return {wp.media.model.Attachments} 1627 */ 1628 media.query = function( props ) { 1629 return new Attachments( null, { 1630 props: _.extend( _.defaults( props || {}, { orderby: 'date' } ), { query: true } ) 1631 }); 1632 }; 1633 1634 // Clean up. Prevents mobile browsers caching. 1635 $(window).on('unload', function(){ 1636 window.wp = null; 1637 }); 1638 1639 }(); 1640 /******/ })() 1641 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Dec 22 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |