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