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; |
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 }, |
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 |
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; |