Commit c375a2ed authored by Scott Taylor's avatar Scott Taylor
Browse files

Add an abstraction of the gallery code in `media-editor.js` called...

Add an abstraction of the gallery code in `media-editor.js` called `wp.media.collection`. This will be the basis for parsing `[gallery]`-like shortcodes in the media editor (thing playlists, collections of PDFs, etc).

There are currently no instances of this. Those will be forthcoming.

See #26631.


Built from https://develop.svn.wordpress.org/trunk@27212


git-svn-id: https://core.svn.wordpress.org/trunk@27069 1a063a9b-81f0-0310-95a4-ce76da25c4cd
parent 9e1fbc29
Loading
Loading
Loading
Loading
+263 −0
Original line number Diff line number Diff line
@@ -274,6 +274,269 @@
		}
	};

	/**
	 * wp.media.collection
	 * @namespace
	 */
	wp.media.collection = {
		attachments : function ( prop, type ) {
			/**
			 * Retrieve attachments based on the properties of the passed shortcode
			 *
			 * @global wp.media.query
			 *
			 * @param {wp.shortcode} shortcode An instance of wp.shortcode().
			 * @returns {wp.media.model.Attachments} A Backbone.Collection containing
			 *      the media items belonging to a collection.
			 *      The 'prop' specified by the passed prop is a Backbone.Model
			 *			containing the 'props' for the gallery.
			 */
			return function( shortcode ) {
  				var shortcodeString = shortcode.string(),
 					result = cache[ shortcodeString ],
  					attrs, args, query, others;

 				delete cache[ shortcodeString ];

  				if ( result ) {
  					return result;
				}

  				// Fill the default shortcode attributes.
 				attrs = _.defaults( shortcode.attrs.named, this.defaults );
  				args  = _.pick( attrs, 'orderby', 'order' );

 				args.type = type;
  				args.perPage = -1;

  				// Mark the `orderby` override attribute.
 				if ( undefined !== attrs.orderby ) {
  					attrs._orderByField = attrs.orderby;
				}

				if ( 'rand' === attrs.orderby ) {
					attrs._orderbyRandom = true;
				}

				if ( -1 !== jQuery.inArray( prop, ['playlist', 'video-playlist'] ) ) {
					_.each(['tracknumbers', 'tracklist', 'images'], function (setting) {
						if ( 'undefined' === typeof attrs[setting] ) {
							attrs['_' + setting] = wp.media[ prop ].defaults[ setting ];
						} else if ( 'true' === attrs[setting] || true === attrs[setting] ) {
							attrs['_' + setting] = true;
						}
					});
				}

				// Map the `orderby` attribute to the corresponding model property.
				if ( ! attrs.orderby || /^menu_order(?: ID)?$/i.test( attrs.orderby ) ) {
					args.orderby = 'menuOrder';
				}

				// Map the `ids` param to the correct query args.
				if ( attrs.ids ) {
					args.post__in = attrs.ids.split(',');
					args.orderby  = 'post__in';
				} else if ( attrs.include ) {
					args.post__in = attrs.include.split(',');
				}

				if ( attrs.exclude ) {
					args.post__not_in = attrs.exclude.split(',');
				}

				if ( ! args.post__in ) {
					args.uploadedTo = attrs.id;
				}

				// Collect the attributes that were not included in `args`.
				others = _.omit( attrs, 'id', 'ids', 'include', 'exclude', 'orderby', 'order' );

				query = wp.media.query( args );
				query[ prop ] = new Backbone.Model( others );
				return query;
			};
		},

 		shortcodeAttrs : function ( prop, attachments ) {
 			var props = attachments.props.toJSON(),
 				attrs = _.pick( props, 'orderby', 'order', 'style' );

 			if ( attachments[ prop ] ) {
 				_.extend( attrs, attachments[ prop ].toJSON() );
			}

 			// Convert all collection shortcodes to use the `ids` property.
 			// Ignore `post__in` and `post__not_in`; the attachments in
 			// the collection will already reflect those properties.
 			attrs.ids = attachments.pluck('id');

 			// Copy the `uploadedTo` post ID.
 			if ( props.uploadedTo ) {
 				attrs.id = props.uploadedTo;
			}

 			// Check if the collection is randomly ordered.
 			delete attrs.orderby;

 			if ( attrs._orderbyRandom ) {
 				attrs.orderby = 'rand';
			} else if ( attrs._orderByField && attrs._orderByField != 'rand' ) {
 				attrs.orderby = attrs._orderByField;
			}

 			delete attrs._orderbyRandom;
			delete attrs._orderByField;

 			// If the `ids` attribute is set and `orderby` attribute
 			// is the default value, clear it for cleaner output.
 			if ( attrs.ids && 'post__in' === attrs.orderby ) {
  				delete attrs.orderby;
			}

			if ( -1 !== jQuery.inArray( prop, ['playlist', 'video-playlist'] ) ) {
				_.each(['tracknumbers', 'tracklist', 'images'], function (setting) {
					if ( attrs['_' + setting] ) {
						attrs[setting] = true;
					} else {
						attrs[setting] = false;
					}
					delete attrs['_' + setting];
				});
			}

 			// Remove default attributes from the shortcode.
 			_.each( this.defaults, function( value, key ) {
 				if ( value === attrs[ key ] ) {
 					delete attrs[ key ];
				}
 			});
 			return attrs;
 		},

 		editSelection : function ( prop, shortcode ) {
 			var defaultPostId = wp.media[ prop ].defaults.id,
				attachments, selection;

 			// Ignore the rest of the match object.
 			shortcode = shortcode.shortcode;

 			if ( _.isUndefined( shortcode.get('id') ) && ! _.isUndefined( defaultPostId ) ) {
 				shortcode.set( 'id', defaultPostId );
			}

 			attachments = wp.media[ prop ].attachments( shortcode );

 			selection = new wp.media.model.Selection( attachments.models, {
 				props:    attachments.props.toJSON(),
 				multiple: true
 			});

 			selection[ prop ] = attachments[ prop ];

 			// Fetch the query's attachments, and then break ties from the
			// query to allow for sorting.
 			selection.more().done( function() {
 				// Break ties with the query.
 				selection.props.set({ query: false });
 				selection.unmirror();
 				selection.props.unset('orderby');
 			});

 			return selection;
 		},

		/**
		 *
		 * @param {string} prop The shortcode slug
		 * @param {wp.media.model.Attachments} attachments
		 * @param {wp.shortcode} shortcode
		 * @returns {wp.shortcode}
		 */
 		cacheShortcode : function ( prop, attachments, shortcode ) {
 			// Use a cloned version of the playlist.
 			var clone = new wp.media.model.Attachments( attachments.models, {
 				props: attachments.props.toJSON()
 			});
 			clone[ prop ] = attachments[ prop ];
 			cache[ shortcode.string() ] = clone;

 			return shortcode;
 		},

 		getEditFrame : function ( args ) {
 			// Destroy the previous gallery frame.
 			if ( this.frame ) {
 				this.frame.dispose();
			}

 			// Store the current gallery frame.
 			this.frame = wp.media( _.extend( {
 				frame:     'post',
 				editing:   true,
 				multiple:  true,
 			}, args ) ).open();

 			return this.frame;
 		},

 		instance : function ( prop, args ) {
 			return {
 				attachments: this.attachments( prop, args.type ),
				/**
				 * Triggered when clicking 'Insert {label}' or 'Update {label}'
				 *
				 * @global wp.shortcode
				 * @global wp.media.model.Attachments
				 *
				 * @param {wp.media.model.Attachments} attachments A Backbone.Collection containing
				 *      the media items belonging to a collection.
				 *      The 'prop' specified by the passed prop is a Backbone.Model
				 *			containing the 'props' for the gallery.
				 * @returns {wp.shortcode}
				 */
 				shortcode: function( attachments ) {
 					var shortcode = new wp.shortcode({
 						tag: prop,
 						attrs: wp.media.collection.shortcodeAttrs( prop, attachments ),
 						type: 'single'
 					});

 					return wp.media.collection.cacheShortcode( prop, attachments, shortcode );
				},
				/**
				 * Triggered when double-clicking a collection shortcode placeholder
				 *   in the editor
				 *
				 * @global wp.shortcode
				 * @global wp.media.model.Selection
				 * @global wp.media.view.l10n
				 *
				 * @param {string} content Content that is searched for possible
				 *    shortcode markup matching the passed tag name,
				 *
				 * @this wp.media.{prop}
				 *
				 * @returns {wp.media.view.MediaFrame.Select} A media workflow.
				 */
 				edit: function( content ) {
 					var shortcode = wp.shortcode.next( prop, content );

 					// Bail if we didn't match the shortcode or all of the content.
 					if ( ! shortcode || shortcode.content !== content ) {
 						return;
					}

 					return wp.media.collection.getEditFrame( {
 						title: args.title,
 						state: prop + '-edit',
 						selection:	wp.media.collection.editSelection( prop, shortcode )
 					} );
 				}
 			};
 		}
	};

	/**
	 * wp.media.gallery
	 * @namespace
+1 −1

File changed.

Preview size limit exceeded, changes collapsed.