Passed
Push — master ( d888e7...d5d975 )
by Rafael
01:12
created

src/controls/direction/direction.js   A

Size

Lines of Code 289

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
nc 1
dl 0
loc 289
rs 10
noi 3

1 Function

Rating   Name   Duplication   Size   Complexity  
A direction.js ➔ ??? 0 11 2
1
var $ = window.jQuery;
2
import './direction.scss';
3
import template from './template.html';
4
import config from './config.js';
5
import deepmerge from 'deepmerge';
6
import linkSvg from 'svg-inline-loader!./img/link.svg';
7
import refreshSvg from 'svg-inline-loader!./img/refresh.svg';
8
9
export class Direction {
10
	constructor( options ) {
11
		options = options || {};
12
13
		this.slidersLinked = true;
14
		this.$target = options.target;
15
		this.template = _.template( template );
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
16
17
		if ( ! this.$target ) {
18
			throw Error( 'Your must define a target element' );
19
		}
20
	}
21
22
	/**
23
	 * Merge the default configurations with any requested by a child class.
24
	 *
25
	 * @since 1.0.0
26
	 */
27
	mergeDefaultConfigs() {
28
		this.controlOptions = deepmerge( config.defaults, this.controlOptions, {
29
			arrayMerge: ( destination, source ) => source
30
		} );
31
	}
32
33
	/**
34
	 * Return a jQuery control.
35
	 *
36
	 * @since 1.0
37
	 *
38
	 * @return {jQuery} Control.
39
	 */
40
	render() {
41
		this.mergeDefaultConfigs();
42
43
		this.controlOptions.svg = {};
44
		this.controlOptions.svg.link = linkSvg;
45
		this.controlOptions.svg.refresh = refreshSvg;
46
47
		this.$control = $( this.template( this.controlOptions ) );
48
		this.$sliders = this.$control.find( '.slider' );
49
		this.$inputs = this.$control.find( 'input.number' );
50
		this.$links = this.$control.find( '.link' );
51
		this.$units = this.$control.find( '.unit' );
52
		this.$revert = this.$control.find( '.refresh' );
53
54
		this._bindUnits();
55
		this.setUnits( this.controlOptions.control.units.default );
56
		this._storeDefaultValues();
57
		this._bindInput();
58
		this._bindLinked();
59
		this._bindRevert();
60
		this._bindSliderChange();
61
62
		return this.$control;
63
	}
64
65
	/**
66
	 * Apply the settings to the control.
67
	 *
68
	 * @since 1.0
69
	 *
70
	 * @param  {object} settings Settings.
71
	 */
72
	applySettings( settings ) {
73
		this.setUnits( settings.unit );
74
75
		for ( let key in settings.values ) {
76
			let value = settings.values[key];
77
			this.$sliders.filter( '[data-name="' + key + '"]' ).slider( 'option', 'value', value );
78
		}
79
	}
80
81
	/**
82
	 * Update the target.
83
	 *
84
	 * @since 1.0
85
	 *
86
	 * @param  {jQuery} $target New Target.
87
	 */
88
	updateTarget( $target ) {
89
		this.$target = $target;
90
	}
91
92
	/**
93
	 * Set the unit to use.
94
	 *
95
	 * @since 1.0
96
	 *
97
	 * @param {string} unit Units.
98
	 */
99
	setUnits( unit ) {
100
		this.$units
101
			.filter( '[value="' + unit + '"]' )
102
			.prop( 'checked', true )
103
			.change();
104
	}
105
106
	/**
107
	 * Save the default values for reverts.
108
	 *
109
	 * @since 1.0
110
	 */
111
	_storeDefaultValues() {
112
		this.defaultValues = {
113
			unit: this.controlOptions.control.units.default,
114
			values: this.getValues()
115
		};
116
	}
117
118
	/**
119
	 * Get the values.
120
	 *
121
	 * @since 1.0
122
	 *
123
	 * @return {Object} Current values for each direction.
124
	 */
125
	getValues() {
126
		let values = {};
127
128
		this.$sliders.each( ( index, element ) => {
129
			let $this = $( element );
130
			values[$this.attr( 'data-name' )] = $this.slider( 'value' );
131
		} );
132
133
		return values;
134
	}
135
136
	/**
137
	 * Bind reverting changes to original.
138
	 *
139
	 * @since 1.0
140
	 */
141
	_bindRevert() {
142
		this.$revert.on( 'click', event => {
143
			event.preventDefault();
144
			this.applySettings( this.defaultValues );
145
		} );
146
	}
147
148
	/**
149
	 * Bind changing of units.
150
	 *
151
	 * @since 1.0
152
	 */
153
	_bindUnits() {
154
		this.$control.find( '.unit' ).on( 'change', e => {
155
			let $target = $( e.target );
156
157
			this.selectedUnit = $target.val();
158
			this._bindSlider();
159
		} );
160
	}
161
162
	/**
163
	 * Bind the user linking the controls.
164
	 * @return {[type]} [description]
165
	 */
166
	_bindLinked() {
167
		if ( this.slidersLinked ) {
168
			this.$links.addClass( 'linked' );
169
		}
170
171
		this.$links.on( 'click', event => {
172
			let $target = $( event.target ).closest( 'a' );
173
			event.preventDefault();
174
			$target.toggleClass( 'linked' );
175
			this.slidersLinked = $target.hasClass( 'linked' );
176
			this.$control.trigger( 'linked', { isLinked: this.slidersLinked } );
177
		} );
178
	}
179
180
	/**
181
	 * Bind the inputs change events.
182
	 *
183
	 * @since 1.0
184
	 */
185
	_bindInput() {
186
		this.$inputs.on( 'input', event => {
187
			let $this = $( event.target ),
188
				$slider = $this.prev(),
189
				val = $this.val(),
190
				config = this.getSliderConfig( $slider.data( 'name' ) );
191
192
			val = Math.min( $this.val(), config.max );
193
			val = Math.max( val, config.min );
194
195
			$this.val( val );
196
197
			$slider.slider( 'value', val );
198
		} );
199
	}
200
201
	/**
202
	 * Get a slider configuration.
203
	 *
204
	 * @since 1.0.0
205
	 * @return {object} jquery ui slider config.
206
	 */
207
	getSliderConfig() {
208
		return this.controlOptions.slider[this.selectedUnit];
209
	}
210
211
	/**
212
	 * Bind the slider events.
213
	 *
214
	 * @since 1.0
215
	 */
216
	_bindSlider() {
217
		this.$sliders.each( ( index, slider ) => {
218
			let $slider = $( slider );
219
220
			$slider.slider(
221
				_.defaults( this.getSliderConfig( $slider.data( 'name' ) ), {
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
222
					animate: 'fast',
223
					slide: event => this._onSliderChange( event ),
224
					change: event => this._onSliderChange( event )
225
				} )
226
			);
227
		} );
228
229
		this.$sliders.each( ( index, slider ) => {
230
			this._updateInput( $( slider ) );
231
		} );
232
	}
233
234
	/**
235
	 * When the slider changes.
236
	 *
237
	 * @since 1.0
238
	 *
239
	 * @param  {DOM Event} event When the slider changes.
240
	 */
241
	_onSliderChange( event ) {
242
		let $slider = $( event.target );
243
		this._updateInput( $slider );
244
		this.$control.trigger( 'slide-change', this.getValues() );
245
246
		if ( this.slidersLinked && ! this.linkedDisabled ) {
247
			this.linkedDisabled = true;
248
			this.$sliders.not( $slider ).slider( 'value', $slider.slider( 'value' ) );
249
		}
250
251
		setTimeout( () => {
252
			this.linkedDisabled = false;
253
		} );
254
	}
255
256
	/**
257
	 * Update the input.
258
	 *
259
	 * @since 1.0
260
	 *
261
	 * @param  {$} $slider Slider element jquery.
262
	 */
263
	_updateInput( $slider ) {
264
		let $input = $slider.next(),
265
			value = $slider.slider( 'value' );
266
267
		$input.val( value );
268
	}
269
270
	/**
271
	 * Update css as the control fires updates.
272
	 *
273
	 * @since 1.0.0
274
	 */
275
	_bindSliderChange() {
276
		this.$control.on( 'slide-change', ( e, data ) => {
277
			let name = this.controlOptions.control.name,
278
				property = {};
279
280
			_.each( this.controlOptions.control.sliders, slider => {
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
281
				property[slider.cssProperty] = data[name + '-' + slider.name] + this.selectedUnit;
282
			} );
283
284
			this.$target.css( property );
285
		} );
286
	}
287
}
288
289
export { Direction as default };
290