Media JS: Add media.model.Composite, to aid in the representation of joint views. see #21390.

git-svn-id: https://develop.svn.wordpress.org/trunk@22467 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Daryl Koopersmith 2012-11-08 15:32:40 +00:00
parent 68d143d20d
commit cf75c68b55
2 changed files with 87 additions and 34 deletions

View File

@ -697,4 +697,77 @@ window.wp = window.wp || {};
}
});
/**
* wp.media.model.Composite
*
* Creates a model that can simultaneously pull from two or more collections.
*/
media.model.Composite = Attachments.extend({
initialize: function( models, options ) {
this.observe( this, { silent: true });
Attachments.prototype.initialize.apply( this, arguments );
},
evaluate: function( attachment, options ) {
var valid = this.validator( attachment ),
hasAttachment = !! this.getByCid( attachment.cid );
if ( ! valid && hasAttachment ) {
this.remove( attachment, options );
} else if ( valid && ! hasAttachment ) {
this.add( attachment, options );
// If we haven't been silenced, resort the collection.
if ( this.comparator && ( ! options || ! options.silent ) )
this.sort({ silent: true });
}
return this;
},
validator: function() {
return true;
},
evaluateAll: function( attachments, options ) {
_.each( attachments.models, function( attachment ) {
this.evaluate( attachment, { silent: true });
}, this );
if ( this.comparator )
this.sort( options );
return this;
},
observe: function( attachments, options ) {
var silent = options && options.silent;
attachments.on( 'add remove', silent ? this._evaluateSilentHandler : this._evaluateHandler, this );
attachments.on( 'reset', silent ? this._evaluateAllSilentHandler : this._evaluateAllHandler, this );
this.evaluateAll( attachments, options );
},
unobserve: function( attachments ) {
attachments.off( 'add remove', this._evaluateHandler, this );
attachments.off( 'reset', this._evaluateAllHandler, this );
},
_evaluateHandler: function( attachment, attachments, options ) {
return this.evaluate( attachment, options );
},
_evaluateAllHandler: function( attachments, options ) {
return this.evaluateAll( attachments, options );
},
_evaluateSilentHandler: function( attachment, attachments, options ) {
return this.evaluate( attachment, _.defaults({ silent: true }, options ) );
},
_evaluateAllSilentHandler: function( attachments, options ) {
return this.evaluateAll( attachments, _.defaults({ silent: true }, options ) );
}
});
}(jQuery));

View File

@ -681,52 +681,32 @@
_.each(['gallery-library','gallery-upload'], function( id ) {
var state = this.get( id ),
original = state.get('_library'),
skeleton;
composite;
// Remember the state's original library.
if ( ! original )
state.set( '_library', original = state.get('library') );
// Create a skeleton library in its place.
skeleton = new Attachments( null, {
// Create a composite library in its place.
composite = new media.model.Composite( null, {
props: _.pick( original.props.toJSON(), 'order', 'orderby' )
});
// Rejects attachments that do not exist in the original library
// or that do exist edit state's library.
skeleton.filters.difference = function( attachment ) {
return ! original.getByCid( attachment.cid ) || !! editLibrary.getByCid( attachment.cid );
// Accepts attachments that exist in the original library and
// that do not exist in the state's library.
composite.validator = function( attachment ) {
return !! original.getByCid( attachment.cid ) && ! editLibrary.getByCid( attachment.cid );
};
skeleton.evaluate = function( attachment ) {
var valid = ! this.validator( attachment ),
inSkeleton = !! this.getByCid( attachment.cid );
composite.observe( original );
composite.observe( editLibrary );
if ( ! valid && inSkeleton )
this.remove( attachment );
else if ( valid && ! inSkeleton )
this.add( attachment ).sort();
// When `more()` is triggered on the composite collection,
// pass the command over to the `original`, which will
// populate the query.
composite.more = _.bind( original.more, original );
return this;
};
skeleton.evaluateAll = function ( attachments ) {
_.each( attachments.models, this.evaluate, this );
return this;
};
skeleton.on( 'add remove', skeleton.evaluate, skeleton );
skeleton.on( 'reset', skeleton.evaluateAll, skeleton );
editLibrary.on( 'add remove', skeleton.evaluate, skeleton );
editLibrary.on( 'reset', skeleton.evaluateAll, skeleton );
// Mirror the original library.
skeleton.mirror( original );
// Ensure we've evaluated everything in the edit library.
skeleton.evaluateAll( editLibrary );
state.set( 'library', skeleton );
state.set( 'library', composite );
}, this );
},