| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /******/ (() => { // webpackBootstrap 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 3343 5 (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 /***/ 8266 181 (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( 'reset', this._validateAllHandler, this ); 398 this.validateAll( attachments ); 399 return this; 400 }, 401 /** 402 * Stop replicating collection change events from another attachments collection. 403 * 404 * @param {wp.media.model.Attachments} The attachments collection to stop observing. 405 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 406 */ 407 unobserve: function( attachments ) { 408 if ( attachments ) { 409 attachments.off( null, null, this ); 410 this.observers = _.without( this.observers, attachments ); 411 412 } else { 413 _.each( this.observers, function( attachments ) { 414 attachments.off( null, null, this ); 415 }, this ); 416 delete this.observers; 417 } 418 419 return this; 420 }, 421 /** 422 * Update total attachment count when items are added to a collection. 423 * 424 * @access private 425 * 426 * @since 5.8.0 427 */ 428 _removeFromTotalAttachments: function() { 429 if ( this.mirroring ) { 430 this.mirroring.totalAttachments = this.mirroring.totalAttachments - 1; 431 } 432 }, 433 /** 434 * Update total attachment count when items are added to a collection. 435 * 436 * @access private 437 * 438 * @since 5.8.0 439 */ 440 _addToTotalAttachments: function() { 441 if ( this.mirroring ) { 442 this.mirroring.totalAttachments = this.mirroring.totalAttachments + 1; 443 } 444 }, 445 /** 446 * @access private 447 * 448 * @param {wp.media.model.Attachments} attachment 449 * @param {wp.media.model.Attachments} attachments 450 * @param {Object} options 451 * 452 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 453 */ 454 _validateHandler: function( attachment, attachments, options ) { 455 // If we're not mirroring this `attachments` collection, 456 // only retain the `silent` option. 457 options = attachments === this.mirroring ? options : { 458 silent: options && options.silent 459 }; 460 461 return this.validate( attachment, options ); 462 }, 463 /** 464 * @access private 465 * 466 * @param {wp.media.model.Attachments} attachments 467 * @param {Object} options 468 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 469 */ 470 _validateAllHandler: function( attachments, options ) { 471 return this.validateAll( attachments, options ); 472 }, 473 /** 474 * Start mirroring another attachments collection, clearing out any models already 475 * in the collection. 476 * 477 * @param {wp.media.model.Attachments} The attachments collection to mirror. 478 * @return {wp.media.model.Attachments} Returns itself to allow chaining. 479 */ 480 mirror: function( attachments ) { 481 if ( this.mirroring && this.mirroring === attachments ) { 482 return this; 483 } 484 485 this.unmirror(); 486 this.mirroring = attachments; 487 488 // Clear the collection silently. A `reset` event will be fired 489 // when `observe()` calls `validateAll()`. 490 this.reset( [], { silent: true } ); 491 this.observe( attachments ); 492 493 // Bind total attachment count tracking only to the mirrored query 494 // collection, not to additional observed collections (e.g. selection). 495 // See Trac #65053. 496 attachments.on( 'add', this._addToTotalAttachments, this ); 497 attachments.on( 'remove', this._removeFromTotalAttachments, this ); 498 499 // Used for the search results. 500 this.trigger( 'attachments:received', this ); 501 return this; 502 }, 503 /** 504 * Stop mirroring another attachments collection. 505 */ 506 unmirror: function() { 507 if ( ! this.mirroring ) { 508 return; 509 } 510 511 this.unobserve( this.mirroring ); 512 delete this.mirroring; 513 }, 514 /** 515 * Retrieve more attachments from the server for the collection. 516 * 517 * Only works if the collection is mirroring a Query Attachments collection, 518 * and forwards to its `more` method. This collection class doesn't have 519 * server persistence by itself. 520 * 521 * @param {Object} options 522 * @return {Promise} 523 */ 524 more: function( options ) { 525 var deferred = jQuery.Deferred(), 526 mirroring = this.mirroring, 527 attachments = this; 528 529 if ( ! mirroring || ! mirroring.more ) { 530 return deferred.resolveWith( this ).promise(); 531 } 532 /* 533 * If we're mirroring another collection, forward `more` to 534 * the mirrored collection. Account for a race condition by 535 * checking if we're still mirroring that collection when 536 * the request resolves. 537 */ 538 mirroring.more( options ).done( function() { 539 if ( this === attachments.mirroring ) { 540 deferred.resolveWith( this ); 541 } 542 543 // Used for the search results. 544 attachments.trigger( 'attachments:received', this ); 545 }); 546 547 return deferred.promise(); 548 }, 549 /** 550 * Whether there are more attachments that haven't been sync'd from the server 551 * that match the collection's query. 552 * 553 * Only works if the collection is mirroring a Query Attachments collection, 554 * and forwards to its `hasMore` method. This collection class doesn't have 555 * server persistence by itself. 556 * 557 * @return {boolean} 558 */ 559 hasMore: function() { 560 return this.mirroring ? this.mirroring.hasMore() : false; 561 }, 562 /** 563 * Holds the total number of attachments. 564 * 565 * @since 5.8.0 566 */ 567 totalAttachments: 0, 568 569 /** 570 * Gets the total number of attachments. 571 * 572 * @since 5.8.0 573 * 574 * @return {number} The total number of attachments. 575 */ 576 getTotalAttachments: function() { 577 return this.mirroring ? this.mirroring.totalAttachments : 0; 578 }, 579 580 /** 581 * A custom Ajax-response parser. 582 * 583 * See trac ticket #24753. 584 * 585 * Called automatically by Backbone whenever a collection's models are returned 586 * by the server, in fetch. The default implementation is a no-op, simply 587 * passing through the JSON response. We override this to add attributes to 588 * the collection items. 589 * 590 * @param {Object|Array} response The raw response Object/Array. 591 * @param {Object} xhr 592 * @return {Array} The array of model attributes to be added to the collection 593 */ 594 parse: function( response, xhr ) { 595 if ( ! _.isArray( response ) ) { 596 response = [response]; 597 } 598 return _.map( response, function( attrs ) { 599 var id, attachment, newAttributes; 600 601 if ( attrs instanceof Backbone.Model ) { 602 id = attrs.get( 'id' ); 603 attrs = attrs.attributes; 604 } else { 605 id = attrs.id; 606 } 607 608 attachment = wp.media.model.Attachment.get( id ); 609 newAttributes = attachment.parse( attrs, xhr ); 610 611 if ( ! _.isEqual( attachment.attributes, newAttributes ) ) { 612 attachment.set( newAttributes ); 613 } 614 615 return attachment; 616 }); 617 }, 618 619 /** 620 * If the collection is a query, create and mirror an Attachments Query collection. 621 * 622 * @access private 623 * @param {Boolean} refresh Deprecated, refresh parameter no longer used. 624 */ 625 _requery: function() { 626 var props; 627 if ( this.props.get('query') ) { 628 props = this.props.toJSON(); 629 this.mirror( wp.media.model.Query.get( props ) ); 630 } 631 }, 632 /** 633 * If this collection is sorted by `menuOrder`, recalculates and saves 634 * the menu order to the database. 635 * 636 * @return {undefined|Promise} 637 */ 638 saveMenuOrder: function() { 639 if ( 'menuOrder' !== this.props.get('orderby') ) { 640 return; 641 } 642 643 /* 644 * Removes any uploading attachments, updates each attachment's 645 * menu order, and returns an object with an { id: menuOrder } 646 * mapping to pass to the request. 647 */ 648 var attachments = this.chain().filter( function( attachment ) { 649 return ! _.isUndefined( attachment.id ); 650 }).map( function( attachment, index ) { 651 // Indices start at 1. 652 index = index + 1; 653 attachment.set( 'menuOrder', index ); 654 return [ attachment.id, index ]; 655 }).object().value(); 656 657 if ( _.isEmpty( attachments ) ) { 658 return; 659 } 660 661 return wp.media.post( 'save-attachment-order', { 662 nonce: wp.media.model.settings.post.nonce, 663 post_id: wp.media.model.settings.post.id, 664 attachments: attachments 665 }); 666 } 667 },/** @lends wp.media.model.Attachments */{ 668 /** 669 * A function to compare two attachment models in an attachments collection. 670 * 671 * Used as the default comparator for instances of wp.media.model.Attachments 672 * and its subclasses. @see wp.media.model.Attachments._changeOrderby(). 673 * 674 * @param {Backbone.Model} a 675 * @param {Backbone.Model} b 676 * @param {Object} options 677 * @return {number} -1 if the first model should come before the second, 678 * 0 if they are of the same rank and 679 * 1 if the first model should come after. 680 */ 681 comparator: function( a, b, options ) { 682 var key = this.props.get('orderby'), 683 order = this.props.get('order') || 'DESC', 684 ac = a.cid, 685 bc = b.cid; 686 687 a = a.get( key ); 688 b = b.get( key ); 689 690 if ( 'date' === key || 'modified' === key ) { 691 a = a || new Date(); 692 b = b || new Date(); 693 } 694 695 // If `options.ties` is set, don't enforce the `cid` tiebreaker. 696 if ( options && options.ties ) { 697 ac = bc = null; 698 } 699 700 return ( 'DESC' === order ) ? wp.media.compare( a, b, ac, bc ) : wp.media.compare( b, a, bc, ac ); 701 }, 702 /** @namespace wp.media.model.Attachments.filters */ 703 filters: { 704 /** 705 * @static 706 * Note that this client-side searching is *not* equivalent 707 * to our server-side searching. 708 * 709 * @param {wp.media.model.Attachment} attachment 710 * 711 * @this wp.media.model.Attachments 712 * 713 * @return {Boolean} 714 */ 715 search: function( attachment ) { 716 if ( ! this.props.get('search') ) { 717 return true; 718 } 719 720 return _.any(['title','filename','description','caption','name'], function( key ) { 721 var value = attachment.get( key ); 722 return value && -1 !== value.search( this.props.get('search') ); 723 }, this ); 724 }, 725 /** 726 * @static 727 * @param {wp.media.model.Attachment} attachment 728 * 729 * @this wp.media.model.Attachments 730 * 731 * @return {boolean} 732 */ 733 type: function( attachment ) { 734 var type = this.props.get('type'), atts = attachment.toJSON(), mime, found; 735 736 if ( ! type || ( _.isArray( type ) && ! type.length ) ) { 737 return true; 738 } 739 740 mime = atts.mime || ( atts.file && atts.file.type ) || ''; 741 742 if ( _.isArray( type ) ) { 743 found = _.find( type, function (t) { 744 return -1 !== mime.indexOf( t ); 745 } ); 746 } else { 747 found = -1 !== mime.indexOf( type ); 748 } 749 750 return found; 751 }, 752 /** 753 * @static 754 * @param {wp.media.model.Attachment} attachment 755 * 756 * @this wp.media.model.Attachments 757 * 758 * @return {boolean} 759 */ 760 uploadedTo: function( attachment ) { 761 var uploadedTo = this.props.get('uploadedTo'); 762 if ( _.isUndefined( uploadedTo ) ) { 763 return true; 764 } 765 766 return uploadedTo === attachment.get('uploadedTo'); 767 }, 768 /** 769 * @static 770 * @param {wp.media.model.Attachment} attachment 771 * 772 * @this wp.media.model.Attachments 773 * 774 * @return {boolean} 775 */ 776 status: function( attachment ) { 777 var status = this.props.get('status'); 778 if ( _.isUndefined( status ) ) { 779 return true; 780 } 781 782 return status === attachment.get('status'); 783 } 784 } 785 }); 786 787 module.exports = Attachments; 788 789 790 /***/ }, 791 792 /***/ 9104 793 (module) { 794 795 /** 796 * wp.media.model.PostImage 797 * 798 * An instance of an image that's been embedded into a post. 799 * 800 * Used in the embedded image attachment display settings modal - @see wp.media.view.MediaFrame.ImageDetails. 801 * 802 * @memberOf wp.media.model 803 * 804 * @class 805 * @augments Backbone.Model 806 * 807 * @param {int} [attributes] Initial model attributes. 808 * @param {int} [attributes.attachment_id] ID of the attachment. 809 **/ 810 var PostImage = Backbone.Model.extend(/** @lends wp.media.model.PostImage.prototype */{ 811 812 initialize: function( attributes ) { 813 var Attachment = wp.media.model.Attachment; 814 this.attachment = false; 815 816 if ( attributes.attachment_id ) { 817 this.attachment = Attachment.get( attributes.attachment_id ); 818 if ( this.attachment.get( 'url' ) ) { 819 this.dfd = jQuery.Deferred(); 820 this.dfd.resolve(); 821 } else { 822 this.dfd = this.attachment.fetch(); 823 } 824 this.bindAttachmentListeners(); 825 } 826 827 // Keep URL in sync with changes to the type of link. 828 this.on( 'change:link', this.updateLinkUrl, this ); 829 this.on( 'change:size', this.updateSize, this ); 830 831 this.setLinkTypeFromUrl(); 832 this.setAspectRatio(); 833 834 this.set( 'originalUrl', attributes.url ); 835 }, 836 837 bindAttachmentListeners: function() { 838 this.listenTo( this.attachment, 'sync', this.setLinkTypeFromUrl ); 839 this.listenTo( this.attachment, 'sync', this.setAspectRatio ); 840 this.listenTo( this.attachment, 'change', this.updateSize ); 841 }, 842 843 changeAttachment: function( attachment, props ) { 844 this.stopListening( this.attachment ); 845 this.attachment = attachment; 846 this.bindAttachmentListeners(); 847 848 this.set( 'attachment_id', this.attachment.get( 'id' ) ); 849 this.set( 'caption', this.attachment.get( 'caption' ) ); 850 this.set( 'alt', this.attachment.get( 'alt' ) ); 851 this.set( 'size', props.get( 'size' ) ); 852 this.set( 'align', props.get( 'align' ) ); 853 this.set( 'link', props.get( 'link' ) ); 854 this.updateLinkUrl(); 855 this.updateSize(); 856 }, 857 858 setLinkTypeFromUrl: function() { 859 var linkUrl = this.get( 'linkUrl' ), 860 type; 861 862 if ( ! linkUrl ) { 863 this.set( 'link', 'none' ); 864 return; 865 } 866 867 // Default to custom if there is a linkUrl. 868 type = 'custom'; 869 870 if ( this.attachment ) { 871 if ( this.attachment.get( 'url' ) === linkUrl ) { 872 type = 'file'; 873 } else if ( this.attachment.get( 'link' ) === linkUrl ) { 874 type = 'post'; 875 } 876 } else { 877 if ( this.get( 'url' ) === linkUrl ) { 878 type = 'file'; 879 } 880 } 881 882 this.set( 'link', type ); 883 }, 884 885 updateLinkUrl: function() { 886 var link = this.get( 'link' ), 887 url; 888 889 switch( link ) { 890 case 'file': 891 if ( this.attachment ) { 892 url = this.attachment.get( 'url' ); 893 } else { 894 url = this.get( 'url' ); 895 } 896 this.set( 'linkUrl', url ); 897 break; 898 case 'post': 899 this.set( 'linkUrl', this.attachment.get( 'link' ) ); 900 break; 901 case 'none': 902 this.set( 'linkUrl', '' ); 903 break; 904 } 905 }, 906 907 updateSize: function() { 908 var size; 909 910 if ( ! this.attachment ) { 911 return; 912 } 913 914 if ( this.get( 'size' ) === 'custom' ) { 915 this.set( 'width', this.get( 'customWidth' ) ); 916 this.set( 'height', this.get( 'customHeight' ) ); 917 this.set( 'url', this.get( 'originalUrl' ) ); 918 return; 919 } 920 921 size = this.attachment.get( 'sizes' )[ this.get( 'size' ) ]; 922 923 if ( ! size ) { 924 return; 925 } 926 927 this.set( 'url', size.url ); 928 this.set( 'width', size.width ); 929 this.set( 'height', size.height ); 930 }, 931 932 setAspectRatio: function() { 933 var full; 934 935 if ( this.attachment && this.attachment.get( 'sizes' ) ) { 936 full = this.attachment.get( 'sizes' ).full; 937 938 if ( full ) { 939 this.set( 'aspectRatio', full.width / full.height ); 940 return; 941 } 942 } 943 944 this.set( 'aspectRatio', this.get( 'customWidth' ) / this.get( 'customHeight' ) ); 945 } 946 }); 947 948 module.exports = PostImage; 949 950 951 /***/ }, 952 953 /***/ 1288 954 (module) { 955 956 var Attachments = wp.media.model.Attachments, 957 Query; 958 959 /** 960 * wp.media.model.Query 961 * 962 * A collection of attachments that match the supplied query arguments. 963 * 964 * Note: Do NOT change this.args after the query has been initialized. 965 * Things will break. 966 * 967 * @memberOf wp.media.model 968 * 969 * @class 970 * @augments wp.media.model.Attachments 971 * @augments Backbone.Collection 972 * 973 * @param {array} [models] Models to initialize with the collection. 974 * @param {object} [options] Options hash. 975 * @param {object} [options.args] Attachments query arguments. 976 * @param {object} [options.args.posts_per_page] 977 */ 978 Query = Attachments.extend(/** @lends wp.media.model.Query.prototype */{ 979 /** 980 * @param {Array} [models=[]] Array of initial models to populate the collection. 981 * @param {Object} [options={}] 982 */ 983 initialize: function( models, options ) { 984 var allowed; 985 986 options = options || {}; 987 Attachments.prototype.initialize.apply( this, arguments ); 988 989 this.args = options.args; 990 this._hasMore = true; 991 this.created = new Date(); 992 993 this.filters.order = function( attachment ) { 994 var orderby = this.props.get('orderby'), 995 order = this.props.get('order'); 996 997 if ( ! this.comparator ) { 998 return true; 999 } 1000 1001 /* 1002 * We want any items that can be placed before the last 1003 * item in the set. If we add any items after the last 1004 * item, then we can't guarantee the set is complete. 1005 */ 1006 if ( this.length ) { 1007 return 1 !== this.comparator( attachment, this.last(), { ties: true }); 1008 1009 /* 1010 * Handle the case where there are no items yet and 1011 * we're sorting for recent items. In that case, we want 1012 * changes that occurred after we created the query. 1013 */ 1014 } else if ( 'DESC' === order && ( 'date' === orderby || 'modified' === orderby ) ) { 1015 return attachment.get( orderby ) >= this.created; 1016 1017 // If we're sorting by menu order and we have no items, 1018 // accept any items that have the default menu order (0). 1019 } else if ( 'ASC' === order && 'menuOrder' === orderby ) { 1020 return attachment.get( orderby ) === 0; 1021 } 1022 1023 // Otherwise, we don't want any items yet. 1024 return false; 1025 }; 1026 1027 /* 1028 * Observe the central `wp.Uploader.queue` collection to watch for 1029 * new matches for the query. 1030 * 1031 * Only observe when a limited number of query args are set. There 1032 * are no filters for other properties, so observing will result in 1033 * false positives in those queries. 1034 */ 1035 allowed = [ 's', 'order', 'orderby', 'posts_per_page', 'post_mime_type', 'post_parent', 'author' ]; 1036 if ( wp.Uploader && _( this.args ).chain().keys().difference( allowed ).isEmpty().value() ) { 1037 this.observe( wp.Uploader.queue ); 1038 } 1039 }, 1040 /** 1041 * Whether there are more attachments that haven't been sync'd from the server 1042 * that match the collection's query. 1043 * 1044 * @return {boolean} 1045 */ 1046 hasMore: function() { 1047 return this._hasMore; 1048 }, 1049 /** 1050 * Fetch more attachments from the server for the collection. 1051 * 1052 * @param {Object} [options={}] 1053 * @return {Promise} 1054 */ 1055 more: function( options ) { 1056 var query = this; 1057 1058 // If there is already a request pending, return early with the Deferred object. 1059 if ( this._more && 'pending' === this._more.state() ) { 1060 return this._more; 1061 } 1062 1063 if ( ! this.hasMore() ) { 1064 return jQuery.Deferred().resolveWith( this ).promise(); 1065 } 1066 1067 options = options || {}; 1068 options.remove = false; 1069 1070 return this._more = this.fetch( options ).done( function( response ) { 1071 if ( _.isEmpty( response ) || -1 === query.args.posts_per_page || response.length < query.args.posts_per_page ) { 1072 query._hasMore = false; 1073 } 1074 }); 1075 }, 1076 /** 1077 * Overrides Backbone.Collection.sync 1078 * Overrides wp.media.model.Attachments.sync 1079 * 1080 * @param {string} method 1081 * @param {Backbone.Model} model 1082 * @param {Object} [options={}] 1083 * @return {Promise} 1084 */ 1085 sync: function( method, model, options ) { 1086 var args, fallback; 1087 1088 // Overload the read method so Attachment.fetch() functions correctly. 1089 if ( 'read' === method ) { 1090 options = options || {}; 1091 options.context = this; 1092 options.data = _.extend( options.data || {}, { 1093 action: 'query-attachments', 1094 post_id: wp.media.model.settings.post.id 1095 }); 1096 1097 // Clone the args so manipulation is non-destructive. 1098 args = _.clone( this.args ); 1099 1100 // Determine which page to query. 1101 if ( -1 !== args.posts_per_page ) { 1102 args.paged = Math.round( this.length / args.posts_per_page ) + 1; 1103 } 1104 1105 options.data.query = args; 1106 return wp.media.ajax( options ); 1107 1108 // Otherwise, fall back to `Backbone.sync()`. 1109 } else { 1110 /** 1111 * Call wp.media.model.Attachments.sync or Backbone.sync 1112 */ 1113 fallback = Attachments.prototype.sync ? Attachments.prototype : Backbone; 1114 return fallback.sync.apply( this, arguments ); 1115 } 1116 } 1117 }, /** @lends wp.media.model.Query */{ 1118 /** 1119 * @readonly 1120 */ 1121 defaultProps: { 1122 orderby: 'date', 1123 order: 'DESC' 1124 }, 1125 /** 1126 * @readonly 1127 */ 1128 defaultArgs: { 1129 posts_per_page: 80 1130 }, 1131 /** 1132 * @readonly 1133 */ 1134 orderby: { 1135 allowed: [ 'name', 'author', 'date', 'title', 'modified', 'uploadedTo', 'id', 'post__in', 'menuOrder' ], 1136 /** 1137 * A map of JavaScript orderby values to their WP_Query equivalents. 1138 * @type {Object} 1139 */ 1140 valuemap: { 1141 'id': 'ID', 1142 'uploadedTo': 'parent', 1143 'menuOrder': 'menu_order ID' 1144 } 1145 }, 1146 /** 1147 * A map of JavaScript query properties to their WP_Query equivalents. 1148 * 1149 * @readonly 1150 */ 1151 propmap: { 1152 'search': 's', 1153 'type': 'post_mime_type', 1154 'perPage': 'posts_per_page', 1155 'menuOrder': 'menu_order', 1156 'uploadedTo': 'post_parent', 1157 'status': 'post_status', 1158 'include': 'post__in', 1159 'exclude': 'post__not_in', 1160 'author': 'author' 1161 }, 1162 /** 1163 * Creates and returns an Attachments Query collection given the properties. 1164 * 1165 * Caches query objects and reuses where possible. 1166 * 1167 * @static 1168 * @method 1169 * 1170 * @param {object} [props] 1171 * @param {Object} [props.order] 1172 * @param {Object} [props.orderby] 1173 * @param {Object} [props.include] 1174 * @param {Object} [props.exclude] 1175 * @param {Object} [props.s] 1176 * @param {Object} [props.post_mime_type] 1177 * @param {Object} [props.posts_per_page] 1178 * @param {Object} [props.menu_order] 1179 * @param {Object} [props.post_parent] 1180 * @param {Object} [props.post_status] 1181 * @param {Object} [props.author] 1182 * @param {Object} [options] 1183 * 1184 * @return {wp.media.model.Query} A new Attachments Query collection. 1185 */ 1186 get: (function(){ 1187 /** 1188 * @static 1189 * @type Array 1190 */ 1191 var queries = []; 1192 1193 /** 1194 * @return {Query} 1195 */ 1196 return function( props, options ) { 1197 var args = {}, 1198 orderby = Query.orderby, 1199 defaults = Query.defaultProps, 1200 query; 1201 1202 // Remove the `query` property. This isn't linked to a query, 1203 // this *is* the query. 1204 delete props.query; 1205 1206 // Fill default args. 1207 _.defaults( props, defaults ); 1208 1209 // Normalize the order. 1210 props.order = props.order.toUpperCase(); 1211 if ( 'DESC' !== props.order && 'ASC' !== props.order ) { 1212 props.order = defaults.order.toUpperCase(); 1213 } 1214 1215 // Ensure we have a valid orderby value. 1216 if ( ! _.contains( orderby.allowed, props.orderby ) ) { 1217 props.orderby = defaults.orderby; 1218 } 1219 1220 _.each( [ 'include', 'exclude' ], function( prop ) { 1221 if ( props[ prop ] && ! _.isArray( props[ prop ] ) ) { 1222 props[ prop ] = [ props[ prop ] ]; 1223 } 1224 } ); 1225 1226 // Generate the query `args` object. 1227 // Correct any differing property names. 1228 _.each( props, function( value, prop ) { 1229 if ( _.isNull( value ) ) { 1230 return; 1231 } 1232 1233 args[ Query.propmap[ prop ] || prop ] = value; 1234 }); 1235 1236 // Fill any other default query args. 1237 _.defaults( args, Query.defaultArgs ); 1238 1239 // `props.orderby` does not always map directly to `args.orderby`. 1240 // Substitute exceptions specified in orderby.keymap. 1241 args.orderby = orderby.valuemap[ props.orderby ] || props.orderby; 1242 1243 queries = []; 1244 1245 // Otherwise, create a new query and add it to the cache. 1246 if ( ! query ) { 1247 query = new Query( [], _.extend( options || {}, { 1248 props: props, 1249 args: args 1250 } ) ); 1251 queries.push( query ); 1252 } 1253 1254 return query; 1255 }; 1256 }()) 1257 }); 1258 1259 module.exports = Query; 1260 1261 1262 /***/ }, 1263 1264 /***/ 4134 1265 (module) { 1266 1267 var Attachments = wp.media.model.Attachments, 1268 Selection; 1269 1270 /** 1271 * wp.media.model.Selection 1272 * 1273 * A selection of attachments. 1274 * 1275 * @memberOf wp.media.model 1276 * 1277 * @class 1278 * @augments wp.media.model.Attachments 1279 * @augments Backbone.Collection 1280 */ 1281 Selection = Attachments.extend(/** @lends wp.media.model.Selection.prototype */{ 1282 /** 1283 * Refresh the `single` model whenever the selection changes. 1284 * Binds `single` instead of using the context argument to ensure 1285 * it receives no parameters. 1286 * 1287 * @param {Array} [models=[]] Array of models used to populate the collection. 1288 * @param {Object} [options={}] 1289 */ 1290 initialize: function( models, options ) { 1291 /** 1292 * call 'initialize' directly on the parent class 1293 */ 1294 Attachments.prototype.initialize.apply( this, arguments ); 1295 this.multiple = options && options.multiple; 1296 1297 this.on( 'add remove reset', _.bind( this.single, this, false ) ); 1298 }, 1299 1300 /** 1301 * If the workflow does not support multi-select, clear out the selection 1302 * before adding a new attachment to it. 1303 * 1304 * @param {Array} models 1305 * @param {Object} options 1306 * @return {wp.media.model.Attachment[]} 1307 */ 1308 add: function( models, options ) { 1309 if ( ! this.multiple ) { 1310 this.remove( this.models ); 1311 } 1312 /** 1313 * call 'add' directly on the parent class 1314 */ 1315 return Attachments.prototype.add.call( this, models, options ); 1316 }, 1317 1318 /** 1319 * Fired when toggling (clicking on) an attachment in the modal. 1320 * 1321 * @param {undefined|boolean|wp.media.model.Attachment} model 1322 * 1323 * @fires wp.media.model.Selection#selection:single 1324 * @fires wp.media.model.Selection#selection:unsingle 1325 * 1326 * @return {Backbone.Model} 1327 */ 1328 single: function( model ) { 1329 var previous = this._single; 1330 1331 // If a `model` is provided, use it as the single model. 1332 if ( model ) { 1333 this._single = model; 1334 } 1335 // If the single model isn't in the selection, remove it. 1336 if ( this._single && ! this.get( this._single.cid ) ) { 1337 delete this._single; 1338 } 1339 1340 this._single = this._single || this.last(); 1341 1342 // If single has changed, fire an event. 1343 if ( this._single !== previous ) { 1344 if ( previous ) { 1345 previous.trigger( 'selection:unsingle', previous, this ); 1346 1347 // If the model was already removed, trigger the collection 1348 // event manually. 1349 if ( ! this.get( previous.cid ) ) { 1350 this.trigger( 'selection:unsingle', previous, this ); 1351 } 1352 } 1353 if ( this._single ) { 1354 this._single.trigger( 'selection:single', this._single, this ); 1355 } 1356 } 1357 1358 // Return the single model, or the last model as a fallback. 1359 return this._single; 1360 } 1361 }); 1362 1363 module.exports = Selection; 1364 1365 1366 /***/ } 1367 1368 /******/ }); 1369 /************************************************************************/ 1370 /******/ // The module cache 1371 /******/ const __webpack_module_cache__ = {}; 1372 /******/ 1373 /******/ // The require function 1374 /******/ function __webpack_require__(moduleId) { 1375 /******/ // Check if module is in cache 1376 /******/ const cachedModule = __webpack_module_cache__[moduleId]; 1377 /******/ if (cachedModule !== undefined) { 1378 /******/ return cachedModule.exports; 1379 /******/ } 1380 /******/ // Create a new module (and put it into the cache) 1381 /******/ const module = __webpack_module_cache__[moduleId] = { 1382 /******/ // no module.id needed 1383 /******/ // no module.loaded needed 1384 /******/ exports: {} 1385 /******/ }; 1386 /******/ 1387 /******/ // Execute the module function 1388 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 1389 /******/ 1390 /******/ // Return the exports of the module 1391 /******/ return module.exports; 1392 /******/ } 1393 /******/ 1394 /************************************************************************/ 1395 /** 1396 * @output wp-includes/js/media-models.js 1397 */ 1398 1399 var 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__( 3343 ); 1465 Attachments = media.model.Attachments = __webpack_require__( 8266 ); 1466 1467 media.model.Query = __webpack_require__( 1288 ); 1468 media.model.PostImage = __webpack_require__( 9104 ); 1469 media.model.Selection = __webpack_require__( 4134 ); 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 /******/ })() 1635 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Mon Jul 20 08:20:16 2026 | Cross-referenced by PHPXref |