235 lines
7.5 KiB
JavaScript
Executable File
235 lines
7.5 KiB
JavaScript
Executable File
/* global wp, JSON */
|
|
/* eslint consistent-this: [ "error", "control" ] */
|
|
/* eslint complexity: ["error", 8] */
|
|
|
|
( function( api, $ ) {
|
|
'use strict';
|
|
|
|
/**
|
|
* An image gallery control.
|
|
*
|
|
* @class
|
|
* @augments wp.customize.Control
|
|
* @augments wp.customize.Class
|
|
*/
|
|
api.ImageGalleryControl = api.Control.extend({
|
|
initialize: function( id, options ) {
|
|
var control = this,
|
|
args;
|
|
|
|
args = options || {};
|
|
|
|
if ( ! args.params.file_type ) {
|
|
args.params.file_type = 'image';
|
|
}
|
|
|
|
if ( ! args.params.type ) {
|
|
args.params.type = 'bloghash-gallery';
|
|
}
|
|
if ( ! args.params.content ) {
|
|
args.params.content = $( '<li></li>' );
|
|
args.params.content.attr( 'id', 'customize-control-' + id.replace( /]/g, '' ).replace( /\[/g, '-' ) );
|
|
args.params.content.attr( 'class', 'customize-control customize-control-' + args.params.type );
|
|
}
|
|
|
|
if ( ! args.params.attachments ) {
|
|
args.params.attachments = [];
|
|
}
|
|
|
|
api.Control.prototype.initialize.call( control, id, args );
|
|
},
|
|
|
|
/**
|
|
* When the control's DOM structure is ready,
|
|
* set up internal event bindings.
|
|
*/
|
|
ready: function() {
|
|
var control = this;
|
|
|
|
// Shortcut so that we don't have to use _.bind every time we add a callback.
|
|
_.bindAll( control, 'openFrame', 'select' );
|
|
|
|
/**
|
|
* Set gallery data and render content.
|
|
*/
|
|
function setGalleryDataAndRenderContent() {
|
|
|
|
var value = control.setting.get();
|
|
control.setAttachmentsData( value ).done( function() {
|
|
control.renderContent();
|
|
control.setupSortable();
|
|
});
|
|
}
|
|
|
|
// Ensure attachment data is initially set.
|
|
setGalleryDataAndRenderContent();
|
|
|
|
// Update the attachment data and re-render the control when the setting changes.
|
|
control.setting.bind( setGalleryDataAndRenderContent );
|
|
|
|
// Bind events.
|
|
control.container.on( 'click keydown', '.upload-button', control.openFrame );
|
|
},
|
|
|
|
/**
|
|
* Fetch attachment data for rendering in control content.
|
|
*
|
|
* @param {Array} value Setting value, array of attachment ids.
|
|
* @returns {*}
|
|
*/
|
|
setAttachmentsData: function( value ) {
|
|
var control = this,
|
|
promises = [];
|
|
|
|
control.params.attachments = [];
|
|
|
|
_.each( value, function( id, index ) {
|
|
var hasAttachmentData = new $.Deferred();
|
|
wp.media.attachment( id ).fetch().done( function() {
|
|
control.params.attachments[ index ] = this.attributes;
|
|
hasAttachmentData.resolve();
|
|
});
|
|
promises.push( hasAttachmentData );
|
|
});
|
|
|
|
return $.when.apply( undefined, promises ).promise();
|
|
},
|
|
|
|
/**
|
|
* Open the media modal.
|
|
*/
|
|
openFrame: function( event ) {
|
|
event.preventDefault();
|
|
|
|
if ( ! this.frame ) {
|
|
this.initFrame();
|
|
}
|
|
|
|
this.frame.open();
|
|
},
|
|
|
|
/**
|
|
* Initiate the media modal select frame.
|
|
* Save it for using later in case needed.
|
|
*/
|
|
initFrame: function() {
|
|
|
|
var control = this,
|
|
preSelectImages;
|
|
this.frame = wp.media({
|
|
button: {
|
|
text: control.params.button_labels.frame_button
|
|
},
|
|
states: [
|
|
new wp.media.controller.Library({
|
|
title: control.params.button_labels.frame_title,
|
|
library: wp.media.query({ type: control.params.file_type }),
|
|
multiple: true
|
|
})
|
|
]
|
|
});
|
|
|
|
/**
|
|
* Pre-select images according to saved settings.
|
|
*/
|
|
preSelectImages = function() {
|
|
var selection, ids, attachment, library;
|
|
|
|
library = control.frame.state().get( 'library' );
|
|
selection = control.frame.state().get( 'selection' );
|
|
|
|
ids = control.setting.get();
|
|
|
|
// Sort the selected images to top when opening media modal.
|
|
library.comparator = function( a, b ) {
|
|
var hasA = true === this.mirroring.get( a.cid ),
|
|
hasB = true === this.mirroring.get( b.cid );
|
|
|
|
if ( ! hasA && hasB ) {
|
|
return -1;
|
|
} else if ( hasA && ! hasB ) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
_.each( ids, function( id ) {
|
|
attachment = wp.media.attachment( id );
|
|
selection.add( attachment ? [ attachment ] : []);
|
|
library.add( attachment ? [ attachment ] : []);
|
|
});
|
|
};
|
|
control.frame.on( 'open', preSelectImages );
|
|
control.frame.on( 'select', control.select );
|
|
},
|
|
|
|
/**
|
|
* Callback for selecting attachments.
|
|
*/
|
|
select: function() {
|
|
|
|
var control = this,
|
|
attachments, attachmentIds;
|
|
|
|
attachments = control.frame.state().get( 'selection' ).toJSON();
|
|
control.params.attachments = attachments;
|
|
|
|
attachmentIds = control.getAttachmentIds( attachments );
|
|
control.setSettingValues( attachmentIds );
|
|
},
|
|
|
|
/**
|
|
* Get array of attachment id-s from attachment objects.
|
|
*
|
|
* @param {Array} attachments Attachments.
|
|
* @returns {Array}
|
|
*/
|
|
getAttachmentIds: function( attachments ) {
|
|
var ids = [],
|
|
i;
|
|
for ( i in attachments ) {
|
|
ids.push( attachments[ i ].id );
|
|
}
|
|
return ids;
|
|
},
|
|
|
|
/**
|
|
* Set setting values.
|
|
*
|
|
* @param {Array} values Array of ids.
|
|
*/
|
|
setSettingValues: function( values ) {
|
|
var control = this;
|
|
control.setting.set( values );
|
|
},
|
|
|
|
/**
|
|
* Setup sortable.
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
setupSortable: function() {
|
|
var control = this,
|
|
list = $( '.image-gallery-attachments' );
|
|
list.sortable({
|
|
items: '.image-gallery-thumbnail-wrapper',
|
|
tolerance: 'pointer',
|
|
stop: function() {
|
|
var selectedValues = [];
|
|
list.find( '.image-gallery-thumbnail-wrapper' ).each( function() {
|
|
var id;
|
|
id = parseInt( $( this ).data( 'postId' ), 10 );
|
|
selectedValues.push( id );
|
|
});
|
|
control.setSettingValues( selectedValues );
|
|
}
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
api.controlConstructor['bloghash-gallery'] = api.ImageGalleryControl;
|
|
|
|
}( wp.customize, jQuery ) );
|