PluginProbe
Customify / 2.5.1
Customify v2.5.1
2.10.9 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.7.1 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.0.1 1.6.5 1.7.0 1.7.1 All 77 releases
← All changes | js/customizer.js +865 -1166 1.4.02.5.1 View file →
@@ -1,1416 +1,1115 @@
1 -(function ( $, exports, api ) {
2 - 'use strict';
1 +(
2 + function ($, exports, wp) {
3 + var api = wp.customize
4 + var $window = $(window)
3 5
4 - // when the customizer is ready prepare our fields events
5 - api.bind('ready', function () {
6 - var timeout = null;
6 + // when the customizer is ready prepare our fields events
7 + wp.customize.bind('ready', function () {
8 + var timeout = null
7 9
8 - // add ace editors
9 - $('.customify_ace_editor').each(function ( key, el ) {
10 - var id = $(this).attr('id'),
11 - css_editor = ace.edit(id);
10 + // Create a stack of callbacks bound to parent settings to be able to unbind them
11 + // when altering the connected_fields attribute.
12 + if (typeof window.connectedFieldsCallbacks === 'undefined') {
13 + window.connectedFieldsCallbacks = {}
14 + }
12 15
13 - var editor_type = $(this).data('editor_type');
14 - // init the ace editor
15 - css_editor.setTheme("ace/theme/github");
16 - css_editor.getSession().setMode("ace/mode/" + editor_type);
16 + // add ace editors
17 + $('.customify_ace_editor').each(function (key, el) {
18 + const id = $(this).attr('id'),
19 + css_editor = ace.edit(id)
17 20
18 - // hide the textarea and enable the ace editor
19 - var textarea = $('#' + id + '_textarea').hide();
20 - css_editor.getSession().setValue(textarea.val());
21 + const editor_type = $(this).data('editor_type')
22 + // init the ace editor
23 + css_editor.setTheme('ace/theme/github')
24 + css_editor.getSession().setMode('ace/mode/' + editor_type)
21 25
22 - // each time a change is triggered start a timeout of 1,5s and when is finished refresh the previewer
23 - // if the user types faster than this delay then reset it
24 - css_editor.getSession().on('change', function ( e ) {
25 - if ( timeout !== null ) {
26 - clearTimeout(timeout);
27 - timeout = null;
28 - } else {
29 - timeout = setTimeout(function () {
30 - //var state = css_editor.session.getState();
31 - textarea.val(css_editor.getSession().getValue());
32 - textarea.trigger('change');
33 - }, 1500);
34 - }
35 - });
36 - });
26 + // hide the textarea and enable the ace editor
27 + const textarea = $('#' + id + '_textarea').hide()
28 + css_editor.getSession().setValue(textarea.val())
37 29
38 - // simple select2 field
39 - $('.customify_select2').select2();
30 + // each time a change is triggered start a timeout of 1,5s and when is finished refresh the previewer
31 + // if the user types faster than this delay then reset it
32 + css_editor.getSession().on('change', function (e) {
33 + if (timeout !== null) {
34 + clearTimeout(timeout)
35 + timeout = null
36 + } else {
37 + timeout = setTimeout(function () {
38 + //var state = css_editor.session.getState();
39 + textarea.val(css_editor.getSession().getValue())
40 + textarea.trigger('change')
41 + }, 1500)
42 + }
43 + })
44 + })
40 45
41 - customifyFontSelect.init(this);
46 + // simple select2 field
47 + $('.customify_select2').select2()
42 48
43 - prepare_typography_field();
49 + setTimeout(function () {
50 + CustomifyFontSelectFields.init()
51 + }, 333)
44 52
45 - /**
46 - * Make the customizer save on CMD/CTRL+S action
47 - * This is awesome!!!
48 - */
49 - $(window).bind('keydown', function ( event ) {
50 - if ( event.ctrlKey || event.metaKey ) {
51 - switch ( String.fromCharCode(event.which).toLowerCase() ) {
52 - case 's':
53 - event.preventDefault();
54 - api.previewer.save();
55 - break;
53 + prepare_typography_field()
54 +
55 + /**
56 + * Make the customizer save on CMD/CTRL+S action
57 + * This is awesome!!!
58 + */
59 + $(window).bind('keydown', function (event) {
60 + if (event.ctrlKey || event.metaKey) {
61 + switch (String.fromCharCode(event.which).toLowerCase()) {
62 + case 's':
63 + event.preventDefault()
64 + api.previewer.save()
65 + break
66 + }
56 67 }
57 - }
58 - });
68 + })
59 69
60 - // for each range input add a value preview output
61 - $('input[type="range"]').each(function () {
62 - var $clone = $(this).clone();
70 + // for each range input add a value preview output
71 + $('.accordion-section-content[id*="' + customify_settings.options_name + '"], #sub-accordion-section-style_manager_section').each(function () {
63 72
64 - $clone
65 - .attr('type', 'number')
66 - .attr('class', 'range-value');
73 + // Initialize range fields logic
74 + customifyHandleRangeFields(this)
75 + })
67 76
68 - $(this).after($clone);
77 + if ($('button[data-action="reset_customify"]').length > 0) {
78 + // reset_button
79 + $(document).on('click', '#customize-control-reset_customify button', function (ev) {
80 + ev.preventDefault()
69 81
70 - $(this).on('input', function () {
71 - $(this).siblings('.range-value').val($(this).val());
72 - });
73 - });
82 + var iAgree = confirm('Do you really want to reset to defaults all the fields? Watch out, this will reset all your Customify options and will save them!')
74 83
75 - if ( $('button[data-action="reset_customify"]').length > 0 ) {
76 - // reset_button
77 - $(document).on('click', '#customize-control-reset_customify button', function ( ev ) {
78 - ev.preventDefault();
84 + if (!iAgree) {
85 + return
86 + }
79 87
80 - var iAgree = confirm('Do you really want to reset to defaults all the fields? Watch out, this will reset all your Customify options and will save them!');
88 + $.each(api.settings.controls, function (key, ctrl) {
89 + const setting_id = key.replace('_control', '')
90 + const setting = customify_settings.settings[setting_id]
81 91
82 - if ( !iAgree ) {
83 - return;
84 - }
92 + if (!_.isUndefined(setting) && !_.isUndefined(setting.default)) {
93 + api_set_setting_value(setting_id, setting.default)
94 + }
95 + })
85 96
86 - $.each(api.settings.controls, function ( key, ctrl ) {
87 - var id = key.replace('_control', '');
88 - var setting = customify_settings.settings[id];
97 + api.previewer.save()
98 + })
89 99
90 - if ( !_.isUndefined(setting) && !_.isUndefined(setting.default) ) {
100 + // add a reset button for each panel
101 + $('.panel-meta').each(function (el, key) {
102 + const container = $(this).parents('.control-panel'),
103 + id = container.attr('id')
91 104
92 - var start_pos = id.indexOf('[') + 1;
93 - var end_pos = id.indexOf(']', start_pos);
94 -
95 - id = id.substring(start_pos, end_pos);
96 - api_set_setting_value(id, setting.default);
105 + if (typeof id !== 'undefined') {
106 + const panel_id = id.replace('accordion-panel-', '')
107 + $(this).parent().append('<button class="reset_panel button" data-panel="' + panel_id + '">Panel\'s defaults</button>')
97 108 }
98 - });
109 + })
99 110
100 - api.previewer.save();
101 - });
111 + // reset panel
112 + $(document).on('click', '.reset_panel', function (e) {
113 + e.preventDefault()
102 114
103 - // add a reset button for each panel
104 - $('.panel-meta').each(function ( el, key ) {
105 - var container = $(this).parents('.control-panel'),
106 - id = container.attr('id'),
107 - panel_id = id.replace('accordion-panel-', '');
115 + const panel_id = $(this).data('panel'),
116 + panel = api.panel(panel_id),
117 + sections = panel.sections(),
118 + iAgree = confirm('Do you really want to reset ' + panel.params.title + '?')
108 119
120 + if (!iAgree) {
121 + return
122 + }
123 + if (sections.length > 0) {
124 + $.each(sections, function () {
125 + //var settings = this.settings();
126 + const controls = this.controls()
109 127
110 - $(this).parent().append('<button class="reset_panel button" data-panel="' + panel_id + '">Panel\'s defaults</button>');
111 - });
128 + if (controls.length > 0) {
129 + $.each(controls, function (key, ctrl) {
130 + const setting_id = ctrl.id.replace('_control', ''),
131 + setting = customify_settings.settings[setting_id]
112 132
113 - // reset panel
114 - $(document).on('click', '.reset_panel', function ( e ) {
115 - e.preventDefault();
133 + if (!_.isUndefined(setting) && !_.isUndefined(setting.default)) {
134 + api_set_setting_value(setting_id, setting.default)
135 + }
136 + })
137 + }
138 + })
139 + }
140 + })
116 141
117 - var panel_id = $(this).data('panel'),
118 - panel = api.panel(panel_id),
119 - sections = panel.sections(),
120 - iAgree = confirm("Do you really want to reset " + panel.params.title + "?");
142 + //add reset section
143 + $('.accordion-section-content').each(function (el, key) {
144 + const section_id = $(this).attr('id')
121 145
122 - if ( !iAgree ) {
123 - return;
124 - }
125 - if ( sections.length > 0 ) {
126 - $.each(sections, function () {
127 - //var settings = this.settings();
128 - var controls = this.controls();
146 + if ((
147 + (
148 + !_.isUndefined(section_id)
149 + ) ? section_id.indexOf(customify_settings.options_name) : -1
150 + ) === -1) {
151 + return
152 + }
129 153
130 - if ( controls.length > 0 ) {
131 - $.each(controls, function ( key, ctrl ) {
132 - var id = ctrl.id.replace('_control', ''),
133 - setting = customify_settings.settings[id];
154 + if (!_.isUndefined(section_id) && section_id.indexOf('sub-accordion-section-') > -1) {
155 + const id = section_id.replace('sub-accordion-section-', '')
156 + $(this).append('<button class="reset_section button" data-section="' + id + '">Reset All Options for This Section</button>')
157 + }
158 + })
134 159
135 - if ( !_.isUndefined(setting) && !_.isUndefined(setting.default) ) {
160 + // reset section event
161 + $(document).on('click', '.reset_section', function (e) {
162 + e.preventDefault()
136 163
137 - var start_pos = id.indexOf('[') + 1,
138 - end_pos = id.indexOf(']', start_pos);
164 + const section_id = $(this).data('section'),
165 + section = api.section(section_id),
166 + controls = section.controls()
139 167
140 - id = id.substring(start_pos, end_pos);
141 - api_set_setting_value(id, setting.default);
142 - }
143 - });
144 - }
145 - });
146 - }
147 - });
168 + const iAgree = confirm('Do you really want to reset ' + section.params.title + '?')
148 169
149 - //add reset section
150 - $('.accordion-section-content').each(function ( el, key ) {
151 - var section = $(this).parent(),
152 - section_id = section.attr('id');
170 + if (!iAgree) {
171 + return
172 + }
153 173
154 - if ( ( ( !_.isUndefined(section_id) ) ? section_id.indexOf(customify_settings.options_name) : -1 ) === -1 ) {
155 - return;
156 - }
174 + if (controls.length > 0) {
175 + $.each(controls, function (key, ctrl) {
176 + const setting_id = ctrl.id.replace('_control', ''),
177 + setting = customify_settings.settings[setting_id]
157 178
158 - if ( !_.isUndefined(section_id) && section_id.indexOf('accordion-section-') > -1 ) {
159 - var id = section_id.replace('accordion-section-', '');
160 - $(this).prepend('<button class="reset_section button" data-section="' + id + '">Section\'s defaults</button>');
161 - }
162 - });
179 + if (!_.isUndefined(setting) && !_.isUndefined(setting.default)) {
180 + api_set_setting_value(setting_id, setting.default)
181 + }
182 + })
183 + }
184 + })
185 + }
163 186
164 - // reset section event
165 - $(document).on('click', '.reset_section', function ( e ) {
166 - e.preventDefault();
187 + $(document).on('change keyup', '.customize-control-range input.range-value', function () {
188 + const range = $(this).siblings('input[type="range"]')
189 + range.val($(this).val())
190 + range.trigger('change')
191 + })
167 192
168 - var section_id = $(this).data('section'),
169 - section = api.section(section_id),
170 - controls = section.controls();
193 + $(document).on('change', '.customify_typography_font_subsets', function (ev) {
171 194
172 - var iAgree = confirm("Do you really want to reset " + section.params.title + "?");
195 + const $input = $(this).parents('.options').siblings('.customify_typography').children('.customify_typography_values');
196 + let current_val = $input.val()
173 197
174 - if ( !iAgree ) {
175 - return;
176 - }
198 + current_val = JSON.parse(decodeURIComponent(current_val))
177 199
178 - if ( controls.length > 0 ) {
179 - $.each(controls, function ( key, ctrl ) {
180 - var id = ctrl.id.replace('_control', ''),
181 - setting = customify_settings.settings[id];
200 + //maybe the selected option holds a JSON in its value
201 + current_val.selected_subsets = maybeJsonParse($(this).val())
182 202
183 - if ( !_.isUndefined(setting) && !_.isUndefined(setting.default) ) {
203 + $input.val(encodeURIComponent(JSON.stringify(current_val)))
184 204
185 - var start_pos = id.indexOf('[') + 1,
186 - end_pos = id.indexOf(']', start_pos);
205 + $input.trigger('change')
206 + })
187 207
188 - id = id.substring(start_pos, end_pos);
189 - api_set_setting_value(id, setting.default);
190 - }
191 - });
192 - }
193 - });
194 - }
208 + $(document).on('change', '.customify_typography_font_weight', function (ev) {
195 209
196 - $(document).on('change', '.customize-control input.range-value', function () {
197 - var range = $(this).siblings('input[type="range"]');
198 - range.val($(this).val());
199 - });
210 + const $input = $(this).parents('.options').siblings('.customify_typography').children('.customify_typography_values');
211 + let current_val = $input.val();
200 212
201 - $(document).on('change', '.customify_typography_font_subsets', function ( ev ) {
213 + current_val = maybeJsonParse(current_val)
214 + // @todo currently the font weight selector works for one value only
215 + // maybe make this a multiselect
202 216
203 - var $input = $(this).parents('.options').siblings('.customify_typography').children('.customify_typography_values'),
204 - current_val = $input.val();
217 + //maybe the selected option holds a JSON in its value
218 + current_val.selected_variants = {0: maybeJsonParse($(this).val())}
205 219
206 - current_val = JSON.parse(decodeURIComponent(current_val));
220 + $input.val(encodeURIComponent(JSON.stringify(current_val)))
221 + $input.trigger('change')
222 + })
207 223
208 - //maybe the selected option holds a JSON in its value
209 - current_val.selected_subsets = maybeJsonParse($(this).val());
224 + $('body').on('customify:preset-change', function (e) {
225 + const data = $(e.target).data('options')
210 226
211 - $input.val(encodeURIComponent(JSON.stringify(current_val)));
227 + if (!_.isUndefined(data)) {
228 + $.each(data, function (setting_id, value) {
229 + api_set_setting_value(setting_id, value)
230 + })
231 + }
232 + })
212 233
213 - $input.trigger('change');
214 - });
234 + $(document).on('change', '.customify_preset.select', function () {
235 + const $source = $(this)
236 + const $target = $source.children('[value="' + $source.val() + '"]')
237 + $target.trigger('customify:preset-change')
238 + })
215 239
216 - $(document).on('change', '.customify_typography_font_weight', function ( ev ) {
240 + $(document).on('click', '.customify_preset.radio input, .customify_preset.radio_buttons input, .awesome_presets input', function () {
241 + $(this).trigger('customify:preset-change')
242 + })
217 243
218 - var $input = $(this).parents('.options').siblings('.customify_typography').children('.customify_typography_values'),
219 - current_val = $input.val();
244 + customifyBackgroundJsControl.init()
220 245
221 - current_val = maybeJsonParse(current_val);
222 - // @todo currently the font weight selector works for one value only
223 - // maybe make this a multiselect
224 -
225 - //maybe the selected option holds a JSON in its value
226 - current_val.selected_variants = {0: maybeJsonParse($(this).val())};
227 -
228 - $input.val(encodeURIComponent(JSON.stringify(current_val)));
229 - $input.trigger('change');
230 - });
231 -
232 - // presets
233 - $(document).on('change', '.customify_preset.select', function () {
234 - var this_option = $(this).children('[value="' + $(this).val() + '"]'),
235 - data = $(this_option).data('options');
236 -
237 - if ( !_.isUndefined(data) ) {
238 - $.each(data, function ( id, value ) {
239 - api_set_setting_value(id, value);
240 - });
246 + // sometimes a php save may be needed
247 + if (getUrlVars('save_customizer_once')) {
248 + api.previewer.save()
241 249 }
242 250
243 - api.previewer.refresh();
244 - });
251 + setTimeout(function () {
252 + customifyFoldingFields()
253 + }, 1000);
245 254
246 - $(document).on('click', '.customify_preset.radio input, .customify_preset.radio_buttons input, .awesome_presets input', function () {
247 - var this_option = this,//$(this).children('[value="' + $(this).val() + '"]');
248 - data = $(this_option).data('options');
255 + // Handle the section tabs (ex: Layout | Fonts | Colors)
256 + (
257 + function () {
258 + const $navs = $('.js-section-navigation')
249 259
250 - if ( !_.isUndefined(data) ) {
251 - $.each(data, function ( id, value ) {
252 - api_set_setting_value(id, value);
253 - });
254 - }
260 + $navs.each(function () {
261 + const $nav = $(this)
262 + const $title = $nav.parents('.accordion-section-content').find('.customize-section-title')
255 263
256 - api.previewer.refresh();
257 - });
264 + $nav.closest('.customize-control').addClass('screen-reader-text')
265 + $title.append($nav).parent().addClass('has-nav')
266 + })
258 267
259 - // bind our event on click
260 - $(document).on('click', '.customify_import_demo_data_button', function ( event ) {
261 - //if ( $( this ).hasClass( '.wpGrade_button_inactive' ) ) {
262 - // return false;
263 - //} else {
264 - // $( this ).addClass( '.wpGrade_button_inactive' );
265 - // $( this ).attr( 'disabled', 'disabled' );
266 - //}
267 - //var confirmImport = confirm( listable_demodata_params.l10n.import_confirm );
268 - //if ( confirmImport == false ) return false;
268 + $('.js-section-navigation a').on('click', function (e) {
269 + e.preventDefault()
269 270
270 - //@todo start an animation here
271 - var key = $(this).data('key');
271 + const $sidebar = $(this).parents('.customize-pane-child'),
272 + $parent = $(this).parents('.accordion-section-content'),
273 + href = $.attr(this, 'href')
272 274
273 - var import_queue = new Queue(api);
275 + if (href != '#') {
276 + $sidebar.animate({
277 + scrollTop: $($.attr(this, 'href')).position().top - $parent.find('.customize-section-title').outerHeight()
278 + }, 500)
279 + }
280 + })
281 + }
282 + )();
274 283
275 - /// calculate the number of steps
276 - var steps = [];
284 + (
285 + function () {
286 + // Close a font field when clicking on another field
287 + $('.customify_font_tooltip').on('click', function () {
288 + if ($(this).prop('checked') === true) {
289 + $('.customify_font_tooltip').prop('checked', false)
290 + $(this).prop('checked', true)
291 + }
292 + })
293 + }
294 + )()
277 295
278 - if ( !_.isUndefined(customify_settings.settings[key].imports) ) {
296 + // Bind any connected fields, except those in the Style Manager.
297 + // Those are handled by the appropriate Style Manager component (Color Palettes, Font Palettes, etc ).
298 + bindConnectedFields()
279 299
280 - $.each(customify_settings.settings[key].imports, function ( i, import_setts, k ) {
281 - if ( _.isUndefined(import_setts.steps) ) {
282 - steps.push({id: i, type: import_setts.type});
283 - } else {
284 - var count = import_setts.steps;
300 + })
285 301
286 - while ( count >= 1 ) {
287 - steps.push({id: i, type: import_setts.type, count: count});
288 - count = count - 1;
289 - }
302 + const getConnectedFieldsCallback = function (parent_setting_data, parent_setting_id) {
303 + return function (new_value, old_value) {
304 + _.each(parent_setting_data.connected_fields, function (connected_field_data) {
305 + if (_.isUndefined(connected_field_data) || _.isUndefined(connected_field_data.setting_id) || !_.isString(connected_field_data.setting_id)) {
306 + return
290 307 }
291 - });
308 + const setting = wp.customize(connected_field_data.setting_id)
309 + if (_.isUndefined(setting)) {
310 + return
311 + }
312 + setting.set(new_value)
313 + })
292 314 }
315 + }
293 316
294 - import_queue.add_steps('import_demo_data_action_id', steps);
295 - return false;
296 - });
317 + const bindConnectedFields = function () {
318 + _.each(wp.customize.settings.settings, function (parent_setting_data, parent_setting_id) {
319 + // We don't want to handle the binding of the Style Manager settings
320 + if (typeof ColorPalettes !== 'undefined'
321 + && typeof ColorPalettes.masterSettingIds !== 'undefined'
322 + && _.contains(ColorPalettes.masterSettingIds, parent_setting_id)) {
323 + return
324 + }
325 + if (typeof FontPalettes !== 'undefined'
326 + && typeof FontPalettes.masterSettingIds !== 'undefined'
327 + && _.contains(FontPalettes.masterSettingIds, parent_setting_id)) {
328 + return
329 + }
297 330
298 - customifyBackgroundJsControl.init();
299 -
300 - // sometimes there may be needed a php save
301 - if ( getUrlVars('save_customizer_once') ) {
302 - api.previewer.save();
331 + let parent_setting = wp.customize(parent_setting_id)
332 + if (typeof parent_setting_data.connected_fields !== 'undefined') {
333 + connectedFieldsCallbacks[parent_setting_id] = getConnectedFieldsCallback(parent_setting_data, parent_setting_id)
334 + parent_setting.bind(connectedFieldsCallbacks[parent_setting_id])
335 + }
336 + })
303 337 }
304 338
305 - setTimeout(function () {
306 - customifyFoldingFields();
307 - }, 1000);
339 + const unbindConnectedFields = function () {
340 + _.each(wp.customize.settings.settings, function (parent_setting_data, parent_setting_id) {
341 + // We don't want to handle the binding of the Style Manager settings
342 + if (typeof ColorPalettes !== 'undefined'
343 + && typeof ColorPalettes.masterSettingIds !== 'undefined'
344 + && _.contains(ColorPalettes.masterSettingIds, parent_setting_id)) {
345 + return
346 + }
347 + if (typeof FontPalettes !== 'undefined'
348 + && typeof FontPalettes.masterSettingIds !== 'undefined'
349 + && _.contains(FontPalettes.masterSettingIds, parent_setting_id)) {
350 + return
351 + }
308 352
353 + let parent_setting = wp.customize(parent_setting_id)
354 + if (typeof parent_setting_data.connected_fields !== 'undefined' && typeof connectedFieldsCallbacks[parent_setting_id] !== 'undefined') {
355 + parent_setting.unbind(connectedFieldsCallbacks[parent_setting_id])
356 + }
357 + delete connectedFieldsCallbacks[parent_setting_id]
358 + })
359 + }
309 360
310 - // Handle the section tabs (ex: Layout | Fonts | Colors)
311 - (function() {
312 - var $navs = $( '.js-section-navigation' );
361 + const customifyHandleRangeFields = function (el) {
313 362
314 - $navs.each( function () {
315 - var $nav = $( this );
316 - var $title = $nav.parents( '.accordion-section-content' ).find( '.customize-section-title' );
363 + // For each range input add a number field (for preview mainly - but it can also be used for input)
364 + $(el).find('input[type="range"]').each(function () {
365 + if (!$(this).siblings('.range-value').length) {
366 + const $clone = $(this).clone()
317 367
318 - $nav.closest('.customize-control').addClass('screen-reader-text');
319 - $title.append( $nav ).parent().addClass( 'has-nav' );
320 - });
368 + $clone
369 + .attr('type', 'number')
370 + .attr('class', 'range-value')
371 + .removeAttr('data-field')
321 372
322 - $('.js-section-navigation a').on( 'click', function(e) {
323 - e.preventDefault();
373 + $(this).after($clone)
324 374
325 - var $sidebar = $('.wp-full-overlay-sidebar-content');
326 - var $parent = $(this).parents( '.accordion-section-content' );
327 - var href = $.attr(this, 'href');
328 -
329 - if ( href != '#' ) {
330 - $sidebar.animate({
331 - scrollTop: $( $.attr(this, 'href') ).position().top - $parent.find( '.customize-section-title' ).outerHeight()
332 - }, 500);
375 + // Update the range field when changing the number
376 + $($clone).on('change', function () {
377 + $(this).siblings('input[type="range"]').val($(this).val())
378 + })
333 379 }
334 - });
335 - })();
336 - });
337 380
338 - /**
339 - * This function will search for all the interdependend fields and make a bound between them.
340 - * So whenever a target is changed, it will take actions to the dependent fields.
341 - * @TOOD this is still written in a barbaric way, refactor when needed
342 - */
343 - var customifyFoldingFields = function () {
344 -
345 - if ( _.isUndefined(customify_settings) || _.isUndefined(customify_settings.settings) ) {
346 - return; // bail
381 + // Update the number field when changing the range
382 + $(this).on('change', function () {
383 + $(this).siblings('.range-value').val($(this).val())
384 + })
385 + })
347 386 }
348 387
349 388 /**
350 - * Let's iterate through all the customify settings and gather all the fields that have a "show_if"
351 - * property set.
352 - *
353 - * At the end `targets` will hold a list of [ target : [field, field,...], ... ]
354 - * so when a target is changed we will change all the fields.
389 + * This function will search for all the interdependend fields and make a bound between them.
390 + * So whenever a target is changed, it will take actions to the dependent fields.
391 + * @TODO this is still written in a barbaric way, refactor when needed
355 392 */
356 - var targets = {};
393 + const customifyFoldingFields = function () {
357 394
358 - $.fn.reactor.defaults.compliant = function () {
359 - $(this).slideDown();
360 - // $(this).animate({opacity: 1});
361 - $(this).find(':disabled').attr({disabled: false});
362 - };
363 -
364 - $.fn.reactor.defaults.uncompliant = function () {
365 - $(this).slideUp();
366 - // $(this).animate({opacity: 0.25});
367 - $(this).find(':enabled').attr({disabled: true});
368 - };
369 -
370 - var IS = $.extend({}, $.fn.reactor.helpers);
371 -
372 - var bind_folding_events = function ( parent_id, field, relation ) {
373 -
374 - var key = null;
375 -
376 - if ( _.isString(field) ) {
377 - key = field;
378 - } else if ( ! _.isUndefined(field.id) ) {
379 - key = field.id;
380 - } else if ( isString( field[0] ) ) {
381 - key = field[0];
382 - } else {
383 - return; // no key, no fun
395 + if (_.isUndefined(customify_settings) || _.isUndefined(customify_settings.settings)) {
396 + return // bail
384 397 }
385 398
386 - var value = 1, // by default we use 1 the most used value for checboxes or inputs
387 - compare = '==', // ... ye
388 - action = "show",
389 - between = [0,1]; // can only be `show` or `hide`
399 + /**
400 + * Let's iterate through all the customify settings and gather all the fields that have a "show_if"
401 + * property set.
402 + *
403 + * At the end `targets` will hold a list of [ target : [field, field,...], ... ]
404 + * so when a target is changed we will change all the fields.
405 + */
406 + var targets = {}
390 407
391 - var target_key = customify_settings.options_name + '[' + key + ']';
392 -
393 - var target_type = customify_settings.settings[target_key].type;
394 -
395 - // we support the usual syntax like a config array like `array( 'id' => $id, 'value' => $value, 'compare' => $compare )`
396 - // but we also support a non-associative array like `array( $id, $value, $compare )`
397 - if ( ! _.isUndefined ( field.value ) ) {
398 - value = field.value;
399 - } else if ( ! _.isUndefined( field[1] ) && ! _.isString(field[1]) ) {
400 - value = field[1];
408 + $.fn.reactor.defaults.compliant = function () {
409 + $(this).slideDown()
410 + // $(this).animate({opacity: 1});
411 + $(this).find(':disabled').attr({disabled: false})
401 412 }
402 413
403 - if ( ! _.isUndefined(field.compare) ) {
404 - compare = field.compare;
405 - } else if ( ! _.isUndefined(field[2]) ) {
406 - compare = field[2];
414 + $.fn.reactor.defaults.uncompliant = function () {
415 + $(this).slideUp()
416 + // $(this).animate({opacity: 0.25});
417 + $(this).find(':enabled').attr({disabled: true})
407 418 }
408 419
409 - if ( !_.isUndefined(field.action) ) {
410 - action = field.action;
411 - } else if ( !_.isUndefined(field[3]) ) {
412 - action = field[3];
413 - }
420 + let IS = $.extend({}, $.fn.reactor.helpers)
414 421
415 - // a field can also overwrite the parent relation
416 - if ( !_.isUndefined(field.relation) ) {
417 - action = field.relation;
418 - } else if ( !_.isUndefined(field[4]) ) {
419 - action = field[4];
420 - }
422 + let bind_folding_events = function (parent_id, field, relation) {
421 423
422 - if ( !_.isUndefined(field.between) ) {
423 - between = field.between;
424 - }
424 + let key = null
425 425
426 - /**
427 - * Now for each target we have, we will bind a change event to hide or show the dependent fields
428 - */
429 - var target_selector = '[data-customize-setting-link="' + customify_settings.options_name + '[' + key + ']"]';
426 + if (_.isString(field)) {
427 + key = field
428 + } else if (!_.isUndefined(field.id)) {
429 + key = field.id
430 + } else if (isString(field[0])) {
431 + key = field[0]
432 + } else {
433 + return // no key, no fun
434 + }
430 435
431 - switch ( target_type ) {
432 - case 'checkbox':
433 - $(parent_id).reactIf(target_selector, function () {
434 - return $(this).is(':checked') == value;
435 - });
436 - break;
436 + let value = 1, // by default we use 1 the most used value for checkboxes or inputs
437 + compare = '==', // ... ye
438 + action = 'show',
439 + between = [0, 1] // can only be `show` or `hide`
437 440
438 - case 'radio':
439 - case 'radio_image':
441 + const target_key = customify_settings.options_name + '[' + key + ']'
442 + const target_type = customify_settings.settings[target_key].type
440 443
441 - // in case of an array of values we use the ( val in array) condition
442 - if ( _.isObject(value) ) {
443 - $(parent_id).reactIf(target_selector, function () {
444 - return ( value.indexOf( $(target_selector + ':checked').val() ) !== -1 );
445 - });
446 - } else { // in any other case we use a simple == comparison
447 - $(parent_id).reactIf(target_selector, function () {
448 - return $(target_selector + ':checked').val() == value;
449 - });
450 - }
451 - break;
444 + // we support the usual syntax like a config array like `array( 'id' => $id, 'value' => $value, 'compare' => $compare )`
445 + // but we also support a non-associative array like `array( $id, $value, $compare )`
446 + if (!_.isUndefined(field.value)) {
447 + value = field.value
448 + } else if (!_.isUndefined(field[1]) && !_.isString(field[1])) {
449 + value = field[1]
450 + }
452 451
453 - case 'range':
454 - var x = IS.Between(between[0], between[1]);
452 + if (!_.isUndefined(field.compare)) {
453 + compare = field.compare
454 + } else if (!_.isUndefined(field[2])) {
455 + compare = field[2]
456 + }
455 457
456 - $(parent_id).reactIf(target_selector, x);
457 - break;
458 + if (!_.isUndefined(field.action)) {
459 + action = field.action
460 + } else if (!_.isUndefined(field[3])) {
461 + action = field[3]
462 + }
458 463
459 - default:
460 - // in case of an array of values we use the ( val in array) condition
461 - if ( _.isObject(value) ) {
462 - $(parent_id).reactIf(target_selector, function () {
463 - return ( value.indexOf($(target_selector).val()) !== -1 );
464 - });
465 - } else { // in any other case we use a simple == comparison
466 - $(parent_id).reactIf(target_selector, function () {
467 - return $(target_selector).val() == value;
468 - });
469 - }
470 - break;
471 - }
464 + // a field can also overwrite the parent relation
465 + if (!_.isUndefined(field.relation)) {
466 + action = field.relation
467 + } else if (!_.isUndefined(field[4])) {
468 + action = field[4]
469 + }
472 470
473 - $(target_selector).trigger('change');
474 - $('.reactor').trigger('change.reactor'); // triggers all events on load
475 - };
476 -
477 - $.each(customify_settings.settings, function ( id, field ) {
478 - /**
479 - * Here we have the id of the fields. but we know for sure that we just need his parent selector
480 - * So we just create it
481 - */
482 - var parent_id = id.replace('[', '-');
483 - parent_id = parent_id.replace(']', '');
484 - parent_id = '#customize-control-' + parent_id + '_control';
485 -
486 - // get only the fields that have a 'show_if' property
487 - if ( field.hasOwnProperty('show_if') ) {
488 - var relation = 'AND';
489 -
490 - if ( ! _.isUndefined( field.show_if.relation ) ) {
491 - relation = field.show_if.relation;
492 - // remove the relation property, we need the config to be array based only
493 - delete field.show_if.relation;
471 + if (!_.isUndefined(field.between)) {
472 + between = field.between
494 473 }
495 474
496 475 /**
497 - * The 'show_if' can be a simple array with one target like: [ id, value, comparison, action ]
498 - * Or it could be an array of multiple targets and we need to process both cases
476 + * Now for each target we have, we will bind a change event to hide or show the dependent fields
499 477 */
478 + const target_selector = '[data-customize-setting-link="' + customify_settings.options_name + '[' + key + ']"]'
500 479
501 - if ( ! _.isUndefined( field.show_if.id ) ) {
502 - bind_folding_events(parent_id, field.show_if, relation );
503 - } else if ( _.isObject( field.show_if ) ) {
504 - $.each(field.show_if, function ( i, j ) {
505 - bind_folding_events( parent_id, j, relation );
506 - });
507 - }
508 - }
509 - });
510 - };
480 + switch (target_type) {
481 + case 'checkbox':
482 + $(parent_id).reactIf(target_selector, function () {
483 + return $(this).is(':checked') == value
484 + })
485 + break
511 486
512 - var get_typography_font_family = function ( $el ) {
487 + case 'radio':
488 + case 'sm_radio':
489 + case 'sm_switch':
490 + case 'radio_image':
513 491
514 - var font_family_value = $el.val();
515 - // first time this will not be a json so catch that error
516 - try {
517 - font_family_value = JSON.parse(font_family_value);
518 - } catch ( e ) {
519 - return {font_family: font_family_value};
520 - }
492 + // in case of an array of values we use the ( val in array) condition
493 + if (_.isObject(value)) {
494 + $(parent_id).reactIf(target_selector, function () {
495 + return (
496 + value.indexOf($(target_selector + ':checked').val()) !== -1
497 + )
498 + })
499 + } else { // in any other case we use a simple == comparison
500 + $(parent_id).reactIf(target_selector, function () {
501 + return $(target_selector + ':checked').val() == value
502 + })
503 + }
504 + break
521 505
522 - if ( !_.isUndefined(font_family_value.font_family) ) {
523 - return font_family_value.font_family;
524 - }
506 + case 'range':
507 + const x = IS.Between(between[0], between[1])
525 508
526 - return false;
527 - };
509 + $(parent_id).reactIf(target_selector, x)
510 + break
528 511
529 - // get each typography field and bind events
530 - var prepare_typography_field = function () {
512 + default:
513 + // in case of an array of values we use the ( val in array) condition
514 + if (_.isObject(value)) {
515 + $(parent_id).reactIf(target_selector, function () {
516 + return (
517 + value.indexOf($(target_selector).val()) !== -1
518 + )
519 + })
520 + } else { // in any other case we use a simple == comparison
521 + $(parent_id).reactIf(target_selector, function () {
522 + return $(target_selector).val() == value
523 + })
524 + }
525 + break
526 + }
531 527
532 - var $typos = $('.customify_typography_font_family');
528 + $(target_selector).trigger('change')
529 + $('.reactor').trigger('change.reactor') // triggers all events on load
530 + }
533 531
534 - $typos.each(function () {
535 - var font_family_select = this,
536 - $input = $(font_family_select).siblings('.customify_typography_values');
537 - // on change
538 - $(font_family_select).on('change', function () {
539 - update_siblings_selects(font_family_select);
540 - $input.trigger('change');
541 - });
542 - update_siblings_selects(font_family_select);
543 - });
544 - };
532 + $.each(customify_settings.settings, function (id, field) {
533 + /**
534 + * Here we have the id of the fields. but we know for sure that we just need his parent selector
535 + * So we just create it
536 + */
537 + let parent_id = id.replace('[', '-')
538 + parent_id = parent_id.replace(']', '')
539 + parent_id = '#customize-control-' + parent_id + '_control'
545 540
546 - var api_set_setting_value = function ( id, value ) {
541 + // get only the fields that have a 'show_if' property
542 + if (field.hasOwnProperty('show_if')) {
543 + let relation = 'AND'
547 544
548 - var setting_id = customify_settings.options_name + '[' + id + ']',
549 - setting = api(setting_id),
550 - field = $('[data-customize-setting-link="' + setting_id + '"]'),
551 - field_class = $(field).parent().attr('class');
545 + if (!_.isUndefined(field.show_if.relation)) {
546 + relation = field.show_if.relation
547 + // remove the relation property, we need the config to be array based only
548 + delete field.show_if.relation
549 + }
552 550
553 - if ( !_.isUndefined(field_class) && field_class === 'customify_typography' ) {
551 + /**
552 + * The 'show_if' can be a simple array with one target like: [ id, value, comparison, action ]
553 + * Or it could be an array of multiple targets and we need to process both cases
554 + */
554 555
555 - var family_select = field.siblings('select');
556 + if (!_.isUndefined(field.show_if.id)) {
557 + bind_folding_events(parent_id, field.show_if, relation)
558 + } else if (_.isObject(field.show_if)) {
559 + $.each(field.show_if, function (i, j) {
560 + bind_folding_events(parent_id, j, relation)
561 + })
562 + }
563 + }
564 + })
565 + }
556 566
557 - if ( _.isString(value) ) {
558 - var this_option = family_select.find('option[value="' + value + '"]');
559 - $(this_option[0]).attr('selected', 'selected');
560 - update_siblings_selects(family_select);
561 - } else if ( _.isObject(value) ) {
562 - var this_family_option = family_select.find('option[value="' + value['font_family'] + '"]');
563 - $(this_family_option[0]).attr('selected', 'selected');
567 + const get_typography_font_family = function ($el) {
564 568
565 - update_siblings_selects(this_family_option);
569 + let font_family_value = $el.val()
570 + // first time this will not be a json so catch that error
571 + try {
572 + font_family_value = JSON.parse(font_family_value)
573 + } catch (e) {
574 + return {font_family: font_family_value}
575 + }
566 576
567 - setTimeout(function () {
568 - var weight_select = field.parent().siblings('.options').find('.customify_typography_font_weight');
569 -
570 - var this_weight_option = weight_select.find('option[value="' + value['selected_variants'] + '"]');
571 -
572 - $(this_weight_option[0]).attr('selected', 'selected');
573 -
574 - update_siblings_selects(this_family_option);
575 -
576 - weight_select.trigger('change');
577 - }, 300);
577 + if (!_.isUndefined(font_family_value.font_family)) {
578 + return font_family_value.font_family
578 579 }
579 580
580 - family_select.trigger('change');
581 -
582 - } else {
583 - setting.set(value);
581 + return false
584 582 }
585 - };
586 583
587 - var update_siblings_selects = function ( font_select ) {
588 - var selected_font = $(font_select).val(),
589 - $input = $(font_select).siblings('.customify_typography_values'),
590 - current_val = $input.attr('value');
584 + // get each typography field and bind events
585 + // @todo Are we still using the typography field since we have the font field?
586 + const prepare_typography_field = function () {
591 587
592 - if ( current_val === '[object Object]' ) {
593 - current_val = $input.data('default');
594 - } else if ( _.isString(current_val) && !isJsonString(current_val) && current_val.substr(0, 1) == '[' ) {
595 - // a rare case when the value isn't a json but is a representative string like [family,weight]
596 - current_val = current_val.split(',');
597 - var new_current_value = {};
598 - if ( !_.isUndefined(current_val[0]) ) {
599 - new_current_value['font_family'] = current_val[0];
600 - }
588 + const $typos = $('.customify_typography_font_family')
601 589
602 - if ( !_.isUndefined(current_val[1]) ) {
603 - new_current_value['selected_variants'] = current_val[1];
604 - }
590 + $typos.each(function () {
591 + var font_family_select = this,
592 + $input = $(font_family_select).siblings('.customify_typography_values')
593 + // on change
594 + $(font_family_select).on('change', function () {
595 + update_siblings_selects(font_family_select)
596 + $input.trigger('change')
597 + })
598 + update_siblings_selects(font_family_select)
599 + })
600 + }
605 601
606 - current_val = JSON.stringify(new_current_value);
607 - }
602 + const api_set_setting_value = function (setting_id, value) {
603 + let setting = api(setting_id),
604 + field = $('[data-customize-setting-link="' + setting_id + '"]'),
605 + field_class = $(field).parent().attr('class')
608 606
609 - var $font_weight = $(font_select).parent().siblings('ul.options').find('.customify_typography_font_weight'),
610 - $font_subsets = $(font_select).parent().siblings('ul.options').find('.customify_typography_font_subsets');
607 + // Legacy field type
608 + if (!_.isUndefined(field_class) && field_class === 'customify_typography') {
611 609
612 - try {
613 - current_val = JSON.parse(decodeURIComponent(current_val));
614 - } catch ( e ) {
610 + let family_select = field.siblings('select')
615 611
616 - // in case of an error, force the rebuild of the json
617 - if ( _.isUndefined($(font_select).data('bound_once')) ) {
612 + if (_.isString(value)) {
613 + let this_option = family_select.find('option[value="' + value + '"]')
614 + $(this_option[0]).attr('selected', 'selected')
615 + update_siblings_selects(family_select)
616 + } else if (_.isObject(value)) {
617 + let this_family_option = family_select.find('option[value="' + value['font_family'] + '"]')
618 618
619 - $(font_select).data('bound_once', true);
619 + $(this_family_option[0]).attr('selected', 'selected')
620 620
621 - $(font_select).change();
622 - $font_weight.change();
623 - $font_subsets.change();
624 - }
625 - }
621 + update_siblings_selects(this_family_option)
626 622
627 - // first try to get the font from sure sources, not from the recommended list.
628 - var option_data = $(font_select).find(':not(optgroup[label=Recommended]) option[value="' + selected_font + '"]');
629 - // however, if there isn't an option found, get what you can
630 - if ( option_data.length < 1 ) {
631 - option_data = $(font_select).find('option[value="' + selected_font + '"]');
632 - }
623 + setTimeout(function () {
624 + let weight_select = field.parent().siblings('.options').find('.customify_typography_font_weight'),
625 + this_weight_option = weight_select.find('option[value="' + value['selected_variants'] + '"]')
633 626
634 - if ( option_data.length > 0 ) {
627 + $(this_weight_option[0]).attr('selected', 'selected')
635 628
636 - var font_type = option_data.data('type'),
637 - value_to_add = {'type': font_type, 'font_family': selected_font},
638 - variants = null,
639 - subsets = null;
629 + update_siblings_selects(this_family_option)
640 630
641 - if ( font_type == 'std' ) {
642 - variants = {
643 - 0: '100',
644 - 1: '200',
645 - 3: '300',
646 - 4: '400',
647 - 5: '500',
648 - 6: '600',
649 - 7: '700',
650 - 8: '800',
651 - 9: '900'
652 - };
653 - if ( !_.isUndefined($(option_data[0]).data('variants')) ) {
654 - //maybe the variants are a JSON
655 - variants = maybeJsonParse($(option_data[0]).data('variants'));
631 + weight_select.trigger('change')
632 + }, 300)
656 633 }
657 - } else {
658 - //maybe the variants are a JSON
659 - variants = maybeJsonParse($(option_data[0]).data('variants'));
660 634
661 - //maybe the subsets are a JSON
662 - subsets = maybeJsonParse($(option_data[0]).data('subsets'));
663 - }
635 + family_select.trigger('change')
664 636
665 - // make the variants selector
666 - if ( !_.isUndefined(variants) && !_.isNull(variants) && !_.isEmpty(variants) ) {
637 + } else if (!_.isUndefined(field_class) && field_class === 'font-options__wrapper') {
667 638
668 - value_to_add['variants'] = variants;
669 - // when a font is selected force the first weight to load
670 - value_to_add['selected_variants'] = {0: variants[0]};
639 + // if the value is a simple string it must be the font family
640 + if (_.isString(value)) {
641 + let option = field.parent().find('option[value="' + value + '"]')
671 642
672 - var variants_options = '',
673 - count_weights = 0;
643 + option.attr('selected', 'selected')
644 + // option.parents('select').trigger('change');
645 + } else if (_.isObject(value)) {
646 + // Find the options list wrapper
647 + let optionsList = field.parent().children('.font-options__options-list')
674 648
675 - if ( _.isArray(variants) || _.isObject(variants) ) {
676 - // Take each variant and produce the option markup
677 - $.each(variants, function ( key, el ) {
678 - var is_selected = '';
679 - if ( _.isObject(current_val.selected_variants) && inObject(el, current_val.selected_variants) ) {
680 - is_selected = ' selected="selected"';
681 - } else if ( _.isString(current_val.selected_variants) && el === current_val.selected_variants ) {
682 - is_selected = ' selected="selected"';
683 - }
649 + if (optionsList.length) {
650 + // We will process each font property and update it
651 + _.each(value, function (val, key) {
652 + // We need to map the keys to the data attributes we are using - I know :(
653 + let mappedKey = key
654 + switch (key) {
655 + case 'font-family':
656 + mappedKey = 'font_family'
657 + break
658 + case 'font-size':
659 + mappedKey = 'font_size'
660 + break
661 + case 'font-weight':
662 + mappedKey = 'selected_variants'
663 + break
664 + case 'letter-spacing':
665 + mappedKey = 'letter_spacing'
666 + break
667 + case 'text-transform':
668 + mappedKey = 'text_transform'
669 + break
670 + default:
671 + break
672 + }
673 + let subField = optionsList.find('[data-field="' + mappedKey + '"]')
674 + if (subField.length) {
675 + subField.val(val)
676 + subField.trigger('change')
677 + }
678 + })
679 + }
680 + }
684 681
685 - // initialize
686 - var variant_option_value = el,
687 - variant_option_display = el;
682 + } else {
683 + setting.set(value)
684 + }
685 + }
688 686
689 - // If we are dealing with a object variant then it means things get tricky (probably it's our fault but bear with us)
690 - // This probably comes from our Fonto plugin - a font with individually named variants - hence each has its own font-family
691 - if ( _.isObject(el) ) {
692 - //put the entire object in the variation value - we will need it when outputting the custom CSS
693 - variant_option_value = encodeURIComponent(JSON.stringify(el));
694 - variant_option_display = '';
687 + const update_siblings_selects = function (font_select) {
688 + let selected_font = $(font_select).val(),
689 + $input = $(font_select).siblings('.customify_typography_values'),
690 + current_val = $input.attr('value')
695 691
696 - //if we have weight and style then "compose" them into something standard
697 - if ( !_.isUndefined(el['font-weight']) ) {
698 - variant_option_display += el['font-weight'];
699 - }
692 + if (current_val === '[object Object]') {
693 + current_val = $input.data('default')
694 + } else if (_.isString(current_val) && !isJsonString(current_val) && current_val.substr(0, 1) == '[') {
695 + // a rare case when the value isn't a json but is a representative string like [family,weight]
696 + current_val = current_val.split(',')
697 + let new_current_value = {}
698 + if (!_.isUndefined(current_val[0])) {
699 + new_current_value['font_family'] = current_val[0]
700 + }
700 701
701 - if ( _.isString(el['font-style']) && $.inArray(el['font-style'].toLowerCase(), ["normal", "regular"]) < 0 ) { //this comparison means it hasn't been found
702 - variant_option_display += el['font-style'];
703 - }
704 - }
705 -
706 - variants_options += '<option value="' + variant_option_value + '"' + is_selected + '>' + variant_option_display + '</option>';
707 - count_weights++;
708 - });
702 + if (!_.isUndefined(current_val[1])) {
703 + new_current_value['selected_variants'] = current_val[1]
709 704 }
710 705
711 - if ( !_.isUndefined($font_weight) ) {
712 - $font_weight.html(variants_options);
713 - // if there is no weight or just 1 we hide the weight select ... cuz is useless
714 - if ( $(font_select).data('load_all_weights') === true || count_weights <= 1 ) {
715 - $font_weight.parent().css('display', 'none');
716 - } else {
717 - $font_weight.parent().css('display', 'inline-block');
718 - }
719 - }
720 - } else if ( !_.isUndefined($font_weight) ) {
721 - $font_weight.parent().css('display', 'none');
706 + current_val = JSON.stringify(new_current_value)
722 707 }
723 708
724 - // make the subsets selector
725 - if ( !_.isUndefined(subsets) && !_.isNull(subsets) && !_.isEmpty(subsets) ) {
709 + let $font_weight = $(font_select).parent().siblings('ul.options').find('.customify_typography_font_weight'),
710 + $font_subsets = $(font_select).parent().siblings('ul.options').find('.customify_typography_font_subsets')
726 711
727 - value_to_add['subsets'] = subsets;
728 - // when a font is selected force the first subset to load
729 - value_to_add['selected_subsets'] = {0: subsets[0]};
730 - var subsets_options = '',
731 - count_subsets = 0;
732 - $.each(subsets, function ( key, el ) {
733 - var is_selected = '';
734 - if ( _.isObject(current_val.selected_subsets) && inObject(el, current_val.selected_subsets) ) {
735 - is_selected = ' selected="selected"';
736 - }
712 + try {
713 + current_val = JSON.parse(decodeURIComponent(current_val))
714 + } catch (e) {
737 715
738 - subsets_options += '<option value="' + el + '"' + is_selected + '>' + el + '</option>';
739 - count_subsets++;
740 - });
716 + // in case of an error, force the rebuild of the json
717 + if (_.isUndefined($(font_select).data('bound_once'))) {
741 718
742 - if ( !_.isUndefined($font_subsets) ) {
743 - $font_subsets.html(subsets_options);
719 + $(font_select).data('bound_once', true)
744 720
745 - // if there is no subset or just 1 we hide the subsets select ... cuz is useless
746 - if ( count_subsets <= 1 ) {
747 - $font_subsets.parent().css('display', 'none');
748 - } else {
749 - $font_subsets.parent().css('display', 'inline-block');
750 - }
721 + $(font_select).change()
722 + $font_weight.change()
723 + $font_subsets.change()
751 724 }
752 - } else if ( !_.isUndefined($font_subsets) ) {
753 - $font_subsets.parent().css('display', 'none');
754 725 }
755 726
756 - $input.val(encodeURIComponent(JSON.stringify(value_to_add)));
757 - }
758 - };
727 + // first try to get the font from sure sources, not from the recommended list.
728 + let option_data = $(font_select).find(':not(optgroup[label=Recommended]) option[value="' + selected_font + '"]')
729 + // however, if there isn't an option found, get what you can
730 + if (option_data.length < 1) {
731 + option_data = $(font_select).find('option[value="' + selected_font + '"]')
732 + }
759 733
760 - /** Modules **/
734 + if (option_data.length > 0) {
761 735
762 - var customifyBackgroundJsControl = (function () {
763 - "use strict";
736 + let font_type = option_data.data('type'),
737 + value_to_add = {'type': font_type, 'font_family': selected_font},
738 + variants = null,
739 + subsets = null
764 740
765 - function init() {
766 - // Remove the image button
767 - $('.customize-control-custom_background .remove-image, .customize-control-custom_background .remove-file').unbind('click').on('click', function ( e ) {
768 - removeImage($(this).parents('.customize-control-custom_background:first'));
769 - preview($(this));
770 - return false;
771 - });
741 + if (font_type == 'std') {
742 + variants = {
743 + 0: '100',
744 + 1: '200',
745 + 3: '300',
746 + 4: '400',
747 + 5: '500',
748 + 6: '600',
749 + 7: '700',
750 + 8: '800',
751 + 9: '900'
752 + }
753 + if (!_.isUndefined($(option_data[0]).data('variants'))) {
754 + //maybe the variants are a JSON
755 + variants = maybeJsonParse($(option_data[0]).data('variants'))
756 + }
757 + } else {
758 + //maybe the variants are a JSON
759 + variants = maybeJsonParse($(option_data[0]).data('variants'))
772 760
773 - // Upload media button
774 - $('.customize-control-custom_background .background_upload_button').unbind().on('click', function ( event ) {
775 - addImage(event, $(this).parents('.customize-control-custom_background:first'));
776 - });
761 + //maybe the subsets are a JSON
762 + subsets = maybeJsonParse($(option_data[0]).data('subsets'))
763 + }
777 764
778 - $('.customify_background_select').on('change', function () {
779 - preview($(this));
780 - });
781 - }
765 + // make the variants selector
766 + if (!_.isUndefined(variants) && !_.isNull(variants) && !_.isEmpty(variants)) {
782 767
783 - // Add a file via the wp.media function
784 - function addImage( event, selector ) {
768 + value_to_add['variants'] = variants
769 + // when a font is selected force the first weight to load
770 + value_to_add['selected_variants'] = {0: variants[0]}
785 771
786 - event.preventDefault();
772 + let variants_options = '',
773 + count_weights = 0
787 774
788 - var frame;
789 - var jQueryel = jQuery(this);
775 + if (_.isArray(variants) || _.isObject(variants)) {
776 + // Take each variant and produce the option markup
777 + $.each(variants, function (key, el) {
778 + let is_selected = ''
779 + if (_.isObject(current_val.selected_variants) && inObject(el, current_val.selected_variants)) {
780 + is_selected = ' selected="selected"'
781 + } else if (_.isString(current_val.selected_variants) && el === current_val.selected_variants) {
782 + is_selected = ' selected="selected"'
783 + }
790 784
791 - // If the media frame already exists, reopen it.
792 - if ( frame ) {
793 - frame.open();
794 - return;
795 - }
785 + // initialize
786 + let variant_option_value = el,
787 + variant_option_display = el
796 788
797 - // Create the media frame.
798 - frame = wp.media({
799 - multiple: false,
800 - library: {
801 - //type: 'image' //Only allow images
802 - },
803 - // Set the title of the modal.
804 - title: jQueryel.data('choose'),
789 + // If we are dealing with a object variant then it means things get tricky (probably it's our fault but bear with us)
790 + // This probably comes from our Fonto plugin - a font with individually named variants - hence each has its own font-family
791 + if (_.isObject(el)) {
792 + //put the entire object in the variation value - we will need it when outputting the custom CSS
793 + variant_option_value = encodeURIComponent(JSON.stringify(el))
794 + variant_option_display = ''
805 795
806 - // Customize the submit button.
807 - button: {
808 - // Set the text of the button.
809 - text: jQueryel.data('update')
810 - // Tell the button not to close the modal, since we're
811 - // going to refresh the page when the image is selected.
812 - }
813 - });
796 + //if we have weight and style then "compose" them into something standard
797 + if (!_.isUndefined(el['font-weight'])) {
798 + variant_option_display += el['font-weight']
799 + }
814 800
815 - // When an image is selected, run a callback.
816 - frame.on('select', function () {
817 - // Grab the selected attachment.
818 - var attachment = frame.state().get('selection').first();
819 - frame.close();
801 + if (_.isString(el['font-style']) && $.inArray(el['font-style'].toLowerCase(), [
802 + 'normal',
803 + 'regular'
804 + ]) < 0) { //this comparison means it hasn't been found
805 + variant_option_display += el['font-style']
806 + }
807 + }
820 808
821 - if ( attachment.attributes.type !== "image" ) {
822 - return;
823 - }
809 + variants_options += '<option value="' + variant_option_value + '"' + is_selected + '>' + variant_option_display + '</option>'
810 + count_weights++
811 + })
812 + }
824 813
825 - selector.find('.upload').attr('value', attachment.attributes.url);
826 - selector.find('.upload-id').attr('value', attachment.attributes.id);
827 - selector.find('.upload-height').attr('value', attachment.attributes.height);
828 - selector.find('.upload-width').attr('value', attachment.attributes.width);
829 -
830 - var thumbSrc = attachment.attributes.url;
831 - if ( !_.isUndefined(attachment.attributes.sizes) && !_.isUndefined(attachment.attributes.sizes.thumbnail) ) {
832 - thumbSrc = attachment.attributes.sizes.thumbnail.url;
833 - } else if ( !_.isUndefined(attachment.attributes.sizes) ) {
834 - var height = attachment.attributes.height;
835 - for ( var key in attachment.attributes.sizes ) {
836 - var object = attachment.attributes.sizes[key];
837 - if ( object.height < height ) {
838 - height = object.height;
839 - thumbSrc = object.url;
814 + if (!_.isUndefined($font_weight)) {
815 + $font_weight.html(variants_options)
816 + // if there is no weight or just 1 we hide the weight select ... cuz is useless
817 + if ($(font_select).data('load_all_weights') === true || count_weights <= 1) {
818 + $font_weight.parent().css('display', 'none')
819 + } else {
820 + $font_weight.parent().css('display', 'inline-block')
840 821 }
841 822 }
842 - } else {
843 - thumbSrc = attachment.attributes.icon;
823 + } else if (!_.isUndefined($font_weight)) {
824 + $font_weight.parent().css('display', 'none')
844 825 }
845 826
846 - selector.find('.customify_background_input.background-image').val(attachment.attributes.url);
827 + // make the subsets selector
828 + if (!_.isUndefined(subsets) && !_.isNull(subsets) && !_.isEmpty(subsets)) {
847 829
848 - if ( !selector.find('.upload').hasClass('noPreview') ) {
849 - selector.find('.preview_screenshot').empty().hide().append('<img class="preview_image" src="' + thumbSrc + '">').slideDown('fast');
850 - }
851 - //selector.find('.media_upload_button').unbind();
852 - selector.find('.remove-image').removeClass('hide');//show "Remove" button
853 - selector.find('.customify_background_select').removeClass('hide');//show "Remove" button
830 + value_to_add['subsets'] = subsets
831 + // when a font is selected force the first subset to load
832 + value_to_add['selected_subsets'] = {0: subsets[0]}
833 + let subsets_options = '',
834 + count_subsets = 0
835 + $.each(subsets, function (key, el) {
836 + let is_selected = ''
837 + if (_.isObject(current_val.selected_subsets) && inObject(el, current_val.selected_subsets)) {
838 + is_selected = ' selected="selected"'
839 + }
854 840
855 - preview(selector);
856 - });
841 + subsets_options += '<option value="' + el + '"' + is_selected + '>' + el + '</option>'
842 + count_subsets++
843 + })
857 844
858 - // Finally, open the modal.
859 - frame.open();
860 - }
845 + if (!_.isUndefined($font_subsets)) {
846 + $font_subsets.html(subsets_options)
861 847
862 - // Update the background preview
863 - function preview( selector ) {
848 + // if there is no subset or just 1 we hide the subsets select ... cuz is useless
849 + if (count_subsets <= 1) {
850 + $font_subsets.parent().css('display', 'none')
851 + } else {
852 + $font_subsets.parent().css('display', 'inline-block')
853 + }
854 + }
855 + } else if (!_.isUndefined($font_subsets)) {
856 + $font_subsets.parent().css('display', 'none')
857 + }
864 858
865 - var $parent = selector.parents('.customize-control-custom_background:first');
866 -
867 - if ( selector.hasClass('customize-control-custom_background') ) {
868 - $parent = selector;
859 + $input.val(encodeURIComponent(JSON.stringify(value_to_add)))
869 860 }
861 + }
870 862
871 - if ( $parent.length > 0 ) {
872 - $parent = $($parent[0]);
873 - } else {
874 - return;
875 - }
863 + /** Modules **/
876 864
877 - var image_holder = $parent.find('.background-preview');
865 + const customifyBackgroundJsControl = (
866 + function () {
867 + 'use strict'
878 868
879 - if ( !image_holder ) { // No preview present
880 - return;
881 - }
869 + function init () {
870 + // Remove the image button
871 + $('.customize-control-custom_background .remove-image, .customize-control-custom_background .remove-file').unbind('click').on('click', function (e) {
872 + removeImage($(this).parents('.customize-control-custom_background:first'))
873 + preview($(this))
874 + return false
875 + })
882 876
883 - var the_id = $parent.find('.button.background_upload_button').data('setting_id'),
884 - this_setting = api.instance(the_id);
877 + // Upload media button
878 + $('.customize-control-custom_background .background_upload_button').unbind().on('click', function (event) {
879 + addImage(event, $(this).parents('.customize-control-custom_background:first'))
880 + })
885 881
886 - var background_data = {};
887 -
888 - $parent.find('.customify_background_select, .customify_background_input').each(function () {
889 - var data = $(this).serializeArray();
890 -
891 - data = data[0];
892 - if ( data && data.name.indexOf('[background-') != -1 ) {
893 -
894 - background_data[$(this).data('select_name')] = data.value;
895 -
896 - //default_default[data.name] = data.value;
897 - //if (data.name == "background-image") {
898 - // css += data.name + ':url("' + data.value + '");';
899 - //} else {
900 - // css += data.name + ':' + data.value + ';';
901 - //}
882 + $('.customify_background_select').on('change', function () {
883 + preview($(this))
884 + })
902 885 }
903 - });
904 886
905 - api.instance(the_id).set(background_data);
906 - //// Notify the customizer api about this change
907 - api.trigger('change');
908 - api.previewer.refresh();
887 + // Add a file via the wp.media function
888 + function addImage (event, selector) {
909 889
910 - //image_holder.attr('style', css).fadeIn();
911 - }
890 + event.preventDefault()
912 891
913 - // Update the background preview
914 - function removeImage( parent ) {
915 - var selector = parent.find('.upload_button_div');
916 - // This shouldn't have been run...
917 - if ( !selector.find('.remove-image').addClass('hide') ) {
918 - return;
919 - }
892 + var frame
893 + var jQueryel = jQuery(this)
920 894
921 - selector.find('.remove-image').addClass('hide');//hide "Remove" button
922 - parent.find('.customify_background_select').addClass('hide');
895 + // If the media frame already exists, reopen it.
896 + if (frame) {
897 + frame.open()
898 + return
899 + }
923 900
924 - selector.find('.upload').val('');
925 - selector.find('.upload-id').val('');
926 - selector.find('.upload-height').val('');
927 - selector.find('.upload-width').val('');
928 - parent.find('.customify_background_input.background-image').val('');
901 + // Create the media frame.
902 + frame = wp.media({
903 + multiple: false,
904 + library: {
905 + //type: 'image' //Only allow images
906 + },
907 + // Set the title of the modal.
908 + title: jQueryel.data('choose'),
929 909
930 - var customizer_id = selector.find('.background_upload_button').data('setting_id'),
931 - this_setting = api.control(customizer_id + '_control'),
932 - current_vals = this_setting.setting(),
933 - screenshot = parent.find('.preview_screenshot'),
934 - to_array = $.map(current_vals, function ( value, index ) {
935 - return [value];
936 - });
910 + // Customize the submit button.
911 + button: {
912 + // Set the text of the button.
913 + text: jQueryel.data('update')
914 + // Tell the button not to close the modal, since we're
915 + // going to refresh the page when the image is selected.
916 + }
917 + })
937 918
938 - // Hide the screenshot
939 - screenshot.slideUp();
940 - selector.find('.remove-file').unbind();
941 - to_array['background-image'] = '';
942 - this_setting.setting(to_array);
943 - }
919 + // When an image is selected, run a callback.
920 + frame.on('select', function () {
921 + // Grab the selected attachment.
922 + const attachment = frame.state().get('selection').first()
923 + frame.close()
944 924
945 - return {
946 - init: init
947 - }
948 - })(jQuery);
925 + if (attachment.attributes.type !== 'image') {
926 + return
927 + }
949 928
950 - var customifyFontSelect = (function () {
951 - var wpapi = null,
952 - fontSelector = '.customify_font_family',
953 - selectPlacehoder = "Select a font family",
954 - weightPlaceholder = "Select a font weight",
955 - subsetPlaceholder = "Select a font subset";
929 + selector.find('.upload').attr('value', attachment.attributes.url)
930 + selector.find('.upload-id').attr('value', attachment.attributes.id)
931 + selector.find('.upload-height').attr('value', attachment.attributes.height)
932 + selector.find('.upload-width').attr('value', attachment.attributes.width)
956 933
957 - function init( wpapi ) {
934 + let thumbSrc = attachment.attributes.url
935 + if (!_.isUndefined(attachment.attributes.sizes) && !_.isUndefined(attachment.attributes.sizes.thumbnail)) {
936 + thumbSrc = attachment.attributes.sizes.thumbnail.url
937 + } else if (!_.isUndefined(attachment.attributes.sizes)) {
938 + let height = attachment.attributes.height
939 + for (let key in attachment.attributes.sizes) {
940 + const object = attachment.attributes.sizes[key]
941 + if (object.height < height) {
942 + height = object.height
943 + thumbSrc = object.url
944 + }
945 + }
946 + } else {
947 + thumbSrc = attachment.attributes.icon
948 + }
958 949
959 - this.wpapi = wpapi;
950 + selector.find('.customify_background_input.background-image').val(attachment.attributes.url)
960 951
961 - setTimeout(function () {
962 - $(fontSelector).select2({
963 - placeholder: selectPlacehoder
964 - }).on('change', function ( e ) {
965 - var new_option = $(e.target).find('option:selected'),
966 - wraper = $(e.target).closest('.font-options__wrapper'),
967 - type = $(new_option).data('type');
952 + if (!selector.find('.upload').hasClass('noPreview')) {
953 + selector.find('.preview_screenshot').empty().hide().append('<img class="preview_image" src="' + thumbSrc + '">').slideDown('fast')
954 + }
955 + //selector.find('.media_upload_button').unbind();
956 + selector.find('.remove-image').removeClass('hide')//show "Remove" button
957 + selector.find('.customify_background_select').removeClass('hide')//show "Remove" button
968 958
969 - update_weight_field(new_option, wraper);
970 - update_subset_field(new_option, wraper);
959 + preview(selector)
960 + })
971 961
972 - // serialize stuff and refresh
973 - update_font_value(wraper);
974 - });
975 - }, 333);
962 + // Finally, open the modal.
963 + frame.open()
964 + }
976 965
977 - $('.customify_font_weight').each(function ( i, el ) {
966 + // Update the background preview
967 + function preview (selector) {
978 968
979 - var select2_args = {
980 - debug: false
981 - };
969 + let $parent = selector.parents('.customize-control-custom_background:first')
982 970
983 - // all this fuss is for the case when the font doesn't come with variants from PHP, lile a theme_font
984 - if ( this.options.length === 0 ) {
985 - var wraper = $(el).closest('.font-options__wrapper'),
986 - font = wraper.find('.customify_font_family'),
987 - option = font[0].options[font[0].selectedIndex],
988 - variants = maybeJsonParse( $(option).data('variants') ),
989 - data = [],
990 - selecter_variants = $(el).data('default') || null;
971 + if (selector.hasClass('customize-control-custom_background')) {
972 + $parent = selector
973 + }
991 974
992 - if ( typeof variants === "undefined" ) {
993 - $(this).hide();
994 - return;
975 + if ($parent.length > 0) {
976 + $parent = $($parent[0])
977 + } else {
978 + return
995 979 }
996 980
997 - $.each( variants, function ( index, weight ) {
998 - var this_value = {
999 - id: weight,
1000 - text: weight
1001 - };
1002 - if ( selecter_variants !== null && weight == selecter_variants ) {
1003 - this_value.selected = true;
1004 - }
981 + const image_holder = $parent.find('.background-preview')
1005 982
1006 - data.push(this_value);
1007 - } );
1008 -
1009 - if ( data !== [] ) {
1010 - select2_args.data = data;
983 + if (!image_holder) { // No preview present
984 + return
1011 985 }
1012 - }
1013 986
1014 - $(this).select2( select2_args )
1015 - .on('change', function ( e ) {
1016 - var wraper = $(e.target).closest('.font-options__wrapper');
1017 - var current_value = update_font_value(wraper);
1018 - // temporary just set the new value and refresh the previewr
1019 - // we may update this with a live version sometime
1020 - var value_holder = wraper.children('.customify_font_values');
1021 - var setting_id = $(value_holder).data('customize-setting-link');
1022 - var setting = wpapi(setting_id);
1023 - setting.set(encodeValues(current_value));
1024 - });
1025 - });
987 + const the_id = $parent.find('.button.background_upload_button').data('setting_id'),
988 + this_setting = api.instance(the_id)
1026 989
1027 - $('.customify_font_subsets')
1028 - .select2({
1029 - placeholder: "Extra Subsets"
1030 - })
1031 - .on('change', function ( e ) {
1032 - var wraper = $(e.target).closest('.font-options__wrapper');
1033 - var current_value = update_font_value(wraper);
1034 - // temporary just set the new value and refresh the previewr
1035 - // we may update this with a live version sometime
1036 - var value_holder = wraper.children('.customify_font_values');
1037 - var setting_id = $(value_holder).data('customize-setting-link');
1038 - var setting = wpapi(setting_id);
1039 - setting.set(encodeValues(current_value));
1040 - });
990 + let background_data = {}
1041 991
1042 - var rangers = $(fontSelector).parents('.font-options__wrapper').find('input[type=range]');
1043 - var selects = $(fontSelector).parents('.font-options__wrapper').find('select');
992 + $parent.find('.customify_background_select, .customify_background_input').each(function () {
993 + var data = $(this).serializeArray()
1044 994
1045 - if ( selects.length > 0 ) {
1046 - selects.on('change', function ( e ) {
1047 - var wraper = $(e.target).closest('.font-options__wrapper');
1048 - var current_value = update_font_value(wraper);
1049 - // temporary just set the new value and refresh the previewr
1050 - // we may update this with a live version sometime
1051 - var value_holder = wraper.children('.customify_font_values');
1052 - var setting_id = $(value_holder).data('customize-setting-link');
1053 - var setting = wpapi(setting_id);
1054 - setting.set(encodeValues(current_value));
1055 - });
1056 - }
995 + data = data[0]
996 + if (data && data.name.indexOf('[background-') != -1) {
1057 997
1058 - if ( rangers.length > 0 ) {
1059 - rangers.on('mousemove', function ( e ) {
1060 - var wraper = $(e.target).closest('.font-options__wrapper');
1061 - var current_value = update_font_value(wraper);
1062 - // temporary just set the new value and refresh the previewr
1063 - // we may update this with a live version sometime
1064 - var value_holder = wraper.children('.customify_font_values');
1065 - var setting_id = $(value_holder).data('customize-setting-link');
1066 - var setting = wpapi(setting_id);
1067 - setting.set(encodeValues(current_value));
1068 - // setting.trigger('change');
1069 - wpapi.previewer.send( 'font-changed' );
1070 - });
1071 - }
1072 - }
998 + background_data[$(this).data('select_name')] = data.value
1073 999
1074 - /**
1075 - * This function updates the data in font weight selector from the givin <option> element
1076 - *
1077 - * @param new_option
1078 - * @param wraper
1079 - */
1080 - function update_weight_field( option, wraper ) {
1081 - var variants = $(option).data('variants'),
1082 - font_weights = wraper.find('.customify_font_weight'),
1083 - new_variants = [],
1084 - type = $(option).data('type'),
1085 - id = wraper.find('.customify_font_values').data('customizeSettingLink');
1000 + //default_default[data.name] = data.value;
1001 + //if (data.name == "background-image") {
1002 + // css += data.name + ':url("' + data.value + '");';
1003 + //} else {
1004 + // css += data.name + ':' + data.value + ';';
1005 + //}
1006 + }
1007 + })
1086 1008
1087 - variants = maybeJsonParse(variants);
1009 + api.instance(the_id).set(background_data)
1010 + //// Notify the customizer api about this change
1011 + api.trigger('change')
1012 + api.previewer.refresh()
1088 1013
1089 - if ( customify_settings.settings[id].load_all_weights || typeof variants === "undefined" || Object.keys(variants).length < 2 ) {
1090 - font_weights.parent().hide();
1091 - } else {
1092 - font_weights.parent().show();
1093 - }
1094 -
1095 - var selected = 1;
1096 -
1097 - // we need to turn the data array into a specific form like [{id:"id", text:"Text"}]
1098 - $.each(variants, function ( i, j ) {
1099 - new_variants[i] = {
1100 - 'id': j,
1101 - 'text': j
1102 - };
1103 -
1104 - if ( selected === 3 ) {
1105 - new_variants[i].selected = true;
1014 + //image_holder.attr('style', css).fadeIn();
1106 1015 }
1107 - selected++;
1108 - });
1109 1016
1110 - // we need to clear the old values
1111 - $(font_weights).select2().empty();
1112 - $(font_weights).select2({
1113 - data: new_variants
1114 - }).on('change', function ( e ) {
1115 - var select_element = e.target;
1116 - var wraper = $(select_element).closest('.font-options__wrapper');
1117 - update_font_value(wraper);
1118 - });
1119 - }
1017 + // Update the background preview
1018 + function removeImage (parent) {
1019 + const selector = parent.find('.upload_button_div')
1020 + // This shouldn't have been run...
1021 + if (!selector.find('.remove-image').addClass('hide')) {
1022 + return
1023 + }
1120 1024
1121 - /**
1122 - * This function updates the data in font subset selector from the givin <option> element
1123 - * @param new_option
1124 - * @param wraper
1125 - */
1126 - function update_subset_field( option, wraper ) {
1127 - var subsets = $(option).data('subsets'),
1128 - font_subsets = wraper.find('.customify_font_subsets'),
1129 - new_subsets = [],
1130 - type = $(option).data('type');
1025 + selector.find('.remove-image').addClass('hide')//hide "Remove" button
1026 + parent.find('.customify_background_select').addClass('hide')
1131 1027
1132 - if ( type !== 'google' ) {
1133 - font_subsets.parent().hide();
1134 - return;
1135 - }
1028 + selector.find('.upload').val('')
1029 + selector.find('.upload-id').val('')
1030 + selector.find('.upload-height').val('')
1031 + selector.find('.upload-width').val('')
1032 + parent.find('.customify_background_input.background-image').val('')
1136 1033
1137 - subsets = maybeJsonParse(subsets);
1034 + let customizer_id = selector.find('.background_upload_button').data('setting_id'),
1035 + this_setting = api.control(customizer_id + '_control'),
1036 + current_vals = this_setting.setting(),
1037 + screenshot = parent.find('.preview_screenshot'),
1038 + to_array = $.map(current_vals, function (value, index) {
1039 + return [value]
1040 + })
1138 1041
1139 - if ( Object.keys(subsets).length < 2 ) {
1140 - font_subsets.parent().hide();
1141 - } else {
1142 - font_subsets.parent().show();
1143 - }
1042 + // Hide the screenshot
1043 + screenshot.slideUp()
1044 + selector.find('.remove-file').unbind()
1045 + to_array['background-image'] = ''
1046 + this_setting.setting(to_array)
1047 + }
1144 1048
1145 - // we need to turn the data array into a specific form like [{id:"id", text:"Text"}]
1146 - $.each(subsets, function ( i, j ) {
1147 - new_subsets[i] = {
1148 - 'id': j,
1149 - 'text': j
1049 + return {
1050 + init: init
1150 1051 }
1151 - });
1052 + }
1053 + )(jQuery)
1152 1054
1153 - // we need to clear the old values
1154 - $(font_subsets).select2().empty();
1155 - $(font_subsets).select2({
1156 - data: new_subsets
1157 - }).on('change', function ( e ) {
1158 - var select_element = e.target;
1159 - var wraper = $(select_element).closest('.font-options__wrapper');
1160 - update_font_value(wraper);
1161 - });
1162 - }
1055 + /** HELPERS **/
1163 1056
1164 1057 /**
1165 - * This function is a custom value serializer for our entire font field
1166 - * It collects values and saves them (encoded) into the `.customify_font_values` input's value
1058 + * Function to check if a value exists in an object
1059 + * @param value
1060 + * @param obj
1061 + * @returns {boolean}
1167 1062 */
1168 - function update_font_value( wraper ) {
1169 - var element = $(wraper).find('.font-options__wrapper'),
1170 - options_list = $(wraper).find('.font-options__options-list'),
1171 - inputs = options_list.find('select, input'),
1172 - value_holder = wraper.children('.customify_font_values'),
1173 - new_vals = {};
1174 -
1175 - inputs.each(function ( key, el ) {
1176 - var field = $(el).data('field'),
1177 - value = $(el).val();
1178 -
1179 - if ( field === 'font_family' ) {
1180 - // the font family also holds the type
1181 - var selected_opt = $(el.options[el.selectedIndex]),
1182 - type = selected_opt.data('type'),
1183 - subsets = selected_opt.data('subsets'),
1184 - variants = selected_opt.data('variants');
1185 -
1186 - if ( typeof type !== "undefined") {
1187 - new_vals['type'] = type;
1188 - if ( type === 'theme_font' ) {
1189 - new_vals['src'] = selected_opt.data('src');
1190 - }
1191 - }
1192 -
1193 - if ( typeof variants !== "undefined") {
1194 - new_vals['variants'] = maybeJsonParse(variants);
1195 - }
1196 -
1197 - if ( typeof subsets !== "subsets") {
1198 - new_vals['subsets'] = maybeJsonParse(subsets);
1199 - }
1063 + const inObject = function (value, obj) {
1064 + for (let k in obj) {
1065 + if (!obj.hasOwnProperty(k)) {
1066 + continue
1200 1067 }
1201 -
1202 -
1203 - if ( typeof field !== "undefined" && typeof value !== "undefined" && value !== "" ) {
1204 - new_vals[field] = value;
1068 + if (_.isEqual(obj[k], value)) {
1069 + return true
1205 1070 }
1206 - });
1207 -
1208 - value_holder.val(encodeValues(new_vals));
1209 -
1210 - return new_vals;
1071 + }
1072 + return false
1211 1073 }
1212 1074
1213 - var maybeJsonParse = function ( value ) {
1214 - var parsed;
1075 + const maybeJsonParse = function (value) {
1076 + let parsed
1215 1077
1216 1078 //try and parse it, with decodeURIComponent
1217 1079 try {
1218 - parsed = JSON.parse(decodeURIComponent(value));
1219 - } catch ( e ) {
1080 + parsed = JSON.parse(decodeURIComponent(value))
1081 + } catch (e) {
1220 1082
1221 1083 // in case of an error, treat is as a string
1222 - parsed = value;
1084 + parsed = value
1223 1085 }
1224 1086
1225 - return parsed;
1226 - };
1227 -
1228 - function encodeValues( obj ) {
1229 - return encodeURIComponent(JSON.stringify(obj));
1087 + return parsed
1230 1088 }
1231 1089
1232 - return {
1233 - init: init,
1234 - update_font_value: update_font_value
1235 - };
1236 - })();
1090 + const getUrlVars = function (name) {
1091 + let vars = [], hash
1092 + const hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&')
1093 + for (let i = 0; i < hashes.length; i++) {
1094 + hash = hashes[i].split('=')
1237 1095
1238 - var Queue = function () {
1239 - var lastPromise = null;
1240 - var queueDeferred = null;
1241 - var methodDeferred = null;
1242 -
1243 - this.add_steps = function ( key, steps, args ) {
1244 - var self = this;
1245 - this.methodDeferred = $.Deferred();
1246 - this.queueDeferred = this.setup();
1247 -
1248 - $.each(steps, function ( i, step ) {
1249 - self.queue(key, step);
1250 - });
1251 - };
1252 -
1253 - this.process_remote_step = function ( key, data, step ) {
1254 - var self = this;
1255 -
1256 - if ( _.isUndefined(data) || _.isNull(data) ) {
1257 - return false;
1096 + vars.push(hash[0])
1097 + vars[hash[0]] = hash[1]
1258 1098 }
1259 1099
1260 - var new_step = step;
1261 - $.each(data, function ( i, k ) {
1262 - debugger;
1263 - // prepare data for new requests
1264 - new_step.recall_data = k.data;
1265 - new_step.recall_type = k.type;
1266 - new_step.type = 'recall';
1267 -
1268 - self.queue(key, new_step, k.id);
1269 - });
1270 - };
1271 -
1272 - this.log_action = function ( action, key, msg ) {
1273 - if ( action === 'start' ) {
1274 - $('.wpGrade-import-results').show();
1275 - $('.wpGrade-import-results').append('<span class="import_step_note imports_step_' + key + '" ><span class="step_info" data-balloon="Working on it" data-balloon-pos="up"></span>Importing ' + key + '</span>');
1276 - } else if ( action === 'end' ) {
1277 - var $notice = $('.imports_step_' + key + ' .step_info');
1278 -
1279 - if ( $notice.length > 0 || msg !== "undefined" ) {
1280 - $notice.attr('data-balloon', msg);
1281 - $notice.addClass('success');
1282 - } else {
1283 - $notice.attr('data-balloon', 'Done');
1284 - $notice.addClass('failed');
1285 - }
1100 + if (!_.isUndefined(vars[name])) {
1101 + return vars[name]
1286 1102 }
1287 - };
1288 -
1289 - this.queue = function ( key, data, step_key ) {
1290 - var self = this;
1291 - if ( !_.isUndefined(step_key) ) {
1292 - this.log_action('start', step_key);
1293 - }
1294 -
1295 - // execute next queue method
1296 - this.queueDeferred.done(this.request(key, data, step_key));
1297 - lastPromise = self.methodDeferred.promise();
1298 - };
1299 -
1300 - this.request = function ( key, step, step_key ) {
1301 - var self = this;
1302 - // call actual method and wrap output in deferred
1303 - //setTimeout( function() {
1304 - var data_args = {
1305 - action: 'customify_import_step',
1306 - step_id: step.id,
1307 - step_type: step.type,
1308 - option_key: key
1309 - };
1310 -
1311 - if ( !_.isUndefined(step.recall_data) ) {
1312 - data_args.recall_data = step.recall_data;
1313 - }
1314 -
1315 - if ( !_.isUndefined(step.recall_type) ) {
1316 - data_args.recall_type = step.recall_type;
1317 - }
1318 -
1319 - $.ajax({
1320 - url: customify_settings.import_rest_url + 'customify/1.0/import',
1321 - method: 'POST',
1322 - beforeSend: function ( xhr ) {
1323 - xhr.setRequestHeader('X-WP-Nonce', WP_API_Settings.nonce);
1324 - },
1325 - dataType: 'json',
1326 - contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
1327 - data: data_args
1328 - }).done(function ( response ) {
1329 - if ( !_.isUndefined(response.success) && response.success ) {
1330 - var results = response.data;
1331 - if ( step.type === 'remote' ) {
1332 - self.process_remote_step(key, results, step);
1333 - }
1334 - }
1335 -
1336 - if ( !_.isUndefined(step_key) && !_.isUndefined(response.message) ) {
1337 - self.log_action('end', step_key, response.message);
1338 - }
1339 - });
1340 -
1341 - self.methodDeferred.resolve();
1342 - //}, 3450 );
1343 - };
1344 -
1345 - this.setup = function () {
1346 - var self = this;
1347 -
1348 - self.queueDeferred = $.Deferred();
1349 -
1350 - // when the previous method returns, resolve this one
1351 - $.when(lastPromise).always(function () {
1352 - self.queueDeferred.resolve();
1353 - });
1354 -
1355 - return self.queueDeferred.promise();
1103 + return false
1356 1104 }
1357 - };
1358 1105
1359 - /** HELPERS **/
1360 -
1361 - /**
1362 - * Function to check if a value exists in an object
1363 - * @param value
1364 - * @param obj
1365 - * @returns {boolean}
1366 - */
1367 - var inObject = function ( value, obj ) {
1368 - for ( var k in obj ) {
1369 - if ( !obj.hasOwnProperty(k) ) continue;
1370 - if ( _.isEqual(obj[k], value) ) {
1371 - return true;
1106 + const isJsonString = function (str) {
1107 + try {
1108 + JSON.parse(str)
1109 + } catch (e) {
1110 + return false
1372 1111 }
1112 + return true
1373 1113 }
1374 - return false;
1375 - };
1376 -
1377 - var maybeJsonParse = function ( value ) {
1378 - var parsed;
1379 -
1380 - //try and parse it, with decodeURIComponent
1381 - try {
1382 - parsed = JSON.parse(decodeURIComponent(value));
1383 - } catch ( e ) {
1384 -
1385 - // in case of an error, treat is as a string
1386 - parsed = value;
1387 - }
1388 -
1389 - return parsed;
1390 - };
1391 -
1392 - var getUrlVars = function ( name ) {
1393 - var vars = [], hash;
1394 - var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
1395 - for ( var i = 0; i < hashes.length; i++ ) {
1396 - hash = hashes[i].split('=');
1397 -
1398 - vars.push(hash[0]);
1399 - vars[hash[0]] = hash[1];
1400 - }
1401 -
1402 - if ( !_.isUndefined(vars[name]) ) {
1403 - return vars[name];
1404 - }
1405 - return false;
1406 - };
1407 -
1408 - var isJsonString = function ( str ) {
1409 - try {
1410 - JSON.parse(str);
1411 - } catch ( e ) {
1412 - return false;
1413 - }
1414 - return true;
1415 - };
1416 -})(jQuery, window, wp.customize);
1114 + }
1115 +)(jQuery, window, wp)