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