wp/wp-includes/js/media-editor.js
changeset 16 a86126ab1dd4
parent 9 177826044cd9
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    17 	/**
    17 	/**
    18 	 * A helper mixin function to avoid truthy and falsey values being
    18 	 * A helper mixin function to avoid truthy and falsey values being
    19 	 *   passed as an input that expects booleans. If key is undefined in the map,
    19 	 *   passed as an input that expects booleans. If key is undefined in the map,
    20 	 *   but has a default value, set it.
    20 	 *   but has a default value, set it.
    21 	 *
    21 	 *
    22 	 * @param {object} attrs Map of props from a shortcode or settings.
    22 	 * @param {Object} attrs Map of props from a shortcode or settings.
    23 	 * @param {string} key The key within the passed map to check for a value.
    23 	 * @param {string} key The key within the passed map to check for a value.
    24 	 * @returns {mixed|undefined} The original or coerced value of key within attrs
    24 	 * @return {mixed|undefined} The original or coerced value of key within attrs.
    25 	 */
    25 	 */
    26 	wp.media.coerce = function ( attrs, key ) {
    26 	wp.media.coerce = function ( attrs, key ) {
    27 		if ( _.isUndefined( attrs[ key ] ) && ! _.isUndefined( this.defaults[ key ] ) ) {
    27 		if ( _.isUndefined( attrs[ key ] ) && ! _.isUndefined( this.defaults[ key ] ) ) {
    28 			attrs[ key ] = this.defaults[ key ];
    28 			attrs[ key ] = this.defaults[ key ];
    29 		} else if ( 'true' === attrs[ key ] ) {
    29 		} else if ( 'true' === attrs[ key ] ) {
    41 		 * outputting the proper object format based on the
    41 		 * outputting the proper object format based on the
    42 		 * attachment's type.
    42 		 * attachment's type.
    43 		 *
    43 		 *
    44 		 * @param {Object} [props={}] Attachment details (align, link, size, etc).
    44 		 * @param {Object} [props={}] Attachment details (align, link, size, etc).
    45 		 * @param {Object} attachment The attachment object, media version of Post.
    45 		 * @param {Object} attachment The attachment object, media version of Post.
    46 		 * @returns {Object} Joined props
    46 		 * @return {Object} Joined props
    47 		 */
    47 		 */
    48 		props: function( props, attachment ) {
    48 		props: function( props, attachment ) {
    49 			var link, linkUrl, size, sizes,
    49 			var link, linkUrl, size, sizes,
    50 				defaultProps = wp.media.view.settings.defaultProps;
    50 				defaultProps = wp.media.view.settings.defaultProps;
    51 
    51 
   107 		/**
   107 		/**
   108 		 * Create link markup that is suitable for passing to the editor
   108 		 * Create link markup that is suitable for passing to the editor
   109 		 *
   109 		 *
   110 		 * @param {Object} props Attachment details (align, link, size, etc).
   110 		 * @param {Object} props Attachment details (align, link, size, etc).
   111 		 * @param {Object} attachment The attachment object, media version of Post.
   111 		 * @param {Object} attachment The attachment object, media version of Post.
   112 		 * @returns {string} The link markup
   112 		 * @return {string} The link markup
   113 		 */
   113 		 */
   114 		link: function( props, attachment ) {
   114 		link: function( props, attachment ) {
   115 			var options;
   115 			var options;
   116 
   116 
   117 			props = wp.media.string.props( props, attachment );
   117 			props = wp.media.string.props( props, attachment );
   133 		/**
   133 		/**
   134 		 * Create an Audio shortcode string that is suitable for passing to the editor
   134 		 * Create an Audio shortcode string that is suitable for passing to the editor
   135 		 *
   135 		 *
   136 		 * @param {Object} props Attachment details (align, link, size, etc).
   136 		 * @param {Object} props Attachment details (align, link, size, etc).
   137 		 * @param {Object} attachment The attachment object, media version of Post.
   137 		 * @param {Object} attachment The attachment object, media version of Post.
   138 		 * @returns {string} The audio shortcode
   138 		 * @return {string} The audio shortcode
   139 		 */
   139 		 */
   140 		audio: function( props, attachment ) {
   140 		audio: function( props, attachment ) {
   141 			return wp.media.string._audioVideo( 'audio', props, attachment );
   141 			return wp.media.string._audioVideo( 'audio', props, attachment );
   142 		},
   142 		},
   143 		/**
   143 		/**
   144 		 * Create a Video shortcode string that is suitable for passing to the editor
   144 		 * Create a Video shortcode string that is suitable for passing to the editor
   145 		 *
   145 		 *
   146 		 * @param {Object} props Attachment details (align, link, size, etc).
   146 		 * @param {Object} props Attachment details (align, link, size, etc).
   147 		 * @param {Object} attachment The attachment object, media version of Post.
   147 		 * @param {Object} attachment The attachment object, media version of Post.
   148 		 * @returns {string} The video shortcode
   148 		 * @return {string} The video shortcode
   149 		 */
   149 		 */
   150 		video: function( props, attachment ) {
   150 		video: function( props, attachment ) {
   151 			return wp.media.string._audioVideo( 'video', props, attachment );
   151 			return wp.media.string._audioVideo( 'video', props, attachment );
   152 		},
   152 		},
   153 		/**
   153 		/**
   156 		 * @access private
   156 		 * @access private
   157 		 *
   157 		 *
   158 		 * @param {string} type The shortcode tag name: 'audio' or 'video'.
   158 		 * @param {string} type The shortcode tag name: 'audio' or 'video'.
   159 		 * @param {Object} props Attachment details (align, link, size, etc).
   159 		 * @param {Object} props Attachment details (align, link, size, etc).
   160 		 * @param {Object} attachment The attachment object, media version of Post.
   160 		 * @param {Object} attachment The attachment object, media version of Post.
   161 		 * @returns {string} The media shortcode
   161 		 * @return {string} The media shortcode
   162 		 */
   162 		 */
   163 		_audioVideo: function( type, props, attachment ) {
   163 		_audioVideo: function( type, props, attachment ) {
   164 			var shortcode, html, extension;
   164 			var shortcode, html, extension;
   165 
   165 
   166 			props = wp.media.string.props( props, attachment );
   166 			props = wp.media.string.props( props, attachment );
   167 			if ( props.link !== 'embed' )
   167 			if ( props.link !== 'embed' ) {
   168 				return wp.media.string.link( props );
   168 				return wp.media.string.link( props );
       
   169 			}
   169 
   170 
   170 			shortcode = {};
   171 			shortcode = {};
   171 
   172 
   172 			if ( 'video' === type ) {
   173 			if ( 'video' === type ) {
   173 				if ( attachment.image && -1 === attachment.image.src.indexOf( attachment.icon ) ) {
   174 				if ( attachment.image && -1 === attachment.image.src.indexOf( attachment.icon ) ) {
   203 		 * Create image markup, optionally with a link and/or wrapped in a caption shortcode,
   204 		 * Create image markup, optionally with a link and/or wrapped in a caption shortcode,
   204 		 *  that is suitable for passing to the editor
   205 		 *  that is suitable for passing to the editor
   205 		 *
   206 		 *
   206 		 * @param {Object} props Attachment details (align, link, size, etc).
   207 		 * @param {Object} props Attachment details (align, link, size, etc).
   207 		 * @param {Object} attachment The attachment object, media version of Post.
   208 		 * @param {Object} attachment The attachment object, media version of Post.
   208 		 * @returns {string}
   209 		 * @return {string}
   209 		 */
   210 		 */
   210 		image: function( props, attachment ) {
   211 		image: function( props, attachment ) {
   211 			var img = {},
   212 			var img = {},
   212 				options, classes, shortcode, html;
   213 				options, classes, shortcode, html;
   213 
   214 
   343 			coerce : wp.media.coerce,
   344 			coerce : wp.media.coerce,
   344 			/**
   345 			/**
   345 			 * Retrieve attachments based on the properties of the passed shortcode
   346 			 * Retrieve attachments based on the properties of the passed shortcode
   346 			 *
   347 			 *
   347 			 * @param {wp.shortcode} shortcode An instance of wp.shortcode().
   348 			 * @param {wp.shortcode} shortcode An instance of wp.shortcode().
   348 			 * @returns {wp.media.model.Attachments} A Backbone.Collection containing
   349 			 * @return {wp.media.model.Attachments} A Backbone.Collection containing
   349 			 *      the media items belonging to a collection.
   350 			 *                                      the media items belonging to a collection.
   350 			 *      The query[ this.tag ] property is a Backbone.Model
   351 			 *                                      The query[ this.tag ] property is a Backbone.Model
   351 			 *          containing the 'props' for the collection.
   352 			 *                                      containing the 'props' for the collection.
   352 			 */
   353 			 */
   353 			attachments: function( shortcode ) {
   354 			attachments: function( shortcode ) {
   354 				var shortcodeString = shortcode.string(),
   355 				var shortcodeString = shortcode.string(),
   355 					result = collections[ shortcodeString ],
   356 					result = collections[ shortcodeString ],
   356 					attrs, args, query, others, self = this;
   357 					attrs, args, query, others, self = this;
   412 			 *
   413 			 *
   413 			 * @param {wp.media.model.Attachments} attachments A Backbone.Collection containing
   414 			 * @param {wp.media.model.Attachments} attachments A Backbone.Collection containing
   414 			 *      the media items belonging to a collection.
   415 			 *      the media items belonging to a collection.
   415 			 *      The query[ this.tag ] property is a Backbone.Model
   416 			 *      The query[ this.tag ] property is a Backbone.Model
   416 			 *          containing the 'props' for the collection.
   417 			 *          containing the 'props' for the collection.
   417 			 * @returns {wp.shortcode}
   418 			 * @return {wp.shortcode}
   418 			 */
   419 			 */
   419 			shortcode: function( attachments ) {
   420 			shortcode: function( attachments ) {
   420 				var props = attachments.props.toJSON(),
   421 				var props = attachments.props.toJSON(),
   421 					attrs = _.pick( props, 'orderby', 'order' ),
   422 					attrs = _.pick( props, 'orderby', 'order' ),
   422 					shortcode, clone;
   423 					shortcode, clone;
   428 
   429 
   429 				if ( attachments[this.tag] ) {
   430 				if ( attachments[this.tag] ) {
   430 					_.extend( attrs, attachments[this.tag].toJSON() );
   431 					_.extend( attrs, attachments[this.tag].toJSON() );
   431 				}
   432 				}
   432 
   433 
   433 				// Convert all gallery shortcodes to use the `ids` property.
   434 				/*
   434 				// Ignore `post__in` and `post__not_in`; the attachments in
   435 				 * Convert all gallery shortcodes to use the `ids` property.
   435 				// the collection will already reflect those properties.
   436 				 * Ignore `post__in` and `post__not_in`; the attachments in
       
   437 				 * the collection will already reflect those properties.
       
   438 				 */
   436 				attrs.ids = attachments.pluck('id');
   439 				attrs.ids = attachments.pluck('id');
   437 
   440 
   438 				// Copy the `uploadedTo` post ID.
   441 				// Copy the `uploadedTo` post ID.
   439 				if ( props.uploadedTo ) {
   442 				if ( props.uploadedTo ) {
   440 					attrs.id = props.uploadedTo;
   443 					attrs.id = props.uploadedTo;
   442 				// Check if the gallery is randomly ordered.
   445 				// Check if the gallery is randomly ordered.
   443 				delete attrs.orderby;
   446 				delete attrs.orderby;
   444 
   447 
   445 				if ( attrs._orderbyRandom ) {
   448 				if ( attrs._orderbyRandom ) {
   446 					attrs.orderby = 'rand';
   449 					attrs.orderby = 'rand';
   447 				} else if ( attrs._orderByField && attrs._orderByField != 'rand' ) {
   450 				} else if ( attrs._orderByField && 'rand' !== attrs._orderByField ) {
   448 					attrs.orderby = attrs._orderByField;
   451 					attrs.orderby = attrs._orderByField;
   449 				}
   452 				}
   450 
   453 
   451 				delete attrs._orderbyRandom;
   454 				delete attrs._orderbyRandom;
   452 				delete attrs._orderByField;
   455 				delete attrs._orderByField;
   481 			 * @param {string} content Content that is searched for possible
   484 			 * @param {string} content Content that is searched for possible
   482 			 *    shortcode markup matching the passed tag name,
   485 			 *    shortcode markup matching the passed tag name,
   483 			 *
   486 			 *
   484 			 * @this wp.media.{prop}
   487 			 * @this wp.media.{prop}
   485 			 *
   488 			 *
   486 			 * @returns {wp.media.view.MediaFrame.Select} A media workflow.
   489 			 * @return {wp.media.view.MediaFrame.Select} A media workflow.
   487 			 */
   490 			 */
   488 			edit: function( content ) {
   491 			edit: function( content ) {
   489 				var shortcode = wp.shortcode.next( this.tag, content ),
   492 				var shortcode = wp.shortcode.next( this.tag, content ),
   490 					defaultPostId = this.defaults.id,
   493 					defaultPostId = this.defaults.id,
   491 					attachments, selection, state;
   494 					attachments, selection, state;
   601 	 */
   604 	 */
   602 	wp.media.featuredImage = {
   605 	wp.media.featuredImage = {
   603 		/**
   606 		/**
   604 		 * Get the featured image post ID
   607 		 * Get the featured image post ID
   605 		 *
   608 		 *
   606 		 * @returns {wp.media.view.settings.post.featuredImageId|number}
   609 		 * @return {wp.media.view.settings.post.featuredImageId|number}
   607 		 */
   610 		 */
   608 		get: function() {
   611 		get: function() {
   609 			return wp.media.view.settings.post.featuredImageId;
   612 			return wp.media.view.settings.post.featuredImageId;
   610 		},
   613 		},
   611 		/**
   614 		/**
   621 			wp.media.post( 'get-post-thumbnail-html', {
   624 			wp.media.post( 'get-post-thumbnail-html', {
   622 				post_id:      settings.post.id,
   625 				post_id:      settings.post.id,
   623 				thumbnail_id: settings.post.featuredImageId,
   626 				thumbnail_id: settings.post.featuredImageId,
   624 				_wpnonce:     settings.post.nonce
   627 				_wpnonce:     settings.post.nonce
   625 			}).done( function( html ) {
   628 			}).done( function( html ) {
   626 				if ( html == '0' ) {
   629 				if ( '0' === html ) {
   627 					window.alert( window.setPostThumbnailL10n.error );
   630 					window.alert( wp.i18n.__( 'Could not set that as the thumbnail image. Try a different attachment.' ) );
   628 					return;
   631 					return;
   629 				}
   632 				}
   630 				$( '.inside', '#postimagediv' ).html( html );
   633 				$( '.inside', '#postimagediv' ).html( html );
   631 			});
   634 			});
   632 		},
   635 		},
   640 		/**
   643 		/**
   641 		 * The Featured Image workflow
   644 		 * The Featured Image workflow
   642 		 *
   645 		 *
   643 		 * @this wp.media.featuredImage
   646 		 * @this wp.media.featuredImage
   644 		 *
   647 		 *
   645 		 * @returns {wp.media.view.MediaFrame.Select} A media workflow.
   648 		 * @return {wp.media.view.MediaFrame.Select} A media workflow.
   646 		 */
   649 		 */
   647 		frame: function() {
   650 		frame: function() {
   648 			if ( this._frame ) {
   651 			if ( this._frame ) {
   649 				wp.media.frame = this._frame;
   652 				wp.media.frame = this._frame;
   650 				return this._frame;
   653 				return this._frame;
   668 				var selection = this.state('featured-image').get('selection'),
   671 				var selection = this.state('featured-image').get('selection'),
   669 					view = new wp.media.view.EditImage( { model: selection.single(), controller: this } ).render();
   672 					view = new wp.media.view.EditImage( { model: selection.single(), controller: this } ).render();
   670 
   673 
   671 				this.content.set( view );
   674 				this.content.set( view );
   672 
   675 
   673 				// after bringing in the frame, load the actual editor via an ajax call
   676 				// After bringing in the frame, load the actual editor via an Ajax call.
   674 				view.loadEditor();
   677 				view.loadEditor();
   675 
   678 
   676 			}, this._frame );
   679 			}, this._frame );
   677 
   680 
   678 			this._frame.state('featured-image').on( 'select', this.select );
   681 			this._frame.state('featured-image').on( 'select', this.select );
   731 				wpActiveEditor = window.wpActiveEditor = this.activeEditor;
   734 				wpActiveEditor = window.wpActiveEditor = this.activeEditor;
   732 			} else {
   735 			} else {
   733 				wpActiveEditor = window.wpActiveEditor;
   736 				wpActiveEditor = window.wpActiveEditor;
   734 			}
   737 			}
   735 
   738 
   736 			// Delegate to the global `send_to_editor` if it exists.
   739 			/*
   737 			// This attempts to play nice with any themes/plugins that have
   740 			 * Delegate to the global `send_to_editor` if it exists.
   738 			// overridden the insert functionality.
   741 			 * This attempts to play nice with any themes/plugins
       
   742 			 * that have overridden the insert functionality.
       
   743 			 */
   739 			if ( window.send_to_editor ) {
   744 			if ( window.send_to_editor ) {
   740 				return window.send_to_editor.apply( this, arguments );
   745 				return window.send_to_editor.apply( this, arguments );
   741 			}
   746 			}
   742 
   747 
   743 			if ( ! wpActiveEditor ) {
   748 			if ( ! wpActiveEditor ) {
   773 		 * @param {string} id A slug used to identify the workflow.
   778 		 * @param {string} id A slug used to identify the workflow.
   774 		 * @param {Object} [options={}]
   779 		 * @param {Object} [options={}]
   775 		 *
   780 		 *
   776 		 * @this wp.media.editor
   781 		 * @this wp.media.editor
   777 		 *
   782 		 *
   778 		 * @returns {wp.media.view.MediaFrame.Select} A media workflow.
   783 		 * @return {wp.media.view.MediaFrame.Select} A media workflow.
   779 		 */
   784 		 */
   780 		add: function( id, options ) {
   785 		add: function( id, options ) {
   781 			var workflow = this.get( id );
   786 			var workflow = this.get( id );
   782 
   787 
   783 			// only add once: if exists return existing
   788 			// Only add once: if exists return existing.
   784 			if ( workflow ) {
   789 			if ( workflow ) {
   785 				return workflow;
   790 				return workflow;
   786 			}
   791 			}
   787 
   792 
   788 			workflow = workflows[ id ] = wp.media( _.defaults( options || {}, {
   793 			workflow = workflows[ id ] = wp.media( _.defaults( options || {}, {
   795 			workflow.on( 'insert', function( selection ) {
   800 			workflow.on( 'insert', function( selection ) {
   796 				var state = workflow.state();
   801 				var state = workflow.state();
   797 
   802 
   798 				selection = selection || state.get('selection');
   803 				selection = selection || state.get('selection');
   799 
   804 
   800 				if ( ! selection )
   805 				if ( ! selection ) {
   801 					return;
   806 					return;
       
   807 				}
   802 
   808 
   803 				$.when.apply( $, selection.map( function( attachment ) {
   809 				$.when.apply( $, selection.map( function( attachment ) {
   804 					var display = state.display( attachment ).toJSON();
   810 					var display = state.display( attachment ).toJSON();
   805 					/**
   811 					/**
   806 					 * @this wp.media.editor
   812 					 * @this wp.media.editor
   877 		/**
   883 		/**
   878 		 * Determines the proper current workflow id
   884 		 * Determines the proper current workflow id
   879 		 *
   885 		 *
   880 		 * @param {string} [id=''] A slug used to identify the workflow.
   886 		 * @param {string} [id=''] A slug used to identify the workflow.
   881 		 *
   887 		 *
   882 		 * @returns {wpActiveEditor|string|tinymce.activeEditor.id}
   888 		 * @return {wpActiveEditor|string|tinymce.activeEditor.id}
   883 		 */
   889 		 */
   884 		id: function( id ) {
   890 		id: function( id ) {
   885 			if ( id ) {
   891 			if ( id ) {
   886 				return id;
   892 				return id;
   887 			}
   893 			}
   903 		 *
   909 		 *
   904 		 * @param {string} id A slug used to identify the workflow.
   910 		 * @param {string} id A slug used to identify the workflow.
   905 		 *
   911 		 *
   906 		 * @this wp.media.editor
   912 		 * @this wp.media.editor
   907 		 *
   913 		 *
   908 		 * @returns {wp.media.view.MediaFrame} A media workflow.
   914 		 * @return {wp.media.view.MediaFrame} A media workflow.
   909 		 */
   915 		 */
   910 		get: function( id ) {
   916 		get: function( id ) {
   911 			id = this.id( id );
   917 			id = this.id( id );
   912 			return workflows[ id ];
   918 			return workflows[ id ];
   913 		},
   919 		},
   928 			 * Called when sending an attachment to the editor
   934 			 * Called when sending an attachment to the editor
   929 			 *   from the medial modal.
   935 			 *   from the medial modal.
   930 			 *
   936 			 *
   931 			 * @param {Object} props Attachment details (align, link, size, etc).
   937 			 * @param {Object} props Attachment details (align, link, size, etc).
   932 			 * @param {Object} attachment The attachment object, media version of Post.
   938 			 * @param {Object} attachment The attachment object, media version of Post.
   933 			 * @returns {Promise}
   939 			 * @return {Promise}
   934 			 */
   940 			 */
   935 			attachment: function( props, attachment ) {
   941 			attachment: function( props, attachment ) {
   936 				var caption = attachment.caption,
   942 				var caption = attachment.caption,
   937 					options, html;
   943 					options, html;
   938 
   944 
   959 					_.each({
   965 					_.each({
   960 						align: 'align',
   966 						align: 'align',
   961 						size:  'image-size',
   967 						size:  'image-size',
   962 						alt:   'image_alt'
   968 						alt:   'image_alt'
   963 					}, function( option, prop ) {
   969 					}, function( option, prop ) {
   964 						if ( props[ prop ] )
   970 						if ( props[ prop ] ) {
   965 							options[ option ] = props[ prop ];
   971 							options[ option ] = props[ prop ];
       
   972 						}
   966 					});
   973 					});
   967 				} else if ( 'video' === attachment.type ) {
   974 				} else if ( 'video' === attachment.type ) {
   968 					html = wp.media.string.video( props, attachment );
   975 					html = wp.media.string.video( props, attachment );
   969 				} else if ( 'audio' === attachment.type ) {
   976 				} else if ( 'audio' === attachment.type ) {
   970 					html = wp.media.string.audio( props, attachment );
   977 					html = wp.media.string.audio( props, attachment );
   982 			},
   989 			},
   983 			/**
   990 			/**
   984 			 * Called when 'Insert From URL' source is not an image. Example: YouTube url.
   991 			 * Called when 'Insert From URL' source is not an image. Example: YouTube url.
   985 			 *
   992 			 *
   986 			 * @param {Object} embed
   993 			 * @param {Object} embed
   987 			 * @returns {Promise}
   994 			 * @return {Promise}
   988 			 */
   995 			 */
   989 			link: function( embed ) {
   996 			link: function( embed ) {
   990 				return wp.media.post( 'send-link-to-editor', {
   997 				return wp.media.post( 'send-link-to-editor', {
   991 					nonce:     wp.media.view.settings.nonce.sendToEditor,
   998 					nonce:     wp.media.view.settings.nonce.sendToEditor,
   992 					src:       embed.linkUrl,
   999 					src:       embed.linkUrl,
  1002 		 * @param {string} [id=undefined] Optional. A slug used to identify the workflow.
  1009 		 * @param {string} [id=undefined] Optional. A slug used to identify the workflow.
  1003 		 * @param {Object} [options={}]
  1010 		 * @param {Object} [options={}]
  1004 		 *
  1011 		 *
  1005 		 * @this wp.media.editor
  1012 		 * @this wp.media.editor
  1006 		 *
  1013 		 *
  1007 		 * @returns {wp.media.view.MediaFrame}
  1014 		 * @return {wp.media.view.MediaFrame}
  1008 		 */
  1015 		 */
  1009 		open: function( id, options ) {
  1016 		open: function( id, options ) {
  1010 			var workflow;
  1017 			var workflow;
  1011 
  1018 
  1012 			options = options || {};
  1019 			options = options || {};
  1014 			id = this.id( id );
  1021 			id = this.id( id );
  1015 			this.activeEditor = id;
  1022 			this.activeEditor = id;
  1016 
  1023 
  1017 			workflow = this.get( id );
  1024 			workflow = this.get( id );
  1018 
  1025 
  1019 			// Redo workflow if state has changed
  1026 			// Redo workflow if state has changed.
  1020 			if ( ! workflow || ( workflow.options && options.state !== workflow.options.state ) ) {
  1027 			if ( ! workflow || ( workflow.options && options.state !== workflow.options.state ) ) {
  1021 				workflow = this.add( id, options );
  1028 				workflow = this.add( id, options );
  1022 			}
  1029 			}
  1023 
  1030 
  1024 			wp.media.frame = workflow;
  1031 			wp.media.frame = workflow;