Completed
Push — master ( fe9946...c73065 )
by Aristeides
18s
created

controls/js/src/typography-legacy.js   D

Complexity

Total Complexity 72
Complexity/F 2.12

Size

Lines of Code 422
Function Count 34

Duplication

Duplicated Lines 198
Ratio 46.92 %

Importance

Changes 0
Metric Value
cc 0
nc 256
dl 198
loc 422
rs 4.0246
c 0
b 0
f 0
wmc 72
mnd 3
bc 68
fnc 34
bpm 2
cpm 2.1176
noi 15

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like controls/js/src/typography-legacy.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/* global kirkiControlLoader, kirkiAllFonts */
2
wp.customize.controlConstructor['kirki-typography'] = wp.customize.Control.extend({
3
4
	// When we're finished loading continue processing
5
	ready: function() {
6
7
		'use strict';
8
9
		var control = this;
10
11
		// Init the control.
12
		if ( ! _.isUndefined( window.kirkiControlLoader ) && _.isFunction( kirkiControlLoader ) ) {
13
			kirkiControlLoader( control );
14
		} else {
15
			control.initKirkiControl();
16
		}
17
	},
18
19
	initKirkiControl: function() {
20
21
		'use strict';
22
23
		var control = this,
24
		    value   = control.getValue(),
25
		    picker;
26
27
		control.renderFontSelector();
28
		control.renderBackupFontSelector();
29
		control.renderVariantSelector();
30
		control.renderSubsetSelector();
31
32
		// Font-size.
33
		if ( control.params['default']['font-size'] ) {
34
			this.container.on( 'change keyup paste', '.font-size input', function() {
35
				control.saveValue( 'font-size', jQuery( this ).val() );
36
			});
37
		}
38
39
		// Line-height.
40
		if ( control.params['default']['line-height'] ) {
41
			this.container.on( 'change keyup paste', '.line-height input', function() {
42
				control.saveValue( 'line-height', jQuery( this ).val() );
43
			});
44
		}
45
46
		// Margin-top.
47
		if ( control.params['default']['margin-top'] ) {
48
			this.container.on( 'change keyup paste', '.margin-top input', function() {
49
				control.saveValue( 'margin-top', jQuery( this ).val() );
50
			});
51
		}
52
53
		// Margin-bottom.
54
		if ( control.params['default']['margin-bottom'] ) {
55
			this.container.on( 'change keyup paste', '.margin-bottom input', function() {
56
				control.saveValue( 'margin-bottom', jQuery( this ).val() );
57
			});
58
		}
59
60
		// Letter-spacing.
61
		if ( control.params['default']['letter-spacing'] ) {
62
			value['letter-spacing'] = ( jQuery.isNumeric( value['letter-spacing'] ) ) ? value['letter-spacing'] + 'px' : value['letter-spacing'];
63
			this.container.on( 'change keyup paste', '.letter-spacing input', function() {
64
				value['letter-spacing'] = ( jQuery.isNumeric( jQuery( this ).val() ) ) ? jQuery( this ).val() + 'px' : jQuery( this ).val();
65
				control.saveValue( 'letter-spacing', value['letter-spacing'] );
66
			});
67
		}
68
69
		// Word-spacing.
70
		if ( control.params['default']['word-spacing'] ) {
71
			this.container.on( 'change keyup paste', '.word-spacing input', function() {
72
				control.saveValue( 'word-spacing', jQuery( this ).val() );
73
			});
74
		}
75
76
		// Text-align.
77
		if ( control.params['default']['text-align'] ) {
78
			this.container.on( 'change', '.text-align input', function() {
79
				control.saveValue( 'text-align', jQuery( this ).val() );
80
			});
81
		}
82
83
		// Text-transform.
84
		if ( control.params['default']['text-transform'] ) {
85
			jQuery( control.selector + ' .text-transform select' ).selectWoo().on( 'change', function() {
86
				control.saveValue( 'text-transform', jQuery( this ).val() );
87
			});
88
		}
89
90
		// Color.
91
		if ( control.params['default'].color ) {
92
			picker = this.container.find( '.kirki-color-control' );
93
			picker.wpColorPicker({
94
				change: function() {
95
					setTimeout( function() {
96
						control.saveValue( 'color', picker.val() );
97
					}, 100 );
98
				}
99
			});
100
		}
101
	},
102
103
	/**
104
	 * Adds the font-families to the font-family dropdown
105
	 * and instantiates selectWoo.
106
	 */
107
	renderFontSelector: function() {
108
109
		var control         = this,
110
		    selector        = control.selector + ' .font-family select',
111
		    data            = [],
112
		    standardFonts   = [],
113
		    googleFonts     = [],
114
		    value           = control.getValue(),
115
		    fonts           = control.getFonts(),
116
		    fontSelect;
117
118
		// Format standard fonts as an array.
119
		if ( ! _.isUndefined( fonts.standard ) ) {
120
			_.each( fonts.standard, function( font ) {
121
				standardFonts.push({
122
					id: font.family.replace( /"/g, '&#39' ),
123
					text: font.label
124
				});
125
			});
126
		}
127
128
		// Format google fonts as an array.
129
		if ( ! _.isUndefined( fonts.standard ) ) {
130
			_.each( fonts.google, function( font ) {
131
				googleFonts.push({
132
					id: font.family,
133
					text: font.label
134
				});
135
			});
136
		}
137
138
		// Combine forces and build the final data.
139
		data = [
140
			{ text: 'Standard Fonts', children: standardFonts },
141
			{ text: 'Google Fonts',   children: googleFonts }
142
		];
143
144
		// Instantiate selectWoo with the data.
145
		fontSelect = jQuery( selector ).selectWoo({
146
			data: data
147
		});
148
149
		// Set the initial value.
150
		if ( value['font-family'] ) {
151
			fontSelect.val( value['font-family'].replace( /'/g, '"' ) ).trigger( 'change' );
152
		}
153
154
		// When the value changes
155
		fontSelect.on( 'change', function() {
156
157
			// Set the value.
158
			control.saveValue( 'font-family', jQuery( this ).val() );
159
160
			// Re-init the font-backup selector.
161
			control.renderBackupFontSelector();
162
163
			// Re-init variants selector.
164
			control.renderVariantSelector();
165
166
			// Re-init subsets selector.
167
			control.renderSubsetSelector();
168
		});
169
	},
170
171
	/**
172
	 * Adds the font-families to the font-family dropdown
173
	 * and instantiates selectWoo.
174
	 */
175
	renderBackupFontSelector: function() {
176
177
		var control       = this,
178
		    selector      = control.selector + ' .font-backup select',
179
		    standardFonts = [],
180
		    value         = control.getValue(),
181
		    fontFamily    = value['font-family'],
182
		    variants      = control.getVariants( fontFamily ),
183
		    fonts         = control.getFonts(),
184
		    fontSelect;
185
186
		if ( _.isUndefined( value['font-backup'] ) || null === value['font-backup'] ) {
187
			value['font-backup'] = '';
188
		}
189
190
		// Hide if we're not on a google-font.
191
		if ( false !== variants ) {
192
			jQuery( control.selector + ' .font-backup' ).show();
193
		} else {
194
			jQuery( control.selector + ' .font-backup' ).hide();
195
		}
196
197
		// Format standard fonts as an array.
198
		if ( ! _.isUndefined( fonts.standard ) ) {
199
			_.each( fonts.standard, function( font ) {
200
				standardFonts.push({
201
					id: font.family.replace( /"/g, '&#39' ),
202
					text: font.label
203
				});
204
			});
205
		}
206
207
		// Instantiate selectWoo with the data.
208
		fontSelect = jQuery( selector ).selectWoo({
209
			data: standardFonts
210
		});
211
212
		// Set the initial value.
213
		if ( 'undefined' !== typeof value['font-backup'] ) {
214
			fontSelect.val( value['font-backup'].replace( /'/g, '"' ) ).trigger( 'change' );
215
		}
216
217
		// When the value changes
218
		fontSelect.on( 'change', function() {
219
220
			// Set the value.
221
			control.saveValue( 'font-backup', jQuery( this ).val() );
222
		});
223
	},
224
225
	/**
226
	 * Renders the variants selector using selectWoo
227
	 * Displays font-variants for the currently selected font-family.
228
	 */
229
	renderVariantSelector: function() {
230
231
		var control    = this,
232
		    value      = control.getValue(),
233
		    fontFamily = value['font-family'],
234
		    variants   = control.getVariants( fontFamily ),
235
		    selector   = control.selector + ' .variant select',
236
		    data       = [],
237
		    isValid    = false,
238
		    fontWeight,
239
		    variantSelector,
240
		    fontStyle;
241
242
		if ( false !== variants ) {
243
			jQuery( control.selector + ' .variant' ).show();
244
			_.each( variants, function( variant ) {
245
				if ( value.variant === variant.id ) {
246
					isValid = true;
247
				}
248
				data.push({
249
					id: variant.id,
250
					text: variant.label
251
				});
252
			});
253
			if ( ! isValid ) {
254
				value.variant = 'regular';
255
			}
256
257
			if ( jQuery( selector ).hasClass( 'select2-hidden-accessible' ) ) {
258
				jQuery( selector ).selectWoo( 'destroy' );
259
				jQuery( selector ).empty();
260
			}
261
262
			// Instantiate selectWoo with the data.
263
			variantSelector = jQuery( selector ).selectWoo({
264
				data: data
265
			});
266
			variantSelector.val( value.variant ).trigger( 'change' );
267
			variantSelector.on( 'change', function() {
268
				control.saveValue( 'variant', jQuery( this ).val() );
269
270
				fontWeight = ( ! _.isString( value.variant ) ) ? '400' : value.variant.match( /\d/g );
271
				fontWeight = ( ! _.isObject( fontWeight ) ) ? '400' : fontWeight.join( '' );
272
				fontStyle  = ( -1 !== value.variant.indexOf( 'italic' ) ) ? 'italic' : 'normal';
273
274
				control.saveValue( 'font-weight', fontWeight );
275
				control.saveValue( 'font-style', fontStyle );
276
			});
277
		} else {
278
			jQuery( control.selector + ' .variant' ).hide();
279
		}
280
	},
281
282
	/**
283
	 * Renders the subsets selector using selectWoo
284
	 * Displays font-subsets for the currently selected font-family.
285
	 */
286
	renderSubsetSelector: function() {
287
288
		var control    = this,
289
		    value      = control.getValue(),
290
		    fontFamily = value['font-family'],
291
		    subsets    = control.getSubsets( fontFamily ),
292
		    selector   = control.selector + ' .subsets select',
293
		    data       = [],
294
		    validValue = value.subsets,
295
		    subsetSelector;
296
297
		if ( false !== subsets ) {
298
			jQuery( control.selector + ' .subsets' ).show();
299
			_.each( subsets, function( subset ) {
300
301
				if ( _.isObject( validValue ) ) {
302
					if ( -1 === validValue.indexOf( subset.id ) ) {
303
						validValue = _.reject( validValue, function( subValue ) {
304
							return subValue === subset.id;
305
						});
306
					}
307
				}
308
309
				data.push({
310
					id: subset.id,
311
					text: subset.label
312
				});
313
			});
314
315
		} else {
316
			jQuery( control.selector + ' .subsets' ).hide();
317
		}
318
319
		if ( jQuery( selector ).hasClass( 'select2-hidden-accessible' ) ) {
320
			jQuery( selector ).selectWoo( 'destroy' );
321
			jQuery( selector ).empty();
322
		}
323
324
		// Instantiate selectWoo with the data.
325
		subsetSelector = jQuery( selector ).selectWoo({
326
			data: data
327
		});
328
		subsetSelector.val( validValue ).trigger( 'change' );
329
		subsetSelector.on( 'change', function() {
330
			control.saveValue( 'subsets', jQuery( this ).val() );
331
		});
332
	},
333
334
	/**
335
	 * Get fonts.
336
	 */
337
	getFonts: function() {
338
		var control = this;
339
340
		if ( ! _.isUndefined( window[ 'kirkiFonts' + control.id ] ) ) {
341
			return window[ 'kirkiFonts' + control.id ];
342
		}
343
		if ( 'undefined' !== typeof kirkiAllFonts ) {
344
			return kirkiAllFonts;
345
		}
346
		return {
347
			google: [],
348
			standard: []
349
		};
350
	},
351
352
	/**
353
	 * Get variants for a font-family.
354
	 */
355
	getVariants: function( fontFamily ) {
356
		var control = this,
357
		    fonts   = control.getFonts();
358
359
		var variants = false;
360
		_.each( fonts.standard, function( font ) {
361
			if ( fontFamily && font.family === fontFamily.replace( /'/g, '"' ) ) {
362
				variants = font.variants;
363
				return font.variants;
364
			}
365
		});
366
367
		_.each( fonts.google, function( font ) {
368
			if ( font.family === fontFamily ) {
369
				variants = font.variants;
370
				return font.variants;
371
			}
372
		});
373
		return variants;
374
	},
375
376
	/**
377
	 * Get subsets for a font-family.
378
	 */
379
	getSubsets: function( fontFamily ) {
380
381
		var control = this,
382
		    subsets = false,
383
		    fonts   = control.getFonts();
384
385
		_.each( fonts.google, function( font ) {
386
			if ( font.family === fontFamily ) {
387
				subsets = font.subsets;
388
			}
389
		});
390
		return subsets;
391
	},
392
393
	/**
394
	 * Gets the value.
395
	 */
396
	getValue: function() {
397
398
		'use strict';
399
400
		var control   = this,
401
		    input     = control.container.find( '.typography-hidden-value' ),
402
		    valueJSON = jQuery( input ).val();
403
404
		return JSON.parse( valueJSON );
405
	},
406
407
	/**
408
	 * Saves the value.
409
	 */
410
	saveValue: function( property, value ) {
411
412
		'use strict';
413
414
		var control   = this,
415
		    input     = control.container.find( '.typography-hidden-value' ),
416
		    valueJSON = jQuery( input ).val(),
417
		    valueObj  = JSON.parse( valueJSON );
418
419
		valueObj[ property ] = value;
420
		wp.customize.control( control.id ).setting.set( valueObj );
421
		jQuery( input ).attr( 'value', JSON.stringify( valueObj ) ).trigger( 'change' );
422
	}
423
});
424