root/galaxy-central/static/scripts/jquery.ui.sortable.slider.js @ 2

リビジョン 2, 74.0 KB (コミッタ: hatakeyama, 14 年 前)

import galaxy-central

行番号 
1/*!
2 * jQuery UI 1.8.5
3 *
4 * Copyright 2010, 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
9 */
10(function( $, undefined ) {
11
12// prevent duplicate loading
13// this is only a problem because we proxy existing functions
14// and we don't want to double proxy them
15$.ui = $.ui || {};
16if ( $.ui.version ) {
17        return;
18}
19
20$.extend( $.ui, {
21        version: "1.8.5",
22
23        keyCode: {
24                ALT: 18,
25                BACKSPACE: 8,
26                CAPS_LOCK: 20,
27                COMMA: 188,
28                COMMAND: 91,
29                COMMAND_LEFT: 91, // COMMAND
30                COMMAND_RIGHT: 93,
31                CONTROL: 17,
32                DELETE: 46,
33                DOWN: 40,
34                END: 35,
35                ENTER: 13,
36                ESCAPE: 27,
37                HOME: 36,
38                INSERT: 45,
39                LEFT: 37,
40                MENU: 93, // COMMAND_RIGHT
41                NUMPAD_ADD: 107,
42                NUMPAD_DECIMAL: 110,
43                NUMPAD_DIVIDE: 111,
44                NUMPAD_ENTER: 108,
45                NUMPAD_MULTIPLY: 106,
46                NUMPAD_SUBTRACT: 109,
47                PAGE_DOWN: 34,
48                PAGE_UP: 33,
49                PERIOD: 190,
50                RIGHT: 39,
51                SHIFT: 16,
52                SPACE: 32,
53                TAB: 9,
54                UP: 38,
55                WINDOWS: 91 // COMMAND
56        }
57});
58
59// plugins
60$.fn.extend({
61        _focus: $.fn.focus,
62        focus: function( delay, fn ) {
63                return typeof delay === "number" ?
64                        this.each(function() {
65                                var elem = this;
66                                setTimeout(function() {
67                                        $( elem ).focus();
68                                        if ( fn ) {
69                                                fn.call( elem );
70                                        }
71                                }, delay );
72                        }) :
73                        this._focus.apply( this, arguments );
74        },
75
76        scrollParent: function() {
77                var scrollParent;
78                if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
79                        scrollParent = this.parents().filter(function() {
80                                return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
81                        }).eq(0);
82                } else {
83                        scrollParent = this.parents().filter(function() {
84                                return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
85                        }).eq(0);
86                }
87
88                return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
89        },
90
91        zIndex: function( zIndex ) {
92                if ( zIndex !== undefined ) {
93                        return this.css( "zIndex", zIndex );
94                }
95
96                if ( this.length ) {
97                        var elem = $( this[ 0 ] ), position, value;
98                        while ( elem.length && elem[ 0 ] !== document ) {
99                                // Ignore z-index if position is set to a value where z-index is ignored by the browser
100                                // This makes behavior of this function consistent across browsers
101                                // WebKit always returns auto if the element is positioned
102                                position = elem.css( "position" );
103                                if ( position === "absolute" || position === "relative" || position === "fixed" ) {
104                                        // IE returns 0 when zIndex is not specified
105                                        // other browsers return a string
106                                        // we ignore the case of nested elements with an explicit value of 0
107                                        // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
108                                        value = parseInt( elem.css( "zIndex" ) );
109                                        if ( !isNaN( value ) && value != 0 ) {
110                                                return value;
111                                        }
112                                }
113                                elem = elem.parent();
114                        }
115                }
116
117                return 0;
118        },
119       
120        disableSelection: function() {
121                return this.bind(
122                        "mousedown.ui-disableSelection selectstart.ui-disableSelection",
123                        function( event ) {
124                                event.preventDefault();
125                        });
126        },
127
128        enableSelection: function() {
129                return this.unbind( ".ui-disableSelection" );
130        }
131});
132
133$.each( [ "Width", "Height" ], function( i, name ) {
134        var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
135                type = name.toLowerCase(),
136                orig = {
137                        innerWidth: $.fn.innerWidth,
138                        innerHeight: $.fn.innerHeight,
139                        outerWidth: $.fn.outerWidth,
140                        outerHeight: $.fn.outerHeight
141                };
142
143        function reduce( elem, size, border, margin ) {
144                $.each( side, function() {
145                        size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
146                        if ( border ) {
147                                size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
148                        }
149                        if ( margin ) {
150                                size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
151                        }
152                });
153                return size;
154        }
155
156        $.fn[ "inner" + name ] = function( size ) {
157                if ( size === undefined ) {
158                        return orig[ "inner" + name ].call( this );
159                }
160
161                return this.each(function() {
162                        $.style( this, type, reduce( this, size ) + "px" );
163                });
164        };
165
166        $.fn[ "outer" + name] = function( size, margin ) {
167                if ( typeof size !== "number" ) {
168                        return orig[ "outer" + name ].call( this, size );
169                }
170
171                return this.each(function() {
172                        $.style( this, type, reduce( this, size, true, margin ) + "px" );
173                });
174        };
175});
176
177// selectors
178function visible( element ) {
179        return !$( element ).parents().andSelf().filter(function() {
180                return $.curCSS( this, "visibility" ) === "hidden" ||
181                        $.expr.filters.hidden( this );
182        }).length;
183}
184
185$.extend( $.expr[ ":" ], {
186        data: function( elem, i, match ) {
187                return !!$.data( elem, match[ 3 ] );
188        },
189
190        focusable: function( element ) {
191                var nodeName = element.nodeName.toLowerCase(),
192                        tabIndex = $.attr( element, "tabindex" );
193                if ( "area" === nodeName ) {
194                        var map = element.parentNode,
195                                mapName = map.name,
196                                img;
197                        if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
198                                return false;
199                        }
200                        img = $( "img[usemap=#" + mapName + "]" )[0];
201                        return !!img && visible( img );
202                }
203                return ( /input|select|textarea|button|object/.test( nodeName )
204                        ? !element.disabled
205                        : "a" == nodeName
206                                ? element.href || !isNaN( tabIndex )
207                                : !isNaN( tabIndex ))
208                        // the element and all of its ancestors must be visible
209                        && visible( element );
210        },
211
212        tabbable: function( element ) {
213                var tabIndex = $.attr( element, "tabindex" );
214                return ( isNaN( tabIndex ) || tabIndex >= 0 ) && $( element ).is( ":focusable" );
215        }
216});
217
218// support
219$(function() {
220        var div = document.createElement( "div" ),
221                body = document.body;
222
223        $.extend( div.style, {
224                minHeight: "100px",
225                height: "auto",
226                padding: 0,
227                borderWidth: 0
228        });
229
230        $.support.minHeight = body.appendChild( div ).offsetHeight === 100;
231        // set display to none to avoid a layout bug in IE
232        // http://dev.jquery.com/ticket/4014
233        body.removeChild( div ).style.display = "none";
234});
235
236
237
238
239
240// deprecated
241$.extend( $.ui, {
242        // $.ui.plugin is deprecated.  Use the proxy pattern instead.
243        plugin: {
244                add: function( module, option, set ) {
245                        var proto = $.ui[ module ].prototype;
246                        for ( var i in set ) {
247                                proto.plugins[ i ] = proto.plugins[ i ] || [];
248                                proto.plugins[ i ].push( [ option, set[ i ] ] );
249                        }
250                },
251                call: function( instance, name, args ) {
252                        var set = instance.plugins[ name ];
253                        if ( !set || !instance.element[ 0 ].parentNode ) {
254                                return;
255                        }
256       
257                        for ( var i = 0; i < set.length; i++ ) {
258                                if ( instance.options[ set[ i ][ 0 ] ] ) {
259                                        set[ i ][ 1 ].apply( instance.element, args );
260                                }
261                        }
262                }
263        },
264       
265        // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
266        contains: function( a, b ) {
267                return document.compareDocumentPosition ?
268                        a.compareDocumentPosition( b ) & 16 :
269                        a !== b && a.contains( b );
270        },
271       
272        // only used by resizable
273        hasScroll: function( el, a ) {
274       
275                //If overflow is hidden, the element might have extra content, but the user wants to hide it
276                if ( $( el ).css( "overflow" ) === "hidden") {
277                        return false;
278                }
279       
280                var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
281                        has = false;
282       
283                if ( el[ scroll ] > 0 ) {
284                        return true;
285                }
286       
287                // TODO: determine which cases actually cause this to happen
288                // if the element doesn't have the scroll set, see if it's possible to
289                // set the scroll
290                el[ scroll ] = 1;
291                has = ( el[ scroll ] > 0 );
292                el[ scroll ] = 0;
293                return has;
294        },
295       
296        // these are odd functions, fix the API or move into individual plugins
297        isOverAxis: function( x, reference, size ) {
298                //Determines when x coordinate is over "b" element axis
299                return ( x > reference ) && ( x < ( reference + size ) );
300        },
301        isOver: function( y, x, top, left, height, width ) {
302                //Determines when x, y coordinates is over "b" element
303                return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
304        }
305});
306
307})( jQuery );
308/*!
309 * jQuery UI Widget 1.8.5
310 *
311 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
312 * Dual licensed under the MIT or GPL Version 2 licenses.
313 * http://jquery.org/license
314 *
315 * http://docs.jquery.com/UI/Widget
316 */
317(function( $, undefined ) {
318
319// jQuery 1.4+
320if ( $.cleanData ) {
321        var _cleanData = $.cleanData;
322        $.cleanData = function( elems ) {
323                for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
324                        $( elem ).triggerHandler( "remove" );
325                }
326                _cleanData( elems );
327        };
328} else {
329        var _remove = $.fn.remove;
330        $.fn.remove = function( selector, keepData ) {
331                return this.each(function() {
332                        if ( !keepData ) {
333                                if ( !selector || $.filter( selector, [ this ] ).length ) {
334                                        $( "*", this ).add( [ this ] ).each(function() {
335                                                $( this ).triggerHandler( "remove" );
336                                        });
337                                }
338                        }
339                        return _remove.call( $(this), selector, keepData );
340                });
341        };
342}
343
344$.widget = function( name, base, prototype ) {
345        var namespace = name.split( "." )[ 0 ],
346                fullName;
347        name = name.split( "." )[ 1 ];
348        fullName = namespace + "-" + name;
349
350        if ( !prototype ) {
351                prototype = base;
352                base = $.Widget;
353        }
354
355        // create selector for plugin
356        $.expr[ ":" ][ fullName ] = function( elem ) {
357                return !!$.data( elem, name );
358        };
359
360        $[ namespace ] = $[ namespace ] || {};
361        $[ namespace ][ name ] = function( options, element ) {
362                // allow instantiation without initializing for simple inheritance
363                if ( arguments.length ) {
364                        this._createWidget( options, element );
365                }
366        };
367
368        var basePrototype = new base();
369        // we need to make the options hash a property directly on the new instance
370        // otherwise we'll modify the options hash on the prototype that we're
371        // inheriting from
372//      $.each( basePrototype, function( key, val ) {
373//              if ( $.isPlainObject(val) ) {
374//                      basePrototype[ key ] = $.extend( {}, val );
375//              }
376//      });
377        basePrototype.options = $.extend( true, {}, basePrototype.options );
378        $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
379                namespace: namespace,
380                widgetName: name,
381                widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
382                widgetBaseClass: fullName
383        }, prototype );
384
385        $.widget.bridge( name, $[ namespace ][ name ] );
386};
387
388$.widget.bridge = function( name, object ) {
389        $.fn[ name ] = function( options ) {
390                var isMethodCall = typeof options === "string",
391                        args = Array.prototype.slice.call( arguments, 1 ),
392                        returnValue = this;
393
394                // allow multiple hashes to be passed on init
395                options = !isMethodCall && args.length ?
396                        $.extend.apply( null, [ true, options ].concat(args) ) :
397                        options;
398
399                // prevent calls to internal methods
400                if ( isMethodCall && options.substring( 0, 1 ) === "_" ) {
401                        return returnValue;
402                }
403
404                if ( isMethodCall ) {
405                        this.each(function() {
406                                var instance = $.data( this, name );
407                                if ( !instance ) {
408                                        throw "cannot call methods on " + name + " prior to initialization; " +
409                                                "attempted to call method '" + options + "'";
410                                }
411                                if ( !$.isFunction( instance[options] ) ) {
412                                        throw "no such method '" + options + "' for " + name + " widget instance";
413                                }
414                                var methodValue = instance[ options ].apply( instance, args );
415                                if ( methodValue !== instance && methodValue !== undefined ) {
416                                        returnValue = methodValue;
417                                        return false;
418                                }
419                        });
420                } else {
421                        this.each(function() {
422                                var instance = $.data( this, name );
423                                if ( instance ) {
424                                        instance.option( options || {} )._init();
425                                } else {
426                                        $.data( this, name, new object( options, this ) );
427                                }
428                        });
429                }
430
431                return returnValue;
432        };
433};
434
435$.Widget = function( options, element ) {
436        // allow instantiation without initializing for simple inheritance
437        if ( arguments.length ) {
438                this._createWidget( options, element );
439        }
440};
441
442$.Widget.prototype = {
443        widgetName: "widget",
444        widgetEventPrefix: "",
445        options: {
446                disabled: false
447        },
448        _createWidget: function( options, element ) {
449                // $.widget.bridge stores the plugin instance, but we do it anyway
450                // so that it's stored even before the _create function runs
451                $.data( element, this.widgetName, this );
452                this.element = $( element );
453                this.options = $.extend( true, {},
454                        this.options,
455                        $.metadata && $.metadata.get( element )[ this.widgetName ],
456                        options );
457
458                var self = this;
459                this.element.bind( "remove." + this.widgetName, function() {
460                        self.destroy();
461                });
462
463                this._create();
464                this._init();
465        },
466        _create: function() {},
467        _init: function() {},
468
469        destroy: function() {
470                this.element
471                        .unbind( "." + this.widgetName )
472                        .removeData( this.widgetName );
473                this.widget()
474                        .unbind( "." + this.widgetName )
475                        .removeAttr( "aria-disabled" )
476                        .removeClass(
477                                this.widgetBaseClass + "-disabled " +
478                                "ui-state-disabled" );
479        },
480
481        widget: function() {
482                return this.element;
483        },
484
485        option: function( key, value ) {
486                var options = key,
487                        self = this;
488
489                if ( arguments.length === 0 ) {
490                        // don't return a reference to the internal hash
491                        return $.extend( {}, self.options );
492                }
493
494                if  (typeof key === "string" ) {
495                        if ( value === undefined ) {
496                                return this.options[ key ];
497                        }
498                        options = {};
499                        options[ key ] = value;
500                }
501
502                $.each( options, function( key, value ) {
503                        self._setOption( key, value );
504                });
505
506                return self;
507        },
508        _setOption: function( key, value ) {
509                this.options[ key ] = value;
510
511                if ( key === "disabled" ) {
512                        this.widget()
513                                [ value ? "addClass" : "removeClass"](
514                                        this.widgetBaseClass + "-disabled" + " " +
515                                        "ui-state-disabled" )
516                                .attr( "aria-disabled", value );
517                }
518
519                return this;
520        },
521
522        enable: function() {
523                return this._setOption( "disabled", false );
524        },
525        disable: function() {
526                return this._setOption( "disabled", true );
527        },
528
529        _trigger: function( type, event, data ) {
530                var callback = this.options[ type ];
531
532                event = $.Event( event );
533                event.type = ( type === this.widgetEventPrefix ?
534                        type :
535                        this.widgetEventPrefix + type ).toLowerCase();
536                data = data || {};
537
538                // copy original event properties over to the new event
539                // this would happen if we could call $.event.fix instead of $.Event
540                // but we don't have a way to force an event to be fixed multiple times
541                if ( event.originalEvent ) {
542                        for ( var i = $.event.props.length, prop; i; ) {
543                                prop = $.event.props[ --i ];
544                                event[ prop ] = event.originalEvent[ prop ];
545                        }
546                }
547
548                this.element.trigger( event, data );
549
550                return !( $.isFunction(callback) &&
551                        callback.call( this.element[0], event, data ) === false ||
552                        event.isDefaultPrevented() );
553        }
554};
555
556})( jQuery );
557/*!
558 * jQuery UI Mouse 1.8.5
559 *
560 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
561 * Dual licensed under the MIT or GPL Version 2 licenses.
562 * http://jquery.org/license
563 *
564 * http://docs.jquery.com/UI/Mouse
565 *
566 * Depends:
567 *      jquery.ui.widget.js
568 */
569(function( $, undefined ) {
570
571$.widget("ui.mouse", {
572        options: {
573                cancel: ':input,option',
574                distance: 1,
575                delay: 0
576        },
577        _mouseInit: function() {
578                var self = this;
579
580                this.element
581                        .bind('mousedown.'+this.widgetName, function(event) {
582                                return self._mouseDown(event);
583                        })
584                        .bind('click.'+this.widgetName, function(event) {
585                                if(self._preventClickEvent) {
586                                        self._preventClickEvent = false;
587                                        event.stopImmediatePropagation();
588                                        return false;
589                                }
590                        });
591
592                this.started = false;
593        },
594
595        // TODO: make sure destroying one instance of mouse doesn't mess with
596        // other instances of mouse
597        _mouseDestroy: function() {
598                this.element.unbind('.'+this.widgetName);
599        },
600
601        _mouseDown: function(event) {
602                // don't let more than one widget handle mouseStart
603                // TODO: figure out why we have to use originalEvent
604                event.originalEvent = event.originalEvent || {};
605                if (event.originalEvent.mouseHandled) { return; }
606
607                // we may have missed mouseup (out of window)
608                (this._mouseStarted && this._mouseUp(event));
609
610                this._mouseDownEvent = event;
611
612                var self = this,
613                        btnIsLeft = (event.which == 1),
614                        elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
615                if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
616                        return true;
617                }
618
619                this.mouseDelayMet = !this.options.delay;
620                if (!this.mouseDelayMet) {
621                        this._mouseDelayTimer = setTimeout(function() {
622                                self.mouseDelayMet = true;
623                        }, this.options.delay);
624                }
625
626                if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
627                        this._mouseStarted = (this._mouseStart(event) !== false);
628                        if (!this._mouseStarted) {
629                                event.preventDefault();
630                                return true;
631                        }
632                }
633
634                // these delegates are required to keep context
635                this._mouseMoveDelegate = function(event) {
636                        return self._mouseMove(event);
637                };
638                this._mouseUpDelegate = function(event) {
639                        return self._mouseUp(event);
640                };
641                $(document)
642                        .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
643                        .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
644
645                // preventDefault() is used to prevent the selection of text here -
646                // however, in Safari, this causes select boxes not to be selectable
647                // anymore, so this fix is needed
648                ($.browser.safari || event.preventDefault());
649
650                event.originalEvent.mouseHandled = true;
651                return true;
652        },
653
654        _mouseMove: function(event) {
655                // IE mouseup check - mouseup happened when mouse was out of window
656                if ($.browser.msie && !event.button) {
657                        return this._mouseUp(event);
658                }
659
660                if (this._mouseStarted) {
661                        this._mouseDrag(event);
662                        return event.preventDefault();
663                }
664
665                if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
666                        this._mouseStarted =
667                                (this._mouseStart(this._mouseDownEvent, event) !== false);
668                        (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
669                }
670
671                return !this._mouseStarted;
672        },
673
674        _mouseUp: function(event) {
675                $(document)
676                        .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
677                        .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
678
679                if (this._mouseStarted) {
680                        this._mouseStarted = false;
681                        this._preventClickEvent = (event.target == this._mouseDownEvent.target);
682                        this._mouseStop(event);
683                }
684
685                return false;
686        },
687
688        _mouseDistanceMet: function(event) {
689                return (Math.max(
690                                Math.abs(this._mouseDownEvent.pageX - event.pageX),
691                                Math.abs(this._mouseDownEvent.pageY - event.pageY)
692                        ) >= this.options.distance
693                );
694        },
695
696        _mouseDelayMet: function(event) {
697                return this.mouseDelayMet;
698        },
699
700        // These are placeholder methods, to be overriden by extending plugin
701        _mouseStart: function(event) {},
702        _mouseDrag: function(event) {},
703        _mouseStop: function(event) {},
704        _mouseCapture: function(event) { return true; }
705});
706
707})(jQuery);
708/*
709 * jQuery UI Sortable 1.8.5
710 *
711 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
712 * Dual licensed under the MIT or GPL Version 2 licenses.
713 * http://jquery.org/license
714 *
715 * http://docs.jquery.com/UI/Sortables
716 *
717 * Depends:
718 *      jquery.ui.core.js
719 *      jquery.ui.mouse.js
720 *      jquery.ui.widget.js
721 */
722(function( $, undefined ) {
723
724$.widget("ui.sortable", $.ui.mouse, {
725        widgetEventPrefix: "sort",
726        options: {
727                appendTo: "parent",
728                axis: false,
729                connectWith: false,
730                containment: false,
731                cursor: 'auto',
732                cursorAt: false,
733                dropOnEmpty: true,
734                forcePlaceholderSize: false,
735                forceHelperSize: false,
736                grid: false,
737                handle: false,
738                helper: "original",
739                items: '> *',
740                opacity: false,
741                placeholder: false,
742                revert: false,
743                scroll: true,
744                scrollSensitivity: 20,
745                scrollSpeed: 20,
746                scope: "default",
747                tolerance: "intersect",
748                zIndex: 1000
749        },
750        _create: function() {
751
752                var o = this.options;
753                this.containerCache = {};
754                this.element.addClass("ui-sortable");
755
756                //Get the items
757                this.refresh();
758
759                //Let's determine if the items are floating
760                this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false;
761
762                //Let's determine the parent's offset
763                this.offset = this.element.offset();
764
765                //Initialize mouse events for interaction
766                this._mouseInit();
767
768        },
769
770        destroy: function() {
771                this.element
772                        .removeClass("ui-sortable ui-sortable-disabled")
773                        .removeData("sortable")
774                        .unbind(".sortable");
775                this._mouseDestroy();
776
777                for ( var i = this.items.length - 1; i >= 0; i-- )
778                        this.items[i].item.removeData("sortable-item");
779
780                return this;
781        },
782
783        _setOption: function(key, value){
784                if ( key === "disabled" ) {
785                        this.options[ key ] = value;
786       
787                        this.widget()
788                                [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
789                } else {
790                        // Don't call widget base _setOption for disable as it adds ui-state-disabled class
791                        $.Widget.prototype._setOption.apply(this, arguments);
792                }
793        },
794
795        _mouseCapture: function(event, overrideHandle) {
796
797                if (this.reverting) {
798                        return false;
799                }
800
801                if(this.options.disabled || this.options.type == 'static') return false;
802
803                //We have to refresh the items data once first
804                this._refreshItems(event);
805
806                //Find out if the clicked node (or one of its parents) is a actual item in this.items
807                var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
808                        if($.data(this, 'sortable-item') == self) {
809                                currentItem = $(this);
810                                return false;
811                        }
812                });
813                if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
814
815                if(!currentItem) return false;
816                if(this.options.handle && !overrideHandle) {
817                        var validHandle = false;
818
819                        $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
820                        if(!validHandle) return false;
821                }
822
823                this.currentItem = currentItem;
824                this._removeCurrentsFromItems();
825                return true;
826
827        },
828
829        _mouseStart: function(event, overrideHandle, noActivation) {
830
831                var o = this.options, self = this;
832                this.currentContainer = this;
833
834                //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
835                this.refreshPositions();
836
837                //Create and append the visible helper
838                this.helper = this._createHelper(event);
839
840                //Cache the helper size
841                this._cacheHelperProportions();
842
843                /*
844                 * - Position generation -
845                 * This block generates everything position related - it's the core of draggables.
846                 */
847
848                //Cache the margins of the original element
849                this._cacheMargins();
850
851                //Get the next scrolling parent
852                this.scrollParent = this.helper.scrollParent();
853
854                //The element's absolute position on the page minus margins
855                this.offset = this.currentItem.offset();
856                this.offset = {
857                        top: this.offset.top - this.margins.top,
858                        left: this.offset.left - this.margins.left
859                };
860
861                // Only after we got the offset, we can change the helper's position to absolute
862                // TODO: Still need to figure out a way to make relative sorting possible
863                this.helper.css("position", "absolute");
864                this.cssPosition = this.helper.css("position");
865
866                $.extend(this.offset, {
867                        click: { //Where the click happened, relative to the element
868                                left: event.pageX - this.offset.left,
869                                top: event.pageY - this.offset.top
870                        },
871                        parent: this._getParentOffset(),
872                        relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
873                });
874
875                //Generate the original position
876                this.originalPosition = this._generatePosition(event);
877                this.originalPageX = event.pageX;
878                this.originalPageY = event.pageY;
879
880                //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
881                (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
882
883                //Cache the former DOM position
884                this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
885
886                //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
887                if(this.helper[0] != this.currentItem[0]) {
888                        this.currentItem.hide();
889                }
890
891                //Create the placeholder
892                this._createPlaceholder();
893
894                //Set a containment if given in the options
895                if(o.containment)
896                        this._setContainment();
897
898                if(o.cursor) { // cursor option
899                        if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
900                        $('body').css("cursor", o.cursor);
901                }
902
903                if(o.opacity) { // opacity option
904                        if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
905                        this.helper.css("opacity", o.opacity);
906                }
907
908                if(o.zIndex) { // zIndex option
909                        if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
910                        this.helper.css("zIndex", o.zIndex);
911                }
912
913                //Prepare scrolling
914                if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
915                        this.overflowOffset = this.scrollParent.offset();
916
917                //Call callbacks
918                this._trigger("start", event, this._uiHash());
919
920                //Recache the helper size
921                if(!this._preserveHelperProportions)
922                        this._cacheHelperProportions();
923
924
925                //Post 'activate' events to possible containers
926                if(!noActivation) {
927                         for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
928                }
929
930                //Prepare possible droppables
931                if($.ui.ddmanager)
932                        $.ui.ddmanager.current = this;
933
934                if ($.ui.ddmanager && !o.dropBehaviour)
935                        $.ui.ddmanager.prepareOffsets(this, event);
936
937                this.dragging = true;
938
939                this.helper.addClass("ui-sortable-helper");
940                this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
941                return true;
942
943        },
944
945        _mouseDrag: function(event) {
946
947                //Compute the helpers position
948                this.position = this._generatePosition(event);
949                this.positionAbs = this._convertPositionTo("absolute");
950
951                if (!this.lastPositionAbs) {
952                        this.lastPositionAbs = this.positionAbs;
953                }
954
955                //Do scrolling
956                if(this.options.scroll) {
957                        var o = this.options, scrolled = false;
958                        if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
959
960                                if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
961                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
962                                else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
963                                        this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
964
965                                if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
966                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
967                                else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
968                                        this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
969
970                        } else {
971
972                                if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
973                                        scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
974                                else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
975                                        scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
976
977                                if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
978                                        scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
979                                else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
980                                        scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
981
982                        }
983
984                        if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
985                                $.ui.ddmanager.prepareOffsets(this, event);
986                }
987
988                //Regenerate the absolute position used for position checks
989                this.positionAbs = this._convertPositionTo("absolute");
990
991                //Set the helper position
992                if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
993                if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
994
995                //Rearrange
996                for (var i = this.items.length - 1; i >= 0; i--) {
997
998                        //Cache variables and intersection, continue if no intersection
999                        var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
1000                        if (!intersection) continue;
1001
1002                        if(itemElement != this.currentItem[0] //cannot intersect with itself
1003                                &&      this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
1004                                &&      !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
1005                                && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
1006                                //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
1007                        ) {
1008
1009                                this.direction = intersection == 1 ? "down" : "up";
1010
1011                                if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
1012                                        this._rearrange(event, item);
1013                                } else {
1014                                        break;
1015                                }
1016
1017                                this._trigger("change", event, this._uiHash());
1018                                break;
1019                        }
1020                }
1021
1022                //Post events to containers
1023                this._contactContainers(event);
1024
1025                //Interconnect with droppables
1026                if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1027
1028                //Call callbacks
1029                this._trigger('sort', event, this._uiHash());
1030
1031                this.lastPositionAbs = this.positionAbs;
1032                return false;
1033
1034        },
1035
1036        _mouseStop: function(event, noPropagation) {
1037
1038                if(!event) return;
1039
1040                //If we are using droppables, inform the manager about the drop
1041                if ($.ui.ddmanager && !this.options.dropBehaviour)
1042                        $.ui.ddmanager.drop(this, event);
1043
1044                if(this.options.revert) {
1045                        var self = this;
1046                        var cur = self.placeholder.offset();
1047
1048                        self.reverting = true;
1049
1050                        $(this.helper).animate({
1051                                left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
1052                                top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
1053                        }, parseInt(this.options.revert, 10) || 500, function() {
1054                                self._clear(event);
1055                        });
1056                } else {
1057                        this._clear(event, noPropagation);
1058                }
1059
1060                return false;
1061
1062        },
1063
1064        cancel: function() {
1065
1066                var self = this;
1067
1068                if(this.dragging) {
1069
1070                        this._mouseUp();
1071
1072                        if(this.options.helper == "original")
1073                                this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
1074                        else
1075                                this.currentItem.show();
1076
1077                        //Post deactivating events to containers
1078                        for (var i = this.containers.length - 1; i >= 0; i--){
1079                                this.containers[i]._trigger("deactivate", null, self._uiHash(this));
1080                                if(this.containers[i].containerCache.over) {
1081                                        this.containers[i]._trigger("out", null, self._uiHash(this));
1082                                        this.containers[i].containerCache.over = 0;
1083                                }
1084                        }
1085
1086                }
1087
1088                //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
1089                if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
1090                if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
1091
1092                $.extend(this, {
1093                        helper: null,
1094                        dragging: false,
1095                        reverting: false,
1096                        _noFinalSort: null
1097                });
1098
1099                if(this.domPosition.prev) {
1100                        $(this.domPosition.prev).after(this.currentItem);
1101                } else {
1102                        $(this.domPosition.parent).prepend(this.currentItem);
1103                }
1104
1105                return this;
1106
1107        },
1108
1109        serialize: function(o) {
1110
1111                var items = this._getItemsAsjQuery(o && o.connected);
1112                var str = []; o = o || {};
1113
1114                $(items).each(function() {
1115                        var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
1116                        if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
1117                });
1118
1119                if(!str.length && o.key) {
1120                        str.push(o.key + '=');
1121                }
1122
1123                return str.join('&');
1124
1125        },
1126
1127        toArray: function(o) {
1128
1129                var items = this._getItemsAsjQuery(o && o.connected);
1130                var ret = []; o = o || {};
1131
1132                items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
1133                return ret;
1134
1135        },
1136
1137        /* Be careful with the following core functions */
1138        _intersectsWith: function(item) {
1139
1140                var x1 = this.positionAbs.left,
1141                        x2 = x1 + this.helperProportions.width,
1142                        y1 = this.positionAbs.top,
1143                        y2 = y1 + this.helperProportions.height;
1144
1145                var l = item.left,
1146                        r = l + item.width,
1147                        t = item.top,
1148                        b = t + item.height;
1149
1150                var dyClick = this.offset.click.top,
1151                        dxClick = this.offset.click.left;
1152
1153                var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
1154
1155                if(        this.options.tolerance == "pointer"
1156                        || this.options.forcePointerForContainers
1157                        || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
1158                ) {
1159                        return isOverElement;
1160                } else {
1161
1162                        return (l < x1 + (this.helperProportions.width / 2) // Right Half
1163                                && x2 - (this.helperProportions.width / 2) < r // Left Half
1164                                && t < y1 + (this.helperProportions.height / 2) // Bottom Half
1165                                && y2 - (this.helperProportions.height / 2) < b ); // Top Half
1166
1167                }
1168        },
1169
1170        _intersectsWithPointer: function(item) {
1171
1172                var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
1173                        isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
1174                        isOverElement = isOverElementHeight && isOverElementWidth,
1175                        verticalDirection = this._getDragVerticalDirection(),
1176                        horizontalDirection = this._getDragHorizontalDirection();
1177
1178                if (!isOverElement)
1179                        return false;
1180
1181                return this.floating ?
1182                        ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
1183                        : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
1184
1185        },
1186
1187        _intersectsWithSides: function(item) {
1188
1189                var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
1190                        isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
1191                        verticalDirection = this._getDragVerticalDirection(),
1192                        horizontalDirection = this._getDragHorizontalDirection();
1193
1194                if (this.floating && horizontalDirection) {
1195                        return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
1196                } else {
1197                        return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
1198                }
1199
1200        },
1201
1202        _getDragVerticalDirection: function() {
1203                var delta = this.positionAbs.top - this.lastPositionAbs.top;
1204                return delta != 0 && (delta > 0 ? "down" : "up");
1205        },
1206
1207        _getDragHorizontalDirection: function() {
1208                var delta = this.positionAbs.left - this.lastPositionAbs.left;
1209                return delta != 0 && (delta > 0 ? "right" : "left");
1210        },
1211
1212        refresh: function(event) {
1213                this._refreshItems(event);
1214                this.refreshPositions();
1215                return this;
1216        },
1217
1218        _connectWith: function() {
1219                var options = this.options;
1220                return options.connectWith.constructor == String
1221                        ? [options.connectWith]
1222                        : options.connectWith;
1223        },
1224       
1225        _getItemsAsjQuery: function(connected) {
1226
1227                var self = this;
1228                var items = [];
1229                var queries = [];
1230                var connectWith = this._connectWith();
1231
1232                if(connectWith && connected) {
1233                        for (var i = connectWith.length - 1; i >= 0; i--){
1234                                var cur = $(connectWith[i]);
1235                                for (var j = cur.length - 1; j >= 0; j--){
1236                                        var inst = $.data(cur[j], 'sortable');
1237                                        if(inst && inst != this && !inst.options.disabled) {
1238                                                queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
1239                                        }
1240                                };
1241                        };
1242                }
1243
1244                queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
1245
1246                for (var i = queries.length - 1; i >= 0; i--){
1247                        queries[i][0].each(function() {
1248                                items.push(this);
1249                        });
1250                };
1251
1252                return $(items);
1253
1254        },
1255
1256        _removeCurrentsFromItems: function() {
1257
1258                var list = this.currentItem.find(":data(sortable-item)");
1259
1260                for (var i=0; i < this.items.length; i++) {
1261
1262                        for (var j=0; j < list.length; j++) {
1263                                if(list[j] == this.items[i].item[0])
1264                                        this.items.splice(i,1);
1265                        };
1266
1267                };
1268
1269        },
1270
1271        _refreshItems: function(event) {
1272
1273                this.items = [];
1274                this.containers = [this];
1275                var items = this.items;
1276                var self = this;
1277                var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
1278                var connectWith = this._connectWith();
1279
1280                if(connectWith) {
1281                        for (var i = connectWith.length - 1; i >= 0; i--){
1282                                var cur = $(connectWith[i]);
1283                                for (var j = cur.length - 1; j >= 0; j--){
1284                                        var inst = $.data(cur[j], 'sortable');
1285                                        if(inst && inst != this && !inst.options.disabled) {
1286                                                queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
1287                                                this.containers.push(inst);
1288                                        }
1289                                };
1290                        };
1291                }
1292
1293                for (var i = queries.length - 1; i >= 0; i--) {
1294                        var targetData = queries[i][1];
1295                        var _queries = queries[i][0];
1296
1297                        for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
1298                                var item = $(_queries[j]);
1299
1300                                item.data('sortable-item', targetData); // Data for target checking (mouse manager)
1301
1302                                items.push({
1303                                        item: item,
1304                                        instance: targetData,
1305                                        width: 0, height: 0,
1306                                        left: 0, top: 0
1307                                });
1308                        };
1309                };
1310
1311        },
1312
1313        refreshPositions: function(fast) {
1314
1315                //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
1316                if(this.offsetParent && this.helper) {
1317                        this.offset.parent = this._getParentOffset();
1318                }
1319
1320                for (var i = this.items.length - 1; i >= 0; i--){
1321                        var item = this.items[i];
1322
1323                        var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
1324
1325                        if (!fast) {
1326                                item.width = t.outerWidth();
1327                                item.height = t.outerHeight();
1328                        }
1329
1330                        var p = t.offset();
1331                        item.left = p.left;
1332                        item.top = p.top;
1333                };
1334
1335                if(this.options.custom && this.options.custom.refreshContainers) {
1336                        this.options.custom.refreshContainers.call(this);
1337                } else {
1338                        for (var i = this.containers.length - 1; i >= 0; i--){
1339                                var p = this.containers[i].element.offset();
1340                                this.containers[i].containerCache.left = p.left;
1341                                this.containers[i].containerCache.top = p.top;
1342                                this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
1343                                this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
1344                        };
1345                }
1346
1347                return this;
1348        },
1349
1350        _createPlaceholder: function(that) {
1351
1352                var self = that || this, o = self.options;
1353
1354                if(!o.placeholder || o.placeholder.constructor == String) {
1355                        var className = o.placeholder;
1356                        o.placeholder = {
1357                                element: function() {
1358
1359                                        var el = $(document.createElement(self.currentItem[0].nodeName))
1360                                                .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
1361                                                .removeClass("ui-sortable-helper")[0];
1362
1363                                        if(!className)
1364                                                el.style.visibility = "hidden";
1365
1366                                        return el;
1367                                },
1368                                update: function(container, p) {
1369
1370                                        // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
1371                                        // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
1372                                        if(className && !o.forcePlaceholderSize) return;
1373
1374                                        //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
1375                                        if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
1376                                        if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
1377                                }
1378                        };
1379                }
1380
1381                //Create the placeholder
1382                self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
1383
1384                //Append it after the actual current item
1385                self.currentItem.after(self.placeholder);
1386
1387                //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
1388                o.placeholder.update(self, self.placeholder);
1389
1390        },
1391
1392        _contactContainers: function(event) {
1393               
1394                // get innermost container that intersects with item
1395                var innermostContainer = null, innermostIndex = null;           
1396               
1397               
1398                for (var i = this.containers.length - 1; i >= 0; i--){
1399
1400                        // never consider a container that's located within the item itself
1401                        if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
1402                                continue;
1403
1404                        if(this._intersectsWith(this.containers[i].containerCache)) {
1405
1406                                // if we've already found a container and it's more "inner" than this, then continue
1407                                if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
1408                                        continue;
1409
1410                                innermostContainer = this.containers[i];
1411                                innermostIndex = i;
1412                                       
1413                        } else {
1414                                // container doesn't intersect. trigger "out" event if necessary
1415                                if(this.containers[i].containerCache.over) {
1416                                        this.containers[i]._trigger("out", event, this._uiHash(this));
1417                                        this.containers[i].containerCache.over = 0;
1418                                }
1419                        }
1420
1421                }
1422               
1423                // if no intersecting containers found, return
1424                if(!innermostContainer) return;
1425
1426                // move the item into the container if it's not there already
1427                if(this.containers.length === 1) {
1428                        this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
1429                        this.containers[innermostIndex].containerCache.over = 1;
1430                } else if(this.currentContainer != this.containers[innermostIndex]) {
1431
1432                        //When entering a new container, we will find the item with the least distance and append our item near it
1433                        var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
1434                        for (var j = this.items.length - 1; j >= 0; j--) {
1435                                if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
1436                                var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top'];
1437                                if(Math.abs(cur - base) < dist) {
1438                                        dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
1439                                }
1440                        }
1441
1442                        if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
1443                                return;
1444
1445                        this.currentContainer = this.containers[innermostIndex];
1446                        itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
1447                        this._trigger("change", event, this._uiHash());
1448                        this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
1449
1450                        //Update the placeholder
1451                        this.options.placeholder.update(this.currentContainer, this.placeholder);
1452               
1453                        this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
1454                        this.containers[innermostIndex].containerCache.over = 1;
1455                }
1456       
1457               
1458        },
1459
1460        _createHelper: function(event) {
1461
1462                var o = this.options;
1463                var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
1464
1465                if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
1466                        $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
1467
1468                if(helper[0] == this.currentItem[0])
1469                        this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
1470
1471                if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
1472                if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
1473
1474                return helper;
1475
1476        },
1477
1478        _adjustOffsetFromHelper: function(obj) {
1479                if (typeof obj == 'string') {
1480                        obj = obj.split(' ');
1481                }
1482                if ($.isArray(obj)) {
1483                        obj = {left: +obj[0], top: +obj[1] || 0};
1484                }
1485                if ('left' in obj) {
1486                        this.offset.click.left = obj.left + this.margins.left;
1487                }
1488                if ('right' in obj) {
1489                        this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1490                }
1491                if ('top' in obj) {
1492                        this.offset.click.top = obj.top + this.margins.top;
1493                }
1494                if ('bottom' in obj) {
1495                        this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1496                }
1497        },
1498
1499        _getParentOffset: function() {
1500
1501
1502                //Get the offsetParent and cache its position
1503                this.offsetParent = this.helper.offsetParent();
1504                var po = this.offsetParent.offset();
1505
1506                // This is a special case where we need to modify a offset calculated on start, since the following happened:
1507                // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1508                // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1509                //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1510                if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1511                        po.left += this.scrollParent.scrollLeft();
1512                        po.top += this.scrollParent.scrollTop();
1513                }
1514
1515                if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1516                || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1517                        po = { top: 0, left: 0 };
1518
1519                return {
1520                        top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1521                        left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1522                };
1523
1524        },
1525
1526        _getRelativeOffset: function() {
1527
1528                if(this.cssPosition == "relative") {
1529                        var p = this.currentItem.position();
1530                        return {
1531                                top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1532                                left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1533                        };
1534                } else {
1535                        return { top: 0, left: 0 };
1536                }
1537
1538        },
1539
1540        _cacheMargins: function() {
1541                this.margins = {
1542                        left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
1543                        top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
1544                };
1545        },
1546
1547        _cacheHelperProportions: function() {
1548                this.helperProportions = {
1549                        width: this.helper.outerWidth(),
1550                        height: this.helper.outerHeight()
1551                };
1552        },
1553
1554        _setContainment: function() {
1555
1556                var o = this.options;
1557                if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1558                if(o.containment == 'document' || o.containment == 'window') this.containment = [
1559                        0 - this.offset.relative.left - this.offset.parent.left,
1560                        0 - this.offset.relative.top - this.offset.parent.top,
1561                        $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1562                        ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1563                ];
1564
1565                if(!(/^(document|window|parent)$/).test(o.containment)) {
1566                        var ce = $(o.containment)[0];
1567                        var co = $(o.containment).offset();
1568                        var over = ($(ce).css("overflow") != 'hidden');
1569
1570                        this.containment = [
1571                                co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
1572                                co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
1573                                co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
1574                                co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
1575                        ];
1576                }
1577
1578        },
1579
1580        _convertPositionTo: function(d, pos) {
1581
1582                if(!pos) pos = this.position;
1583                var mod = d == "absolute" ? 1 : -1;
1584                var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1585
1586                return {
1587                        top: (
1588                                pos.top                                                                                                                                 // The absolute mouse position
1589                                + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1590                                + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
1591                                - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1592                        ),
1593                        left: (
1594                                pos.left                                                                                                                                // The absolute mouse position
1595                                + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
1596                                + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
1597                                - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1598                        )
1599                };
1600
1601        },
1602
1603        _generatePosition: function(event) {
1604
1605                var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1606
1607                // This is another very weird special case that only happens for relative elements:
1608                // 1. If the css position is relative
1609                // 2. and the scroll parent is the document or similar to the offset parent
1610                // we have to refresh the relative offset during the scroll so there are no jumps
1611                if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
1612                        this.offset.relative = this._getRelativeOffset();
1613                }
1614
1615                var pageX = event.pageX;
1616                var pageY = event.pageY;
1617
1618                /*
1619                 * - Position constraining -
1620                 * Constrain the position to a mix of grid, containment.
1621                 */
1622
1623                if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1624
1625                        if(this.containment) {
1626                                if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
1627                                if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
1628                                if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
1629                                if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
1630                        }
1631
1632                        if(o.grid) {
1633                                var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
1634                                pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1635
1636                                var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
1637                                pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1638                        }
1639
1640                }
1641
1642                return {
1643                        top: (
1644                                pageY                                                                                                                           // The absolute mouse position
1645                                - this.offset.click.top                                                                                                 // Click offset (relative to the element)
1646                                - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
1647                                - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
1648                                + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1649                        ),
1650                        left: (
1651                                pageX                                                                                                                           // The absolute mouse position
1652                                - this.offset.click.left                                                                                                // Click offset (relative to the element)
1653                                - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
1654                                - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
1655                                + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1656                        )
1657                };
1658
1659        },
1660
1661        _rearrange: function(event, i, a, hardRefresh) {
1662
1663                a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
1664
1665                //Various things done here to improve the performance:
1666                // 1. we create a setTimeout, that calls refreshPositions
1667                // 2. on the instance, we have a counter variable, that get's higher after every append
1668                // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
1669                // 4. this lets only the last addition to the timeout stack through
1670                this.counter = this.counter ? ++this.counter : 1;
1671                var self = this, counter = this.counter;
1672
1673                window.setTimeout(function() {
1674                        if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
1675                },0);
1676
1677        },
1678
1679        _clear: function(event, noPropagation) {
1680
1681                this.reverting = false;
1682                // We delay all events that have to be triggered to after the point where the placeholder has been removed and
1683                // everything else normalized again
1684                var delayedTriggers = [], self = this;
1685
1686                // We first have to update the dom position of the actual currentItem
1687                // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
1688                if(!this._noFinalSort && this.currentItem[0].parentNode) this.placeholder.before(this.currentItem);
1689                this._noFinalSort = null;
1690
1691                if(this.helper[0] == this.currentItem[0]) {
1692                        for(var i in this._storedCSS) {
1693                                if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
1694                        }
1695                        this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
1696                } else {
1697                        this.currentItem.show();
1698                }
1699
1700                if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
1701                if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
1702                if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
1703                        if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
1704                        for (var i = this.containers.length - 1; i >= 0; i--){
1705                                if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
1706                                        delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
1707                                        delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
1708                                }
1709                        };
1710                };
1711
1712                //Post events to containers
1713                for (var i = this.containers.length - 1; i >= 0; i--){
1714                        if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
1715                        if(this.containers[i].containerCache.over) {
1716                                delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
1717                                this.containers[i].containerCache.over = 0;
1718                        }
1719                }
1720
1721                //Do what was originally in plugins
1722                if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
1723                if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
1724                if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
1725
1726                this.dragging = false;
1727                if(this.cancelHelperRemoval) {
1728                        if(!noPropagation) {
1729                                this._trigger("beforeStop", event, this._uiHash());
1730                                for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
1731                                this._trigger("stop", event, this._uiHash());
1732                        }
1733                        return false;
1734                }
1735
1736                if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
1737
1738                //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
1739                this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
1740
1741                if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
1742
1743                if(!noPropagation) {
1744                        for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
1745                        this._trigger("stop", event, this._uiHash());
1746                }
1747
1748                this.fromOutside = false;
1749                return true;
1750
1751        },
1752
1753        _trigger: function() {
1754                if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
1755                        this.cancel();
1756                }
1757        },
1758
1759        _uiHash: function(inst) {
1760                var self = inst || this;
1761                return {
1762                        helper: self.helper,
1763                        placeholder: self.placeholder || $([]),
1764                        position: self.position,
1765                        originalPosition: self.originalPosition,
1766                        offset: self.positionAbs,
1767                        item: self.currentItem,
1768                        sender: inst ? inst.element : null
1769                };
1770        }
1771
1772});
1773
1774$.extend($.ui.sortable, {
1775        version: "1.8.5"
1776});
1777
1778})(jQuery);
1779/*
1780 * jQuery UI Slider 1.8.5
1781 *
1782 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
1783 * Dual licensed under the MIT or GPL Version 2 licenses.
1784 * http://jquery.org/license
1785 *
1786 * http://docs.jquery.com/UI/Slider
1787 *
1788 * Depends:
1789 *      jquery.ui.core.js
1790 *      jquery.ui.mouse.js
1791 *      jquery.ui.widget.js
1792 */
1793(function( $, undefined ) {
1794
1795// number of pages in a slider
1796// (how many times can you page up/down to go through the whole range)
1797var numPages = 5;
1798
1799$.widget( "ui.slider", $.ui.mouse, {
1800
1801        widgetEventPrefix: "slide",
1802
1803        options: {
1804                animate: false,
1805                distance: 0,
1806                max: 100,
1807                min: 0,
1808                orientation: "horizontal",
1809                range: false,
1810                step: 1,
1811                value: 0,
1812                values: null
1813        },
1814
1815        _create: function() {
1816                var self = this,
1817                        o = this.options;
1818
1819                this._keySliding = false;
1820                this._mouseSliding = false;
1821                this._animateOff = true;
1822                this._handleIndex = null;
1823                this._detectOrientation();
1824                this._mouseInit();
1825
1826                this.element
1827                        .addClass( "ui-slider" +
1828                                " ui-slider-" + this.orientation +
1829                                " ui-widget" +
1830                                " ui-widget-content" +
1831                                " ui-corner-all" );
1832               
1833                if ( o.disabled ) {
1834                        this.element.addClass( "ui-slider-disabled ui-disabled" );
1835                }
1836
1837                this.range = $([]);
1838
1839                if ( o.range ) {
1840                        if ( o.range === true ) {
1841                                this.range = $( "<div></div>" );
1842                                if ( !o.values ) {
1843                                        o.values = [ this._valueMin(), this._valueMin() ];
1844                                }
1845                                if ( o.values.length && o.values.length !== 2 ) {
1846                                        o.values = [ o.values[0], o.values[0] ];
1847                                }
1848                        } else {
1849                                this.range = $( "<div></div>" );
1850                        }
1851
1852                        this.range
1853                                .appendTo( this.element )
1854                                .addClass( "ui-slider-range" );
1855
1856                        if ( o.range === "min" || o.range === "max" ) {
1857                                this.range.addClass( "ui-slider-range-" + o.range );
1858                        }
1859
1860                        // note: this isn't the most fittingly semantic framework class for this element,
1861                        // but worked best visually with a variety of themes
1862                        this.range.addClass( "ui-widget-header" );
1863                }
1864
1865                if ( $( ".ui-slider-handle", this.element ).length === 0 ) {
1866                        $( "<a href='#'></a>" )
1867                                .appendTo( this.element )
1868                                .addClass( "ui-slider-handle" );
1869                }
1870
1871                if ( o.values && o.values.length ) {
1872                        while ( $(".ui-slider-handle", this.element).length < o.values.length ) {
1873                                $( "<a href='#'></a>" )
1874                                        .appendTo( this.element )
1875                                        .addClass( "ui-slider-handle" );
1876                        }
1877                }
1878
1879                this.handles = $( ".ui-slider-handle", this.element )
1880                        .addClass( "ui-state-default" +
1881                                " ui-corner-all" );
1882
1883                this.handle = this.handles.eq( 0 );
1884
1885                this.handles.add( this.range ).filter( "a" )
1886                        .click(function( event ) {
1887                                event.preventDefault();
1888                        })
1889                        .hover(function() {
1890                                if ( !o.disabled ) {
1891                                        $( this ).addClass( "ui-state-hover" );
1892                                }
1893                        }, function() {
1894                                $( this ).removeClass( "ui-state-hover" );
1895                        })
1896                        .focus(function() {
1897                                if ( !o.disabled ) {
1898                                        $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
1899                                        $( this ).addClass( "ui-state-focus" );
1900                                } else {
1901                                        $( this ).blur();
1902                                }
1903                        })
1904                        .blur(function() {
1905                                $( this ).removeClass( "ui-state-focus" );
1906                        });
1907
1908                this.handles.each(function( i ) {
1909                        $( this ).data( "index.ui-slider-handle", i );
1910                });
1911
1912                this.handles
1913                        .keydown(function( event ) {
1914                                var ret = true,
1915                                        index = $( this ).data( "index.ui-slider-handle" ),
1916                                        allowed,
1917                                        curVal,
1918                                        newVal,
1919                                        step;
1920       
1921                                if ( self.options.disabled ) {
1922                                        return;
1923                                }
1924       
1925                                switch ( event.keyCode ) {
1926                                        case $.ui.keyCode.HOME:
1927                                        case $.ui.keyCode.END:
1928                                        case $.ui.keyCode.PAGE_UP:
1929                                        case $.ui.keyCode.PAGE_DOWN:
1930                                        case $.ui.keyCode.UP:
1931                                        case $.ui.keyCode.RIGHT:
1932                                        case $.ui.keyCode.DOWN:
1933                                        case $.ui.keyCode.LEFT:
1934                                                ret = false;
1935                                                if ( !self._keySliding ) {
1936                                                        self._keySliding = true;
1937                                                        $( this ).addClass( "ui-state-active" );
1938                                                        allowed = self._start( event, index );
1939                                                        if ( allowed === false ) {
1940                                                                return;
1941                                                        }
1942                                                }
1943                                                break;
1944                                }
1945       
1946                                step = self.options.step;
1947                                if ( self.options.values && self.options.values.length ) {
1948                                        curVal = newVal = self.values( index );
1949                                } else {
1950                                        curVal = newVal = self.value();
1951                                }
1952       
1953                                switch ( event.keyCode ) {
1954                                        case $.ui.keyCode.HOME:
1955                                                newVal = self._valueMin();
1956                                                break;
1957                                        case $.ui.keyCode.END:
1958                                                newVal = self._valueMax();
1959                                                break;
1960                                        case $.ui.keyCode.PAGE_UP:
1961                                                newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
1962                                                break;
1963                                        case $.ui.keyCode.PAGE_DOWN:
1964                                                newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
1965                                                break;
1966                                        case $.ui.keyCode.UP:
1967                                        case $.ui.keyCode.RIGHT:
1968                                                if ( curVal === self._valueMax() ) {
1969                                                        return;
1970                                                }
1971                                                newVal = self._trimAlignValue( curVal + step );
1972                                                break;
1973                                        case $.ui.keyCode.DOWN:
1974                                        case $.ui.keyCode.LEFT:
1975                                                if ( curVal === self._valueMin() ) {
1976                                                        return;
1977                                                }
1978                                                newVal = self._trimAlignValue( curVal - step );
1979                                                break;
1980                                }
1981       
1982                                self._slide( event, index, newVal );
1983       
1984                                return ret;
1985       
1986                        })
1987                        .keyup(function( event ) {
1988                                var index = $( this ).data( "index.ui-slider-handle" );
1989       
1990                                if ( self._keySliding ) {
1991                                        self._keySliding = false;
1992                                        self._stop( event, index );
1993                                        self._change( event, index );
1994                                        $( this ).removeClass( "ui-state-active" );
1995                                }
1996       
1997                        });
1998
1999                this._refreshValue();
2000
2001                this._animateOff = false;
2002        },
2003
2004        destroy: function() {
2005                this.handles.remove();
2006                this.range.remove();
2007
2008                this.element
2009                        .removeClass( "ui-slider" +
2010                                " ui-slider-horizontal" +
2011                                " ui-slider-vertical" +
2012                                " ui-slider-disabled" +
2013                                " ui-widget" +
2014                                " ui-widget-content" +
2015                                " ui-corner-all" )
2016                        .removeData( "slider" )
2017                        .unbind( ".slider" );
2018
2019                this._mouseDestroy();
2020
2021                return this;
2022        },
2023
2024        _mouseCapture: function( event ) {
2025                var o = this.options,
2026                        position,
2027                        normValue,
2028                        distance,
2029                        closestHandle,
2030                        self,
2031                        index,
2032                        allowed,
2033                        offset,
2034                        mouseOverHandle;
2035
2036                if ( o.disabled ) {
2037                        return false;
2038                }
2039
2040                this.elementSize = {
2041                        width: this.element.outerWidth(),
2042                        height: this.element.outerHeight()
2043                };
2044                this.elementOffset = this.element.offset();
2045
2046                position = { x: event.pageX, y: event.pageY };
2047                normValue = this._normValueFromMouse( position );
2048                distance = this._valueMax() - this._valueMin() + 1;
2049                self = this;
2050                this.handles.each(function( i ) {
2051                        var thisDistance = Math.abs( normValue - self.values(i) );
2052                        if ( distance > thisDistance ) {
2053                                distance = thisDistance;
2054                                closestHandle = $( this );
2055                                index = i;
2056                        }
2057                });
2058
2059                // workaround for bug #3736 (if both handles of a range are at 0,
2060                // the first is always used as the one with least distance,
2061                // and moving it is obviously prevented by preventing negative ranges)
2062                if( o.range === true && this.values(1) === o.min ) {
2063                        index += 1;
2064                        closestHandle = $( this.handles[index] );
2065                }
2066
2067                allowed = this._start( event, index );
2068                if ( allowed === false ) {
2069                        return false;
2070                }
2071                this._mouseSliding = true;
2072
2073                self._handleIndex = index;
2074
2075                closestHandle
2076                        .addClass( "ui-state-active" )
2077                        .focus();
2078               
2079                offset = closestHandle.offset();
2080                mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
2081                this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
2082                        left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
2083                        top: event.pageY - offset.top -
2084                                ( closestHandle.height() / 2 ) -
2085                                ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
2086                                ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
2087                                ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
2088                };
2089
2090                this._slide( event, index, normValue );
2091                this._animateOff = true;
2092                return true;
2093        },
2094
2095        _mouseStart: function( event ) {
2096                return true;
2097        },
2098
2099        _mouseDrag: function( event ) {
2100                var position = { x: event.pageX, y: event.pageY },
2101                        normValue = this._normValueFromMouse( position );
2102               
2103                this._slide( event, this._handleIndex, normValue );
2104
2105                return false;
2106        },
2107
2108        _mouseStop: function( event ) {
2109                this.handles.removeClass( "ui-state-active" );
2110                this._mouseSliding = false;
2111
2112                this._stop( event, this._handleIndex );
2113                this._change( event, this._handleIndex );
2114
2115                this._handleIndex = null;
2116                this._clickOffset = null;
2117                this._animateOff = false;
2118
2119                return false;
2120        },
2121       
2122        _detectOrientation: function() {
2123                this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
2124        },
2125
2126        _normValueFromMouse: function( position ) {
2127                var pixelTotal,
2128                        pixelMouse,
2129                        percentMouse,
2130                        valueTotal,
2131                        valueMouse;
2132
2133                if ( this.orientation === "horizontal" ) {
2134                        pixelTotal = this.elementSize.width;
2135                        pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
2136                } else {
2137                        pixelTotal = this.elementSize.height;
2138                        pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
2139                }
2140
2141                percentMouse = ( pixelMouse / pixelTotal );
2142                if ( percentMouse > 1 ) {
2143                        percentMouse = 1;
2144                }
2145                if ( percentMouse < 0 ) {
2146                        percentMouse = 0;
2147                }
2148                if ( this.orientation === "vertical" ) {
2149                        percentMouse = 1 - percentMouse;
2150                }
2151
2152                valueTotal = this._valueMax() - this._valueMin();
2153                valueMouse = this._valueMin() + percentMouse * valueTotal;
2154
2155                return this._trimAlignValue( valueMouse );
2156        },
2157
2158        _start: function( event, index ) {
2159                var uiHash = {
2160                        handle: this.handles[ index ],
2161                        value: this.value()
2162                };
2163                if ( this.options.values && this.options.values.length ) {
2164                        uiHash.value = this.values( index );
2165                        uiHash.values = this.values();
2166                }
2167                return this._trigger( "start", event, uiHash );
2168        },
2169
2170        _slide: function( event, index, newVal ) {
2171                var otherVal,
2172                        newValues,
2173                        allowed;
2174
2175                if ( this.options.values && this.options.values.length ) {
2176                        otherVal = this.values( index ? 0 : 1 );
2177
2178                        if ( ( this.options.values.length === 2 && this.options.range === true ) &&
2179                                        ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
2180                                ) {
2181                                newVal = otherVal;
2182                        }
2183
2184                        if ( newVal !== this.values( index ) ) {
2185                                newValues = this.values();
2186                                newValues[ index ] = newVal;
2187                                // A slide can be canceled by returning false from the slide callback
2188                                allowed = this._trigger( "slide", event, {
2189                                        handle: this.handles[ index ],
2190                                        value: newVal,
2191                                        values: newValues
2192                                } );
2193                                otherVal = this.values( index ? 0 : 1 );
2194                                if ( allowed !== false ) {
2195                                        this.values( index, newVal, true );
2196                                }
2197                        }
2198                } else {
2199                        if ( newVal !== this.value() ) {
2200                                // A slide can be canceled by returning false from the slide callback
2201                                allowed = this._trigger( "slide", event, {
2202                                        handle: this.handles[ index ],
2203                                        value: newVal
2204                                } );
2205                                if ( allowed !== false ) {
2206                                        this.value( newVal );
2207                                }
2208                        }
2209                }
2210        },
2211
2212        _stop: function( event, index ) {
2213                var uiHash = {
2214                        handle: this.handles[ index ],
2215                        value: this.value()
2216                };
2217                if ( this.options.values && this.options.values.length ) {
2218                        uiHash.value = this.values( index );
2219                        uiHash.values = this.values();
2220                }
2221
2222                this._trigger( "stop", event, uiHash );
2223        },
2224
2225        _change: function( event, index ) {
2226                if ( !this._keySliding && !this._mouseSliding ) {
2227                        var uiHash = {
2228                                handle: this.handles[ index ],
2229                                value: this.value()
2230                        };
2231                        if ( this.options.values && this.options.values.length ) {
2232                                uiHash.value = this.values( index );
2233                                uiHash.values = this.values();
2234                        }
2235
2236                        this._trigger( "change", event, uiHash );
2237                }
2238        },
2239
2240        value: function( newValue ) {
2241                if ( arguments.length ) {
2242                        this.options.value = this._trimAlignValue( newValue );
2243                        this._refreshValue();
2244                        this._change( null, 0 );
2245                }
2246
2247                return this._value();
2248        },
2249
2250        values: function( index, newValue ) {
2251                var vals,
2252                        newValues,
2253                        i;
2254
2255                if ( arguments.length > 1 ) {
2256                        this.options.values[ index ] = this._trimAlignValue( newValue );
2257                        this._refreshValue();
2258                        this._change( null, index );
2259                }
2260
2261                if ( arguments.length ) {
2262                        if ( $.isArray( arguments[ 0 ] ) ) {
2263                                vals = this.options.values;
2264                                newValues = arguments[ 0 ];
2265                                for ( i = 0; i < vals.length; i += 1 ) {
2266                                        vals[ i ] = this._trimAlignValue( newValues[ i ] );
2267                                        this._change( null, i );
2268                                }
2269                                this._refreshValue();
2270                        } else {
2271                                if ( this.options.values && this.options.values.length ) {
2272                                        return this._values( index );
2273                                } else {
2274                                        return this.value();
2275                                }
2276                        }
2277                } else {
2278                        return this._values();
2279                }
2280        },
2281
2282        _setOption: function( key, value ) {
2283                var i,
2284                        valsLength = 0;
2285
2286                if ( $.isArray( this.options.values ) ) {
2287                        valsLength = this.options.values.length;
2288                }
2289
2290                $.Widget.prototype._setOption.apply( this, arguments );
2291
2292                switch ( key ) {
2293                        case "disabled":
2294                                if ( value ) {
2295                                        this.handles.filter( ".ui-state-focus" ).blur();
2296                                        this.handles.removeClass( "ui-state-hover" );
2297                                        this.handles.attr( "disabled", "disabled" );
2298                                        this.element.addClass( "ui-disabled" );
2299                                } else {
2300                                        this.handles.removeAttr( "disabled" );
2301                                        this.element.removeClass( "ui-disabled" );
2302                                }
2303                                break;
2304                        case "orientation":
2305                                this._detectOrientation();
2306                                this.element
2307                                        .removeClass( "ui-slider-horizontal ui-slider-vertical" )
2308                                        .addClass( "ui-slider-" + this.orientation );
2309                                this._refreshValue();
2310                                break;
2311                        case "value":
2312                                this._animateOff = true;
2313                                this._refreshValue();
2314                                this._change( null, 0 );
2315                                this._animateOff = false;
2316                                break;
2317                        case "values":
2318                                this._animateOff = true;
2319                                this._refreshValue();
2320                                for ( i = 0; i < valsLength; i += 1 ) {
2321                                        this._change( null, i );
2322                                }
2323                                this._animateOff = false;
2324                                break;
2325                }
2326        },
2327
2328        //internal value getter
2329        // _value() returns value trimmed by min and max, aligned by step
2330        _value: function() {
2331                var val = this.options.value;
2332                val = this._trimAlignValue( val );
2333
2334                return val;
2335        },
2336
2337        //internal values getter
2338        // _values() returns array of values trimmed by min and max, aligned by step
2339        // _values( index ) returns single value trimmed by min and max, aligned by step
2340        _values: function( index ) {
2341                var val,
2342                        vals,
2343                        i;
2344
2345                if ( arguments.length ) {
2346                        val = this.options.values[ index ];
2347                        val = this._trimAlignValue( val );
2348
2349                        return val;
2350                } else {
2351                        // .slice() creates a copy of the array
2352                        // this copy gets trimmed by min and max and then returned
2353                        vals = this.options.values.slice();
2354                        for ( i = 0; i < vals.length; i+= 1) {
2355                                vals[ i ] = this._trimAlignValue( vals[ i ] );
2356                        }
2357
2358                        return vals;
2359                }
2360        },
2361       
2362        // returns the step-aligned value that val is closest to, between (inclusive) min and max
2363        _trimAlignValue: function( val ) {
2364                if ( val < this._valueMin() ) {
2365                        return this._valueMin();
2366                }
2367                if ( val > this._valueMax() ) {
2368                        return this._valueMax();
2369                }
2370                var step = ( this.options.step > 0 ) ? this.options.step : 1,
2371                        valModStep = val % step,
2372                        alignValue = val - valModStep;
2373
2374                if ( Math.abs(valModStep) * 2 >= step ) {
2375                        alignValue += ( valModStep > 0 ) ? step : ( -step );
2376                }
2377
2378                // Since JavaScript has problems with large floats, round
2379                // the final value to 5 digits after the decimal point (see #4124)
2380                return parseFloat( alignValue.toFixed(5) );
2381        },
2382
2383        _valueMin: function() {
2384                return this.options.min;
2385        },
2386
2387        _valueMax: function() {
2388                return this.options.max;
2389        },
2390       
2391        _refreshValue: function() {
2392                var oRange = this.options.range,
2393                        o = this.options,
2394                        self = this,
2395                        animate = ( !this._animateOff ) ? o.animate : false,
2396                        valPercent,
2397                        _set = {},
2398                        lastValPercent,
2399                        value,
2400                        valueMin,
2401                        valueMax;
2402
2403                if ( this.options.values && this.options.values.length ) {
2404                        this.handles.each(function( i, j ) {
2405                                valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
2406                                _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
2407                                $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
2408                                if ( self.options.range === true ) {
2409                                        if ( self.orientation === "horizontal" ) {
2410                                                if ( i === 0 ) {
2411                                                        self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
2412                                                }
2413                                                if ( i === 1 ) {
2414                                                        self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
2415                                                }
2416                                        } else {
2417                                                if ( i === 0 ) {
2418                                                        self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
2419                                                }
2420                                                if ( i === 1 ) {
2421                                                        self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
2422                                                }
2423                                        }
2424                                }
2425                                lastValPercent = valPercent;
2426                        });
2427                } else {
2428                        value = this.value();
2429                        valueMin = this._valueMin();
2430                        valueMax = this._valueMax();
2431                        valPercent = ( valueMax !== valueMin ) ?
2432                                        ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
2433                                        0;
2434                        _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
2435                        this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
2436
2437                        if ( oRange === "min" && this.orientation === "horizontal" ) {
2438                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
2439                        }
2440                        if ( oRange === "max" && this.orientation === "horizontal" ) {
2441                                this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
2442                        }
2443                        if ( oRange === "min" && this.orientation === "vertical" ) {
2444                                this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
2445                        }
2446                        if ( oRange === "max" && this.orientation === "vertical" ) {
2447                                this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
2448                        }
2449                }
2450        }
2451
2452});
2453
2454$.extend( $.ui.slider, {
2455        version: "1.8.5"
2456});
2457
2458}(jQuery));
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。