Test Setup Failed
Pull Request — master (#1653)
by Aristeides
05:27
created

controls/js/src/dynamic-control.js   B

Complexity

Total Complexity 40
Complexity/F 2

Size

Lines of Code 223
Function Count 20

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 0
nc 216
dl 0
loc 223
rs 8.2608
c 0
b 0
f 0
wmc 40
mnd 2
bc 34
fnc 20
bpm 1.7
cpm 2
noi 13

10 Functions

Rating   Name   Duplication   Size   Complexity  
A wp.customize.Control.extend.embed 0 20 2
A wp.customize.Control.extend.actuallyEmbed 0 8 2
A wp.customize.Control.extend.initKirkiControl 0 11 2
A _.each 0 3 1
A wp.customize.Control.extend.focus 0 5 1
A wp.customize.Control.extend.ready 0 12 1
D wp.customize.Control.extend.kirkiValidateCSSValue 0 27 9
A wp.customize.Control.extend._setUpSettingRootLinks 0 15 1
A wp.customize.Control.extend.initialize 0 17 3
B wp.customize.Control.extend._setUpSettingPropertyLinks 0 35 2

How to fix   Complexity   

Complexity

Complex classes like controls/js/src/dynamic-control.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 kirki */
2
/**
3
 * The majority of the code in this file
4
 * is derived from the wp-customize-posts plugin
5
 * and the work of @westonruter to whom I am very grateful.
6
 *
7
 * @see https://github.com/xwp/wp-customize-posts
8
 */
9
10
( function() {
11
	'use strict';
12
13
	/**
14
	 * A dynamic color-alpha control.
15
	 *
16
	 * @class
17
	 * @augments wp.customize.Control
18
	 * @augments wp.customize.Class
19
	 */
20
	wp.customize.kirkiDynamicControl = wp.customize.Control.extend({
21
22
		initialize: function( id, options ) {
23
			var control = this,
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
24
			    args    = options || {};
25
26
			args.params = args.params || {};
27
			if ( ! args.params.type ) {
28
				args.params.type = 'kirki-generic';
29
			}
30
			if ( ! args.params.content ) {
31
				args.params.content = jQuery( '<li></li>' );
32
				args.params.content.attr( 'id', 'customize-control-' + id.replace( /]/g, '' ).replace( /\[/g, '-' ) );
33
				args.params.content.attr( 'class', 'customize-control customize-control-' + args.params.type );
34
			}
35
36
			control.propertyElements = [];
37
			wp.customize.Control.prototype.initialize.call( control, id, args );
38
		},
39
40
		/**
41
		 * Add bidirectional data binding links between inputs and the setting(s).
42
		 *
43
		 * This is copied from wp.customize.Control.prototype.initialize(). It
44
		 * should be changed in Core to be applied once the control is embedded.
45
		 *
46
		 * @private
47
		 * @returns {null}
48
		 */
49
		_setUpSettingRootLinks: function() {
50
			var control = this,
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
51
			    nodes   = control.container.find( '[data-customize-setting-link]' );
52
53
			nodes.each( function() {
54
				var node = jQuery( this );
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
55
56
				wp.customize( node.data( 'customizeSettingLink' ), function( setting ) {
57
					var element = new wp.customize.Element( node );
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
58
					control.elements.push( element );
59
					element.sync( setting );
60
					element.set( setting() );
61
				});
62
			});
63
		},
64
65
		/**
66
		 * Add bidirectional data binding links between inputs and the setting properties.
67
		 *
68
		 * @private
69
		 * @returns {null}
70
		 */
71
		_setUpSettingPropertyLinks: function() {
72
			var control = this,
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
73
			    nodes;
74
75
			if ( ! control.setting ) {
76
				return;
77
			}
78
79
			nodes = control.container.find( '[data-customize-setting-property-link]' );
80
81
			nodes.each( function() {
82
				var node = jQuery( this ),
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
83
				    element,
84
				    propertyName = node.data( 'customizeSettingPropertyLink' );
85
86
				element = new wp.customize.Element( node );
87
				control.propertyElements.push( element );
88
				element.set( control.setting()[ propertyName ] );
89
90
				element.bind( function( newPropertyValue ) {
91
					var newSetting = control.setting();
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
92
					if ( newPropertyValue === newSetting[ propertyName ] ) {
93
						return;
94
					}
95
					newSetting = _.clone( newSetting );
96
					newSetting[ propertyName ] = newPropertyValue;
97
					control.setting.set( newSetting );
98
				} );
99
				control.setting.bind( function( newValue ) {
100
					if ( newValue[ propertyName ] !== element.get() ) {
101
						element.set( newValue[ propertyName ] );
102
					}
103
				} );
104
			});
105
		},
106
107
		/**
108
		 * @inheritdoc
109
		 */
110
		ready: function() {
111
			var control = this;
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
112
113
			control._setUpSettingRootLinks();
114
			control._setUpSettingPropertyLinks();
115
116
			wp.customize.Control.prototype.ready.call( control );
117
118
			control.deferred.embedded.done( function() {
119
				control.initKirkiControl( control );
120
			});
121
		},
122
123
		/**
124
		 * Embed the control in the document.
125
		 *
126
		 * Override the embed() method to do nothing,
127
		 * so that the control isn't embedded on load,
128
		 * unless the containing section is already expanded.
129
		 *
130
		 * @returns {null}
131
		 */
132
		embed: function() {
133
			var control   = this,
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
134
			    sectionId = control.section();
135
136
			if ( ! sectionId ) {
137
				return;
138
			}
139
140
			wp.customize.section( sectionId, function( section ) {
141
				if ( 'kirki-expanded' === section.params.type || section.expanded() || wp.customize.settings.autofocus.control === control.id ) {
142
					control.actuallyEmbed();
143
				} else {
144
					section.expanded.bind( function( expanded ) {
145
						if ( expanded ) {
146
							control.actuallyEmbed();
147
						}
148
					} );
149
				}
150
			} );
151
		},
152
153
		/**
154
		 * Deferred embedding of control when actually
155
		 *
156
		 * This function is called in Section.onChangeExpanded() so the control
157
		 * will only get embedded when the Section is first expanded.
158
		 *
159
		 * @returns {null}
160
		 */
161
		actuallyEmbed: function() {
162
			var control = this;
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
163
			if ( 'resolved' === control.deferred.embedded.state() ) {
164
				return;
165
			}
166
			control.renderContent();
167
			control.deferred.embedded.resolve(); // This triggers control.ready().
168
		},
169
170
		/**
171
		 * This is not working with autofocus.
172
		 *
173
		 * @param {object} [args] Args.
174
		 * @returns {null}
175
		 */
176
		focus: function( args ) {
177
			var control = this;
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
178
			control.actuallyEmbed();
179
			wp.customize.Control.prototype.focus.call( control, args );
180
		},
181
182
		/**
183
		 * Additional actions that run on ready.
184
		 *
185
		 * @param {object} [args] Args.
0 ignored issues
show
Documentation introduced by
The parameter args does not exist. Did you maybe forget to remove this comment?
Loading history...
186
		 * @returns {null}
187
		 */
188
		initKirkiControl: function( control ) {
189
			if ( 'undefined' !== typeof kirki.control[ control.params.type ] ) {
190
				kirki.control[ control.params.type ].init( control );
191
				return;
192
			}
193
194
			// Save the value
195
			this.container.on( 'change keyup paste click', 'input', function() {
196
				control.setting.set( jQuery( this ).val() );
197
			});
198
		},
199
200
		kirkiValidateCSSValue: function( value ) {
201
202
			var validUnits = ['rem', 'em', 'ex', '%', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ch', 'vh', 'vw', 'vmin', 'vmax'],
0 ignored issues
show
Coding Style introduced by
As per coding-style, prefer block-scoped variables using let or const which have better semantics than var.

Since ECMAScript 6, you can create block-scoped vars or constants with the keywords let or const. These variables/constants are only valid in the code block where they have been declared.

Consider the following two pieces of code:

if (true)
 {
    var x = "Hello, Stonehenge!";
}

console.log(x); //prints Hello, Stonehenge! to the console

and

if (true)
 {
    let x = "Hello, Stonehenge!";
}

console.log(x); //ReferenceError: x is not defined

The variable is not defined otuside of its block. This limits bleeding of variables into other contexts.

To know more about this ECMA6 feature, look at the MDN pages on let and const.

Loading history...
203
				numericValue,
204
				unit;
205
206
			// 0 is always a valid value, and we can't check calc() values effectively.
207
			if ( '0' === value || ( 0 <= value.indexOf( 'calc(' ) && 0 <= value.indexOf( ')' ) ) ) {
208
				return true;
209
			}
210
211
			if ( 'auto' === value || 'inherit' === value || 'initial' === value ) {
212
				return true;
213
			}
214
215
			// Get the numeric value.
216
			numericValue = parseFloat( value );
217
218
			// Get the unit
219
			unit = value.replace( numericValue, '' );
220
221
			// Check the validity of the numeric value and units.
222
			if ( isNaN( numericValue ) || -1 === jQuery.inArray( unit, validUnits ) ) {
223
				return false;
224
			}
225
			return true;
226
		}
227
	});
228
})();
229
230
_.each( kirki.control, function( obj, type ) {
231
	wp.customize.controlConstructor[ type ] = wp.customize.kirkiDynamicControl.extend({});
232
} );
233