Completed
Pull Request — develop (#1826)
by Aristeides
02:31
created

modules/field-dependencies/field-dependencies.js   C

Complexity

Total Complexity 58
Complexity/F 3.87

Size

Lines of Code 168
Function Count 15

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 4 Features 0
Metric Value
cc 0
wmc 58
c 5
b 4
f 0
nc 1
mnd 3
bc 38
fnc 15
dl 0
loc 168
rs 5.4871
bpm 2.5333
cpm 3.8666
noi 8

4 Functions

Rating   Name   Duplication   Size   Complexity  
B kirkiDependencies.showKirkiControl 0 48 5
B kirkiDependencies.init 0 30 1
C kirkiDependencies.evaluate 0 63 28
A $(document).ready 0 3 1

How to fix   Complexity   

Complexity

Complex classes like modules/field-dependencies/field-dependencies.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
var kirkiDependencies = {
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...
2
3
	listenTo: {},
4
5
	init: function() {
6
		var self = 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...
7
8
		wp.customize.control.each( function( control ) {
9
			self.showKirkiControl( control );
10
		} );
11
12
		_.each( self.listenTo, function( slaves, master ) {
13
			_.each( slaves, function( slave ) {
14
				wp.customize( master, function( setting ) {
15
					var setupControl = function( control ) {
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...
16
						var setActiveState,
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...
17
							isDisplayed;
18
19
						isDisplayed = function() {
20
							return self.showKirkiControl( wp.customize.control( slave ) );
21
						};
22
						setActiveState = function() {
23
							control.active.set( isDisplayed() );
24
						};
25
26
						setActiveState();
27
						setting.bind( setActiveState );
28
						control.active.validate = isDisplayed;
29
					};
30
					wp.customize.control( slave, setupControl );
31
				} );
32
			} );
33
		} );
34
	},
35
36
	/**
37
	 * Should we show the control?
38
	 *
39
	 * @since 3.0.17
40
	 * @param {string|object} control - The control-id or the control object.
41
	 * @returns {bool}
42
	 */
43
	showKirkiControl: function( control ) {
44
		var self = 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...
45
			show = true;
46
47
		if ( _.isString( control ) ) {
48
			control = wp.customize.control( control );
0 ignored issues
show
Comprehensibility Best Practice introduced by
This re-assigns to the parameter control. Re-assigning to parameters often makes code less readable, consider introducing a new variable instead.
Loading history...
49
		}
50
51
		// Exit early if control not found or if "required" argument is not defined.
52
		if ( 'undefined' === typeof control || ( control.params && _.isEmpty( control.params.required ) ) ) {
53
			return true;
54
		}
55
56
		// Loop control requirements.
57
		_.each( control.params.required, function( requirement ) {
58
			let requirementShow;
59
60
			// Tweak for using active callbacks with serialized options instead of theme_mods.
61
			if (
62
				control.params && // Check if control.params exists.
63
				control.params.kirkiOptionType &&  // Check if option_type exists.
64
				'option' === control.params.kirkiOptionType &&  // We're using options.
65
				control.params.kirkiOptionName && // Check if option_name exists.
66
				! _.isEmpty( control.params.kirkiOptionName ) && // Check if option_name is not empty.
67
				-1 === requirement.setting.indexOf( control.params.kirkiOptionName + '[' ) // Make sure we don't already have the option_name in there.
68
			) {
69
				requirement.setting = control.params.kirkiOptionName + '[' + requirement.setting + ']';
70
			}
71
72
			// Early exit if setting is not defined.
73
			if ( 'undefined' === typeof wp.customize.control( requirement.setting ) ) {
74
				show = true;
75
				return;
76
			}
77
78
			requirementShow = self.evaluate( requirement.value, wp.customize.control( requirement.setting ).setting._value, requirement.operator );
79
80
			self.listenTo[ requirement.setting ] = self.listenTo[ requirement.setting ] || [];
81
			if ( -1 === self.listenTo[ requirement.setting ].indexOf( control.id ) ) {
82
				self.listenTo[ requirement.setting ].push( control.id );
83
			}
84
85
			if ( ! requirementShow ) {
86
				show = false;
87
			}
88
		} );
89
		return show;
90
	},
91
92
	/**
93
	 * Figure out if the 2 values have the relation we want.
94
	 *
95
	 * @since 3.0.17
96
	 * @param {mixed} value1 - The 1st value.
97
	 * @param {mixed} value2 - The 2nd value.
98
	 * @param {string} operator - The comparison to use.
99
	 * @returns {bool}
100
	 */
101
	evaluate: function( value1, value2, operator ) {
102
		var found  = false,
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...
103
			result = null;
104
105
		if ( '===' === operator ) {
106
			return value1 === value2;
107
		}
108
		if ( '==' === operator || '=' === operator || 'equals' === operator || 'equal' === operator ) {
109
			return value1 == value2;
110
		}
111
		if ( '!==' === operator ) {
112
			return value1 !== value2;
113
		}
114
		if ( '!=' === operator || 'not equal' === operator ) {
115
			return value1 != value2;
116
		}
117
		if ( '>=' === operator || 'greater or equal' === operator || 'equal or greater' === operator ) {
118
			return value2 >= value1;
119
		}
120
		if ( '<=' === operator || 'smaller or equal' === operator || 'equal or smaller' === operator ) {
121
			return value2 <= value1;
122
		}
123
		if ( '>' === operator || 'greater' === operator ) {
124
			return value2 > value1;
125
		}
126
		if ( '<' === operator || 'smaller' === operator ) {
127
			return value2 < value1;
128
		}
129
		if ( 'contains' === operator || 'in' === operator ) {
130
			if ( _.isArray( value1 ) && _.isArray( value2 ) ) {
131
				_.each( value2, function( value ) {
132
					if ( value1.includes( value ) ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if value1.includes(value) is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
133
						found = true;
134
						return false;
135
					}
136
                } );
137
				return found;
138
			}
139
			if ( _.isArray( value2 ) ) {
140
				_.each( value2, function( value ) {
141
					if ( value == value1 ) { // jshint ignore:line
142
						found = true;
143
					}
144
				} );
145
				return found;
146
			}
147
			if ( _.isObject( value2 ) ) {
148
				if ( ! _.isUndefined( value2[ value1 ] ) ) {
149
					found = true;
150
				}
151
				_.each( value2, function( subValue ) {
152
					if ( value1 === subValue ) {
153
						found = true;
154
					}
155
				} );
156
				return found;
157
			}
158
			if ( _.isString( value2 ) ) {
159
				return -1 < value1.indexOf( value2 );
160
			}
161
		}
162
		return ( null === result ) ? true : result;
163
	}
164
};
165
166
jQuery( document ).ready( function() {
167
	kirkiDependencies.init();
168
} );
169