balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

media-gallery-widget.js (10354B)


      1 /**
      2  * @output wp-admin/js/widgets/media-gallery-widget.js
      3  */
      4 
      5 /* eslint consistent-this: [ "error", "control" ] */
      6 (function( component ) {
      7 	'use strict';
      8 
      9 	var GalleryWidgetModel, GalleryWidgetControl, GalleryDetailsMediaFrame;
     10 
     11 	/**
     12 	 * Custom gallery details frame.
     13 	 *
     14 	 * @since 4.9.0
     15 	 * @class    wp.mediaWidgets~GalleryDetailsMediaFrame
     16 	 * @augments wp.media.view.MediaFrame.Post
     17 	 */
     18 	GalleryDetailsMediaFrame = wp.media.view.MediaFrame.Post.extend(/** @lends wp.mediaWidgets~GalleryDetailsMediaFrame.prototype */{
     19 
     20 		/**
     21 		 * Create the default states.
     22 		 *
     23 		 * @since 4.9.0
     24 		 * @return {void}
     25 		 */
     26 		createStates: function createStates() {
     27 			this.states.add([
     28 				new wp.media.controller.Library({
     29 					id:         'gallery',
     30 					title:      wp.media.view.l10n.createGalleryTitle,
     31 					priority:   40,
     32 					toolbar:    'main-gallery',
     33 					filterable: 'uploaded',
     34 					multiple:   'add',
     35 					editable:   true,
     36 
     37 					library:  wp.media.query( _.defaults({
     38 						type: 'image'
     39 					}, this.options.library ) )
     40 				}),
     41 
     42 				// Gallery states.
     43 				new wp.media.controller.GalleryEdit({
     44 					library: this.options.selection,
     45 					editing: this.options.editing,
     46 					menu:    'gallery'
     47 				}),
     48 
     49 				new wp.media.controller.GalleryAdd()
     50 			]);
     51 		}
     52 	} );
     53 
     54 	/**
     55 	 * Gallery widget model.
     56 	 *
     57 	 * See WP_Widget_Gallery::enqueue_admin_scripts() for amending prototype from PHP exports.
     58 	 *
     59 	 * @since 4.9.0
     60 	 *
     61 	 * @class    wp.mediaWidgets.modelConstructors.media_gallery
     62 	 * @augments wp.mediaWidgets.MediaWidgetModel
     63 	 */
     64 	GalleryWidgetModel = component.MediaWidgetModel.extend(/** @lends wp.mediaWidgets.modelConstructors.media_gallery.prototype */{} );
     65 
     66 	GalleryWidgetControl = component.MediaWidgetControl.extend(/** @lends wp.mediaWidgets.controlConstructors.media_gallery.prototype */{
     67 
     68 		/**
     69 		 * View events.
     70 		 *
     71 		 * @since 4.9.0
     72 		 * @type {object}
     73 		 */
     74 		events: _.extend( {}, component.MediaWidgetControl.prototype.events, {
     75 			'click .media-widget-gallery-preview': 'editMedia'
     76 		} ),
     77 
     78 		/**
     79 		 * Gallery widget control.
     80 		 *
     81 		 * See WP_Widget_Gallery::enqueue_admin_scripts() for amending prototype from PHP exports.
     82 		 *
     83 		 * @constructs wp.mediaWidgets.controlConstructors.media_gallery
     84 		 * @augments   wp.mediaWidgets.MediaWidgetControl
     85 		 *
     86 		 * @since 4.9.0
     87 		 * @param {Object}         options - Options.
     88 		 * @param {Backbone.Model} options.model - Model.
     89 		 * @param {jQuery}         options.el - Control field container element.
     90 		 * @param {jQuery}         options.syncContainer - Container element where fields are synced for the server.
     91 		 * @return {void}
     92 		 */
     93 		initialize: function initialize( options ) {
     94 			var control = this;
     95 
     96 			component.MediaWidgetControl.prototype.initialize.call( control, options );
     97 
     98 			_.bindAll( control, 'updateSelectedAttachments', 'handleAttachmentDestroy' );
     99 			control.selectedAttachments = new wp.media.model.Attachments();
    100 			control.model.on( 'change:ids', control.updateSelectedAttachments );
    101 			control.selectedAttachments.on( 'change', control.renderPreview );
    102 			control.selectedAttachments.on( 'reset', control.renderPreview );
    103 			control.updateSelectedAttachments();
    104 
    105 			/*
    106 			 * Refresh a Gallery widget partial when the user modifies one of the selected attachments.
    107 			 * This ensures that when an attachment's caption is updated in the media modal the Gallery
    108 			 * widget in the preview will then be refreshed to show the change. Normally doing this
    109 			 * would not be necessary because all of the state should be contained inside the changeset,
    110 			 * as everything done in the Customizer should not make a change to the site unless the
    111 			 * changeset itself is published. Attachments are a current exception to this rule.
    112 			 * For a proposal to include attachments in the customized state, see #37887.
    113 			 */
    114 			if ( wp.customize && wp.customize.previewer ) {
    115 				control.selectedAttachments.on( 'change', function() {
    116 					wp.customize.previewer.send( 'refresh-widget-partial', control.model.get( 'widget_id' ) );
    117 				} );
    118 			}
    119 		},
    120 
    121 		/**
    122 		 * Update the selected attachments if necessary.
    123 		 *
    124 		 * @since 4.9.0
    125 		 * @return {void}
    126 		 */
    127 		updateSelectedAttachments: function updateSelectedAttachments() {
    128 			var control = this, newIds, oldIds, removedIds, addedIds, addedQuery;
    129 
    130 			newIds = control.model.get( 'ids' );
    131 			oldIds = _.pluck( control.selectedAttachments.models, 'id' );
    132 
    133 			removedIds = _.difference( oldIds, newIds );
    134 			_.each( removedIds, function( removedId ) {
    135 				control.selectedAttachments.remove( control.selectedAttachments.get( removedId ) );
    136 			});
    137 
    138 			addedIds = _.difference( newIds, oldIds );
    139 			if ( addedIds.length ) {
    140 				addedQuery = wp.media.query({
    141 					order: 'ASC',
    142 					orderby: 'post__in',
    143 					perPage: -1,
    144 					post__in: newIds,
    145 					query: true,
    146 					type: 'image'
    147 				});
    148 				addedQuery.more().done( function() {
    149 					control.selectedAttachments.reset( addedQuery.models );
    150 				});
    151 			}
    152 		},
    153 
    154 		/**
    155 		 * Render preview.
    156 		 *
    157 		 * @since 4.9.0
    158 		 * @return {void}
    159 		 */
    160 		renderPreview: function renderPreview() {
    161 			var control = this, previewContainer, previewTemplate, data;
    162 
    163 			previewContainer = control.$el.find( '.media-widget-preview' );
    164 			previewTemplate = wp.template( 'wp-media-widget-gallery-preview' );
    165 
    166 			data = control.previewTemplateProps.toJSON();
    167 			data.attachments = {};
    168 			control.selectedAttachments.each( function( attachment ) {
    169 				data.attachments[ attachment.id ] = attachment.toJSON();
    170 			} );
    171 
    172 			previewContainer.html( previewTemplate( data ) );
    173 		},
    174 
    175 		/**
    176 		 * Determine whether there are selected attachments.
    177 		 *
    178 		 * @since 4.9.0
    179 		 * @return {boolean} Selected.
    180 		 */
    181 		isSelected: function isSelected() {
    182 			var control = this;
    183 
    184 			if ( control.model.get( 'error' ) ) {
    185 				return false;
    186 			}
    187 
    188 			return control.model.get( 'ids' ).length > 0;
    189 		},
    190 
    191 		/**
    192 		 * Open the media select frame to edit images.
    193 		 *
    194 		 * @since 4.9.0
    195 		 * @return {void}
    196 		 */
    197 		editMedia: function editMedia() {
    198 			var control = this, selection, mediaFrame, mediaFrameProps;
    199 
    200 			selection = new wp.media.model.Selection( control.selectedAttachments.models, {
    201 				multiple: true
    202 			});
    203 
    204 			mediaFrameProps = control.mapModelToMediaFrameProps( control.model.toJSON() );
    205 			selection.gallery = new Backbone.Model( mediaFrameProps );
    206 			if ( mediaFrameProps.size ) {
    207 				control.displaySettings.set( 'size', mediaFrameProps.size );
    208 			}
    209 			mediaFrame = new GalleryDetailsMediaFrame({
    210 				frame: 'manage',
    211 				text: control.l10n.add_to_widget,
    212 				selection: selection,
    213 				mimeType: control.mime_type,
    214 				selectedDisplaySettings: control.displaySettings,
    215 				showDisplaySettings: control.showDisplaySettings,
    216 				metadata: mediaFrameProps,
    217 				editing:   true,
    218 				multiple:  true,
    219 				state: 'gallery-edit'
    220 			});
    221 			wp.media.frame = mediaFrame; // See wp.media().
    222 
    223 			// Handle selection of a media item.
    224 			mediaFrame.on( 'update', function onUpdate( newSelection ) {
    225 				var state = mediaFrame.state(), resultSelection;
    226 
    227 				resultSelection = newSelection || state.get( 'selection' );
    228 				if ( ! resultSelection ) {
    229 					return;
    230 				}
    231 
    232 				// Copy orderby_random from gallery state.
    233 				if ( resultSelection.gallery ) {
    234 					control.model.set( control.mapMediaToModelProps( resultSelection.gallery.toJSON() ) );
    235 				}
    236 
    237 				// Directly update selectedAttachments to prevent needing to do additional request.
    238 				control.selectedAttachments.reset( resultSelection.models );
    239 
    240 				// Update models in the widget instance.
    241 				control.model.set( {
    242 					ids: _.pluck( resultSelection.models, 'id' )
    243 				} );
    244 			} );
    245 
    246 			mediaFrame.$el.addClass( 'media-widget' );
    247 			mediaFrame.open();
    248 
    249 			if ( selection ) {
    250 				selection.on( 'destroy', control.handleAttachmentDestroy );
    251 			}
    252 		},
    253 
    254 		/**
    255 		 * Open the media select frame to chose an item.
    256 		 *
    257 		 * @since 4.9.0
    258 		 * @return {void}
    259 		 */
    260 		selectMedia: function selectMedia() {
    261 			var control = this, selection, mediaFrame, mediaFrameProps;
    262 			selection = new wp.media.model.Selection( control.selectedAttachments.models, {
    263 				multiple: true
    264 			});
    265 
    266 			mediaFrameProps = control.mapModelToMediaFrameProps( control.model.toJSON() );
    267 			if ( mediaFrameProps.size ) {
    268 				control.displaySettings.set( 'size', mediaFrameProps.size );
    269 			}
    270 			mediaFrame = new GalleryDetailsMediaFrame({
    271 				frame: 'select',
    272 				text: control.l10n.add_to_widget,
    273 				selection: selection,
    274 				mimeType: control.mime_type,
    275 				selectedDisplaySettings: control.displaySettings,
    276 				showDisplaySettings: control.showDisplaySettings,
    277 				metadata: mediaFrameProps,
    278 				state: 'gallery'
    279 			});
    280 			wp.media.frame = mediaFrame; // See wp.media().
    281 
    282 			// Handle selection of a media item.
    283 			mediaFrame.on( 'update', function onUpdate( newSelection ) {
    284 				var state = mediaFrame.state(), resultSelection;
    285 
    286 				resultSelection = newSelection || state.get( 'selection' );
    287 				if ( ! resultSelection ) {
    288 					return;
    289 				}
    290 
    291 				// Copy orderby_random from gallery state.
    292 				if ( resultSelection.gallery ) {
    293 					control.model.set( control.mapMediaToModelProps( resultSelection.gallery.toJSON() ) );
    294 				}
    295 
    296 				// Directly update selectedAttachments to prevent needing to do additional request.
    297 				control.selectedAttachments.reset( resultSelection.models );
    298 
    299 				// Update widget instance.
    300 				control.model.set( {
    301 					ids: _.pluck( resultSelection.models, 'id' )
    302 				} );
    303 			} );
    304 
    305 			mediaFrame.$el.addClass( 'media-widget' );
    306 			mediaFrame.open();
    307 
    308 			if ( selection ) {
    309 				selection.on( 'destroy', control.handleAttachmentDestroy );
    310 			}
    311 
    312 			/*
    313 			 * Make sure focus is set inside of modal so that hitting Esc will close
    314 			 * the modal and not inadvertently cause the widget to collapse in the customizer.
    315 			 */
    316 			mediaFrame.$el.find( ':focusable:first' ).focus();
    317 		},
    318 
    319 		/**
    320 		 * Clear the selected attachment when it is deleted in the media select frame.
    321 		 *
    322 		 * @since 4.9.0
    323 		 * @param {wp.media.models.Attachment} attachment - Attachment.
    324 		 * @return {void}
    325 		 */
    326 		handleAttachmentDestroy: function handleAttachmentDestroy( attachment ) {
    327 			var control = this;
    328 			control.model.set( {
    329 				ids: _.difference(
    330 					control.model.get( 'ids' ),
    331 					[ attachment.id ]
    332 				)
    333 			} );
    334 		}
    335 	} );
    336 
    337 	// Exports.
    338 	component.controlConstructors.media_gallery = GalleryWidgetControl;
    339 	component.modelConstructors.media_gallery = GalleryWidgetModel;
    340 
    341 })( wp.mediaWidgets );