PageSourceSearch

https://www.foment.com/wp-content/plugins/contact-form-7-datepicker-fix/js/jquery.ui.spinner.js

js foment.com collected 2026-09-27 21:30:52 UTC 12,377 bytes, 493 lines download raw bytes

vendor: 12,377 bytes, lines 1-493
1/*!
2 * jQuery UI Spinner 1.10.3
3 * http://jqueryui.com
4 *
5 * Copyright 2013 jQuery Foundation and other contributors
6 * Released under the MIT license.
7 * http://jquery.org/license
8 *
9 * http://api.jqueryui.com/spinner/
10 *
11 * Depends:
12 *  jquery.ui.core.js
13 *  jquery.ui.widget.js
14 *  jquery.ui.button.js
15 */
16(function( $ ) {
17
18function modifier( fn ) {
19	return function() {
20		var previous = this.element.val();
21		fn.apply( this, arguments );
22		this._refresh();
23		if ( previous !== this.element.val() ) {
24			this._trigger( "change" );
25		}
26	};
27}
28
29$.widget( "ui.spinner", {
30	version: "1.10.3",
31	defaultElement: "<input>",
32	widgetEventPrefix: "spin",
33	options: {
34		culture: null,
35		icons: {
36			down: "ui-icon-triangle-1-s",
37			up: "ui-icon-triangle-1-n"
38		},
39		incremental: true,
40		max: null,
41		min: null,
42		numberFormat: null,
43		page: 10,
44		step: 1,
45
46		change: null,
47		spin: null,
48		start: null,
49		stop: null
50	},
51
52	_create: function() {
53		// handle string values that need to be parsed
54		this._setOption( "max", this.options.max );
55		this._setOption( "min", this.options.min );
56		this._setOption( "step", this.options.step );
57
58		// format the value, but don't constrain
59		this._value( this.element.val(), true );
60
61		this._draw();
62		this._on( this._events );
63		this._refresh();
64
65		// turning off autocomplete prevents the browser from remembering the
66		// value when navigating through history, so we re-enable autocomplete
67		// if the page is unloaded before the widget is destroyed. #7790
68		this._on( this.window, {
69			beforeunload: function() {
70				this.element.removeAttr( "autocomplete" );
71			}
72		});
73	},
74
75	_getCreateOptions: function() {
76		var options = {},
77			element = this.element;
78
79		$.each( [ "min", "max", "step" ], function( i, option ) {
80			var value = element.attr( option );
81			if ( value !== undefined && value.length ) {
82				options[ option ] = value;
83			}
84		});
85
86		return options;
87	},
88
89	_events: {
90		keydown: function( event ) {
91			if ( this._start( event ) && this._keydown( event ) ) {
92				event.preventDefault();
93			}
94		},
95		keyup: "_stop",
96		focus: function() {
97			this.previous = this.element.val();
98		},
99		blur: function( event ) {
100			if ( this.cancelBlur ) {
101				delete this.cancelBlur;
102				return;
103			}
104
105			this._stop();
106			this._refresh();
107			if ( this.previous !== this.element.val() ) {
108				this._trigger( "change", event );
109			}
110		},
111		mousewheel: function( event, delta ) {
112			if ( !delta ) {
113				return;
114			}
115			if ( !this.spinning && !this._start( event ) ) {
116				return false;
117			}
118
119			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
120			clearTimeout( this.mousewheelTimer );
121			this.mousewheelTimer = this._delay(function() {
122				if ( this.spinning ) {
123					this._stop( event );
124				}
125			}, 100 );
126			event.preventDefault();
127		},
128		"mousedown .ui-spinner-button": function( event ) {
129			var previous;
130
131			// We never want the buttons to have focus; whenever the user is
132			// interacting with the spinner, the focus should be on the input.
133			// If the input is focused then this.previous is properly set from
134			// when the input first received focus. If the input is not focused
135			// then we need to set this.previous based on the value before spinning.
136			previous = this.element[0] === this.document[0].activeElement ?
137				this.previous : this.element.val();
138			function checkFocus() {
139				var isActive = this.element[0] === this.document[0].activeElement;
140				if ( !isActive ) {
141					this.element.focus();
142					this.previous = previous;
143					// support: IE
144					// IE sets focus asynchronously, so we need to check if focus
145					// moved off of the input because the user clicked on the button.
146					this._delay(function() {
147						this.previous = previous;
148					});
149				}
150			}
151
152			// ensure focus is on (or stays on) the text field
153			event.preventDefault();
154			checkFocus.call( this );
155
156			// support: IE
157			// IE doesn't prevent moving focus even with event.preventDefault()
158			// so we set a flag to know when we should ignore the blur event
159			// and check (again) if focus moved off of the input.
160			this.cancelBlur = true;
161			this._delay(function() {
162				delete this.cancelBlur;
163				checkFocus.call( this );
164			});
165
166			if ( this._start( event ) === false ) {
167				return;
168			}
169
170			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
171		},
172		"mouseup .ui-spinner-button": "_stop",
173		"mouseenter .ui-spinner-button": function( event ) {
174			// button will add ui-state-active if mouse was down while mouseleave and kept down
175			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
176				return;
177			}
178
179			if ( this._start( event ) === false ) {
180				return false;
181			}
182			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
183		},
184		// TODO: do we really want to consider this a stop?
185		// shouldn't we just stop the repeater and wait until mouseup before
186		// we trigger the stop event?
187		"mouseleave .ui-spinner-button": "_stop"
188	},
189
190	_draw: function() {
191		var uiSpinner = this.uiSpinner = this.element
192			.addClass( "ui-spinner-input" )
193			.attr( "autocomplete", "off" )
194			.wrap( this._uiSpinnerHtml() )
195			.parent()
196				// add buttons
197				.append( this._buttonHtml() );
198
199		this.element.attr( "role", "spinbutton" );
200
201		// button bindings
202		this.buttons = uiSpinner.find( ".ui-spinner-button" )
203			.attr( "tabIndex", -1 )
204			.button()
205			.removeClass( "ui-corner-all" );
206
207		// IE 6 doesn't understand height: 50% for the buttons
208		// unless the wrapper has an explicit height
209		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
210				uiSpinner.height() > 0 ) {
211			uiSpinner.height( uiSpinner.height() );
212		}
213
214		// disable spinner if element was already disabled
215		if ( this.options.disabled ) {
216			this.disable();
217		}
218	},
219
220	_keydown: function( event ) {
221		var options = this.options,
222			keyCode = $.ui.keyCode;
223
224		switch ( event.keyCode ) {
225		case keyCode.UP:
226			this._repeat( null, 1, event );
227			return true;
228		case keyCode.DOWN:
229			this._repeat( null, -1, event );
230			return true;
231		case keyCode.PAGE_UP:
232			this._repeat( null, options.page, event );
233			return true;
234		case keyCode.PAGE_DOWN:
235			this._repeat( null, -options.page, event );
236			return true;
237		}
238
239		return false;
240	},
241
242	_uiSpinnerHtml: function() {
243		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
244	},
245
246	_buttonHtml: function() {
247		return "" +
248			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
249				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
250			"</a>" +
251			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
252				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
253			"</a>";
254	},
255
256	_start: function( event ) {
257		if ( !this.spinning && this._trigger( "start", event ) === false ) {
258			return false;
259		}
260
261		if ( !this.counter ) {
262			this.counter = 1;
263		}
264		this.spinning = true;
265		return true;
266	},
267
268	_repeat: function( i, steps, event ) {
269		i = i || 500;
270
271		clearTimeout( this.timer );
272		this.timer = this._delay(function() {
273			this._repeat( 40, steps, event );
274		}, i );
275
276		this._spin( steps * this.options.step, event );
277	},
278
279	_spin: function( step, event ) {
280		var value = this.value() || 0;
281
282		if ( !this.counter ) {
283			this.counter = 1;
284		}
285
286		value = this._adjustValue( value + step * this._increment( this.counter ) );
287
288		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
289			this._value( value );
290			this.counter++;
291		}
292	},
293
294	_increment: function( i ) {
295		var incremental = this.options.incremental;
296
297		if ( incremental ) {
298			return $.isFunction( incremental ) ?
299				incremental( i ) :
300				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
301		}
302
303		return 1;
304	},
305
306	_precision: function() {
307		var precision = this._precisionOf( this.options.step );
308		if ( this.options.min !== null ) {
309			precision = Math.max( precision, this._precisionOf( this.options.min ) );
310		}
311		return precision;
312	},
313
314	_precisionOf: function( num ) {
315		var str = num.toString(),
316			decimal = str.indexOf( "." );
317		return decimal === -1 ? 0 : str.length - decimal - 1;
318	},
319
320	_adjustValue: function( value ) {
321		var base, aboveMin,
322			options = this.options;
323
324		// make sure we're at a valid step
325		// - find out where we are relative to the base (min or 0)
326		base = options.min !== null ? options.min : 0;
327		aboveMin = value - base;
328		// - round to the nearest step
329		aboveMin = Math.round(aboveMin / options.step) * options.step;
330		// - rounding is based on 0, so adjust back to our base
331		value = base + aboveMin;
332
333		// fix precision from bad JS floating point math
334		value = parseFloat( value.toFixed( this._precision() ) );
335
336		// clamp the value
337		if ( options.max !== null && value > options.max) {
338			return options.max;
339		}
340		if ( options.min !== null && value < options.min ) {
341			return options.min;
342		}
343
344		return value;
345	},
346
347	_stop: function( event ) {
348		if ( !this.spinning ) {
349			return;
350		}
351
352		clearTimeout( this.timer );
353		clearTimeout( this.mousewheelTimer );
354		this.counter = 0;
355		this.spinning = false;
356		this._trigger( "stop", event );
357	},
358
359	_setOption: function( key, value ) {
360		if ( key === "culture" || key === "numberFormat" ) {
361			var prevValue = this._parse( this.element.val() );
362			this.options[ key ] = value;
363			this.element.val( this._format( prevValue ) );
364			return;
365		}
366
367		if ( key === "max" || key === "min" || key === "step" ) {
368			if ( typeof value === "string" ) {
369				value = this._parse( value );
370			}
371		}
372		if ( key === "icons" ) {
373			this.buttons.first().find( ".ui-icon" )
374				.removeClass( this.options.icons.up )
375				.addClass( value.up );
376			this.buttons.last().find( ".ui-icon" )
377				.removeClass( this.options.icons.down )
378				.addClass( value.down );
379		}
380
381		this._super( key, value );
382
383		if ( key === "disabled" ) {
384			if ( value ) {
385				this.element.prop( "disabled", true );
386				this.buttons.button( "disable" );
387			} else {
388				this.element.prop( "disabled", false );
389				this.buttons.button( "enable" );
390			}
391		}
392	},
393
394	_setOptions: modifier(function( options ) {
395		this._super( options );
396		this._value( this.element.val() );
397	}),
398
399	_parse: function( val ) {
400		if ( typeof val === "string" && val !== "" ) {
401			val = window.Globalize && this.options.numberFormat ?
402				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
403		}
404		return val === "" || isNaN( val ) ? null : val;
405	},
406
407	_format: function( value ) {
408		if ( value === "" ) {
409			return "";
410		}
411		return window.Globalize && this.options.numberFormat ?
412			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
413			value;
414	},
415
416	_refresh: function() {
417		this.element.attr({
418			"aria-valuemin": this.options.min,
419			"aria-valuemax": this.options.max,
420			// TODO: what should we do with values that can't be parsed?
421			"aria-valuenow": this._parse( this.element.val() )
422		});
423	},
424
425	// update the value without triggering change
426	_value: function( value, allowAny ) {
427		var parsed;
428		if ( value !== "" ) {
429			parsed = this._parse( value );
430			if ( parsed !== null ) {
431				if ( !allowAny ) {
432					parsed = this._adjustValue( parsed );
433				}
434				value = this._format( parsed );
435			}
436		}
437		this.element.val( value );
438		this._refresh();
439	},
440
441	_destroy: function() {
442		this.element
443			.removeClass( "ui-spinner-input" )
444			.prop( "disabled", false )
445			.removeAttr( "autocomplete" )
446			.removeAttr( "role" )
447			.removeAttr( "aria-valuemin" )
448			.removeAttr( "aria-valuemax" )
449			.removeAttr( "aria-valuenow" );
450		this.uiSpinner.replaceWith( this.element );
451	},
452
453	stepUp: modifier(function( steps ) {
454		this._stepUp( steps );
455	}),
456	_stepUp: function( steps ) {
457		if ( this._start() ) {
458			this._spin( (steps || 1) * this.options.step );
459			this._stop();
460		}
461	},
462
463	stepDown: modifier(function( steps ) {
464		this._stepDown( steps );
465	}),
466	_stepDown: function( steps ) {
467		if ( this._start() ) {
468			this._spin( (steps || 1) * -this.options.step );
469			this._stop();
470		}
471	},
472
473	pageUp: modifier(function( pages ) {
474		this._stepUp( (pages || 1) * this.options.page );
475	}),
476
477	pageDown: modifier(function( pages ) {
478		this._stepDown( (pages || 1) * this.options.page );
479	}),
480
481	value: function( newVal ) {
482		if ( !arguments.length ) {
483			return this._parse( this.element.val() );
484		}
485		modifier( this._value ).call( this, newVal );
486	},
487
488	widget: function() {
489		return this.uiSpinner;
490	}
491});
492
493}( jQuery ) );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.