]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - js/ui/jquery.ui.slider.js
jquery javascript was moved to js/extlib
[quix0rs-gnu-social.git] / js / ui / jquery.ui.slider.js
1 /*
2  * jQuery UI Slider 1.8.10
3  *
4  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5  * Dual licensed under the MIT or GPL Version 2 licenses.
6  * http://jquery.org/license
7  *
8  * http://docs.jquery.com/UI/Slider
9  *
10  * Depends:
11  *      jquery.ui.core.js
12  *      jquery.ui.mouse.js
13  *      jquery.ui.widget.js
14  */
15 (function( $, undefined ) {
16
17 // number of pages in a slider
18 // (how many times can you page up/down to go through the whole range)
19 var numPages = 5;
20
21 $.widget( "ui.slider", $.ui.mouse, {
22
23         widgetEventPrefix: "slide",
24
25         options: {
26                 animate: false,
27                 distance: 0,
28                 max: 100,
29                 min: 0,
30                 orientation: "horizontal",
31                 range: false,
32                 step: 1,
33                 value: 0,
34                 values: null
35         },
36
37         _create: function() {
38                 var self = this,
39                         o = this.options;
40
41                 this._keySliding = false;
42                 this._mouseSliding = false;
43                 this._animateOff = true;
44                 this._handleIndex = null;
45                 this._detectOrientation();
46                 this._mouseInit();
47
48                 this.element
49                         .addClass( "ui-slider" +
50                                 " ui-slider-" + this.orientation +
51                                 " ui-widget" +
52                                 " ui-widget-content" +
53                                 " ui-corner-all" );
54                 
55                 if ( o.disabled ) {
56                         this.element.addClass( "ui-slider-disabled ui-disabled" );
57                 }
58
59                 this.range = $([]);
60
61                 if ( o.range ) {
62                         if ( o.range === true ) {
63                                 this.range = $( "<div></div>" );
64                                 if ( !o.values ) {
65                                         o.values = [ this._valueMin(), this._valueMin() ];
66                                 }
67                                 if ( o.values.length && o.values.length !== 2 ) {
68                                         o.values = [ o.values[0], o.values[0] ];
69                                 }
70                         } else {
71                                 this.range = $( "<div></div>" );
72                         }
73
74                         this.range
75                                 .appendTo( this.element )
76                                 .addClass( "ui-slider-range" );
77
78                         if ( o.range === "min" || o.range === "max" ) {
79                                 this.range.addClass( "ui-slider-range-" + o.range );
80                         }
81
82                         // note: this isn't the most fittingly semantic framework class for this element,
83                         // but worked best visually with a variety of themes
84                         this.range.addClass( "ui-widget-header" );
85                 }
86
87                 if ( $( ".ui-slider-handle", this.element ).length === 0 ) {
88                         $( "<a href='#'></a>" )
89                                 .appendTo( this.element )
90                                 .addClass( "ui-slider-handle" );
91                 }
92
93                 if ( o.values && o.values.length ) {
94                         while ( $(".ui-slider-handle", this.element).length < o.values.length ) {
95                                 $( "<a href='#'></a>" )
96                                         .appendTo( this.element )
97                                         .addClass( "ui-slider-handle" );
98                         }
99                 }
100
101                 this.handles = $( ".ui-slider-handle", this.element )
102                         .addClass( "ui-state-default" +
103                                 " ui-corner-all" );
104
105                 this.handle = this.handles.eq( 0 );
106
107                 this.handles.add( this.range ).filter( "a" )
108                         .click(function( event ) {
109                                 event.preventDefault();
110                         })
111                         .hover(function() {
112                                 if ( !o.disabled ) {
113                                         $( this ).addClass( "ui-state-hover" );
114                                 }
115                         }, function() {
116                                 $( this ).removeClass( "ui-state-hover" );
117                         })
118                         .focus(function() {
119                                 if ( !o.disabled ) {
120                                         $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
121                                         $( this ).addClass( "ui-state-focus" );
122                                 } else {
123                                         $( this ).blur();
124                                 }
125                         })
126                         .blur(function() {
127                                 $( this ).removeClass( "ui-state-focus" );
128                         });
129
130                 this.handles.each(function( i ) {
131                         $( this ).data( "index.ui-slider-handle", i );
132                 });
133
134                 this.handles
135                         .keydown(function( event ) {
136                                 var ret = true,
137                                         index = $( this ).data( "index.ui-slider-handle" ),
138                                         allowed,
139                                         curVal,
140                                         newVal,
141                                         step;
142         
143                                 if ( self.options.disabled ) {
144                                         return;
145                                 }
146         
147                                 switch ( event.keyCode ) {
148                                         case $.ui.keyCode.HOME:
149                                         case $.ui.keyCode.END:
150                                         case $.ui.keyCode.PAGE_UP:
151                                         case $.ui.keyCode.PAGE_DOWN:
152                                         case $.ui.keyCode.UP:
153                                         case $.ui.keyCode.RIGHT:
154                                         case $.ui.keyCode.DOWN:
155                                         case $.ui.keyCode.LEFT:
156                                                 ret = false;
157                                                 if ( !self._keySliding ) {
158                                                         self._keySliding = true;
159                                                         $( this ).addClass( "ui-state-active" );
160                                                         allowed = self._start( event, index );
161                                                         if ( allowed === false ) {
162                                                                 return;
163                                                         }
164                                                 }
165                                                 break;
166                                 }
167         
168                                 step = self.options.step;
169                                 if ( self.options.values && self.options.values.length ) {
170                                         curVal = newVal = self.values( index );
171                                 } else {
172                                         curVal = newVal = self.value();
173                                 }
174         
175                                 switch ( event.keyCode ) {
176                                         case $.ui.keyCode.HOME:
177                                                 newVal = self._valueMin();
178                                                 break;
179                                         case $.ui.keyCode.END:
180                                                 newVal = self._valueMax();
181                                                 break;
182                                         case $.ui.keyCode.PAGE_UP:
183                                                 newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
184                                                 break;
185                                         case $.ui.keyCode.PAGE_DOWN:
186                                                 newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
187                                                 break;
188                                         case $.ui.keyCode.UP:
189                                         case $.ui.keyCode.RIGHT:
190                                                 if ( curVal === self._valueMax() ) {
191                                                         return;
192                                                 }
193                                                 newVal = self._trimAlignValue( curVal + step );
194                                                 break;
195                                         case $.ui.keyCode.DOWN:
196                                         case $.ui.keyCode.LEFT:
197                                                 if ( curVal === self._valueMin() ) {
198                                                         return;
199                                                 }
200                                                 newVal = self._trimAlignValue( curVal - step );
201                                                 break;
202                                 }
203         
204                                 self._slide( event, index, newVal );
205         
206                                 return ret;
207         
208                         })
209                         .keyup(function( event ) {
210                                 var index = $( this ).data( "index.ui-slider-handle" );
211         
212                                 if ( self._keySliding ) {
213                                         self._keySliding = false;
214                                         self._stop( event, index );
215                                         self._change( event, index );
216                                         $( this ).removeClass( "ui-state-active" );
217                                 }
218         
219                         });
220
221                 this._refreshValue();
222
223                 this._animateOff = false;
224         },
225
226         destroy: function() {
227                 this.handles.remove();
228                 this.range.remove();
229
230                 this.element
231                         .removeClass( "ui-slider" +
232                                 " ui-slider-horizontal" +
233                                 " ui-slider-vertical" +
234                                 " ui-slider-disabled" +
235                                 " ui-widget" +
236                                 " ui-widget-content" +
237                                 " ui-corner-all" )
238                         .removeData( "slider" )
239                         .unbind( ".slider" );
240
241                 this._mouseDestroy();
242
243                 return this;
244         },
245
246         _mouseCapture: function( event ) {
247                 var o = this.options,
248                         position,
249                         normValue,
250                         distance,
251                         closestHandle,
252                         self,
253                         index,
254                         allowed,
255                         offset,
256                         mouseOverHandle;
257
258                 if ( o.disabled ) {
259                         return false;
260                 }
261
262                 this.elementSize = {
263                         width: this.element.outerWidth(),
264                         height: this.element.outerHeight()
265                 };
266                 this.elementOffset = this.element.offset();
267
268                 position = { x: event.pageX, y: event.pageY };
269                 normValue = this._normValueFromMouse( position );
270                 distance = this._valueMax() - this._valueMin() + 1;
271                 self = this;
272                 this.handles.each(function( i ) {
273                         var thisDistance = Math.abs( normValue - self.values(i) );
274                         if ( distance > thisDistance ) {
275                                 distance = thisDistance;
276                                 closestHandle = $( this );
277                                 index = i;
278                         }
279                 });
280
281                 // workaround for bug #3736 (if both handles of a range are at 0,
282                 // the first is always used as the one with least distance,
283                 // and moving it is obviously prevented by preventing negative ranges)
284                 if( o.range === true && this.values(1) === o.min ) {
285                         index += 1;
286                         closestHandle = $( this.handles[index] );
287                 }
288
289                 allowed = this._start( event, index );
290                 if ( allowed === false ) {
291                         return false;
292                 }
293                 this._mouseSliding = true;
294
295                 self._handleIndex = index;
296
297                 closestHandle
298                         .addClass( "ui-state-active" )
299                         .focus();
300                 
301                 offset = closestHandle.offset();
302                 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
303                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
304                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
305                         top: event.pageY - offset.top -
306                                 ( closestHandle.height() / 2 ) -
307                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
308                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
309                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
310                 };
311
312                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
313                         this._slide( event, index, normValue );
314                 }
315                 this._animateOff = true;
316                 return true;
317         },
318
319         _mouseStart: function( event ) {
320                 return true;
321         },
322
323         _mouseDrag: function( event ) {
324                 var position = { x: event.pageX, y: event.pageY },
325                         normValue = this._normValueFromMouse( position );
326                 
327                 this._slide( event, this._handleIndex, normValue );
328
329                 return false;
330         },
331
332         _mouseStop: function( event ) {
333                 this.handles.removeClass( "ui-state-active" );
334                 this._mouseSliding = false;
335
336                 this._stop( event, this._handleIndex );
337                 this._change( event, this._handleIndex );
338
339                 this._handleIndex = null;
340                 this._clickOffset = null;
341                 this._animateOff = false;
342
343                 return false;
344         },
345         
346         _detectOrientation: function() {
347                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
348         },
349
350         _normValueFromMouse: function( position ) {
351                 var pixelTotal,
352                         pixelMouse,
353                         percentMouse,
354                         valueTotal,
355                         valueMouse;
356
357                 if ( this.orientation === "horizontal" ) {
358                         pixelTotal = this.elementSize.width;
359                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
360                 } else {
361                         pixelTotal = this.elementSize.height;
362                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
363                 }
364
365                 percentMouse = ( pixelMouse / pixelTotal );
366                 if ( percentMouse > 1 ) {
367                         percentMouse = 1;
368                 }
369                 if ( percentMouse < 0 ) {
370                         percentMouse = 0;
371                 }
372                 if ( this.orientation === "vertical" ) {
373                         percentMouse = 1 - percentMouse;
374                 }
375
376                 valueTotal = this._valueMax() - this._valueMin();
377                 valueMouse = this._valueMin() + percentMouse * valueTotal;
378
379                 return this._trimAlignValue( valueMouse );
380         },
381
382         _start: function( event, index ) {
383                 var uiHash = {
384                         handle: this.handles[ index ],
385                         value: this.value()
386                 };
387                 if ( this.options.values && this.options.values.length ) {
388                         uiHash.value = this.values( index );
389                         uiHash.values = this.values();
390                 }
391                 return this._trigger( "start", event, uiHash );
392         },
393
394         _slide: function( event, index, newVal ) {
395                 var otherVal,
396                         newValues,
397                         allowed;
398
399                 if ( this.options.values && this.options.values.length ) {
400                         otherVal = this.values( index ? 0 : 1 );
401
402                         if ( ( this.options.values.length === 2 && this.options.range === true ) && 
403                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
404                                 ) {
405                                 newVal = otherVal;
406                         }
407
408                         if ( newVal !== this.values( index ) ) {
409                                 newValues = this.values();
410                                 newValues[ index ] = newVal;
411                                 // A slide can be canceled by returning false from the slide callback
412                                 allowed = this._trigger( "slide", event, {
413                                         handle: this.handles[ index ],
414                                         value: newVal,
415                                         values: newValues
416                                 } );
417                                 otherVal = this.values( index ? 0 : 1 );
418                                 if ( allowed !== false ) {
419                                         this.values( index, newVal, true );
420                                 }
421                         }
422                 } else {
423                         if ( newVal !== this.value() ) {
424                                 // A slide can be canceled by returning false from the slide callback
425                                 allowed = this._trigger( "slide", event, {
426                                         handle: this.handles[ index ],
427                                         value: newVal
428                                 } );
429                                 if ( allowed !== false ) {
430                                         this.value( newVal );
431                                 }
432                         }
433                 }
434         },
435
436         _stop: function( event, index ) {
437                 var uiHash = {
438                         handle: this.handles[ index ],
439                         value: this.value()
440                 };
441                 if ( this.options.values && this.options.values.length ) {
442                         uiHash.value = this.values( index );
443                         uiHash.values = this.values();
444                 }
445
446                 this._trigger( "stop", event, uiHash );
447         },
448
449         _change: function( event, index ) {
450                 if ( !this._keySliding && !this._mouseSliding ) {
451                         var uiHash = {
452                                 handle: this.handles[ index ],
453                                 value: this.value()
454                         };
455                         if ( this.options.values && this.options.values.length ) {
456                                 uiHash.value = this.values( index );
457                                 uiHash.values = this.values();
458                         }
459
460                         this._trigger( "change", event, uiHash );
461                 }
462         },
463
464         value: function( newValue ) {
465                 if ( arguments.length ) {
466                         this.options.value = this._trimAlignValue( newValue );
467                         this._refreshValue();
468                         this._change( null, 0 );
469                 }
470
471                 return this._value();
472         },
473
474         values: function( index, newValue ) {
475                 var vals,
476                         newValues,
477                         i;
478
479                 if ( arguments.length > 1 ) {
480                         this.options.values[ index ] = this._trimAlignValue( newValue );
481                         this._refreshValue();
482                         this._change( null, index );
483                 }
484
485                 if ( arguments.length ) {
486                         if ( $.isArray( arguments[ 0 ] ) ) {
487                                 vals = this.options.values;
488                                 newValues = arguments[ 0 ];
489                                 for ( i = 0; i < vals.length; i += 1 ) {
490                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
491                                         this._change( null, i );
492                                 }
493                                 this._refreshValue();
494                         } else {
495                                 if ( this.options.values && this.options.values.length ) {
496                                         return this._values( index );
497                                 } else {
498                                         return this.value();
499                                 }
500                         }
501                 } else {
502                         return this._values();
503                 }
504         },
505
506         _setOption: function( key, value ) {
507                 var i,
508                         valsLength = 0;
509
510                 if ( $.isArray( this.options.values ) ) {
511                         valsLength = this.options.values.length;
512                 }
513
514                 $.Widget.prototype._setOption.apply( this, arguments );
515
516                 switch ( key ) {
517                         case "disabled":
518                                 if ( value ) {
519                                         this.handles.filter( ".ui-state-focus" ).blur();
520                                         this.handles.removeClass( "ui-state-hover" );
521                                         this.handles.attr( "disabled", "disabled" );
522                                         this.element.addClass( "ui-disabled" );
523                                 } else {
524                                         this.handles.removeAttr( "disabled" );
525                                         this.element.removeClass( "ui-disabled" );
526                                 }
527                                 break;
528                         case "orientation":
529                                 this._detectOrientation();
530                                 this.element
531                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
532                                         .addClass( "ui-slider-" + this.orientation );
533                                 this._refreshValue();
534                                 break;
535                         case "value":
536                                 this._animateOff = true;
537                                 this._refreshValue();
538                                 this._change( null, 0 );
539                                 this._animateOff = false;
540                                 break;
541                         case "values":
542                                 this._animateOff = true;
543                                 this._refreshValue();
544                                 for ( i = 0; i < valsLength; i += 1 ) {
545                                         this._change( null, i );
546                                 }
547                                 this._animateOff = false;
548                                 break;
549                 }
550         },
551
552         //internal value getter
553         // _value() returns value trimmed by min and max, aligned by step
554         _value: function() {
555                 var val = this.options.value;
556                 val = this._trimAlignValue( val );
557
558                 return val;
559         },
560
561         //internal values getter
562         // _values() returns array of values trimmed by min and max, aligned by step
563         // _values( index ) returns single value trimmed by min and max, aligned by step
564         _values: function( index ) {
565                 var val,
566                         vals,
567                         i;
568
569                 if ( arguments.length ) {
570                         val = this.options.values[ index ];
571                         val = this._trimAlignValue( val );
572
573                         return val;
574                 } else {
575                         // .slice() creates a copy of the array
576                         // this copy gets trimmed by min and max and then returned
577                         vals = this.options.values.slice();
578                         for ( i = 0; i < vals.length; i+= 1) {
579                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
580                         }
581
582                         return vals;
583                 }
584         },
585         
586         // returns the step-aligned value that val is closest to, between (inclusive) min and max
587         _trimAlignValue: function( val ) {
588                 if ( val <= this._valueMin() ) {
589                         return this._valueMin();
590                 }
591                 if ( val >= this._valueMax() ) {
592                         return this._valueMax();
593                 }
594                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
595                         valModStep = (val - this._valueMin()) % step;
596                         alignValue = val - valModStep;
597
598                 if ( Math.abs(valModStep) * 2 >= step ) {
599                         alignValue += ( valModStep > 0 ) ? step : ( -step );
600                 }
601
602                 // Since JavaScript has problems with large floats, round
603                 // the final value to 5 digits after the decimal point (see #4124)
604                 return parseFloat( alignValue.toFixed(5) );
605         },
606
607         _valueMin: function() {
608                 return this.options.min;
609         },
610
611         _valueMax: function() {
612                 return this.options.max;
613         },
614         
615         _refreshValue: function() {
616                 var oRange = this.options.range,
617                         o = this.options,
618                         self = this,
619                         animate = ( !this._animateOff ) ? o.animate : false,
620                         valPercent,
621                         _set = {},
622                         lastValPercent,
623                         value,
624                         valueMin,
625                         valueMax;
626
627                 if ( this.options.values && this.options.values.length ) {
628                         this.handles.each(function( i, j ) {
629                                 valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
630                                 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
631                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
632                                 if ( self.options.range === true ) {
633                                         if ( self.orientation === "horizontal" ) {
634                                                 if ( i === 0 ) {
635                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
636                                                 }
637                                                 if ( i === 1 ) {
638                                                         self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
639                                                 }
640                                         } else {
641                                                 if ( i === 0 ) {
642                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
643                                                 }
644                                                 if ( i === 1 ) {
645                                                         self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
646                                                 }
647                                         }
648                                 }
649                                 lastValPercent = valPercent;
650                         });
651                 } else {
652                         value = this.value();
653                         valueMin = this._valueMin();
654                         valueMax = this._valueMax();
655                         valPercent = ( valueMax !== valueMin ) ?
656                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
657                                         0;
658                         _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
659                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
660
661                         if ( oRange === "min" && this.orientation === "horizontal" ) {
662                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
663                         }
664                         if ( oRange === "max" && this.orientation === "horizontal" ) {
665                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
666                         }
667                         if ( oRange === "min" && this.orientation === "vertical" ) {
668                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
669                         }
670                         if ( oRange === "max" && this.orientation === "vertical" ) {
671                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
672                         }
673                 }
674         }
675
676 });
677
678 $.extend( $.ui.slider, {
679         version: "1.8.10"
680 });
681
682 }(jQuery));