/* 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 = "bloglo-gallery"; } if (!args.params.content) { args.params.content = $("
  • "); 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["bloglo-gallery"] = api.ImageGalleryControl; })(wp.customize, jQuery);