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

controls/js/src/kirki.setting.js   A

Complexity

Total Complexity 21
Complexity/F 4.2

Size

Lines of Code 152
Function Count 5

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 0
nc 8
dl 0
loc 152
rs 10
c 0
b 0
f 0
wmc 21
mnd 3
bc 21
fnc 5
bpm 4.2
cpm 4.2
noi 10
1
var kirki = kirki || {};
2
kirki = jQuery.extend( kirki, {
3
	/**
4
	 * An object containing definitions for settings.
5
	 *
6
	 * @since 3.0.16
7
	 */
8
	setting: {
9
10
		/**
11
		 * Gets the value of a setting.
12
		 *
13
		 * This is a helper function that allows us to get the value of
14
		 * control[key1][key2] for example, when the setting used in the
15
		 * customizer API is "control".
16
		 *
17
		 * @since 3.0.16
18
		 * @param {string} setting - The setting for which we're getting the value.
19
		 * @returns {mixed} Depends on the value.
20
		 */
21
		get: function( setting ) {
22
			var parts        = setting.split( '[' ),
23
			    foundSetting = '',
24
			    foundInStep  = 0,
25
			    currentVal   = '';
26
27
			_.each( parts, function( part, i ) {
28
				part = part.replace( ']', '' );
29
30
				if ( 0 === i ) {
31
					foundSetting = part;
32
				} else {
33
					foundSetting += '[' + part + ']';
34
				}
35
36
				if ( ! _.isUndefined( wp.customize.instance( foundSetting ) ) ) {
37
					currentVal  = wp.customize.instance( foundSetting ).get();
38
					foundInStep = i;
39
				}
40
41
				if ( foundInStep < i ) {
42
					if ( _.isObject( currentVal ) && ! _.isUndefined( currentVal[ part ] ) ) {
43
						currentVal = currentVal[ part ];
44
					}
45
				}
46
			});
47
48
			return currentVal;
49
		},
50
51
		/**
52
		 * Sets the value of a setting.
53
		 *
54
		 * This function is a bit complicated because there any many scenarios to consider.
55
		 * Example: We want to save the value for my_setting[something][3][something-else].
56
		 * The control's setting is my_setting[something].
57
		 * So we need to find that first, then figure out the remaining parts,
58
		 * merge the values recursively to avoid destroying my_setting[something][2]
59
		 * and also take into account any defined "key" arguments which take this even deeper.
60
		 *
61
		 * @since 3.0.16
62
		 * @param {object|string} element - The DOM element whose value has changed,
63
		 *                                  or an ID.
64
		 * @param {mixed}         value - Depends on the control-type.
65
		 * @param {string}        key - If we only want to save an item in an object
66
		 *                                  we can define the key here.
67
		 * @returns {null}
68
		 */
69
		set: function( element, value, key ) {
70
			var setting,
71
			    parts,
72
			    currentNode   = '',
73
			    foundNode     = '',
74
			    subSettingObj = {},
75
			    currentVal,
76
			    subSetting,
77
			    subSettingParts;
78
79
			// Get the setting from the element.
80
			setting = element;
81
			if ( _.isObject( element ) ) {
82
				if ( jQuery( element ).attr( 'data-id' ) ) {
83
					setting = element.attr( 'data-id' );
84
				} else {
85
					setting = element.parents( '[data-id]' ).attr( 'data-id' );
86
				}
87
			}
88
89
			if ( 'undefined' !== typeof wp.customize.control( setting ) ) {
90
				wp.customize.control( setting ).setting.set( value );
91
				return;
92
			}
93
94
			parts = setting.split( '[' ),
95
96
			// Find the setting we're using in the control using the customizer API.
97
			_.each( parts, function( part, i ) {
98
				part = part.replace( ']', '' );
99
100
				// The current part of the setting.
101
				currentNode = ( 0 === i ) ? part : '[' + part + ']';
102
103
				// When we find the node, get the value from it.
104
				// In case of an object we'll need to merge with current values.
105
				if ( ! _.isUndefined( wp.customize.instance( currentNode ) ) ) {
106
					foundNode  = currentNode;
107
					currentVal = wp.customize.instance( foundNode ).get();
108
				}
109
			} );
110
111
			// Get the remaining part of the setting that was unused.
112
			subSetting = setting.replace( foundNode, '' );
113
114
			// If subSetting is not empty, then we're dealing with an object
115
			// and we need to dig deeper and recursively merge the values.
116
			if ( '' !== subSetting ) {
117
				if ( ! _.isObject( currentVal ) ) {
118
					currentVal = {};
119
				}
120
				if ( '[' === subSetting.charAt( 0 ) ) {
121
					subSetting = subSetting.replace( '[', '' );
122
				}
123
				subSettingParts = subSetting.split( '[' );
124
				_.each( subSettingParts, function( subSettingPart, i ) {
125
					subSettingParts[ i ] = subSettingPart.replace( ']', '' );
126
				} );
127
128
				// If using a key, we need to go 1 level deeper.
129
				if ( key ) {
130
					subSettingParts.push( key );
131
				}
132
133
				// Converting to a JSON string and then parsing that to an object
134
				// may seem a bit hacky and crude but it's efficient and works.
135
				subSettingObj = '{"' + subSettingParts.join( '":{"' ) + '":"' + value + '"' + '}'.repeat( subSettingParts.length );
136
				subSettingObj = JSON.parse( subSettingObj );
137
138
				// Recursively merge with current value.
139
				jQuery.extend( true, currentVal, subSettingObj );
140
				value = currentVal;
141
142
			} else {
143
				if ( key ) {
144
					currentVal = ( ! _.isObject( currentVal ) ) ? {} : currentVal;
145
					currentVal[ key ] = value;
146
					value = currentVal;
147
				}
148
			}
149
			wp.customize.control( foundNode ).setting.set( value );
150
		}
151
	}
152
} );
153