comparison Agendas/trunk/src/Agendas.Web/Scripts/jquery-ui.js @ 10:c62b77fc33f4

website inicial
author nelo@MTEySS.neluz.int
date Sun, 13 Mar 2011 18:51:06 -0300
parents
children
comparison
equal deleted inserted replaced
9:c90492faf268 10:c62b77fc33f4
1 /*!
2 * Note: While Microsoft is not the author of this file, Microsoft is
3 * offering you a license subject to the terms of the Microsoft Software
4 * License Terms for Microsoft ASP.NET Model View Controller 3.
5 * Microsoft reserves all other rights. The notices below are provided
6 * for informational purposes only and are not the license terms under
7 * which Microsoft distributed this file.
8 *
9 * jQuery UI 1.8.7
10 *
11 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
12 *
13 * http://docs.jquery.com/UI
14 */
15 (function( $, undefined ) {
16
17 // prevent duplicate loading
18 // this is only a problem because we proxy existing functions
19 // and we don't want to double proxy them
20 $.ui = $.ui || {};
21 if ( $.ui.version ) {
22 return;
23 }
24
25 $.extend( $.ui, {
26 version: "1.8.7",
27
28 keyCode: {
29 ALT: 18,
30 BACKSPACE: 8,
31 CAPS_LOCK: 20,
32 COMMA: 188,
33 COMMAND: 91,
34 COMMAND_LEFT: 91, // COMMAND
35 COMMAND_RIGHT: 93,
36 CONTROL: 17,
37 DELETE: 46,
38 DOWN: 40,
39 END: 35,
40 ENTER: 13,
41 ESCAPE: 27,
42 HOME: 36,
43 INSERT: 45,
44 LEFT: 37,
45 MENU: 93, // COMMAND_RIGHT
46 NUMPAD_ADD: 107,
47 NUMPAD_DECIMAL: 110,
48 NUMPAD_DIVIDE: 111,
49 NUMPAD_ENTER: 108,
50 NUMPAD_MULTIPLY: 106,
51 NUMPAD_SUBTRACT: 109,
52 PAGE_DOWN: 34,
53 PAGE_UP: 33,
54 PERIOD: 190,
55 RIGHT: 39,
56 SHIFT: 16,
57 SPACE: 32,
58 TAB: 9,
59 UP: 38,
60 WINDOWS: 91 // COMMAND
61 }
62 });
63
64 // plugins
65 $.fn.extend({
66 _focus: $.fn.focus,
67 focus: function( delay, fn ) {
68 return typeof delay === "number" ?
69 this.each(function() {
70 var elem = this;
71 setTimeout(function() {
72 $( elem ).focus();
73 if ( fn ) {
74 fn.call( elem );
75 }
76 }, delay );
77 }) :
78 this._focus.apply( this, arguments );
79 },
80
81 scrollParent: function() {
82 var scrollParent;
83 if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
84 scrollParent = this.parents().filter(function() {
85 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));
86 }).eq(0);
87 } else {
88 scrollParent = this.parents().filter(function() {
89 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
90 }).eq(0);
91 }
92
93 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
94 },
95
96 zIndex: function( zIndex ) {
97 if ( zIndex !== undefined ) {
98 return this.css( "zIndex", zIndex );
99 }
100
101 if ( this.length ) {
102 var elem = $( this[ 0 ] ), position, value;
103 while ( elem.length && elem[ 0 ] !== document ) {
104 // Ignore z-index if position is set to a value where z-index is ignored by the browser
105 // This makes behavior of this function consistent across browsers
106 // WebKit always returns auto if the element is positioned
107 position = elem.css( "position" );
108 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
109 // IE returns 0 when zIndex is not specified
110 // other browsers return a string
111 // we ignore the case of nested elements with an explicit value of 0
112 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
113 value = parseInt( elem.css( "zIndex" ), 10 );
114 if ( !isNaN( value ) && value !== 0 ) {
115 return value;
116 }
117 }
118 elem = elem.parent();
119 }
120 }
121
122 return 0;
123 },
124
125 disableSelection: function() {
126 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
127 ".ui-disableSelection", function( event ) {
128 event.preventDefault();
129 });
130 },
131
132 enableSelection: function() {
133 return this.unbind( ".ui-disableSelection" );
134 }
135 });
136
137 $.each( [ "Width", "Height" ], function( i, name ) {
138 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
139 type = name.toLowerCase(),
140 orig = {
141 innerWidth: $.fn.innerWidth,
142 innerHeight: $.fn.innerHeight,
143 outerWidth: $.fn.outerWidth,
144 outerHeight: $.fn.outerHeight
145 };
146
147 function reduce( elem, size, border, margin ) {
148 $.each( side, function() {
149 size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
150 if ( border ) {
151 size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
152 }
153 if ( margin ) {
154 size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
155 }
156 });
157 return size;
158 }
159
160 $.fn[ "inner" + name ] = function( size ) {
161 if ( size === undefined ) {
162 return orig[ "inner" + name ].call( this );
163 }
164
165 return this.each(function() {
166 $( this ).css( type, reduce( this, size ) + "px" );
167 });
168 };
169
170 $.fn[ "outer" + name] = function( size, margin ) {
171 if ( typeof size !== "number" ) {
172 return orig[ "outer" + name ].call( this, size );
173 }
174
175 return this.each(function() {
176 $( this).css( type, reduce( this, size, true, margin ) + "px" );
177 });
178 };
179 });
180
181 // selectors
182 function visible( element ) {
183 return !$( element ).parents().andSelf().filter(function() {
184 return $.curCSS( this, "visibility" ) === "hidden" ||
185 $.expr.filters.hidden( this );
186 }).length;
187 }
188
189 $.extend( $.expr[ ":" ], {
190 data: function( elem, i, match ) {
191 return !!$.data( elem, match[ 3 ] );
192 },
193
194 focusable: function( element ) {
195 var nodeName = element.nodeName.toLowerCase(),
196 tabIndex = $.attr( element, "tabindex" );
197 if ( "area" === nodeName ) {
198 var map = element.parentNode,
199 mapName = map.name,
200 img;
201 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
202 return false;
203 }
204 img = $( "img[usemap=#" + mapName + "]" )[0];
205 return !!img && visible( img );
206 }
207 return ( /input|select|textarea|button|object/.test( nodeName )
208 ? !element.disabled
209 : "a" == nodeName
210 ? element.href || !isNaN( tabIndex )
211 : !isNaN( tabIndex ))
212 // the element and all of its ancestors must be visible
213 && visible( element );
214 },
215
216 tabbable: function( element ) {
217 var tabIndex = $.attr( element, "tabindex" );
218 return ( isNaN( tabIndex ) || tabIndex >= 0 ) && $( element ).is( ":focusable" );
219 }
220 });
221
222 // support
223 $(function() {
224 var body = document.body,
225 div = body.appendChild( div = document.createElement( "div" ) );
226
227 $.extend( div.style, {
228 minHeight: "100px",
229 height: "auto",
230 padding: 0,
231 borderWidth: 0
232 });
233
234 $.support.minHeight = div.offsetHeight === 100;
235 $.support.selectstart = "onselectstart" in div;
236
237 // set display to none to avoid a layout bug in IE
238 // http://dev.jquery.com/ticket/4014
239 body.removeChild( div ).style.display = "none";
240 });
241
242
243
244
245
246 // deprecated
247 $.extend( $.ui, {
248 // $.ui.plugin is deprecated. Use the proxy pattern instead.
249 plugin: {
250 add: function( module, option, set ) {
251 var proto = $.ui[ module ].prototype;
252 for ( var i in set ) {
253 proto.plugins[ i ] = proto.plugins[ i ] || [];
254 proto.plugins[ i ].push( [ option, set[ i ] ] );
255 }
256 },
257 call: function( instance, name, args ) {
258 var set = instance.plugins[ name ];
259 if ( !set || !instance.element[ 0 ].parentNode ) {
260 return;
261 }
262
263 for ( var i = 0; i < set.length; i++ ) {
264 if ( instance.options[ set[ i ][ 0 ] ] ) {
265 set[ i ][ 1 ].apply( instance.element, args );
266 }
267 }
268 }
269 },
270
271 // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
272 contains: function( a, b ) {
273 return document.compareDocumentPosition ?
274 a.compareDocumentPosition( b ) & 16 :
275 a !== b && a.contains( b );
276 },
277
278 // only used by resizable
279 hasScroll: function( el, a ) {
280
281 //If overflow is hidden, the element might have extra content, but the user wants to hide it
282 if ( $( el ).css( "overflow" ) === "hidden") {
283 return false;
284 }
285
286 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
287 has = false;
288
289 if ( el[ scroll ] > 0 ) {
290 return true;
291 }
292
293 // TODO: determine which cases actually cause this to happen
294 // if the element doesn't have the scroll set, see if it's possible to
295 // set the scroll
296 el[ scroll ] = 1;
297 has = ( el[ scroll ] > 0 );
298 el[ scroll ] = 0;
299 return has;
300 },
301
302 // these are odd functions, fix the API or move into individual plugins
303 isOverAxis: function( x, reference, size ) {
304 //Determines when x coordinate is over "b" element axis
305 return ( x > reference ) && ( x < ( reference + size ) );
306 },
307 isOver: function( y, x, top, left, height, width ) {
308 //Determines when x, y coordinates is over "b" element
309 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
310 }
311 });
312
313 })( jQuery );
314 /*!
315 * Note: While Microsoft is not the author of this file, Microsoft is
316 * offering you a license subject to the terms of the Microsoft Software
317 * License Terms for Microsoft ASP.NET Model View Controller 3.
318 * Microsoft reserves all other rights. The notices below are provided
319 * for informational purposes only and are not the license terms under
320 * which Microsoft distributed this file.
321 *
322 * jQuery UI Widget 1.8.7
323 *
324 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
325 *
326 * http://docs.jquery.com/UI/Widget
327 */
328 (function( $, undefined ) {
329
330 // jQuery 1.4+
331 if ( $.cleanData ) {
332 var _cleanData = $.cleanData;
333 $.cleanData = function( elems ) {
334 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
335 $( elem ).triggerHandler( "remove" );
336 }
337 _cleanData( elems );
338 };
339 } else {
340 var _remove = $.fn.remove;
341 $.fn.remove = function( selector, keepData ) {
342 return this.each(function() {
343 if ( !keepData ) {
344 if ( !selector || $.filter( selector, [ this ] ).length ) {
345 $( "*", this ).add( [ this ] ).each(function() {
346 $( this ).triggerHandler( "remove" );
347 });
348 }
349 }
350 return _remove.call( $(this), selector, keepData );
351 });
352 };
353 }
354
355 $.widget = function( name, base, prototype ) {
356 var namespace = name.split( "." )[ 0 ],
357 fullName;
358 name = name.split( "." )[ 1 ];
359 fullName = namespace + "-" + name;
360
361 if ( !prototype ) {
362 prototype = base;
363 base = $.Widget;
364 }
365
366 // create selector for plugin
367 $.expr[ ":" ][ fullName ] = function( elem ) {
368 return !!$.data( elem, name );
369 };
370
371 $[ namespace ] = $[ namespace ] || {};
372 $[ namespace ][ name ] = function( options, element ) {
373 // allow instantiation without initializing for simple inheritance
374 if ( arguments.length ) {
375 this._createWidget( options, element );
376 }
377 };
378
379 var basePrototype = new base();
380 // we need to make the options hash a property directly on the new instance
381 // otherwise we'll modify the options hash on the prototype that we're
382 // inheriting from
383 // $.each( basePrototype, function( key, val ) {
384 // if ( $.isPlainObject(val) ) {
385 // basePrototype[ key ] = $.extend( {}, val );
386 // }
387 // });
388 basePrototype.options = $.extend( true, {}, basePrototype.options );
389 $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
390 namespace: namespace,
391 widgetName: name,
392 widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
393 widgetBaseClass: fullName
394 }, prototype );
395
396 $.widget.bridge( name, $[ namespace ][ name ] );
397 };
398
399 $.widget.bridge = function( name, object ) {
400 $.fn[ name ] = function( options ) {
401 var isMethodCall = typeof options === "string",
402 args = Array.prototype.slice.call( arguments, 1 ),
403 returnValue = this;
404
405 // allow multiple hashes to be passed on init
406 options = !isMethodCall && args.length ?
407 $.extend.apply( null, [ true, options ].concat(args) ) :
408 options;
409
410 // prevent calls to internal methods
411 if ( isMethodCall && options.charAt( 0 ) === "_" ) {
412 return returnValue;
413 }
414
415 if ( isMethodCall ) {
416 this.each(function() {
417 var instance = $.data( this, name ),
418 methodValue = instance && $.isFunction( instance[options] ) ?
419 instance[ options ].apply( instance, args ) :
420 instance;
421 // TODO: add this back in 1.9 and use $.error() (see #5972)
422 // if ( !instance ) {
423 // throw "cannot call methods on " + name + " prior to initialization; " +
424 // "attempted to call method '" + options + "'";
425 // }
426 // if ( !$.isFunction( instance[options] ) ) {
427 // throw "no such method '" + options + "' for " + name + " widget instance";
428 // }
429 // var methodValue = instance[ options ].apply( instance, args );
430 if ( methodValue !== instance && methodValue !== undefined ) {
431 returnValue = methodValue;
432 return false;
433 }
434 });
435 } else {
436 this.each(function() {
437 var instance = $.data( this, name );
438 if ( instance ) {
439 instance.option( options || {} )._init();
440 } else {
441 $.data( this, name, new object( options, this ) );
442 }
443 });
444 }
445
446 return returnValue;
447 };
448 };
449
450 $.Widget = function( options, element ) {
451 // allow instantiation without initializing for simple inheritance
452 if ( arguments.length ) {
453 this._createWidget( options, element );
454 }
455 };
456
457 $.Widget.prototype = {
458 widgetName: "widget",
459 widgetEventPrefix: "",
460 options: {
461 disabled: false
462 },
463 _createWidget: function( options, element ) {
464 // $.widget.bridge stores the plugin instance, but we do it anyway
465 // so that it's stored even before the _create function runs
466 $.data( element, this.widgetName, this );
467 this.element = $( element );
468 this.options = $.extend( true, {},
469 this.options,
470 this._getCreateOptions(),
471 options );
472
473 var self = this;
474 this.element.bind( "remove." + this.widgetName, function() {
475 self.destroy();
476 });
477
478 this._create();
479 this._trigger( "create" );
480 this._init();
481 },
482 _getCreateOptions: function() {
483 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
484 },
485 _create: function() {},
486 _init: function() {},
487
488 destroy: function() {
489 this.element
490 .unbind( "." + this.widgetName )
491 .removeData( this.widgetName );
492 this.widget()
493 .unbind( "." + this.widgetName )
494 .removeAttr( "aria-disabled" )
495 .removeClass(
496 this.widgetBaseClass + "-disabled " +
497 "ui-state-disabled" );
498 },
499
500 widget: function() {
501 return this.element;
502 },
503
504 option: function( key, value ) {
505 var options = key;
506
507 if ( arguments.length === 0 ) {
508 // don't return a reference to the internal hash
509 return $.extend( {}, this.options );
510 }
511
512 if (typeof key === "string" ) {
513 if ( value === undefined ) {
514 return this.options[ key ];
515 }
516 options = {};
517 options[ key ] = value;
518 }
519
520 this._setOptions( options );
521
522 return this;
523 },
524 _setOptions: function( options ) {
525 var self = this;
526 $.each( options, function( key, value ) {
527 self._setOption( key, value );
528 });
529
530 return this;
531 },
532 _setOption: function( key, value ) {
533 this.options[ key ] = value;
534
535 if ( key === "disabled" ) {
536 this.widget()
537 [ value ? "addClass" : "removeClass"](
538 this.widgetBaseClass + "-disabled" + " " +
539 "ui-state-disabled" )
540 .attr( "aria-disabled", value );
541 }
542
543 return this;
544 },
545
546 enable: function() {
547 return this._setOption( "disabled", false );
548 },
549 disable: function() {
550 return this._setOption( "disabled", true );
551 },
552
553 _trigger: function( type, event, data ) {
554 var callback = this.options[ type ];
555
556 event = $.Event( event );
557 event.type = ( type === this.widgetEventPrefix ?
558 type :
559 this.widgetEventPrefix + type ).toLowerCase();
560 data = data || {};
561
562 // copy original event properties over to the new event
563 // this would happen if we could call $.event.fix instead of $.Event
564 // but we don't have a way to force an event to be fixed multiple times
565 if ( event.originalEvent ) {
566 for ( var i = $.event.props.length, prop; i; ) {
567 prop = $.event.props[ --i ];
568 event[ prop ] = event.originalEvent[ prop ];
569 }
570 }
571
572 this.element.trigger( event, data );
573
574 return !( $.isFunction(callback) &&
575 callback.call( this.element[0], event, data ) === false ||
576 event.isDefaultPrevented() );
577 }
578 };
579
580 })( jQuery );
581 /*!
582 * Note: While Microsoft is not the author of this file, Microsoft is
583 * offering you a license subject to the terms of the Microsoft Software
584 * License Terms for Microsoft ASP.NET Model View Controller 3.
585 * Microsoft reserves all other rights. The notices below are provided
586 * for informational purposes only and are not the license terms under
587 * which Microsoft distributed this file.
588 *
589 * jQuery UI Mouse 1.8.7
590 *
591 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
592 *
593 * http://docs.jquery.com/UI/Mouse
594 *
595 * Depends:
596 * jquery.ui.widget.js
597 */
598 (function( $, undefined ) {
599
600 $.widget("ui.mouse", {
601 options: {
602 cancel: ':input,option',
603 distance: 1,
604 delay: 0
605 },
606 _mouseInit: function() {
607 var self = this;
608
609 this.element
610 .bind('mousedown.'+this.widgetName, function(event) {
611 return self._mouseDown(event);
612 })
613 .bind('click.'+this.widgetName, function(event) {
614 if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
615 $.removeData(event.target, self.widgetName + '.preventClickEvent');
616 event.stopImmediatePropagation();
617 return false;
618 }
619 });
620
621 this.started = false;
622 },
623
624 // TODO: make sure destroying one instance of mouse doesn't mess with
625 // other instances of mouse
626 _mouseDestroy: function() {
627 this.element.unbind('.'+this.widgetName);
628 },
629
630 _mouseDown: function(event) {
631 // don't let more than one widget handle mouseStart
632 // TODO: figure out why we have to use originalEvent
633 event.originalEvent = event.originalEvent || {};
634 if (event.originalEvent.mouseHandled) { return; }
635
636 // we may have missed mouseup (out of window)
637 (this._mouseStarted && this._mouseUp(event));
638
639 this._mouseDownEvent = event;
640
641 var self = this,
642 btnIsLeft = (event.which == 1),
643 elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
644 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
645 return true;
646 }
647
648 this.mouseDelayMet = !this.options.delay;
649 if (!this.mouseDelayMet) {
650 this._mouseDelayTimer = setTimeout(function() {
651 self.mouseDelayMet = true;
652 }, this.options.delay);
653 }
654
655 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
656 this._mouseStarted = (this._mouseStart(event) !== false);
657 if (!this._mouseStarted) {
658 event.preventDefault();
659 return true;
660 }
661 }
662
663 // these delegates are required to keep context
664 this._mouseMoveDelegate = function(event) {
665 return self._mouseMove(event);
666 };
667 this._mouseUpDelegate = function(event) {
668 return self._mouseUp(event);
669 };
670 $(document)
671 .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
672 .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
673
674 event.preventDefault();
675 event.originalEvent.mouseHandled = true;
676 return true;
677 },
678
679 _mouseMove: function(event) {
680 // IE mouseup check - mouseup happened when mouse was out of window
681 if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
682 return this._mouseUp(event);
683 }
684
685 if (this._mouseStarted) {
686 this._mouseDrag(event);
687 return event.preventDefault();
688 }
689
690 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
691 this._mouseStarted =
692 (this._mouseStart(this._mouseDownEvent, event) !== false);
693 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
694 }
695
696 return !this._mouseStarted;
697 },
698
699 _mouseUp: function(event) {
700 $(document)
701 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
702 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
703
704 if (this._mouseStarted) {
705 this._mouseStarted = false;
706
707 if (event.target == this._mouseDownEvent.target) {
708 $.data(event.target, this.widgetName + '.preventClickEvent', true);
709 }
710
711 this._mouseStop(event);
712 }
713
714 return false;
715 },
716
717 _mouseDistanceMet: function(event) {
718 return (Math.max(
719 Math.abs(this._mouseDownEvent.pageX - event.pageX),
720 Math.abs(this._mouseDownEvent.pageY - event.pageY)
721 ) >= this.options.distance
722 );
723 },
724
725 _mouseDelayMet: function(event) {
726 return this.mouseDelayMet;
727 },
728
729 // These are placeholder methods, to be overriden by extending plugin
730 _mouseStart: function(event) {},
731 _mouseDrag: function(event) {},
732 _mouseStop: function(event) {},
733 _mouseCapture: function(event) { return true; }
734 });
735
736 })(jQuery);
737 /*
738 * Note: While Microsoft is not the author of this file, Microsoft is
739 * offering you a license subject to the terms of the Microsoft Software
740 * License Terms for Microsoft ASP.NET Model View Controller 3.
741 * Microsoft reserves all other rights. The notices below are provided
742 * for informational purposes only and are not the license terms under
743 * which Microsoft distributed this file.
744 *
745 * jQuery UI Draggable 1.8.7
746 *
747 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
748 *
749 * http://docs.jquery.com/UI/Draggables
750 *
751 * Depends:
752 * jquery.ui.core.js
753 * jquery.ui.mouse.js
754 * jquery.ui.widget.js
755 */
756 (function( $, undefined ) {
757
758 $.widget("ui.draggable", $.ui.mouse, {
759 widgetEventPrefix: "drag",
760 options: {
761 addClasses: true,
762 appendTo: "parent",
763 axis: false,
764 connectToSortable: false,
765 containment: false,
766 cursor: "auto",
767 cursorAt: false,
768 grid: false,
769 handle: false,
770 helper: "original",
771 iframeFix: false,
772 opacity: false,
773 refreshPositions: false,
774 revert: false,
775 revertDuration: 500,
776 scope: "default",
777 scroll: true,
778 scrollSensitivity: 20,
779 scrollSpeed: 20,
780 snap: false,
781 snapMode: "both",
782 snapTolerance: 20,
783 stack: false,
784 zIndex: false
785 },
786 _create: function() {
787
788 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
789 this.element[0].style.position = 'relative';
790
791 (this.options.addClasses && this.element.addClass("ui-draggable"));
792 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
793
794 this._mouseInit();
795
796 },
797
798 destroy: function() {
799 if(!this.element.data('draggable')) return;
800 this.element
801 .removeData("draggable")
802 .unbind(".draggable")
803 .removeClass("ui-draggable"
804 + " ui-draggable-dragging"
805 + " ui-draggable-disabled");
806 this._mouseDestroy();
807
808 return this;
809 },
810
811 _mouseCapture: function(event) {
812
813 var o = this.options;
814
815 // among others, prevent a drag on a resizable-handle
816 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
817 return false;
818
819 //Quit if we're not on a valid handle
820 this.handle = this._getHandle(event);
821 if (!this.handle)
822 return false;
823
824 return true;
825
826 },
827
828 _mouseStart: function(event) {
829
830 var o = this.options;
831
832 //Create and append the visible helper
833 this.helper = this._createHelper(event);
834
835 //Cache the helper size
836 this._cacheHelperProportions();
837
838 //If ddmanager is used for droppables, set the global draggable
839 if($.ui.ddmanager)
840 $.ui.ddmanager.current = this;
841
842 /*
843 * - Position generation -
844 * This block generates everything position related - it's the core of draggables.
845 */
846
847 //Cache the margins of the original element
848 this._cacheMargins();
849
850 //Store the helper's css position
851 this.cssPosition = this.helper.css("position");
852 this.scrollParent = this.helper.scrollParent();
853
854 //The element's absolute position on the page minus margins
855 this.offset = this.positionAbs = this.element.offset();
856 this.offset = {
857 top: this.offset.top - this.margins.top,
858 left: this.offset.left - this.margins.left
859 };
860
861 $.extend(this.offset, {
862 click: { //Where the click happened, relative to the element
863 left: event.pageX - this.offset.left,
864 top: event.pageY - this.offset.top
865 },
866 parent: this._getParentOffset(),
867 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
868 });
869
870 //Generate the original position
871 this.originalPosition = this.position = this._generatePosition(event);
872 this.originalPageX = event.pageX;
873 this.originalPageY = event.pageY;
874
875 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
876 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
877
878 //Set a containment if given in the options
879 if(o.containment)
880 this._setContainment();
881
882 //Trigger event + callbacks
883 if(this._trigger("start", event) === false) {
884 this._clear();
885 return false;
886 }
887
888 //Recache the helper size
889 this._cacheHelperProportions();
890
891 //Prepare the droppable offsets
892 if ($.ui.ddmanager && !o.dropBehaviour)
893 $.ui.ddmanager.prepareOffsets(this, event);
894
895 this.helper.addClass("ui-draggable-dragging");
896 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
897 return true;
898 },
899
900 _mouseDrag: function(event, noPropagation) {
901
902 //Compute the helpers position
903 this.position = this._generatePosition(event);
904 this.positionAbs = this._convertPositionTo("absolute");
905
906 //Call plugins and callbacks and use the resulting position if something is returned
907 if (!noPropagation) {
908 var ui = this._uiHash();
909 if(this._trigger('drag', event, ui) === false) {
910 this._mouseUp({});
911 return false;
912 }
913 this.position = ui.position;
914 }
915
916 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
917 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
918 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
919
920 return false;
921 },
922
923 _mouseStop: function(event) {
924
925 //If we are using droppables, inform the manager about the drop
926 var dropped = false;
927 if ($.ui.ddmanager && !this.options.dropBehaviour)
928 dropped = $.ui.ddmanager.drop(this, event);
929
930 //if a drop comes from outside (a sortable)
931 if(this.dropped) {
932 dropped = this.dropped;
933 this.dropped = false;
934 }
935
936 //if the original element is removed, don't bother to continue
937 if(!this.element[0] || !this.element[0].parentNode)
938 return false;
939
940 if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
941 var self = this;
942 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
943 if(self._trigger("stop", event) !== false) {
944 self._clear();
945 }
946 });
947 } else {
948 if(this._trigger("stop", event) !== false) {
949 this._clear();
950 }
951 }
952
953 return false;
954 },
955
956 cancel: function() {
957
958 if(this.helper.is(".ui-draggable-dragging")) {
959 this._mouseUp({});
960 } else {
961 this._clear();
962 }
963
964 return this;
965
966 },
967
968 _getHandle: function(event) {
969
970 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
971 $(this.options.handle, this.element)
972 .find("*")
973 .andSelf()
974 .each(function() {
975 if(this == event.target) handle = true;
976 });
977
978 return handle;
979
980 },
981
982 _createHelper: function(event) {
983
984 var o = this.options;
985 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
986
987 if(!helper.parents('body').length)
988 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
989
990 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
991 helper.css("position", "absolute");
992
993 return helper;
994
995 },
996
997 _adjustOffsetFromHelper: function(obj) {
998 if (typeof obj == 'string') {
999 obj = obj.split(' ');
1000 }
1001 if ($.isArray(obj)) {
1002 obj = {left: +obj[0], top: +obj[1] || 0};
1003 }
1004 if ('left' in obj) {
1005 this.offset.click.left = obj.left + this.margins.left;
1006 }
1007 if ('right' in obj) {
1008 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1009 }
1010 if ('top' in obj) {
1011 this.offset.click.top = obj.top + this.margins.top;
1012 }
1013 if ('bottom' in obj) {
1014 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1015 }
1016 },
1017
1018 _getParentOffset: function() {
1019
1020 //Get the offsetParent and cache its position
1021 this.offsetParent = this.helper.offsetParent();
1022 var po = this.offsetParent.offset();
1023
1024 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1025 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1026 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1027 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1028 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1029 po.left += this.scrollParent.scrollLeft();
1030 po.top += this.scrollParent.scrollTop();
1031 }
1032
1033 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1034 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1035 po = { top: 0, left: 0 };
1036
1037 return {
1038 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1039 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1040 };
1041
1042 },
1043
1044 _getRelativeOffset: function() {
1045
1046 if(this.cssPosition == "relative") {
1047 var p = this.element.position();
1048 return {
1049 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1050 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1051 };
1052 } else {
1053 return { top: 0, left: 0 };
1054 }
1055
1056 },
1057
1058 _cacheMargins: function() {
1059 this.margins = {
1060 left: (parseInt(this.element.css("marginLeft"),10) || 0),
1061 top: (parseInt(this.element.css("marginTop"),10) || 0)
1062 };
1063 },
1064
1065 _cacheHelperProportions: function() {
1066 this.helperProportions = {
1067 width: this.helper.outerWidth(),
1068 height: this.helper.outerHeight()
1069 };
1070 },
1071
1072 _setContainment: function() {
1073
1074 var o = this.options;
1075 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1076 if(o.containment == 'document' || o.containment == 'window') this.containment = [
1077 (o.containment == 'document' ? 0 : $(window).scrollLeft()) - this.offset.relative.left - this.offset.parent.left,
1078 (o.containment == 'document' ? 0 : $(window).scrollTop()) - this.offset.relative.top - this.offset.parent.top,
1079 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1080 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1081 ];
1082
1083 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1084 var ce = $(o.containment)[0]; if(!ce) return;
1085 var co = $(o.containment).offset();
1086 var over = ($(ce).css("overflow") != 'hidden');
1087
1088 this.containment = [
1089 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
1090 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
1091 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,
1092 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
1093 ];
1094 } else if(o.containment.constructor == Array) {
1095 this.containment = o.containment;
1096 }
1097
1098 },
1099
1100 _convertPositionTo: function(d, pos) {
1101
1102 if(!pos) pos = this.position;
1103 var mod = d == "absolute" ? 1 : -1;
1104 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);
1105
1106 return {
1107 top: (
1108 pos.top // The absolute mouse position
1109 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1110 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
1111 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1112 ),
1113 left: (
1114 pos.left // The absolute mouse position
1115 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1116 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
1117 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1118 )
1119 };
1120
1121 },
1122
1123 _generatePosition: function(event) {
1124
1125 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);
1126 var pageX = event.pageX;
1127 var pageY = event.pageY;
1128
1129 /*
1130 * - Position constraining -
1131 * Constrain the position to a mix of grid, containment.
1132 */
1133
1134 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1135
1136 if(this.containment) {
1137 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
1138 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
1139 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
1140 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
1141 }
1142
1143 if(o.grid) {
1144 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
1145 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;
1146
1147 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
1148 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;
1149 }
1150
1151 }
1152
1153 return {
1154 top: (
1155 pageY // The absolute mouse position
1156 - this.offset.click.top // Click offset (relative to the element)
1157 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
1158 - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
1159 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1160 ),
1161 left: (
1162 pageX // The absolute mouse position
1163 - this.offset.click.left // Click offset (relative to the element)
1164 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
1165 - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
1166 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1167 )
1168 };
1169
1170 },
1171
1172 _clear: function() {
1173 this.helper.removeClass("ui-draggable-dragging");
1174 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1175 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
1176 this.helper = null;
1177 this.cancelHelperRemoval = false;
1178 },
1179
1180 // From now on bulk stuff - mainly helpers
1181
1182 _trigger: function(type, event, ui) {
1183 ui = ui || this._uiHash();
1184 $.ui.plugin.call(this, type, [event, ui]);
1185 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1186 return $.Widget.prototype._trigger.call(this, type, event, ui);
1187 },
1188
1189 plugins: {},
1190
1191 _uiHash: function(event) {
1192 return {
1193 helper: this.helper,
1194 position: this.position,
1195 originalPosition: this.originalPosition,
1196 offset: this.positionAbs
1197 };
1198 }
1199
1200 });
1201
1202 $.extend($.ui.draggable, {
1203 version: "1.8.7"
1204 });
1205
1206 $.ui.plugin.add("draggable", "connectToSortable", {
1207 start: function(event, ui) {
1208
1209 var inst = $(this).data("draggable"), o = inst.options,
1210 uiSortable = $.extend({}, ui, { item: inst.element });
1211 inst.sortables = [];
1212 $(o.connectToSortable).each(function() {
1213 var sortable = $.data(this, 'sortable');
1214 if (sortable && !sortable.options.disabled) {
1215 inst.sortables.push({
1216 instance: sortable,
1217 shouldRevert: sortable.options.revert
1218 });
1219 sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache
1220 sortable._trigger("activate", event, uiSortable);
1221 }
1222 });
1223
1224 },
1225 stop: function(event, ui) {
1226
1227 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1228 var inst = $(this).data("draggable"),
1229 uiSortable = $.extend({}, ui, { item: inst.element });
1230
1231 $.each(inst.sortables, function() {
1232 if(this.instance.isOver) {
1233
1234 this.instance.isOver = 0;
1235
1236 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1237 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1238
1239 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1240 if(this.shouldRevert) this.instance.options.revert = true;
1241
1242 //Trigger the stop of the sortable
1243 this.instance._mouseStop(event);
1244
1245 this.instance.options.helper = this.instance.options._helper;
1246
1247 //If the helper has been the original item, restore properties in the sortable
1248 if(inst.options.helper == 'original')
1249 this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1250
1251 } else {
1252 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1253 this.instance._trigger("deactivate", event, uiSortable);
1254 }
1255
1256 });
1257
1258 },
1259 drag: function(event, ui) {
1260
1261 var inst = $(this).data("draggable"), self = this;
1262
1263 var checkPos = function(o) {
1264 var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1265 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1266 var itemHeight = o.height, itemWidth = o.width;
1267 var itemTop = o.top, itemLeft = o.left;
1268
1269 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1270 };
1271
1272 $.each(inst.sortables, function(i) {
1273
1274 //Copy over some variables to allow calling the sortable's native _intersectsWith
1275 this.instance.positionAbs = inst.positionAbs;
1276 this.instance.helperProportions = inst.helperProportions;
1277 this.instance.offset.click = inst.offset.click;
1278
1279 if(this.instance._intersectsWith(this.instance.containerCache)) {
1280
1281 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1282 if(!this.instance.isOver) {
1283
1284 this.instance.isOver = 1;
1285 //Now we fake the start of dragging for the sortable instance,
1286 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1287 //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1288 this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
1289 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1290 this.instance.options.helper = function() { return ui.helper[0]; };
1291
1292 event.target = this.instance.currentItem[0];
1293 this.instance._mouseCapture(event, true);
1294 this.instance._mouseStart(event, true, true);
1295
1296 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1297 this.instance.offset.click.top = inst.offset.click.top;
1298 this.instance.offset.click.left = inst.offset.click.left;
1299 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1300 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1301
1302 inst._trigger("toSortable", event);
1303 inst.dropped = this.instance.element; //draggable revert needs that
1304 //hack so receive/update callbacks work (mostly)
1305 inst.currentItem = inst.element;
1306 this.instance.fromOutside = inst;
1307
1308 }
1309
1310 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1311 if(this.instance.currentItem) this.instance._mouseDrag(event);
1312
1313 } else {
1314
1315 //If it doesn't intersect with the sortable, and it intersected before,
1316 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1317 if(this.instance.isOver) {
1318
1319 this.instance.isOver = 0;
1320 this.instance.cancelHelperRemoval = true;
1321
1322 //Prevent reverting on this forced stop
1323 this.instance.options.revert = false;
1324
1325 // The out event needs to be triggered independently
1326 this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1327
1328 this.instance._mouseStop(event, true);
1329 this.instance.options.helper = this.instance.options._helper;
1330
1331 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1332 this.instance.currentItem.remove();
1333 if(this.instance.placeholder) this.instance.placeholder.remove();
1334
1335 inst._trigger("fromSortable", event);
1336 inst.dropped = false; //draggable revert needs that
1337 }
1338
1339 };
1340
1341 });
1342
1343 }
1344 });
1345
1346 $.ui.plugin.add("draggable", "cursor", {
1347 start: function(event, ui) {
1348 var t = $('body'), o = $(this).data('draggable').options;
1349 if (t.css("cursor")) o._cursor = t.css("cursor");
1350 t.css("cursor", o.cursor);
1351 },
1352 stop: function(event, ui) {
1353 var o = $(this).data('draggable').options;
1354 if (o._cursor) $('body').css("cursor", o._cursor);
1355 }
1356 });
1357
1358 $.ui.plugin.add("draggable", "iframeFix", {
1359 start: function(event, ui) {
1360 var o = $(this).data('draggable').options;
1361 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1362 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1363 .css({
1364 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1365 position: "absolute", opacity: "0.001", zIndex: 1000
1366 })
1367 .css($(this).offset())
1368 .appendTo("body");
1369 });
1370 },
1371 stop: function(event, ui) {
1372 $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
1373 }
1374 });
1375
1376 $.ui.plugin.add("draggable", "opacity", {
1377 start: function(event, ui) {
1378 var t = $(ui.helper), o = $(this).data('draggable').options;
1379 if(t.css("opacity")) o._opacity = t.css("opacity");
1380 t.css('opacity', o.opacity);
1381 },
1382 stop: function(event, ui) {
1383 var o = $(this).data('draggable').options;
1384 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1385 }
1386 });
1387
1388 $.ui.plugin.add("draggable", "scroll", {
1389 start: function(event, ui) {
1390 var i = $(this).data("draggable");
1391 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1392 },
1393 drag: function(event, ui) {
1394
1395 var i = $(this).data("draggable"), o = i.options, scrolled = false;
1396
1397 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1398
1399 if(!o.axis || o.axis != 'x') {
1400 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1401 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1402 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1403 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1404 }
1405
1406 if(!o.axis || o.axis != 'y') {
1407 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1408 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1409 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1410 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1411 }
1412
1413 } else {
1414
1415 if(!o.axis || o.axis != 'x') {
1416 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1417 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1418 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1419 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1420 }
1421
1422 if(!o.axis || o.axis != 'y') {
1423 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1424 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1425 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1426 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1427 }
1428
1429 }
1430
1431 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1432 $.ui.ddmanager.prepareOffsets(i, event);
1433
1434 }
1435 });
1436
1437 $.ui.plugin.add("draggable", "snap", {
1438 start: function(event, ui) {
1439
1440 var i = $(this).data("draggable"), o = i.options;
1441 i.snapElements = [];
1442
1443 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1444 var $t = $(this); var $o = $t.offset();
1445 if(this != i.element[0]) i.snapElements.push({
1446 item: this,
1447 width: $t.outerWidth(), height: $t.outerHeight(),
1448 top: $o.top, left: $o.left
1449 });
1450 });
1451
1452 },
1453 drag: function(event, ui) {
1454
1455 var inst = $(this).data("draggable"), o = inst.options;
1456 var d = o.snapTolerance;
1457
1458 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1459 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1460
1461 for (var i = inst.snapElements.length - 1; i >= 0; i--){
1462
1463 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1464 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1465
1466 //Yes, I know, this is insane ;)
1467 if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
1468 if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1469 inst.snapElements[i].snapping = false;
1470 continue;
1471 }
1472
1473 if(o.snapMode != 'inner') {
1474 var ts = Math.abs(t - y2) <= d;
1475 var bs = Math.abs(b - y1) <= d;
1476 var ls = Math.abs(l - x2) <= d;
1477 var rs = Math.abs(r - x1) <= d;
1478 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1479 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1480 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1481 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1482 }
1483
1484 var first = (ts || bs || ls || rs);
1485
1486 if(o.snapMode != 'outer') {
1487 var ts = Math.abs(t - y1) <= d;
1488 var bs = Math.abs(b - y2) <= d;
1489 var ls = Math.abs(l - x1) <= d;
1490 var rs = Math.abs(r - x2) <= d;
1491 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1492 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1493 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1494 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1495 }
1496
1497 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1498 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1499 inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1500
1501 };
1502
1503 }
1504 });
1505
1506 $.ui.plugin.add("draggable", "stack", {
1507 start: function(event, ui) {
1508
1509 var o = $(this).data("draggable").options;
1510
1511 var group = $.makeArray($(o.stack)).sort(function(a,b) {
1512 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1513 });
1514 if (!group.length) { return; }
1515
1516 var min = parseInt(group[0].style.zIndex) || 0;
1517 $(group).each(function(i) {
1518 this.style.zIndex = min + i;
1519 });
1520
1521 this[0].style.zIndex = min + group.length;
1522
1523 }
1524 });
1525
1526 $.ui.plugin.add("draggable", "zIndex", {
1527 start: function(event, ui) {
1528 var t = $(ui.helper), o = $(this).data("draggable").options;
1529 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1530 t.css('zIndex', o.zIndex);
1531 },
1532 stop: function(event, ui) {
1533 var o = $(this).data("draggable").options;
1534 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1535 }
1536 });
1537
1538 })(jQuery);
1539 /*
1540 * Note: While Microsoft is not the author of this file, Microsoft is
1541 * offering you a license subject to the terms of the Microsoft Software
1542 * License Terms for Microsoft ASP.NET Model View Controller 3.
1543 * Microsoft reserves all other rights. The notices below are provided
1544 * for informational purposes only and are not the license terms under
1545 * which Microsoft distributed this file.
1546 *
1547 * jQuery UI Droppable 1.8.7
1548 *
1549 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
1550 *
1551 * http://docs.jquery.com/UI/Droppables
1552 *
1553 * Depends:
1554 * jquery.ui.core.js
1555 * jquery.ui.widget.js
1556 * jquery.ui.mouse.js
1557 * jquery.ui.draggable.js
1558 */
1559 (function( $, undefined ) {
1560
1561 $.widget("ui.droppable", {
1562 widgetEventPrefix: "drop",
1563 options: {
1564 accept: '*',
1565 activeClass: false,
1566 addClasses: true,
1567 greedy: false,
1568 hoverClass: false,
1569 scope: 'default',
1570 tolerance: 'intersect'
1571 },
1572 _create: function() {
1573
1574 var o = this.options, accept = o.accept;
1575 this.isover = 0; this.isout = 1;
1576
1577 this.accept = $.isFunction(accept) ? accept : function(d) {
1578 return d.is(accept);
1579 };
1580
1581 //Store the droppable's proportions
1582 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1583
1584 // Add the reference and positions to the manager
1585 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1586 $.ui.ddmanager.droppables[o.scope].push(this);
1587
1588 (o.addClasses && this.element.addClass("ui-droppable"));
1589
1590 },
1591
1592 destroy: function() {
1593 var drop = $.ui.ddmanager.droppables[this.options.scope];
1594 for ( var i = 0; i < drop.length; i++ )
1595 if ( drop[i] == this )
1596 drop.splice(i, 1);
1597
1598 this.element
1599 .removeClass("ui-droppable ui-droppable-disabled")
1600 .removeData("droppable")
1601 .unbind(".droppable");
1602
1603 return this;
1604 },
1605
1606 _setOption: function(key, value) {
1607
1608 if(key == 'accept') {
1609 this.accept = $.isFunction(value) ? value : function(d) {
1610 return d.is(value);
1611 };
1612 }
1613 $.Widget.prototype._setOption.apply(this, arguments);
1614 },
1615
1616 _activate: function(event) {
1617 var draggable = $.ui.ddmanager.current;
1618 if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1619 (draggable && this._trigger('activate', event, this.ui(draggable)));
1620 },
1621
1622 _deactivate: function(event) {
1623 var draggable = $.ui.ddmanager.current;
1624 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1625 (draggable && this._trigger('deactivate', event, this.ui(draggable)));
1626 },
1627
1628 _over: function(event) {
1629
1630 var draggable = $.ui.ddmanager.current;
1631 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1632
1633 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1634 if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1635 this._trigger('over', event, this.ui(draggable));
1636 }
1637
1638 },
1639
1640 _out: function(event) {
1641
1642 var draggable = $.ui.ddmanager.current;
1643 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1644
1645 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1646 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1647 this._trigger('out', event, this.ui(draggable));
1648 }
1649
1650 },
1651
1652 _drop: function(event,custom) {
1653
1654 var draggable = custom || $.ui.ddmanager.current;
1655 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1656
1657 var childrenIntersection = false;
1658 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1659 var inst = $.data(this, 'droppable');
1660 if(
1661 inst.options.greedy
1662 && !inst.options.disabled
1663 && inst.options.scope == draggable.options.scope
1664 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1665 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1666 ) { childrenIntersection = true; return false; }
1667 });
1668 if(childrenIntersection) return false;
1669
1670 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1671 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1672 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1673 this._trigger('drop', event, this.ui(draggable));
1674 return this.element;
1675 }
1676
1677 return false;
1678
1679 },
1680
1681 ui: function(c) {
1682 return {
1683 draggable: (c.currentItem || c.element),
1684 helper: c.helper,
1685 position: c.position,
1686 offset: c.positionAbs
1687 };
1688 }
1689
1690 });
1691
1692 $.extend($.ui.droppable, {
1693 version: "1.8.7"
1694 });
1695
1696 $.ui.intersect = function(draggable, droppable, toleranceMode) {
1697
1698 if (!droppable.offset) return false;
1699
1700 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1701 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1702 var l = droppable.offset.left, r = l + droppable.proportions.width,
1703 t = droppable.offset.top, b = t + droppable.proportions.height;
1704
1705 switch (toleranceMode) {
1706 case 'fit':
1707 return (l <= x1 && x2 <= r
1708 && t <= y1 && y2 <= b);
1709 break;
1710 case 'intersect':
1711 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1712 && x2 - (draggable.helperProportions.width / 2) < r // Left Half
1713 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1714 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1715 break;
1716 case 'pointer':
1717 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
1718 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
1719 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
1720 return isOver;
1721 break;
1722 case 'touch':
1723 return (
1724 (y1 >= t && y1 <= b) || // Top edge touching
1725 (y2 >= t && y2 <= b) || // Bottom edge touching
1726 (y1 < t && y2 > b) // Surrounded vertically
1727 ) && (
1728 (x1 >= l && x1 <= r) || // Left edge touching
1729 (x2 >= l && x2 <= r) || // Right edge touching
1730 (x1 < l && x2 > r) // Surrounded horizontally
1731 );
1732 break;
1733 default:
1734 return false;
1735 break;
1736 }
1737
1738 };
1739
1740 /*
1741 This manager tracks offsets of draggables and droppables
1742 */
1743 $.ui.ddmanager = {
1744 current: null,
1745 droppables: { 'default': [] },
1746 prepareOffsets: function(t, event) {
1747
1748 var m = $.ui.ddmanager.droppables[t.options.scope] || [];
1749 var type = event ? event.type : null; // workaround for #2317
1750 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
1751
1752 droppablesLoop: for (var i = 0; i < m.length; i++) {
1753
1754 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
1755 for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
1756 m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
1757
1758 m[i].offset = m[i].element.offset();
1759 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
1760
1761 if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
1762
1763 }
1764
1765 },
1766 drop: function(draggable, event) {
1767
1768 var dropped = false;
1769 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
1770
1771 if(!this.options) return;
1772 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
1773 dropped = dropped || this._drop.call(this, event);
1774
1775 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1776 this.isout = 1; this.isover = 0;
1777 this._deactivate.call(this, event);
1778 }
1779
1780 });
1781 return dropped;
1782
1783 },
1784 drag: function(draggable, event) {
1785
1786 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
1787 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
1788
1789 //Run through all droppables and check their positions based on specific tolerance options
1790 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
1791
1792 if(this.options.disabled || this.greedyChild || !this.visible) return;
1793 var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
1794
1795 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
1796 if(!c) return;
1797
1798 var parentInstance;
1799 if (this.options.greedy) {
1800 var parent = this.element.parents(':data(droppable):eq(0)');
1801 if (parent.length) {
1802 parentInstance = $.data(parent[0], 'droppable');
1803 parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
1804 }
1805 }
1806
1807 // we just moved into a greedy child
1808 if (parentInstance && c == 'isover') {
1809 parentInstance['isover'] = 0;
1810 parentInstance['isout'] = 1;
1811 parentInstance._out.call(parentInstance, event);
1812 }
1813
1814 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
1815 this[c == "isover" ? "_over" : "_out"].call(this, event);
1816
1817 // we just moved out of a greedy child
1818 if (parentInstance && c == 'isout') {
1819 parentInstance['isout'] = 0;
1820 parentInstance['isover'] = 1;
1821 parentInstance._over.call(parentInstance, event);
1822 }
1823 });
1824
1825 }
1826 };
1827
1828 })(jQuery);
1829 /*
1830 * Note: While Microsoft is not the author of this file, Microsoft is
1831 * offering you a license subject to the terms of the Microsoft Software
1832 * License Terms for Microsoft ASP.NET Model View Controller 3.
1833 * Microsoft reserves all other rights. The notices below are provided
1834 * for informational purposes only and are not the license terms under
1835 * which Microsoft distributed this file.
1836 *
1837 * jQuery UI Resizable 1.8.7
1838 *
1839 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
1840 *
1841 * http://docs.jquery.com/UI/Resizables
1842 *
1843 * Depends:
1844 * jquery.ui.core.js
1845 * jquery.ui.mouse.js
1846 * jquery.ui.widget.js
1847 */
1848 (function( $, undefined ) {
1849
1850 $.widget("ui.resizable", $.ui.mouse, {
1851 widgetEventPrefix: "resize",
1852 options: {
1853 alsoResize: false,
1854 animate: false,
1855 animateDuration: "slow",
1856 animateEasing: "swing",
1857 aspectRatio: false,
1858 autoHide: false,
1859 containment: false,
1860 ghost: false,
1861 grid: false,
1862 handles: "e,s,se",
1863 helper: false,
1864 maxHeight: null,
1865 maxWidth: null,
1866 minHeight: 10,
1867 minWidth: 10,
1868 zIndex: 1000
1869 },
1870 _create: function() {
1871
1872 var self = this, o = this.options;
1873 this.element.addClass("ui-resizable");
1874
1875 $.extend(this, {
1876 _aspectRatio: !!(o.aspectRatio),
1877 aspectRatio: o.aspectRatio,
1878 originalElement: this.element,
1879 _proportionallyResizeElements: [],
1880 _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
1881 });
1882
1883 //Wrap the element if it cannot hold child nodes
1884 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
1885
1886 //Opera fix for relative positioning
1887 if (/relative/.test(this.element.css('position')) && $.browser.opera)
1888 this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
1889
1890 //Create a wrapper element and set the wrapper to the new current internal element
1891 this.element.wrap(
1892 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
1893 position: this.element.css('position'),
1894 width: this.element.outerWidth(),
1895 height: this.element.outerHeight(),
1896 top: this.element.css('top'),
1897 left: this.element.css('left')
1898 })
1899 );
1900
1901 //Overwrite the original this.element
1902 this.element = this.element.parent().data(
1903 "resizable", this.element.data('resizable')
1904 );
1905
1906 this.elementIsWrapper = true;
1907
1908 //Move margins to the wrapper
1909 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
1910 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
1911
1912 //Prevent Safari textarea resize
1913 this.originalResizeStyle = this.originalElement.css('resize');
1914 this.originalElement.css('resize', 'none');
1915
1916 //Push the actual element to our proportionallyResize internal array
1917 this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
1918
1919 // avoid IE jump (hard set the margin)
1920 this.originalElement.css({ margin: this.originalElement.css('margin') });
1921
1922 // fix handlers offset
1923 this._proportionallyResize();
1924
1925 }
1926
1927 this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
1928 if(this.handles.constructor == String) {
1929
1930 if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
1931 var n = this.handles.split(","); this.handles = {};
1932
1933 for(var i = 0; i < n.length; i++) {
1934
1935 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
1936 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
1937
1938 // increase zIndex of sw, se, ne, nw axis
1939 //TODO : this modifies original option
1940 if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
1941
1942 //TODO : What's going on here?
1943 if ('se' == handle) {
1944 axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
1945 };
1946
1947 //Insert into internal handles object and append to element
1948 this.handles[handle] = '.ui-resizable-'+handle;
1949 this.element.append(axis);
1950 }
1951
1952 }
1953
1954 this._renderAxis = function(target) {
1955
1956 target = target || this.element;
1957
1958 for(var i in this.handles) {
1959
1960 if(this.handles[i].constructor == String)
1961 this.handles[i] = $(this.handles[i], this.element).show();
1962
1963 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
1964 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
1965
1966 var axis = $(this.handles[i], this.element), padWrapper = 0;
1967
1968 //Checking the correct pad and border
1969 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
1970
1971 //The padding type i have to apply...
1972 var padPos = [ 'padding',
1973 /ne|nw|n/.test(i) ? 'Top' :
1974 /se|sw|s/.test(i) ? 'Bottom' :
1975 /^e$/.test(i) ? 'Right' : 'Left' ].join("");
1976
1977 target.css(padPos, padWrapper);
1978
1979 this._proportionallyResize();
1980
1981 }
1982
1983 //TODO: What's that good for? There's not anything to be executed left
1984 if(!$(this.handles[i]).length)
1985 continue;
1986
1987 }
1988 };
1989
1990 //TODO: make renderAxis a prototype function
1991 this._renderAxis(this.element);
1992
1993 this._handles = $('.ui-resizable-handle', this.element)
1994 .disableSelection();
1995
1996 //Matching axis name
1997 this._handles.mouseover(function() {
1998 if (!self.resizing) {
1999 if (this.className)
2000 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2001 //Axis, default = se
2002 self.axis = axis && axis[1] ? axis[1] : 'se';
2003 }
2004 });
2005
2006 //If we want to auto hide the elements
2007 if (o.autoHide) {
2008 this._handles.hide();
2009 $(this.element)
2010 .addClass("ui-resizable-autohide")
2011 .hover(function() {
2012 $(this).removeClass("ui-resizable-autohide");
2013 self._handles.show();
2014 },
2015 function(){
2016 if (!self.resizing) {
2017 $(this).addClass("ui-resizable-autohide");
2018 self._handles.hide();
2019 }
2020 });
2021 }
2022
2023 //Initialize the mouse interaction
2024 this._mouseInit();
2025
2026 },
2027
2028 destroy: function() {
2029
2030 this._mouseDestroy();
2031
2032 var _destroy = function(exp) {
2033 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2034 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2035 };
2036
2037 //TODO: Unwrap at same DOM position
2038 if (this.elementIsWrapper) {
2039 _destroy(this.element);
2040 var wrapper = this.element;
2041 wrapper.after(
2042 this.originalElement.css({
2043 position: wrapper.css('position'),
2044 width: wrapper.outerWidth(),
2045 height: wrapper.outerHeight(),
2046 top: wrapper.css('top'),
2047 left: wrapper.css('left')
2048 })
2049 ).remove();
2050 }
2051
2052 this.originalElement.css('resize', this.originalResizeStyle);
2053 _destroy(this.originalElement);
2054
2055 return this;
2056 },
2057
2058 _mouseCapture: function(event) {
2059 var handle = false;
2060 for (var i in this.handles) {
2061 if ($(this.handles[i])[0] == event.target) {
2062 handle = true;
2063 }
2064 }
2065
2066 return !this.options.disabled && handle;
2067 },
2068
2069 _mouseStart: function(event) {
2070
2071 var o = this.options, iniPos = this.element.position(), el = this.element;
2072
2073 this.resizing = true;
2074 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2075
2076 // bugfix for http://dev.jquery.com/ticket/1749
2077 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2078 el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2079 }
2080
2081 //Opera fixing relative position
2082 if ($.browser.opera && (/relative/).test(el.css('position')))
2083 el.css({ position: 'relative', top: 'auto', left: 'auto' });
2084
2085 this._renderProxy();
2086
2087 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2088
2089 if (o.containment) {
2090 curleft += $(o.containment).scrollLeft() || 0;
2091 curtop += $(o.containment).scrollTop() || 0;
2092 }
2093
2094 //Store needed variables
2095 this.offset = this.helper.offset();
2096 this.position = { left: curleft, top: curtop };
2097 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2098 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2099 this.originalPosition = { left: curleft, top: curtop };
2100 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2101 this.originalMousePosition = { left: event.pageX, top: event.pageY };
2102
2103 //Aspect Ratio
2104 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2105
2106 var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2107 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2108
2109 el.addClass("ui-resizable-resizing");
2110 this._propagate("start", event);
2111 return true;
2112 },
2113
2114 _mouseDrag: function(event) {
2115
2116 //Increase performance, avoid regex
2117 var el = this.helper, o = this.options, props = {},
2118 self = this, smp = this.originalMousePosition, a = this.axis;
2119
2120 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2121 var trigger = this._change[a];
2122 if (!trigger) return false;
2123
2124 // Calculate the attrs that will be change
2125 var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
2126
2127 if (this._aspectRatio || event.shiftKey)
2128 data = this._updateRatio(data, event);
2129
2130 data = this._respectSize(data, event);
2131
2132 // plugins callbacks need to be called first
2133 this._propagate("resize", event);
2134
2135 el.css({
2136 top: this.position.top + "px", left: this.position.left + "px",
2137 width: this.size.width + "px", height: this.size.height + "px"
2138 });
2139
2140 if (!this._helper && this._proportionallyResizeElements.length)
2141 this._proportionallyResize();
2142
2143 this._updateCache(data);
2144
2145 // calling the user callback at the end
2146 this._trigger('resize', event, this.ui());
2147
2148 return false;
2149 },
2150
2151 _mouseStop: function(event) {
2152
2153 this.resizing = false;
2154 var o = this.options, self = this;
2155
2156 if(this._helper) {
2157 var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2158 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2159 soffsetw = ista ? 0 : self.sizeDiff.width;
2160
2161 var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2162 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2163 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2164
2165 if (!o.animate)
2166 this.element.css($.extend(s, { top: top, left: left }));
2167
2168 self.helper.height(self.size.height);
2169 self.helper.width(self.size.width);
2170
2171 if (this._helper && !o.animate) this._proportionallyResize();
2172 }
2173
2174 $('body').css('cursor', 'auto');
2175
2176 this.element.removeClass("ui-resizable-resizing");
2177
2178 this._propagate("stop", event);
2179
2180 if (this._helper) this.helper.remove();
2181 return false;
2182
2183 },
2184
2185 _updateCache: function(data) {
2186 var o = this.options;
2187 this.offset = this.helper.offset();
2188 if (isNumber(data.left)) this.position.left = data.left;
2189 if (isNumber(data.top)) this.position.top = data.top;
2190 if (isNumber(data.height)) this.size.height = data.height;
2191 if (isNumber(data.width)) this.size.width = data.width;
2192 },
2193
2194 _updateRatio: function(data, event) {
2195
2196 var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2197
2198 if (data.height) data.width = (csize.height * this.aspectRatio);
2199 else if (data.width) data.height = (csize.width / this.aspectRatio);
2200
2201 if (a == 'sw') {
2202 data.left = cpos.left + (csize.width - data.width);
2203 data.top = null;
2204 }
2205 if (a == 'nw') {
2206 data.top = cpos.top + (csize.height - data.height);
2207 data.left = cpos.left + (csize.width - data.width);
2208 }
2209
2210 return data;
2211 },
2212
2213 _respectSize: function(data, event) {
2214
2215 var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2216 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2217 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2218
2219 if (isminw) data.width = o.minWidth;
2220 if (isminh) data.height = o.minHeight;
2221 if (ismaxw) data.width = o.maxWidth;
2222 if (ismaxh) data.height = o.maxHeight;
2223
2224 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2225 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2226
2227 if (isminw && cw) data.left = dw - o.minWidth;
2228 if (ismaxw && cw) data.left = dw - o.maxWidth;
2229 if (isminh && ch) data.top = dh - o.minHeight;
2230 if (ismaxh && ch) data.top = dh - o.maxHeight;
2231
2232 // fixing jump error on top/left - bug #2330
2233 var isNotwh = !data.width && !data.height;
2234 if (isNotwh && !data.left && data.top) data.top = null;
2235 else if (isNotwh && !data.top && data.left) data.left = null;
2236
2237 return data;
2238 },
2239
2240 _proportionallyResize: function() {
2241
2242 var o = this.options;
2243 if (!this._proportionallyResizeElements.length) return;
2244 var element = this.helper || this.element;
2245
2246 for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2247
2248 var prel = this._proportionallyResizeElements[i];
2249
2250 if (!this.borderDif) {
2251 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2252 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2253
2254 this.borderDif = $.map(b, function(v, i) {
2255 var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2256 return border + padding;
2257 });
2258 }
2259
2260 if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
2261 continue;
2262
2263 prel.css({
2264 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2265 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2266 });
2267
2268 };
2269
2270 },
2271
2272 _renderProxy: function() {
2273
2274 var el = this.element, o = this.options;
2275 this.elementOffset = el.offset();
2276
2277 if(this._helper) {
2278
2279 this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2280
2281 // fix ie6 offset TODO: This seems broken
2282 var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2283 pxyoffset = ( ie6 ? 2 : -1 );
2284
2285 this.helper.addClass(this._helper).css({
2286 width: this.element.outerWidth() + pxyoffset,
2287 height: this.element.outerHeight() + pxyoffset,
2288 position: 'absolute',
2289 left: this.elementOffset.left - ie6offset +'px',
2290 top: this.elementOffset.top - ie6offset +'px',
2291 zIndex: ++o.zIndex //TODO: Don't modify option
2292 });
2293
2294 this.helper
2295 .appendTo("body")
2296 .disableSelection();
2297
2298 } else {
2299 this.helper = this.element;
2300 }
2301
2302 },
2303
2304 _change: {
2305 e: function(event, dx, dy) {
2306 return { width: this.originalSize.width + dx };
2307 },
2308 w: function(event, dx, dy) {
2309 var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2310 return { left: sp.left + dx, width: cs.width - dx };
2311 },
2312 n: function(event, dx, dy) {
2313 var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2314 return { top: sp.top + dy, height: cs.height - dy };
2315 },
2316 s: function(event, dx, dy) {
2317 return { height: this.originalSize.height + dy };
2318 },
2319 se: function(event, dx, dy) {
2320 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2321 },
2322 sw: function(event, dx, dy) {
2323 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2324 },
2325 ne: function(event, dx, dy) {
2326 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2327 },
2328 nw: function(event, dx, dy) {
2329 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2330 }
2331 },
2332
2333 _propagate: function(n, event) {
2334 $.ui.plugin.call(this, n, [event, this.ui()]);
2335 (n != "resize" && this._trigger(n, event, this.ui()));
2336 },
2337
2338 plugins: {},
2339
2340 ui: function() {
2341 return {
2342 originalElement: this.originalElement,
2343 element: this.element,
2344 helper: this.helper,
2345 position: this.position,
2346 size: this.size,
2347 originalSize: this.originalSize,
2348 originalPosition: this.originalPosition
2349 };
2350 }
2351
2352 });
2353
2354 $.extend($.ui.resizable, {
2355 version: "1.8.7"
2356 });
2357
2358 /*
2359 * Resizable Extensions
2360 */
2361
2362 $.ui.plugin.add("resizable", "alsoResize", {
2363
2364 start: function (event, ui) {
2365 var self = $(this).data("resizable"), o = self.options;
2366
2367 var _store = function (exp) {
2368 $(exp).each(function() {
2369 var el = $(this);
2370 el.data("resizable-alsoresize", {
2371 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2372 left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
2373 position: el.css('position') // to reset Opera on stop()
2374 });
2375 });
2376 };
2377
2378 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2379 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2380 else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2381 }else{
2382 _store(o.alsoResize);
2383 }
2384 },
2385
2386 resize: function (event, ui) {
2387 var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2388
2389 var delta = {
2390 height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2391 top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2392 },
2393
2394 _alsoResize = function (exp, c) {
2395 $(exp).each(function() {
2396 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
2397 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2398
2399 $.each(css, function (i, prop) {
2400 var sum = (start[prop]||0) + (delta[prop]||0);
2401 if (sum && sum >= 0)
2402 style[prop] = sum || null;
2403 });
2404
2405 // Opera fixing relative position
2406 if ($.browser.opera && /relative/.test(el.css('position'))) {
2407 self._revertToRelativePosition = true;
2408 el.css({ position: 'absolute', top: 'auto', left: 'auto' });
2409 }
2410
2411 el.css(style);
2412 });
2413 };
2414
2415 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2416 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2417 }else{
2418 _alsoResize(o.alsoResize);
2419 }
2420 },
2421
2422 stop: function (event, ui) {
2423 var self = $(this).data("resizable"), o = self.options;
2424
2425 var _reset = function (exp) {
2426 $(exp).each(function() {
2427 var el = $(this);
2428 // reset position for Opera - no need to verify it was changed
2429 el.css({ position: el.data("resizable-alsoresize").position });
2430 });
2431 };
2432
2433 if (self._revertToRelativePosition) {
2434 self._revertToRelativePosition = false;
2435 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2436 $.each(o.alsoResize, function (exp) { _reset(exp); });
2437 }else{
2438 _reset(o.alsoResize);
2439 }
2440 }
2441
2442 $(this).removeData("resizable-alsoresize");
2443 }
2444 });
2445
2446 $.ui.plugin.add("resizable", "animate", {
2447
2448 stop: function(event, ui) {
2449 var self = $(this).data("resizable"), o = self.options;
2450
2451 var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2452 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2453 soffsetw = ista ? 0 : self.sizeDiff.width;
2454
2455 var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2456 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2457 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2458
2459 self.element.animate(
2460 $.extend(style, top && left ? { top: top, left: left } : {}), {
2461 duration: o.animateDuration,
2462 easing: o.animateEasing,
2463 step: function() {
2464
2465 var data = {
2466 width: parseInt(self.element.css('width'), 10),
2467 height: parseInt(self.element.css('height'), 10),
2468 top: parseInt(self.element.css('top'), 10),
2469 left: parseInt(self.element.css('left'), 10)
2470 };
2471
2472 if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2473
2474 // propagating resize, and updating values for each animation step
2475 self._updateCache(data);
2476 self._propagate("resize", event);
2477
2478 }
2479 }
2480 );
2481 }
2482
2483 });
2484
2485 $.ui.plugin.add("resizable", "containment", {
2486
2487 start: function(event, ui) {
2488 var self = $(this).data("resizable"), o = self.options, el = self.element;
2489 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2490 if (!ce) return;
2491
2492 self.containerElement = $(ce);
2493
2494 if (/document/.test(oc) || oc == document) {
2495 self.containerOffset = { left: 0, top: 0 };
2496 self.containerPosition = { left: 0, top: 0 };
2497
2498 self.parentData = {
2499 element: $(document), left: 0, top: 0,
2500 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2501 };
2502 }
2503
2504 // i'm a node, so compute top, left, right, bottom
2505 else {
2506 var element = $(ce), p = [];
2507 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2508
2509 self.containerOffset = element.offset();
2510 self.containerPosition = element.position();
2511 self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2512
2513 var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
2514 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2515
2516 self.parentData = {
2517 element: ce, left: co.left, top: co.top, width: width, height: height
2518 };
2519 }
2520 },
2521
2522 resize: function(event, ui) {
2523 var self = $(this).data("resizable"), o = self.options,
2524 ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2525 pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2526
2527 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2528
2529 if (cp.left < (self._helper ? co.left : 0)) {
2530 self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2531 if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2532 self.position.left = o.helper ? co.left : 0;
2533 }
2534
2535 if (cp.top < (self._helper ? co.top : 0)) {
2536 self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2537 if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2538 self.position.top = self._helper ? co.top : 0;
2539 }
2540
2541 self.offset.left = self.parentData.left+self.position.left;
2542 self.offset.top = self.parentData.top+self.position.top;
2543
2544 var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2545 hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2546
2547 var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2548 isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2549
2550 if(isParent && isOffsetRelative) woset -= self.parentData.left;
2551
2552 if (woset + self.size.width >= self.parentData.width) {
2553 self.size.width = self.parentData.width - woset;
2554 if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2555 }
2556
2557 if (hoset + self.size.height >= self.parentData.height) {
2558 self.size.height = self.parentData.height - hoset;
2559 if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2560 }
2561 },
2562
2563 stop: function(event, ui){
2564 var self = $(this).data("resizable"), o = self.options, cp = self.position,
2565 co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2566
2567 var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2568
2569 if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2570 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2571
2572 if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2573 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2574
2575 }
2576 });
2577
2578 $.ui.plugin.add("resizable", "ghost", {
2579
2580 start: function(event, ui) {
2581
2582 var self = $(this).data("resizable"), o = self.options, cs = self.size;
2583
2584 self.ghost = self.originalElement.clone();
2585 self.ghost
2586 .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2587 .addClass('ui-resizable-ghost')
2588 .addClass(typeof o.ghost == 'string' ? o.ghost : '');
2589
2590 self.ghost.appendTo(self.helper);
2591
2592 },
2593
2594 resize: function(event, ui){
2595 var self = $(this).data("resizable"), o = self.options;
2596 if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2597 },
2598
2599 stop: function(event, ui){
2600 var self = $(this).data("resizable"), o = self.options;
2601 if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2602 }
2603
2604 });
2605
2606 $.ui.plugin.add("resizable", "grid", {
2607
2608 resize: function(event, ui) {
2609 var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
2610 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2611 var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
2612
2613 if (/^(se|s|e)$/.test(a)) {
2614 self.size.width = os.width + ox;
2615 self.size.height = os.height + oy;
2616 }
2617 else if (/^(ne)$/.test(a)) {
2618 self.size.width = os.width + ox;
2619 self.size.height = os.height + oy;
2620 self.position.top = op.top - oy;
2621 }
2622 else if (/^(sw)$/.test(a)) {
2623 self.size.width = os.width + ox;
2624 self.size.height = os.height + oy;
2625 self.position.left = op.left - ox;
2626 }
2627 else {
2628 self.size.width = os.width + ox;
2629 self.size.height = os.height + oy;
2630 self.position.top = op.top - oy;
2631 self.position.left = op.left - ox;
2632 }
2633 }
2634
2635 });
2636
2637 var num = function(v) {
2638 return parseInt(v, 10) || 0;
2639 };
2640
2641 var isNumber = function(value) {
2642 return !isNaN(parseInt(value, 10));
2643 };
2644
2645 })(jQuery);
2646 /*
2647 * Note: While Microsoft is not the author of this file, Microsoft is
2648 * offering you a license subject to the terms of the Microsoft Software
2649 * License Terms for Microsoft ASP.NET Model View Controller 3.
2650 * Microsoft reserves all other rights. The notices below are provided
2651 * for informational purposes only and are not the license terms under
2652 * which Microsoft distributed this file.
2653 *
2654 * jQuery UI Selectable 1.8.7
2655 *
2656 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
2657 *
2658 * http://docs.jquery.com/UI/Selectables
2659 *
2660 * Depends:
2661 * jquery.ui.core.js
2662 * jquery.ui.mouse.js
2663 * jquery.ui.widget.js
2664 */
2665 (function( $, undefined ) {
2666
2667 $.widget("ui.selectable", $.ui.mouse, {
2668 options: {
2669 appendTo: 'body',
2670 autoRefresh: true,
2671 distance: 0,
2672 filter: '*',
2673 tolerance: 'touch'
2674 },
2675 _create: function() {
2676 var self = this;
2677
2678 this.element.addClass("ui-selectable");
2679
2680 this.dragged = false;
2681
2682 // cache selectee children based on filter
2683 var selectees;
2684 this.refresh = function() {
2685 selectees = $(self.options.filter, self.element[0]);
2686 selectees.each(function() {
2687 var $this = $(this);
2688 var pos = $this.offset();
2689 $.data(this, "selectable-item", {
2690 element: this,
2691 $element: $this,
2692 left: pos.left,
2693 top: pos.top,
2694 right: pos.left + $this.outerWidth(),
2695 bottom: pos.top + $this.outerHeight(),
2696 startselected: false,
2697 selected: $this.hasClass('ui-selected'),
2698 selecting: $this.hasClass('ui-selecting'),
2699 unselecting: $this.hasClass('ui-unselecting')
2700 });
2701 });
2702 };
2703 this.refresh();
2704
2705 this.selectees = selectees.addClass("ui-selectee");
2706
2707 this._mouseInit();
2708
2709 this.helper = $("<div class='ui-selectable-helper'></div>");
2710 },
2711
2712 destroy: function() {
2713 this.selectees
2714 .removeClass("ui-selectee")
2715 .removeData("selectable-item");
2716 this.element
2717 .removeClass("ui-selectable ui-selectable-disabled")
2718 .removeData("selectable")
2719 .unbind(".selectable");
2720 this._mouseDestroy();
2721
2722 return this;
2723 },
2724
2725 _mouseStart: function(event) {
2726 var self = this;
2727
2728 this.opos = [event.pageX, event.pageY];
2729
2730 if (this.options.disabled)
2731 return;
2732
2733 var options = this.options;
2734
2735 this.selectees = $(options.filter, this.element[0]);
2736
2737 this._trigger("start", event);
2738
2739 $(options.appendTo).append(this.helper);
2740 // position helper (lasso)
2741 this.helper.css({
2742 "left": event.clientX,
2743 "top": event.clientY,
2744 "width": 0,
2745 "height": 0
2746 });
2747
2748 if (options.autoRefresh) {
2749 this.refresh();
2750 }
2751
2752 this.selectees.filter('.ui-selected').each(function() {
2753 var selectee = $.data(this, "selectable-item");
2754 selectee.startselected = true;
2755 if (!event.metaKey) {
2756 selectee.$element.removeClass('ui-selected');
2757 selectee.selected = false;
2758 selectee.$element.addClass('ui-unselecting');
2759 selectee.unselecting = true;
2760 // selectable UNSELECTING callback
2761 self._trigger("unselecting", event, {
2762 unselecting: selectee.element
2763 });
2764 }
2765 });
2766
2767 $(event.target).parents().andSelf().each(function() {
2768 var selectee = $.data(this, "selectable-item");
2769 if (selectee) {
2770 var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
2771 selectee.$element
2772 .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
2773 .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
2774 selectee.unselecting = !doSelect;
2775 selectee.selecting = doSelect;
2776 selectee.selected = doSelect;
2777 // selectable (UN)SELECTING callback
2778 if (doSelect) {
2779 self._trigger("selecting", event, {
2780 selecting: selectee.element
2781 });
2782 } else {
2783 self._trigger("unselecting", event, {
2784 unselecting: selectee.element
2785 });
2786 }
2787 return false;
2788 }
2789 });
2790
2791 },
2792
2793 _mouseDrag: function(event) {
2794 var self = this;
2795 this.dragged = true;
2796
2797 if (this.options.disabled)
2798 return;
2799
2800 var options = this.options;
2801
2802 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
2803 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
2804 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
2805 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
2806
2807 this.selectees.each(function() {
2808 var selectee = $.data(this, "selectable-item");
2809 //prevent helper from being selected if appendTo: selectable
2810 if (!selectee || selectee.element == self.element[0])
2811 return;
2812 var hit = false;
2813 if (options.tolerance == 'touch') {
2814 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
2815 } else if (options.tolerance == 'fit') {
2816 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
2817 }
2818
2819 if (hit) {
2820 // SELECT
2821 if (selectee.selected) {
2822 selectee.$element.removeClass('ui-selected');
2823 selectee.selected = false;
2824 }
2825 if (selectee.unselecting) {
2826 selectee.$element.removeClass('ui-unselecting');
2827 selectee.unselecting = false;
2828 }
2829 if (!selectee.selecting) {
2830 selectee.$element.addClass('ui-selecting');
2831 selectee.selecting = true;
2832 // selectable SELECTING callback
2833 self._trigger("selecting", event, {
2834 selecting: selectee.element
2835 });
2836 }
2837 } else {
2838 // UNSELECT
2839 if (selectee.selecting) {
2840 if (event.metaKey && selectee.startselected) {
2841 selectee.$element.removeClass('ui-selecting');
2842 selectee.selecting = false;
2843 selectee.$element.addClass('ui-selected');
2844 selectee.selected = true;
2845 } else {
2846 selectee.$element.removeClass('ui-selecting');
2847 selectee.selecting = false;
2848 if (selectee.startselected) {
2849 selectee.$element.addClass('ui-unselecting');
2850 selectee.unselecting = true;
2851 }
2852 // selectable UNSELECTING callback
2853 self._trigger("unselecting", event, {
2854 unselecting: selectee.element
2855 });
2856 }
2857 }
2858 if (selectee.selected) {
2859 if (!event.metaKey && !selectee.startselected) {
2860 selectee.$element.removeClass('ui-selected');
2861 selectee.selected = false;
2862
2863 selectee.$element.addClass('ui-unselecting');
2864 selectee.unselecting = true;
2865 // selectable UNSELECTING callback
2866 self._trigger("unselecting", event, {
2867 unselecting: selectee.element
2868 });
2869 }
2870 }
2871 }
2872 });
2873
2874 return false;
2875 },
2876
2877 _mouseStop: function(event) {
2878 var self = this;
2879
2880 this.dragged = false;
2881
2882 var options = this.options;
2883
2884 $('.ui-unselecting', this.element[0]).each(function() {
2885 var selectee = $.data(this, "selectable-item");
2886 selectee.$element.removeClass('ui-unselecting');
2887 selectee.unselecting = false;
2888 selectee.startselected = false;
2889 self._trigger("unselected", event, {
2890 unselected: selectee.element
2891 });
2892 });
2893 $('.ui-selecting', this.element[0]).each(function() {
2894 var selectee = $.data(this, "selectable-item");
2895 selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
2896 selectee.selecting = false;
2897 selectee.selected = true;
2898 selectee.startselected = true;
2899 self._trigger("selected", event, {
2900 selected: selectee.element
2901 });
2902 });
2903 this._trigger("stop", event);
2904
2905 this.helper.remove();
2906
2907 return false;
2908 }
2909
2910 });
2911
2912 $.extend($.ui.selectable, {
2913 version: "1.8.7"
2914 });
2915
2916 })(jQuery);
2917 /*
2918 * Note: While Microsoft is not the author of this file, Microsoft is
2919 * offering you a license subject to the terms of the Microsoft Software
2920 * License Terms for Microsoft ASP.NET Model View Controller 3.
2921 * Microsoft reserves all other rights. The notices below are provided
2922 * for informational purposes only and are not the license terms under
2923 * which Microsoft distributed this file.
2924 *
2925 * jQuery UI Sortable 1.8.7
2926 *
2927 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
2928 *
2929 * http://docs.jquery.com/UI/Sortables
2930 *
2931 * Depends:
2932 * jquery.ui.core.js
2933 * jquery.ui.mouse.js
2934 * jquery.ui.widget.js
2935 */
2936 (function( $, undefined ) {
2937
2938 $.widget("ui.sortable", $.ui.mouse, {
2939 widgetEventPrefix: "sort",
2940 options: {
2941 appendTo: "parent",
2942 axis: false,
2943 connectWith: false,
2944 containment: false,
2945 cursor: 'auto',
2946 cursorAt: false,
2947 dropOnEmpty: true,
2948 forcePlaceholderSize: false,
2949 forceHelperSize: false,
2950 grid: false,
2951 handle: false,
2952 helper: "original",
2953 items: '> *',
2954 opacity: false,
2955 placeholder: false,
2956 revert: false,
2957 scroll: true,
2958 scrollSensitivity: 20,
2959 scrollSpeed: 20,
2960 scope: "default",
2961 tolerance: "intersect",
2962 zIndex: 1000
2963 },
2964 _create: function() {
2965
2966 var o = this.options;
2967 this.containerCache = {};
2968 this.element.addClass("ui-sortable");
2969
2970 //Get the items
2971 this.refresh();
2972
2973 //Let's determine if the items are floating
2974 this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false;
2975
2976 //Let's determine the parent's offset
2977 this.offset = this.element.offset();
2978
2979 //Initialize mouse events for interaction
2980 this._mouseInit();
2981
2982 },
2983
2984 destroy: function() {
2985 this.element
2986 .removeClass("ui-sortable ui-sortable-disabled")
2987 .removeData("sortable")
2988 .unbind(".sortable");
2989 this._mouseDestroy();
2990
2991 for ( var i = this.items.length - 1; i >= 0; i-- )
2992 this.items[i].item.removeData("sortable-item");
2993
2994 return this;
2995 },
2996
2997 _setOption: function(key, value){
2998 if ( key === "disabled" ) {
2999 this.options[ key ] = value;
3000
3001 this.widget()
3002 [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
3003 } else {
3004 // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3005 $.Widget.prototype._setOption.apply(this, arguments);
3006 }
3007 },
3008
3009 _mouseCapture: function(event, overrideHandle) {
3010
3011 if (this.reverting) {
3012 return false;
3013 }
3014
3015 if(this.options.disabled || this.options.type == 'static') return false;
3016
3017 //We have to refresh the items data once first
3018 this._refreshItems(event);
3019
3020 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3021 var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
3022 if($.data(this, 'sortable-item') == self) {
3023 currentItem = $(this);
3024 return false;
3025 }
3026 });
3027 if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
3028
3029 if(!currentItem) return false;
3030 if(this.options.handle && !overrideHandle) {
3031 var validHandle = false;
3032
3033 $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3034 if(!validHandle) return false;
3035 }
3036
3037 this.currentItem = currentItem;
3038 this._removeCurrentsFromItems();
3039 return true;
3040
3041 },
3042
3043 _mouseStart: function(event, overrideHandle, noActivation) {
3044
3045 var o = this.options, self = this;
3046 this.currentContainer = this;
3047
3048 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3049 this.refreshPositions();
3050
3051 //Create and append the visible helper
3052 this.helper = this._createHelper(event);
3053
3054 //Cache the helper size
3055 this._cacheHelperProportions();
3056
3057 /*
3058 * - Position generation -
3059 * This block generates everything position related - it's the core of draggables.
3060 */
3061
3062 //Cache the margins of the original element
3063 this._cacheMargins();
3064
3065 //Get the next scrolling parent
3066 this.scrollParent = this.helper.scrollParent();
3067
3068 //The element's absolute position on the page minus margins
3069 this.offset = this.currentItem.offset();
3070 this.offset = {
3071 top: this.offset.top - this.margins.top,
3072 left: this.offset.left - this.margins.left
3073 };
3074
3075 // Only after we got the offset, we can change the helper's position to absolute
3076 // TODO: Still need to figure out a way to make relative sorting possible
3077 this.helper.css("position", "absolute");
3078 this.cssPosition = this.helper.css("position");
3079
3080 $.extend(this.offset, {
3081 click: { //Where the click happened, relative to the element
3082 left: event.pageX - this.offset.left,
3083 top: event.pageY - this.offset.top
3084 },
3085 parent: this._getParentOffset(),
3086 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3087 });
3088
3089 //Generate the original position
3090 this.originalPosition = this._generatePosition(event);
3091 this.originalPageX = event.pageX;
3092 this.originalPageY = event.pageY;
3093
3094 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3095 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3096
3097 //Cache the former DOM position
3098 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3099
3100 //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
3101 if(this.helper[0] != this.currentItem[0]) {
3102 this.currentItem.hide();
3103 }
3104
3105 //Create the placeholder
3106 this._createPlaceholder();
3107
3108 //Set a containment if given in the options
3109 if(o.containment)
3110 this._setContainment();
3111
3112 if(o.cursor) { // cursor option
3113 if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3114 $('body').css("cursor", o.cursor);
3115 }
3116
3117 if(o.opacity) { // opacity option
3118 if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3119 this.helper.css("opacity", o.opacity);
3120 }
3121
3122 if(o.zIndex) { // zIndex option
3123 if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3124 this.helper.css("zIndex", o.zIndex);
3125 }
3126
3127 //Prepare scrolling
3128 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3129 this.overflowOffset = this.scrollParent.offset();
3130
3131 //Call callbacks
3132 this._trigger("start", event, this._uiHash());
3133
3134 //Recache the helper size
3135 if(!this._preserveHelperProportions)
3136 this._cacheHelperProportions();
3137
3138
3139 //Post 'activate' events to possible containers
3140 if(!noActivation) {
3141 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
3142 }
3143
3144 //Prepare possible droppables
3145 if($.ui.ddmanager)
3146 $.ui.ddmanager.current = this;
3147
3148 if ($.ui.ddmanager && !o.dropBehaviour)
3149 $.ui.ddmanager.prepareOffsets(this, event);
3150
3151 this.dragging = true;
3152
3153 this.helper.addClass("ui-sortable-helper");
3154 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3155 return true;
3156
3157 },
3158
3159 _mouseDrag: function(event) {
3160
3161 //Compute the helpers position
3162 this.position = this._generatePosition(event);
3163 this.positionAbs = this._convertPositionTo("absolute");
3164
3165 if (!this.lastPositionAbs) {
3166 this.lastPositionAbs = this.positionAbs;
3167 }
3168
3169 //Do scrolling
3170 if(this.options.scroll) {
3171 var o = this.options, scrolled = false;
3172 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3173
3174 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3175 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3176 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3177 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3178
3179 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3180 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3181 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3182 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3183
3184 } else {
3185
3186 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3187 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3188 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3189 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3190
3191 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3192 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3193 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3194 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3195
3196 }
3197
3198 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3199 $.ui.ddmanager.prepareOffsets(this, event);
3200 }
3201
3202 //Regenerate the absolute position used for position checks
3203 this.positionAbs = this._convertPositionTo("absolute");
3204
3205 //Set the helper position
3206 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3207 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3208
3209 //Rearrange
3210 for (var i = this.items.length - 1; i >= 0; i--) {
3211
3212 //Cache variables and intersection, continue if no intersection
3213 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3214 if (!intersection) continue;
3215
3216 if(itemElement != this.currentItem[0] //cannot intersect with itself
3217 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3218 && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3219 && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
3220 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3221 ) {
3222
3223 this.direction = intersection == 1 ? "down" : "up";
3224
3225 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3226 this._rearrange(event, item);
3227 } else {
3228 break;
3229 }
3230
3231 this._trigger("change", event, this._uiHash());
3232 break;
3233 }
3234 }
3235
3236 //Post events to containers
3237 this._contactContainers(event);
3238
3239 //Interconnect with droppables
3240 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3241
3242 //Call callbacks
3243 this._trigger('sort', event, this._uiHash());
3244
3245 this.lastPositionAbs = this.positionAbs;
3246 return false;
3247
3248 },
3249
3250 _mouseStop: function(event, noPropagation) {
3251
3252 if(!event) return;
3253
3254 //If we are using droppables, inform the manager about the drop
3255 if ($.ui.ddmanager && !this.options.dropBehaviour)
3256 $.ui.ddmanager.drop(this, event);
3257
3258 if(this.options.revert) {
3259 var self = this;
3260 var cur = self.placeholder.offset();
3261
3262 self.reverting = true;
3263
3264 $(this.helper).animate({
3265 left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3266 top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3267 }, parseInt(this.options.revert, 10) || 500, function() {
3268 self._clear(event);
3269 });
3270 } else {
3271 this._clear(event, noPropagation);
3272 }
3273
3274 return false;
3275
3276 },
3277
3278 cancel: function() {
3279
3280 var self = this;
3281
3282 if(this.dragging) {
3283
3284 this._mouseUp();
3285
3286 if(this.options.helper == "original")
3287 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3288 else
3289 this.currentItem.show();
3290
3291 //Post deactivating events to containers
3292 for (var i = this.containers.length - 1; i >= 0; i--){
3293 this.containers[i]._trigger("deactivate", null, self._uiHash(this));
3294 if(this.containers[i].containerCache.over) {
3295 this.containers[i]._trigger("out", null, self._uiHash(this));
3296 this.containers[i].containerCache.over = 0;
3297 }
3298 }
3299
3300 }
3301
3302 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3303 if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3304 if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3305
3306 $.extend(this, {
3307 helper: null,
3308 dragging: false,
3309 reverting: false,
3310 _noFinalSort: null
3311 });
3312
3313 if(this.domPosition.prev) {
3314 $(this.domPosition.prev).after(this.currentItem);
3315 } else {
3316 $(this.domPosition.parent).prepend(this.currentItem);
3317 }
3318
3319 return this;
3320
3321 },
3322
3323 serialize: function(o) {
3324
3325 var items = this._getItemsAsjQuery(o && o.connected);
3326 var str = []; o = o || {};
3327
3328 $(items).each(function() {
3329 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3330 if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3331 });
3332
3333 if(!str.length && o.key) {
3334 str.push(o.key + '=');
3335 }
3336
3337 return str.join('&');
3338
3339 },
3340
3341 toArray: function(o) {
3342
3343 var items = this._getItemsAsjQuery(o && o.connected);
3344 var ret = []; o = o || {};
3345
3346 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3347 return ret;
3348
3349 },
3350
3351 /* Be careful with the following core functions */
3352 _intersectsWith: function(item) {
3353
3354 var x1 = this.positionAbs.left,
3355 x2 = x1 + this.helperProportions.width,
3356 y1 = this.positionAbs.top,
3357 y2 = y1 + this.helperProportions.height;
3358
3359 var l = item.left,
3360 r = l + item.width,
3361 t = item.top,
3362 b = t + item.height;
3363
3364 var dyClick = this.offset.click.top,
3365 dxClick = this.offset.click.left;
3366
3367 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3368
3369 if( this.options.tolerance == "pointer"
3370 || this.options.forcePointerForContainers
3371 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3372 ) {
3373 return isOverElement;
3374 } else {
3375
3376 return (l < x1 + (this.helperProportions.width / 2) // Right Half
3377 && x2 - (this.helperProportions.width / 2) < r // Left Half
3378 && t < y1 + (this.helperProportions.height / 2) // Bottom Half
3379 && y2 - (this.helperProportions.height / 2) < b ); // Top Half
3380
3381 }
3382 },
3383
3384 _intersectsWithPointer: function(item) {
3385
3386 var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3387 isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3388 isOverElement = isOverElementHeight && isOverElementWidth,
3389 verticalDirection = this._getDragVerticalDirection(),
3390 horizontalDirection = this._getDragHorizontalDirection();
3391
3392 if (!isOverElement)
3393 return false;
3394
3395 return this.floating ?
3396 ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3397 : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3398
3399 },
3400
3401 _intersectsWithSides: function(item) {
3402
3403 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3404 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3405 verticalDirection = this._getDragVerticalDirection(),
3406 horizontalDirection = this._getDragHorizontalDirection();
3407
3408 if (this.floating && horizontalDirection) {
3409 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3410 } else {
3411 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3412 }
3413
3414 },
3415
3416 _getDragVerticalDirection: function() {
3417 var delta = this.positionAbs.top - this.lastPositionAbs.top;
3418 return delta != 0 && (delta > 0 ? "down" : "up");
3419 },
3420
3421 _getDragHorizontalDirection: function() {
3422 var delta = this.positionAbs.left - this.lastPositionAbs.left;
3423 return delta != 0 && (delta > 0 ? "right" : "left");
3424 },
3425
3426 refresh: function(event) {
3427 this._refreshItems(event);
3428 this.refreshPositions();
3429 return this;
3430 },
3431
3432 _connectWith: function() {
3433 var options = this.options;
3434 return options.connectWith.constructor == String
3435 ? [options.connectWith]
3436 : options.connectWith;
3437 },
3438
3439 _getItemsAsjQuery: function(connected) {
3440
3441 var self = this;
3442 var items = [];
3443 var queries = [];
3444 var connectWith = this._connectWith();
3445
3446 if(connectWith && connected) {
3447 for (var i = connectWith.length - 1; i >= 0; i--){
3448 var cur = $(connectWith[i]);
3449 for (var j = cur.length - 1; j >= 0; j--){
3450 var inst = $.data(cur[j], 'sortable');
3451 if(inst && inst != this && !inst.options.disabled) {
3452 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]);
3453 }
3454 };
3455 };
3456 }
3457
3458 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]);
3459
3460 for (var i = queries.length - 1; i >= 0; i--){
3461 queries[i][0].each(function() {
3462 items.push(this);
3463 });
3464 };
3465
3466 return $(items);
3467
3468 },
3469
3470 _removeCurrentsFromItems: function() {
3471
3472 var list = this.currentItem.find(":data(sortable-item)");
3473
3474 for (var i=0; i < this.items.length; i++) {
3475
3476 for (var j=0; j < list.length; j++) {
3477 if(list[j] == this.items[i].item[0])
3478 this.items.splice(i,1);
3479 };
3480
3481 };
3482
3483 },
3484
3485 _refreshItems: function(event) {
3486
3487 this.items = [];
3488 this.containers = [this];
3489 var items = this.items;
3490 var self = this;
3491 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3492 var connectWith = this._connectWith();
3493
3494 if(connectWith) {
3495 for (var i = connectWith.length - 1; i >= 0; i--){
3496 var cur = $(connectWith[i]);
3497 for (var j = cur.length - 1; j >= 0; j--){
3498 var inst = $.data(cur[j], 'sortable');
3499 if(inst && inst != this && !inst.options.disabled) {
3500 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3501 this.containers.push(inst);
3502 }
3503 };
3504 };
3505 }
3506
3507 for (var i = queries.length - 1; i >= 0; i--) {
3508 var targetData = queries[i][1];
3509 var _queries = queries[i][0];
3510
3511 for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3512 var item = $(_queries[j]);
3513
3514 item.data('sortable-item', targetData); // Data for target checking (mouse manager)
3515
3516 items.push({
3517 item: item,
3518 instance: targetData,
3519 width: 0, height: 0,
3520 left: 0, top: 0
3521 });
3522 };
3523 };
3524
3525 },
3526
3527 refreshPositions: function(fast) {
3528
3529 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3530 if(this.offsetParent && this.helper) {
3531 this.offset.parent = this._getParentOffset();
3532 }
3533
3534 for (var i = this.items.length - 1; i >= 0; i--){
3535 var item = this.items[i];
3536
3537 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3538
3539 if (!fast) {
3540 item.width = t.outerWidth();
3541 item.height = t.outerHeight();
3542 }
3543
3544 var p = t.offset();
3545 item.left = p.left;
3546 item.top = p.top;
3547 };
3548
3549 if(this.options.custom && this.options.custom.refreshContainers) {
3550 this.options.custom.refreshContainers.call(this);
3551 } else {
3552 for (var i = this.containers.length - 1; i >= 0; i--){
3553 var p = this.containers[i].element.offset();
3554 this.containers[i].containerCache.left = p.left;
3555 this.containers[i].containerCache.top = p.top;
3556 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
3557 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3558 };
3559 }
3560
3561 return this;
3562 },
3563
3564 _createPlaceholder: function(that) {
3565
3566 var self = that || this, o = self.options;
3567
3568 if(!o.placeholder || o.placeholder.constructor == String) {
3569 var className = o.placeholder;
3570 o.placeholder = {
3571 element: function() {
3572
3573 var el = $(document.createElement(self.currentItem[0].nodeName))
3574 .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3575 .removeClass("ui-sortable-helper")[0];
3576
3577 if(!className)
3578 el.style.visibility = "hidden";
3579
3580 return el;
3581 },
3582 update: function(container, p) {
3583
3584 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3585 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3586 if(className && !o.forcePlaceholderSize) return;
3587
3588 //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
3589 if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3590 if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3591 }
3592 };
3593 }
3594
3595 //Create the placeholder
3596 self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3597
3598 //Append it after the actual current item
3599 self.currentItem.after(self.placeholder);
3600
3601 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3602 o.placeholder.update(self, self.placeholder);
3603
3604 },
3605
3606 _contactContainers: function(event) {
3607
3608 // get innermost container that intersects with item
3609 var innermostContainer = null, innermostIndex = null;
3610
3611
3612 for (var i = this.containers.length - 1; i >= 0; i--){
3613
3614 // never consider a container that's located within the item itself
3615 if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
3616 continue;
3617
3618 if(this._intersectsWith(this.containers[i].containerCache)) {
3619
3620 // if we've already found a container and it's more "inner" than this, then continue
3621 if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
3622 continue;
3623
3624 innermostContainer = this.containers[i];
3625 innermostIndex = i;
3626
3627 } else {
3628 // container doesn't intersect. trigger "out" event if necessary
3629 if(this.containers[i].containerCache.over) {
3630 this.containers[i]._trigger("out", event, this._uiHash(this));
3631 this.containers[i].containerCache.over = 0;
3632 }
3633 }
3634
3635 }
3636
3637 // if no intersecting containers found, return
3638 if(!innermostContainer) return;
3639
3640 // move the item into the container if it's not there already
3641 if(this.containers.length === 1) {
3642 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3643 this.containers[innermostIndex].containerCache.over = 1;
3644 } else if(this.currentContainer != this.containers[innermostIndex]) {
3645
3646 //When entering a new container, we will find the item with the least distance and append our item near it
3647 var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
3648 for (var j = this.items.length - 1; j >= 0; j--) {
3649 if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
3650 var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top'];
3651 if(Math.abs(cur - base) < dist) {
3652 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
3653 }
3654 }
3655
3656 if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
3657 return;
3658
3659 this.currentContainer = this.containers[innermostIndex];
3660 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
3661 this._trigger("change", event, this._uiHash());
3662 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
3663
3664 //Update the placeholder
3665 this.options.placeholder.update(this.currentContainer, this.placeholder);
3666
3667 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3668 this.containers[innermostIndex].containerCache.over = 1;
3669 }
3670
3671
3672 },
3673
3674 _createHelper: function(event) {
3675
3676 var o = this.options;
3677 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3678
3679 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3680 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3681
3682 if(helper[0] == this.currentItem[0])
3683 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") };
3684
3685 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3686 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3687
3688 return helper;
3689
3690 },
3691
3692 _adjustOffsetFromHelper: function(obj) {
3693 if (typeof obj == 'string') {
3694 obj = obj.split(' ');
3695 }
3696 if ($.isArray(obj)) {
3697 obj = {left: +obj[0], top: +obj[1] || 0};
3698 }
3699 if ('left' in obj) {
3700 this.offset.click.left = obj.left + this.margins.left;
3701 }
3702 if ('right' in obj) {
3703 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
3704 }
3705 if ('top' in obj) {
3706 this.offset.click.top = obj.top + this.margins.top;
3707 }
3708 if ('bottom' in obj) {
3709 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
3710 }
3711 },
3712
3713 _getParentOffset: function() {
3714
3715
3716 //Get the offsetParent and cache its position
3717 this.offsetParent = this.helper.offsetParent();
3718 var po = this.offsetParent.offset();
3719
3720 // This is a special case where we need to modify a offset calculated on start, since the following happened:
3721 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
3722 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
3723 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
3724 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
3725 po.left += this.scrollParent.scrollLeft();
3726 po.top += this.scrollParent.scrollTop();
3727 }
3728
3729 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
3730 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
3731 po = { top: 0, left: 0 };
3732
3733 return {
3734 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
3735 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
3736 };
3737
3738 },
3739
3740 _getRelativeOffset: function() {
3741
3742 if(this.cssPosition == "relative") {
3743 var p = this.currentItem.position();
3744 return {
3745 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
3746 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
3747 };
3748 } else {
3749 return { top: 0, left: 0 };
3750 }
3751
3752 },
3753
3754 _cacheMargins: function() {
3755 this.margins = {
3756 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
3757 top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
3758 };
3759 },
3760
3761 _cacheHelperProportions: function() {
3762 this.helperProportions = {
3763 width: this.helper.outerWidth(),
3764 height: this.helper.outerHeight()
3765 };
3766 },
3767
3768 _setContainment: function() {
3769
3770 var o = this.options;
3771 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
3772 if(o.containment == 'document' || o.containment == 'window') this.containment = [
3773 0 - this.offset.relative.left - this.offset.parent.left,
3774 0 - this.offset.relative.top - this.offset.parent.top,
3775 $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
3776 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
3777 ];
3778
3779 if(!(/^(document|window|parent)$/).test(o.containment)) {
3780 var ce = $(o.containment)[0];
3781 var co = $(o.containment).offset();
3782 var over = ($(ce).css("overflow") != 'hidden');
3783
3784 this.containment = [
3785 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
3786 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
3787 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,
3788 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
3789 ];
3790 }
3791
3792 },
3793
3794 _convertPositionTo: function(d, pos) {
3795
3796 if(!pos) pos = this.position;
3797 var mod = d == "absolute" ? 1 : -1;
3798 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);
3799
3800 return {
3801 top: (
3802 pos.top // The absolute mouse position
3803 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
3804 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
3805 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
3806 ),
3807 left: (
3808 pos.left // The absolute mouse position
3809 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
3810 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
3811 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
3812 )
3813 };
3814
3815 },
3816
3817 _generatePosition: function(event) {
3818
3819 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);
3820
3821 // This is another very weird special case that only happens for relative elements:
3822 // 1. If the css position is relative
3823 // 2. and the scroll parent is the document or similar to the offset parent
3824 // we have to refresh the relative offset during the scroll so there are no jumps
3825 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
3826 this.offset.relative = this._getRelativeOffset();
3827 }
3828
3829 var pageX = event.pageX;
3830 var pageY = event.pageY;
3831
3832 /*
3833 * - Position constraining -
3834 * Constrain the position to a mix of grid, containment.
3835 */
3836
3837 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
3838
3839 if(this.containment) {
3840 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
3841 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
3842 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
3843 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
3844 }
3845
3846 if(o.grid) {
3847 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
3848 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;
3849
3850 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
3851 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;
3852 }
3853
3854 }
3855
3856 return {
3857 top: (
3858 pageY // The absolute mouse position
3859 - this.offset.click.top // Click offset (relative to the element)
3860 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
3861 - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
3862 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
3863 ),
3864 left: (
3865 pageX // The absolute mouse position
3866 - this.offset.click.left // Click offset (relative to the element)
3867 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
3868 - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
3869 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
3870 )
3871 };
3872
3873 },
3874
3875 _rearrange: function(event, i, a, hardRefresh) {
3876
3877 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));
3878
3879 //Various things done here to improve the performance:
3880 // 1. we create a setTimeout, that calls refreshPositions
3881 // 2. on the instance, we have a counter variable, that get's higher after every append
3882 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
3883 // 4. this lets only the last addition to the timeout stack through
3884 this.counter = this.counter ? ++this.counter : 1;
3885 var self = this, counter = this.counter;
3886
3887 window.setTimeout(function() {
3888 if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
3889 },0);
3890
3891 },
3892
3893 _clear: function(event, noPropagation) {
3894
3895 this.reverting = false;
3896 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
3897 // everything else normalized again
3898 var delayedTriggers = [], self = this;
3899
3900 // We first have to update the dom position of the actual currentItem
3901 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
3902 if(!this._noFinalSort && this.currentItem[0].parentNode) this.placeholder.before(this.currentItem);
3903 this._noFinalSort = null;
3904
3905 if(this.helper[0] == this.currentItem[0]) {
3906 for(var i in this._storedCSS) {
3907 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
3908 }
3909 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3910 } else {
3911 this.currentItem.show();
3912 }
3913
3914 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
3915 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
3916 if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
3917 if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
3918 for (var i = this.containers.length - 1; i >= 0; i--){
3919 if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
3920 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3921 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3922 }
3923 };
3924 };
3925
3926 //Post events to containers
3927 for (var i = this.containers.length - 1; i >= 0; i--){
3928 if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3929 if(this.containers[i].containerCache.over) {
3930 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3931 this.containers[i].containerCache.over = 0;
3932 }
3933 }
3934
3935 //Do what was originally in plugins
3936 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
3937 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
3938 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
3939
3940 this.dragging = false;
3941 if(this.cancelHelperRemoval) {
3942 if(!noPropagation) {
3943 this._trigger("beforeStop", event, this._uiHash());
3944 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
3945 this._trigger("stop", event, this._uiHash());
3946 }
3947 return false;
3948 }
3949
3950 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
3951
3952 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3953 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3954
3955 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
3956
3957 if(!noPropagation) {
3958 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
3959 this._trigger("stop", event, this._uiHash());
3960 }
3961
3962 this.fromOutside = false;
3963 return true;
3964
3965 },
3966
3967 _trigger: function() {
3968 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
3969 this.cancel();
3970 }
3971 },
3972
3973 _uiHash: function(inst) {
3974 var self = inst || this;
3975 return {
3976 helper: self.helper,
3977 placeholder: self.placeholder || $([]),
3978 position: self.position,
3979 originalPosition: self.originalPosition,
3980 offset: self.positionAbs,
3981 item: self.currentItem,
3982 sender: inst ? inst.element : null
3983 };
3984 }
3985
3986 });
3987
3988 $.extend($.ui.sortable, {
3989 version: "1.8.7"
3990 });
3991
3992 })(jQuery);
3993 /*
3994 * Note: While Microsoft is not the author of this file, Microsoft is
3995 * offering you a license subject to the terms of the Microsoft Software
3996 * License Terms for Microsoft ASP.NET Model View Controller 3.
3997 * Microsoft reserves all other rights. The notices below are provided
3998 * for informational purposes only and are not the license terms under
3999 * which Microsoft distributed this file.
4000 *
4001 * jQuery UI Effects 1.8.7
4002 *
4003 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
4004 *
4005 * http://docs.jquery.com/UI/Effects/
4006 */
4007 ;jQuery.effects || (function($, undefined) {
4008
4009 $.effects = {};
4010
4011
4012
4013 /******************************************************************************/
4014 /****************************** COLOR ANIMATIONS ******************************/
4015 /******************************************************************************/
4016
4017 // override the animation for color styles
4018 $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
4019 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
4020 function(i, attr) {
4021 $.fx.step[attr] = function(fx) {
4022 if (!fx.colorInit) {
4023 fx.start = getColor(fx.elem, attr);
4024 fx.end = getRGB(fx.end);
4025 fx.colorInit = true;
4026 }
4027
4028 fx.elem.style[attr] = 'rgb(' +
4029 Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
4030 Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
4031 Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
4032 };
4033 });
4034
4035 // Color Conversion functions from highlightFade
4036 // By Blair Mitchelmore
4037 // http://jquery.offput.ca/highlightFade/
4038
4039 // Parse strings looking for color tuples [255,255,255]
4040 function getRGB(color) {
4041 var result;
4042
4043 // Check if we're already dealing with an array of colors
4044 if ( color && color.constructor == Array && color.length == 3 )
4045 return color;
4046
4047 // Look for rgb(num,num,num)
4048 if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
4049 return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
4050
4051 // Look for rgb(num%,num%,num%)
4052 if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
4053 return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
4054
4055 // Look for #a0b1c2
4056 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
4057 return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
4058
4059 // Look for #fff
4060 if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
4061 return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
4062
4063 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
4064 if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
4065 return colors['transparent'];
4066
4067 // Otherwise, we're most likely dealing with a named color
4068 return colors[$.trim(color).toLowerCase()];
4069 }
4070
4071 function getColor(elem, attr) {
4072 var color;
4073
4074 do {
4075 color = $.curCSS(elem, attr);
4076
4077 // Keep going until we find an element that has color, or we hit the body
4078 if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
4079 break;
4080
4081 attr = "backgroundColor";
4082 } while ( elem = elem.parentNode );
4083
4084 return getRGB(color);
4085 };
4086
4087 // Some named colors to work with
4088 // From Interface by Stefan Petre
4089 // http://interface.eyecon.ro/
4090
4091 var colors = {
4092 aqua:[0,255,255],
4093 azure:[240,255,255],
4094 beige:[245,245,220],
4095 black:[0,0,0],
4096 blue:[0,0,255],
4097 brown:[165,42,42],
4098 cyan:[0,255,255],
4099 darkblue:[0,0,139],
4100 darkcyan:[0,139,139],
4101 darkgrey:[169,169,169],
4102 darkgreen:[0,100,0],
4103 darkkhaki:[189,183,107],
4104 darkmagenta:[139,0,139],
4105 darkolivegreen:[85,107,47],
4106 darkorange:[255,140,0],
4107 darkorchid:[153,50,204],
4108 darkred:[139,0,0],
4109 darksalmon:[233,150,122],
4110 darkviolet:[148,0,211],
4111 fuchsia:[255,0,255],
4112 gold:[255,215,0],
4113 green:[0,128,0],
4114 indigo:[75,0,130],
4115 khaki:[240,230,140],
4116 lightblue:[173,216,230],
4117 lightcyan:[224,255,255],
4118 lightgreen:[144,238,144],
4119 lightgrey:[211,211,211],
4120 lightpink:[255,182,193],
4121 lightyellow:[255,255,224],
4122 lime:[0,255,0],
4123 magenta:[255,0,255],
4124 maroon:[128,0,0],
4125 navy:[0,0,128],
4126 olive:[128,128,0],
4127 orange:[255,165,0],
4128 pink:[255,192,203],
4129 purple:[128,0,128],
4130 violet:[128,0,128],
4131 red:[255,0,0],
4132 silver:[192,192,192],
4133 white:[255,255,255],
4134 yellow:[255,255,0],
4135 transparent: [255,255,255]
4136 };
4137
4138
4139
4140 /******************************************************************************/
4141 /****************************** CLASS ANIMATIONS ******************************/
4142 /******************************************************************************/
4143
4144 var classAnimationActions = ['add', 'remove', 'toggle'],
4145 shorthandStyles = {
4146 border: 1,
4147 borderBottom: 1,
4148 borderColor: 1,
4149 borderLeft: 1,
4150 borderRight: 1,
4151 borderTop: 1,
4152 borderWidth: 1,
4153 margin: 1,
4154 padding: 1
4155 };
4156
4157 function getElementStyles() {
4158 var style = document.defaultView
4159 ? document.defaultView.getComputedStyle(this, null)
4160 : this.currentStyle,
4161 newStyle = {},
4162 key,
4163 camelCase;
4164
4165 // webkit enumerates style porperties
4166 if (style && style.length && style[0] && style[style[0]]) {
4167 var len = style.length;
4168 while (len--) {
4169 key = style[len];
4170 if (typeof style[key] == 'string') {
4171 camelCase = key.replace(/\-(\w)/g, function(all, letter){
4172 return letter.toUpperCase();
4173 });
4174 newStyle[camelCase] = style[key];
4175 }
4176 }
4177 } else {
4178 for (key in style) {
4179 if (typeof style[key] === 'string') {
4180 newStyle[key] = style[key];
4181 }
4182 }
4183 }
4184
4185 return newStyle;
4186 }
4187
4188 function filterStyles(styles) {
4189 var name, value;
4190 for (name in styles) {
4191 value = styles[name];
4192 if (
4193 // ignore null and undefined values
4194 value == null ||
4195 // ignore functions (when does this occur?)
4196 $.isFunction(value) ||
4197 // shorthand styles that need to be expanded
4198 name in shorthandStyles ||
4199 // ignore scrollbars (break in IE)
4200 (/scrollbar/).test(name) ||
4201
4202 // only colors or values that can be converted to numbers
4203 (!(/color/i).test(name) && isNaN(parseFloat(value)))
4204 ) {
4205 delete styles[name];
4206 }
4207 }
4208
4209 return styles;
4210 }
4211
4212 function styleDifference(oldStyle, newStyle) {
4213 var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
4214 name;
4215
4216 for (name in newStyle) {
4217 if (oldStyle[name] != newStyle[name]) {
4218 diff[name] = newStyle[name];
4219 }
4220 }
4221
4222 return diff;
4223 }
4224
4225 $.effects.animateClass = function(value, duration, easing, callback) {
4226 if ($.isFunction(easing)) {
4227 callback = easing;
4228 easing = null;
4229 }
4230
4231 return this.each(function() {
4232 $.queue(this, 'fx', function() {
4233 var that = $(this),
4234 originalStyleAttr = that.attr('style') || ' ',
4235 originalStyle = filterStyles(getElementStyles.call(this)),
4236 newStyle,
4237 className = that.attr('className');
4238
4239 $.each(classAnimationActions, function(i, action) {
4240 if (value[action]) {
4241 that[action + 'Class'](value[action]);
4242 }
4243 });
4244 newStyle = filterStyles(getElementStyles.call(this));
4245 that.attr('className', className);
4246
4247 that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() {
4248 $.each(classAnimationActions, function(i, action) {
4249 if (value[action]) { that[action + 'Class'](value[action]); }
4250 });
4251 // work around bug in IE by clearing the cssText before setting it
4252 if (typeof that.attr('style') == 'object') {
4253 that.attr('style').cssText = '';
4254 that.attr('style').cssText = originalStyleAttr;
4255 } else {
4256 that.attr('style', originalStyleAttr);
4257 }
4258 if (callback) { callback.apply(this, arguments); }
4259 });
4260
4261 // $.animate adds a function to the end of the queue
4262 // but we want it at the front
4263 var queue = $.queue(this),
4264 anim = queue.splice(queue.length - 1, 1)[0];
4265 queue.splice(1, 0, anim);
4266 $.dequeue(this);
4267 });
4268 });
4269 };
4270
4271 $.fn.extend({
4272 _addClass: $.fn.addClass,
4273 addClass: function(classNames, speed, easing, callback) {
4274 return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
4275 },
4276
4277 _removeClass: $.fn.removeClass,
4278 removeClass: function(classNames,speed,easing,callback) {
4279 return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
4280 },
4281
4282 _toggleClass: $.fn.toggleClass,
4283 toggleClass: function(classNames, force, speed, easing, callback) {
4284 if ( typeof force == "boolean" || force === undefined ) {
4285 if ( !speed ) {
4286 // without speed parameter;
4287 return this._toggleClass(classNames, force);
4288 } else {
4289 return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
4290 }
4291 } else {
4292 // without switch parameter;
4293 return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
4294 }
4295 },
4296
4297 switchClass: function(remove,add,speed,easing,callback) {
4298 return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
4299 }
4300 });
4301
4302
4303
4304 /******************************************************************************/
4305 /*********************************** EFFECTS **********************************/
4306 /******************************************************************************/
4307
4308 $.extend($.effects, {
4309 version: "1.8.7",
4310
4311 // Saves a set of properties in a data storage
4312 save: function(element, set) {
4313 for(var i=0; i < set.length; i++) {
4314 if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
4315 }
4316 },
4317
4318 // Restores a set of previously saved properties from a data storage
4319 restore: function(element, set) {
4320 for(var i=0; i < set.length; i++) {
4321 if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
4322 }
4323 },
4324
4325 setMode: function(el, mode) {
4326 if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
4327 return mode;
4328 },
4329
4330 getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
4331 // this should be a little more flexible in the future to handle a string & hash
4332 var y, x;
4333 switch (origin[0]) {
4334 case 'top': y = 0; break;
4335 case 'middle': y = 0.5; break;
4336 case 'bottom': y = 1; break;
4337 default: y = origin[0] / original.height;
4338 };
4339 switch (origin[1]) {
4340 case 'left': x = 0; break;
4341 case 'center': x = 0.5; break;
4342 case 'right': x = 1; break;
4343 default: x = origin[1] / original.width;
4344 };
4345 return {x: x, y: y};
4346 },
4347
4348 // Wraps the element around a wrapper that copies position properties
4349 createWrapper: function(element) {
4350
4351 // if the element is already wrapped, return it
4352 if (element.parent().is('.ui-effects-wrapper')) {
4353 return element.parent();
4354 }
4355
4356 // wrap the element
4357 var props = {
4358 width: element.outerWidth(true),
4359 height: element.outerHeight(true),
4360 'float': element.css('float')
4361 },
4362 wrapper = $('<div></div>')
4363 .addClass('ui-effects-wrapper')
4364 .css({
4365 fontSize: '100%',
4366 background: 'transparent',
4367 border: 'none',
4368 margin: 0,
4369 padding: 0
4370 });
4371
4372 element.wrap(wrapper);
4373 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
4374
4375 // transfer positioning properties to the wrapper
4376 if (element.css('position') == 'static') {
4377 wrapper.css({ position: 'relative' });
4378 element.css({ position: 'relative' });
4379 } else {
4380 $.extend(props, {
4381 position: element.css('position'),
4382 zIndex: element.css('z-index')
4383 });
4384 $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
4385 props[pos] = element.css(pos);
4386 if (isNaN(parseInt(props[pos], 10))) {
4387 props[pos] = 'auto';
4388 }
4389 });
4390 element.css({position: 'relative', top: 0, left: 0 });
4391 }
4392
4393 return wrapper.css(props).show();
4394 },
4395
4396 removeWrapper: function(element) {
4397 if (element.parent().is('.ui-effects-wrapper'))
4398 return element.parent().replaceWith(element);
4399 return element;
4400 },
4401
4402 setTransition: function(element, list, factor, value) {
4403 value = value || {};
4404 $.each(list, function(i, x){
4405 unit = element.cssUnit(x);
4406 if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
4407 });
4408 return value;
4409 }
4410 });
4411
4412
4413 function _normalizeArguments(effect, options, speed, callback) {
4414 // shift params for method overloading
4415 if (typeof effect == 'object') {
4416 callback = options;
4417 speed = null;
4418 options = effect;
4419 effect = options.effect;
4420 }
4421 if ($.isFunction(options)) {
4422 callback = options;
4423 speed = null;
4424 options = {};
4425 }
4426 if (typeof options == 'number' || $.fx.speeds[options]) {
4427 callback = speed;
4428 speed = options;
4429 options = {};
4430 }
4431 if ($.isFunction(speed)) {
4432 callback = speed;
4433 speed = null;
4434 }
4435
4436 options = options || {};
4437
4438 speed = speed || options.duration;
4439 speed = $.fx.off ? 0 : typeof speed == 'number'
4440 ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
4441
4442 callback = callback || options.complete;
4443
4444 return [effect, options, speed, callback];
4445 }
4446
4447 function standardSpeed( speed ) {
4448 // valid standard speeds
4449 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
4450 return true;
4451 }
4452
4453 // invalid strings - treat as "normal" speed
4454 if ( typeof speed === "string" && !$.effects[ speed ] ) {
4455 return true;
4456 }
4457
4458 return false;
4459 }
4460
4461 $.fn.extend({
4462 effect: function(effect, options, speed, callback) {
4463 var args = _normalizeArguments.apply(this, arguments),
4464 // TODO: make effects take actual parameters instead of a hash
4465 args2 = {
4466 options: args[1],
4467 duration: args[2],
4468 callback: args[3]
4469 },
4470 mode = args2.options.mode,
4471 effectMethod = $.effects[effect];
4472
4473 if ( $.fx.off || !effectMethod ) {
4474 // delegate to the original method (e.g., .show()) if possible
4475 if ( mode ) {
4476 return this[ mode ]( args2.duration, args2.callback );
4477 } else {
4478 return this.each(function() {
4479 if ( args2.callback ) {
4480 args2.callback.call( this );
4481 }
4482 });
4483 }
4484 }
4485
4486 return effectMethod.call(this, args2);
4487 },
4488
4489 _show: $.fn.show,
4490 show: function(speed) {
4491 if ( standardSpeed( speed ) ) {
4492 return this._show.apply(this, arguments);
4493 } else {
4494 var args = _normalizeArguments.apply(this, arguments);
4495 args[1].mode = 'show';
4496 return this.effect.apply(this, args);
4497 }
4498 },
4499
4500 _hide: $.fn.hide,
4501 hide: function(speed) {
4502 if ( standardSpeed( speed ) ) {
4503 return this._hide.apply(this, arguments);
4504 } else {
4505 var args = _normalizeArguments.apply(this, arguments);
4506 args[1].mode = 'hide';
4507 return this.effect.apply(this, args);
4508 }
4509 },
4510
4511 // jQuery core overloads toggle and creates _toggle
4512 __toggle: $.fn.toggle,
4513 toggle: function(speed) {
4514 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
4515 return this.__toggle.apply(this, arguments);
4516 } else {
4517 var args = _normalizeArguments.apply(this, arguments);
4518 args[1].mode = 'toggle';
4519 return this.effect.apply(this, args);
4520 }
4521 },
4522
4523 // helper functions
4524 cssUnit: function(key) {
4525 var style = this.css(key), val = [];
4526 $.each( ['em','px','%','pt'], function(i, unit){
4527 if(style.indexOf(unit) > 0)
4528 val = [parseFloat(style), unit];
4529 });
4530 return val;
4531 }
4532 });
4533
4534
4535
4536 /******************************************************************************/
4537 /*********************************** EASING ***********************************/
4538 /******************************************************************************/
4539
4540 /*
4541 * Note: While Microsoft is not the author of this file, Microsoft is
4542 * offering you a license subject to the terms of the Microsoft Software
4543 * License Terms for Microsoft ASP.NET Model View Controller 3.
4544 * Microsoft reserves all other rights. The notices below are provided
4545 * for informational purposes only and are not the license terms under
4546 * which Microsoft distributed this file.
4547 *
4548 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
4549 *
4550 * Uses the built in easing capabilities added In jQuery 1.1
4551 * to offer multiple easing options
4552 *
4553 * Copyright 2008 George McGinley Smith
4554 *
4555 */
4556
4557 // t: current time, b: begInnIng value, c: change In value, d: duration
4558 $.easing.jswing = $.easing.swing;
4559
4560 $.extend($.easing,
4561 {
4562 def: 'easeOutQuad',
4563 swing: function (x, t, b, c, d) {
4564 //alert($.easing.default);
4565 return $.easing[$.easing.def](x, t, b, c, d);
4566 },
4567 easeInQuad: function (x, t, b, c, d) {
4568 return c*(t/=d)*t + b;
4569 },
4570 easeOutQuad: function (x, t, b, c, d) {
4571 return -c *(t/=d)*(t-2) + b;
4572 },
4573 easeInOutQuad: function (x, t, b, c, d) {
4574 if ((t/=d/2) < 1) return c/2*t*t + b;
4575 return -c/2 * ((--t)*(t-2) - 1) + b;
4576 },
4577 easeInCubic: function (x, t, b, c, d) {
4578 return c*(t/=d)*t*t + b;
4579 },
4580 easeOutCubic: function (x, t, b, c, d) {
4581 return c*((t=t/d-1)*t*t + 1) + b;
4582 },
4583 easeInOutCubic: function (x, t, b, c, d) {
4584 if ((t/=d/2) < 1) return c/2*t*t*t + b;
4585 return c/2*((t-=2)*t*t + 2) + b;
4586 },
4587 easeInQuart: function (x, t, b, c, d) {
4588 return c*(t/=d)*t*t*t + b;
4589 },
4590 easeOutQuart: function (x, t, b, c, d) {
4591 return -c * ((t=t/d-1)*t*t*t - 1) + b;
4592 },
4593 easeInOutQuart: function (x, t, b, c, d) {
4594 if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
4595 return -c/2 * ((t-=2)*t*t*t - 2) + b;
4596 },
4597 easeInQuint: function (x, t, b, c, d) {
4598 return c*(t/=d)*t*t*t*t + b;
4599 },
4600 easeOutQuint: function (x, t, b, c, d) {
4601 return c*((t=t/d-1)*t*t*t*t + 1) + b;
4602 },
4603 easeInOutQuint: function (x, t, b, c, d) {
4604 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
4605 return c/2*((t-=2)*t*t*t*t + 2) + b;
4606 },
4607 easeInSine: function (x, t, b, c, d) {
4608 return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
4609 },
4610 easeOutSine: function (x, t, b, c, d) {
4611 return c * Math.sin(t/d * (Math.PI/2)) + b;
4612 },
4613 easeInOutSine: function (x, t, b, c, d) {
4614 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
4615 },
4616 easeInExpo: function (x, t, b, c, d) {
4617 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
4618 },
4619 easeOutExpo: function (x, t, b, c, d) {
4620 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
4621 },
4622 easeInOutExpo: function (x, t, b, c, d) {
4623 if (t==0) return b;
4624 if (t==d) return b+c;
4625 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
4626 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
4627 },
4628 easeInCirc: function (x, t, b, c, d) {
4629 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
4630 },
4631 easeOutCirc: function (x, t, b, c, d) {
4632 return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
4633 },
4634 easeInOutCirc: function (x, t, b, c, d) {
4635 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
4636 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
4637 },
4638 easeInElastic: function (x, t, b, c, d) {
4639 var s=1.70158;var p=0;var a=c;
4640 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
4641 if (a < Math.abs(c)) { a=c; var s=p/4; }
4642 else var s = p/(2*Math.PI) * Math.asin (c/a);
4643 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4644 },
4645 easeOutElastic: function (x, t, b, c, d) {
4646 var s=1.70158;var p=0;var a=c;
4647 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
4648 if (a < Math.abs(c)) { a=c; var s=p/4; }
4649 else var s = p/(2*Math.PI) * Math.asin (c/a);
4650 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
4651 },
4652 easeInOutElastic: function (x, t, b, c, d) {
4653 var s=1.70158;var p=0;var a=c;
4654 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
4655 if (a < Math.abs(c)) { a=c; var s=p/4; }
4656 else var s = p/(2*Math.PI) * Math.asin (c/a);
4657 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4658 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
4659 },
4660 easeInBack: function (x, t, b, c, d, s) {
4661 if (s == undefined) s = 1.70158;
4662 return c*(t/=d)*t*((s+1)*t - s) + b;
4663 },
4664 easeOutBack: function (x, t, b, c, d, s) {
4665 if (s == undefined) s = 1.70158;
4666 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
4667 },
4668 easeInOutBack: function (x, t, b, c, d, s) {
4669 if (s == undefined) s = 1.70158;
4670 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
4671 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
4672 },
4673 easeInBounce: function (x, t, b, c, d) {
4674 return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
4675 },
4676 easeOutBounce: function (x, t, b, c, d) {
4677 if ((t/=d) < (1/2.75)) {
4678 return c*(7.5625*t*t) + b;
4679 } else if (t < (2/2.75)) {
4680 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
4681 } else if (t < (2.5/2.75)) {
4682 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
4683 } else {
4684 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
4685 }
4686 },
4687 easeInOutBounce: function (x, t, b, c, d) {
4688 if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
4689 return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
4690 }
4691 });
4692
4693 /*
4694 * Note: While Microsoft is not the author of this file, Microsoft is
4695 * offering you a license subject to the terms of the Microsoft Software
4696 * License Terms for Microsoft ASP.NET Model View Controller 3.
4697 * Microsoft reserves all other rights. The notices below are provided
4698 * for informational purposes only and are not the license terms under
4699 * which Microsoft distributed this file.
4700 *
4701 * Copyright 2001 Robert Penner
4702 *
4703 */
4704
4705 })(jQuery);
4706 /*
4707 * Note: While Microsoft is not the author of this file, Microsoft is
4708 * offering you a license subject to the terms of the Microsoft Software
4709 * License Terms for Microsoft ASP.NET Model View Controller 3.
4710 * Microsoft reserves all other rights. The notices below are provided
4711 * for informational purposes only and are not the license terms under
4712 * which Microsoft distributed this file.
4713 *
4714 * jQuery UI Effects Blind 1.8.7
4715 *
4716 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
4717 *
4718 * http://docs.jquery.com/UI/Effects/Blind
4719 *
4720 * Depends:
4721 * jquery.effects.core.js
4722 */
4723 (function( $, undefined ) {
4724
4725 $.effects.blind = function(o) {
4726
4727 return this.queue(function() {
4728
4729 // Create element
4730 var el = $(this), props = ['position','top','left'];
4731
4732 // Set options
4733 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4734 var direction = o.options.direction || 'vertical'; // Default direction
4735
4736 // Adjust
4737 $.effects.save(el, props); el.show(); // Save & Show
4738 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
4739 var ref = (direction == 'vertical') ? 'height' : 'width';
4740 var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
4741 if(mode == 'show') wrapper.css(ref, 0); // Shift
4742
4743 // Animation
4744 var animation = {};
4745 animation[ref] = mode == 'show' ? distance : 0;
4746
4747 // Animate
4748 wrapper.animate(animation, o.duration, o.options.easing, function() {
4749 if(mode == 'hide') el.hide(); // Hide
4750 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4751 if(o.callback) o.callback.apply(el[0], arguments); // Callback
4752 el.dequeue();
4753 });
4754
4755 });
4756
4757 };
4758
4759 })(jQuery);
4760 /*
4761 * Note: While Microsoft is not the author of this file, Microsoft is
4762 * offering you a license subject to the terms of the Microsoft Software
4763 * License Terms for Microsoft ASP.NET Model View Controller 3.
4764 * Microsoft reserves all other rights. The notices below are provided
4765 * for informational purposes only and are not the license terms under
4766 * which Microsoft distributed this file.
4767 *
4768 * jQuery UI Effects Bounce 1.8.7
4769 *
4770 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
4771 *
4772 * http://docs.jquery.com/UI/Effects/Bounce
4773 *
4774 * Depends:
4775 * jquery.effects.core.js
4776 */
4777 (function( $, undefined ) {
4778
4779 $.effects.bounce = function(o) {
4780
4781 return this.queue(function() {
4782
4783 // Create element
4784 var el = $(this), props = ['position','top','left'];
4785
4786 // Set options
4787 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
4788 var direction = o.options.direction || 'up'; // Default direction
4789 var distance = o.options.distance || 20; // Default distance
4790 var times = o.options.times || 5; // Default # of times
4791 var speed = o.duration || 250; // Default speed per bounce
4792 if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
4793
4794 // Adjust
4795 $.effects.save(el, props); el.show(); // Save & Show
4796 $.effects.createWrapper(el); // Create Wrapper
4797 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4798 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4799 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
4800 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
4801 if (mode == 'hide') distance = distance / (times * 2);
4802 if (mode != 'hide') times--;
4803
4804 // Animate
4805 if (mode == 'show') { // Show Bounce
4806 var animation = {opacity: 1};
4807 animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4808 el.animate(animation, speed / 2, o.options.easing);
4809 distance = distance / 2;
4810 times--;
4811 };
4812 for (var i = 0; i < times; i++) { // Bounces
4813 var animation1 = {}, animation2 = {};
4814 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4815 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4816 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
4817 distance = (mode == 'hide') ? distance * 2 : distance / 2;
4818 };
4819 if (mode == 'hide') { // Last Bounce
4820 var animation = {opacity: 0};
4821 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4822 el.animate(animation, speed / 2, o.options.easing, function(){
4823 el.hide(); // Hide
4824 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4825 if(o.callback) o.callback.apply(this, arguments); // Callback
4826 });
4827 } else {
4828 var animation1 = {}, animation2 = {};
4829 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4830 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4831 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
4832 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4833 if(o.callback) o.callback.apply(this, arguments); // Callback
4834 });
4835 };
4836 el.queue('fx', function() { el.dequeue(); });
4837 el.dequeue();
4838 });
4839
4840 };
4841
4842 })(jQuery);
4843 /*
4844 * Note: While Microsoft is not the author of this file, Microsoft is
4845 * offering you a license subject to the terms of the Microsoft Software
4846 * License Terms for Microsoft ASP.NET Model View Controller 3.
4847 * Microsoft reserves all other rights. The notices below are provided
4848 * for informational purposes only and are not the license terms under
4849 * which Microsoft distributed this file.
4850 *
4851 * jQuery UI Effects Clip 1.8.7
4852 *
4853 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
4854 *
4855 * http://docs.jquery.com/UI/Effects/Clip
4856 *
4857 * Depends:
4858 * jquery.effects.core.js
4859 */
4860 (function( $, undefined ) {
4861
4862 $.effects.clip = function(o) {
4863
4864 return this.queue(function() {
4865
4866 // Create element
4867 var el = $(this), props = ['position','top','left','height','width'];
4868
4869 // Set options
4870 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4871 var direction = o.options.direction || 'vertical'; // Default direction
4872
4873 // Adjust
4874 $.effects.save(el, props); el.show(); // Save & Show
4875 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
4876 var animate = el[0].tagName == 'IMG' ? wrapper : el;
4877 var ref = {
4878 size: (direction == 'vertical') ? 'height' : 'width',
4879 position: (direction == 'vertical') ? 'top' : 'left'
4880 };
4881 var distance = (direction == 'vertical') ? animate.height() : animate.width();
4882 if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
4883
4884 // Animation
4885 var animation = {};
4886 animation[ref.size] = mode == 'show' ? distance : 0;
4887 animation[ref.position] = mode == 'show' ? 0 : distance / 2;
4888
4889 // Animate
4890 animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4891 if(mode == 'hide') el.hide(); // Hide
4892 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4893 if(o.callback) o.callback.apply(el[0], arguments); // Callback
4894 el.dequeue();
4895 }});
4896
4897 });
4898
4899 };
4900
4901 })(jQuery);
4902 /*
4903 * Note: While Microsoft is not the author of this file, Microsoft is
4904 * offering you a license subject to the terms of the Microsoft Software
4905 * License Terms for Microsoft ASP.NET Model View Controller 3.
4906 * Microsoft reserves all other rights. The notices below are provided
4907 * for informational purposes only and are not the license terms under
4908 * which Microsoft distributed this file.
4909 *
4910 * jQuery UI Effects Drop 1.8.7
4911 *
4912 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
4913 *
4914 * http://docs.jquery.com/UI/Effects/Drop
4915 *
4916 * Depends:
4917 * jquery.effects.core.js
4918 */
4919 (function( $, undefined ) {
4920
4921 $.effects.drop = function(o) {
4922
4923 return this.queue(function() {
4924
4925 // Create element
4926 var el = $(this), props = ['position','top','left','opacity'];
4927
4928 // Set options
4929 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4930 var direction = o.options.direction || 'left'; // Default Direction
4931
4932 // Adjust
4933 $.effects.save(el, props); el.show(); // Save & Show
4934 $.effects.createWrapper(el); // Create Wrapper
4935 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4936 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4937 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
4938 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
4939
4940 // Animation
4941 var animation = {opacity: mode == 'show' ? 1 : 0};
4942 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
4943
4944 // Animate
4945 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4946 if(mode == 'hide') el.hide(); // Hide
4947 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4948 if(o.callback) o.callback.apply(this, arguments); // Callback
4949 el.dequeue();
4950 }});
4951
4952 });
4953
4954 };
4955
4956 })(jQuery);
4957 /*
4958 * Note: While Microsoft is not the author of this file, Microsoft is
4959 * offering you a license subject to the terms of the Microsoft Software
4960 * License Terms for Microsoft ASP.NET Model View Controller 3.
4961 * Microsoft reserves all other rights. The notices below are provided
4962 * for informational purposes only and are not the license terms under
4963 * which Microsoft distributed this file.
4964 *
4965 * jQuery UI Effects Explode 1.8.7
4966 *
4967 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
4968 *
4969 * http://docs.jquery.com/UI/Effects/Explode
4970 *
4971 * Depends:
4972 * jquery.effects.core.js
4973 */
4974 (function( $, undefined ) {
4975
4976 $.effects.explode = function(o) {
4977
4978 return this.queue(function() {
4979
4980 var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
4981 var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
4982
4983 o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
4984 var el = $(this).show().css('visibility', 'hidden');
4985 var offset = el.offset();
4986
4987 //Substract the margins - not fixing the problem yet.
4988 offset.top -= parseInt(el.css("marginTop"),10) || 0;
4989 offset.left -= parseInt(el.css("marginLeft"),10) || 0;
4990
4991 var width = el.outerWidth(true);
4992 var height = el.outerHeight(true);
4993
4994 for(var i=0;i<rows;i++) { // =
4995 for(var j=0;j<cells;j++) { // ||
4996 el
4997 .clone()
4998 .appendTo('body')
4999 .wrap('<div></div>')
5000 .css({
5001 position: 'absolute',
5002 visibility: 'visible',
5003 left: -j*(width/cells),
5004 top: -i*(height/rows)
5005 })
5006 .parent()
5007 .addClass('ui-effects-explode')
5008 .css({
5009 position: 'absolute',
5010 overflow: 'hidden',
5011 width: width/cells,
5012 height: height/rows,
5013 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
5014 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
5015 opacity: o.options.mode == 'show' ? 0 : 1
5016 }).animate({
5017 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
5018 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
5019 opacity: o.options.mode == 'show' ? 1 : 0
5020 }, o.duration || 500);
5021 }
5022 }
5023
5024 // Set a timeout, to call the callback approx. when the other animations have finished
5025 setTimeout(function() {
5026
5027 o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
5028 if(o.callback) o.callback.apply(el[0]); // Callback
5029 el.dequeue();
5030
5031 $('div.ui-effects-explode').remove();
5032
5033 }, o.duration || 500);
5034
5035
5036 });
5037
5038 };
5039
5040 })(jQuery);
5041 /*
5042 * Note: While Microsoft is not the author of this file, Microsoft is
5043 * offering you a license subject to the terms of the Microsoft Software
5044 * License Terms for Microsoft ASP.NET Model View Controller 3.
5045 * Microsoft reserves all other rights. The notices below are provided
5046 * for informational purposes only and are not the license terms under
5047 * which Microsoft distributed this file.
5048 *
5049 * jQuery UI Effects Fade 1.8.7
5050 *
5051 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5052 *
5053 * http://docs.jquery.com/UI/Effects/Fade
5054 *
5055 * Depends:
5056 * jquery.effects.core.js
5057 */
5058 (function( $, undefined ) {
5059
5060 $.effects.fade = function(o) {
5061 return this.queue(function() {
5062 var elem = $(this),
5063 mode = $.effects.setMode(elem, o.options.mode || 'hide');
5064
5065 elem.animate({ opacity: mode }, {
5066 queue: false,
5067 duration: o.duration,
5068 easing: o.options.easing,
5069 complete: function() {
5070 (o.callback && o.callback.apply(this, arguments));
5071 elem.dequeue();
5072 }
5073 });
5074 });
5075 };
5076
5077 })(jQuery);
5078 /*
5079 * Note: While Microsoft is not the author of this file, Microsoft is
5080 * offering you a license subject to the terms of the Microsoft Software
5081 * License Terms for Microsoft ASP.NET Model View Controller 3.
5082 * Microsoft reserves all other rights. The notices below are provided
5083 * for informational purposes only and are not the license terms under
5084 * which Microsoft distributed this file.
5085 *
5086 * jQuery UI Effects Fold 1.8.7
5087 *
5088 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5089 *
5090 * http://docs.jquery.com/UI/Effects/Fold
5091 *
5092 * Depends:
5093 * jquery.effects.core.js
5094 */
5095 (function( $, undefined ) {
5096
5097 $.effects.fold = function(o) {
5098
5099 return this.queue(function() {
5100
5101 // Create element
5102 var el = $(this), props = ['position','top','left'];
5103
5104 // Set options
5105 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
5106 var size = o.options.size || 15; // Default fold size
5107 var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
5108 var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
5109
5110 // Adjust
5111 $.effects.save(el, props); el.show(); // Save & Show
5112 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
5113 var widthFirst = ((mode == 'show') != horizFirst);
5114 var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
5115 var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
5116 var percent = /([0-9]+)%/.exec(size);
5117 if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
5118 if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
5119
5120 // Animation
5121 var animation1 = {}, animation2 = {};
5122 animation1[ref[0]] = mode == 'show' ? distance[0] : size;
5123 animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
5124
5125 // Animate
5126 wrapper.animate(animation1, duration, o.options.easing)
5127 .animate(animation2, duration, o.options.easing, function() {
5128 if(mode == 'hide') el.hide(); // Hide
5129 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5130 if(o.callback) o.callback.apply(el[0], arguments); // Callback
5131 el.dequeue();
5132 });
5133
5134 });
5135
5136 };
5137
5138 })(jQuery);
5139 /*
5140 * Note: While Microsoft is not the author of this file, Microsoft is
5141 * offering you a license subject to the terms of the Microsoft Software
5142 * License Terms for Microsoft ASP.NET Model View Controller 3.
5143 * Microsoft reserves all other rights. The notices below are provided
5144 * for informational purposes only and are not the license terms under
5145 * which Microsoft distributed this file.
5146 *
5147 * jQuery UI Effects Highlight 1.8.7
5148 *
5149 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5150 *
5151 * http://docs.jquery.com/UI/Effects/Highlight
5152 *
5153 * Depends:
5154 * jquery.effects.core.js
5155 */
5156 (function( $, undefined ) {
5157
5158 $.effects.highlight = function(o) {
5159 return this.queue(function() {
5160 var elem = $(this),
5161 props = ['backgroundImage', 'backgroundColor', 'opacity'],
5162 mode = $.effects.setMode(elem, o.options.mode || 'show'),
5163 animation = {
5164 backgroundColor: elem.css('backgroundColor')
5165 };
5166
5167 if (mode == 'hide') {
5168 animation.opacity = 0;
5169 }
5170
5171 $.effects.save(elem, props);
5172 elem
5173 .show()
5174 .css({
5175 backgroundImage: 'none',
5176 backgroundColor: o.options.color || '#ffff99'
5177 })
5178 .animate(animation, {
5179 queue: false,
5180 duration: o.duration,
5181 easing: o.options.easing,
5182 complete: function() {
5183 (mode == 'hide' && elem.hide());
5184 $.effects.restore(elem, props);
5185 (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
5186 (o.callback && o.callback.apply(this, arguments));
5187 elem.dequeue();
5188 }
5189 });
5190 });
5191 };
5192
5193 })(jQuery);
5194 /*
5195 * Note: While Microsoft is not the author of this file, Microsoft is
5196 * offering you a license subject to the terms of the Microsoft Software
5197 * License Terms for Microsoft ASP.NET Model View Controller 3.
5198 * Microsoft reserves all other rights. The notices below are provided
5199 * for informational purposes only and are not the license terms under
5200 * which Microsoft distributed this file.
5201 *
5202 * jQuery UI Effects Pulsate 1.8.7
5203 *
5204 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5205 *
5206 * http://docs.jquery.com/UI/Effects/Pulsate
5207 *
5208 * Depends:
5209 * jquery.effects.core.js
5210 */
5211 (function( $, undefined ) {
5212
5213 $.effects.pulsate = function(o) {
5214 return this.queue(function() {
5215 var elem = $(this),
5216 mode = $.effects.setMode(elem, o.options.mode || 'show');
5217 times = ((o.options.times || 5) * 2) - 1;
5218 duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
5219 isVisible = elem.is(':visible'),
5220 animateTo = 0;
5221
5222 if (!isVisible) {
5223 elem.css('opacity', 0).show();
5224 animateTo = 1;
5225 }
5226
5227 if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
5228 times--;
5229 }
5230
5231 for (var i = 0; i < times; i++) {
5232 elem.animate({ opacity: animateTo }, duration, o.options.easing);
5233 animateTo = (animateTo + 1) % 2;
5234 }
5235
5236 elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
5237 if (animateTo == 0) {
5238 elem.hide();
5239 }
5240 (o.callback && o.callback.apply(this, arguments));
5241 });
5242
5243 elem
5244 .queue('fx', function() { elem.dequeue(); })
5245 .dequeue();
5246 });
5247 };
5248
5249 })(jQuery);
5250 /*
5251 * Note: While Microsoft is not the author of this file, Microsoft is
5252 * offering you a license subject to the terms of the Microsoft Software
5253 * License Terms for Microsoft ASP.NET Model View Controller 3.
5254 * Microsoft reserves all other rights. The notices below are provided
5255 * for informational purposes only and are not the license terms under
5256 * which Microsoft distributed this file.
5257 *
5258 * jQuery UI Effects Scale 1.8.7
5259 *
5260 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5261 *
5262 * http://docs.jquery.com/UI/Effects/Scale
5263 *
5264 * Depends:
5265 * jquery.effects.core.js
5266 */
5267 (function( $, undefined ) {
5268
5269 $.effects.puff = function(o) {
5270 return this.queue(function() {
5271 var elem = $(this),
5272 mode = $.effects.setMode(elem, o.options.mode || 'hide'),
5273 percent = parseInt(o.options.percent, 10) || 150,
5274 factor = percent / 100,
5275 original = { height: elem.height(), width: elem.width() };
5276
5277 $.extend(o.options, {
5278 fade: true,
5279 mode: mode,
5280 percent: mode == 'hide' ? percent : 100,
5281 from: mode == 'hide'
5282 ? original
5283 : {
5284 height: original.height * factor,
5285 width: original.width * factor
5286 }
5287 });
5288
5289 elem.effect('scale', o.options, o.duration, o.callback);
5290 elem.dequeue();
5291 });
5292 };
5293
5294 $.effects.scale = function(o) {
5295
5296 return this.queue(function() {
5297
5298 // Create element
5299 var el = $(this);
5300
5301 // Set options
5302 var options = $.extend(true, {}, o.options);
5303 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5304 var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
5305 var direction = o.options.direction || 'both'; // Set default axis
5306 var origin = o.options.origin; // The origin of the scaling
5307 if (mode != 'effect') { // Set default origin and restore for show/hide
5308 options.origin = origin || ['middle','center'];
5309 options.restore = true;
5310 }
5311 var original = {height: el.height(), width: el.width()}; // Save original
5312 el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
5313
5314 // Adjust
5315 var factor = { // Set scaling factor
5316 y: direction != 'horizontal' ? (percent / 100) : 1,
5317 x: direction != 'vertical' ? (percent / 100) : 1
5318 };
5319 el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
5320
5321 if (o.options.fade) { // Fade option to support puff
5322 if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
5323 if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
5324 };
5325
5326 // Animation
5327 options.from = el.from; options.to = el.to; options.mode = mode;
5328
5329 // Animate
5330 el.effect('size', options, o.duration, o.callback);
5331 el.dequeue();
5332 });
5333
5334 };
5335
5336 $.effects.size = function(o) {
5337
5338 return this.queue(function() {
5339
5340 // Create element
5341 var el = $(this), props = ['position','top','left','width','height','overflow','opacity'];
5342 var props1 = ['position','top','left','overflow','opacity']; // Always restore
5343 var props2 = ['width','height','overflow']; // Copy for children
5344 var cProps = ['fontSize'];
5345 var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
5346 var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
5347
5348 // Set options
5349 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5350 var restore = o.options.restore || false; // Default restore
5351 var scale = o.options.scale || 'both'; // Default scale mode
5352 var origin = o.options.origin; // The origin of the sizing
5353 var original = {height: el.height(), width: el.width()}; // Save original
5354 el.from = o.options.from || original; // Default from state
5355 el.to = o.options.to || original; // Default to state
5356 // Adjust
5357 if (origin) { // Calculate baseline shifts
5358 var baseline = $.effects.getBaseline(origin, original);
5359 el.from.top = (original.height - el.from.height) * baseline.y;
5360 el.from.left = (original.width - el.from.width) * baseline.x;
5361 el.to.top = (original.height - el.to.height) * baseline.y;
5362 el.to.left = (original.width - el.to.width) * baseline.x;
5363 };
5364 var factor = { // Set scaling factor
5365 from: {y: el.from.height / original.height, x: el.from.width / original.width},
5366 to: {y: el.to.height / original.height, x: el.to.width / original.width}
5367 };
5368 if (scale == 'box' || scale == 'both') { // Scale the css box
5369 if (factor.from.y != factor.to.y) { // Vertical props scaling
5370 props = props.concat(vProps);
5371 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
5372 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
5373 };
5374 if (factor.from.x != factor.to.x) { // Horizontal props scaling
5375 props = props.concat(hProps);
5376 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
5377 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
5378 };
5379 };
5380 if (scale == 'content' || scale == 'both') { // Scale the content
5381 if (factor.from.y != factor.to.y) { // Vertical props scaling
5382 props = props.concat(cProps);
5383 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
5384 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
5385 };
5386 };
5387 $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
5388 $.effects.createWrapper(el); // Create Wrapper
5389 el.css('overflow','hidden').css(el.from); // Shift
5390
5391 // Animate
5392 if (scale == 'content' || scale == 'both') { // Scale the children
5393 vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
5394 hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
5395 props2 = props.concat(vProps).concat(hProps); // Concat
5396 el.find("*[width]").each(function(){
5397 child = $(this);
5398 if (restore) $.effects.save(child, props2);
5399 var c_original = {height: child.height(), width: child.width()}; // Save original
5400 child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
5401 child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
5402 if (factor.from.y != factor.to.y) { // Vertical props scaling
5403 child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
5404 child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
5405 };
5406 if (factor.from.x != factor.to.x) { // Horizontal props scaling
5407 child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
5408 child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
5409 };
5410 child.css(child.from); // Shift children
5411 child.animate(child.to, o.duration, o.options.easing, function(){
5412 if (restore) $.effects.restore(child, props2); // Restore children
5413 }); // Animate children
5414 });
5415 };
5416
5417 // Animate
5418 el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5419 if (el.to.opacity === 0) {
5420 el.css('opacity', el.from.opacity);
5421 }
5422 if(mode == 'hide') el.hide(); // Hide
5423 $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
5424 if(o.callback) o.callback.apply(this, arguments); // Callback
5425 el.dequeue();
5426 }});
5427
5428 });
5429
5430 };
5431
5432 })(jQuery);
5433 /*
5434 * Note: While Microsoft is not the author of this file, Microsoft is
5435 * offering you a license subject to the terms of the Microsoft Software
5436 * License Terms for Microsoft ASP.NET Model View Controller 3.
5437 * Microsoft reserves all other rights. The notices below are provided
5438 * for informational purposes only and are not the license terms under
5439 * which Microsoft distributed this file.
5440 *
5441 * jQuery UI Effects Shake 1.8.7
5442 *
5443 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5444 *
5445 * http://docs.jquery.com/UI/Effects/Shake
5446 *
5447 * Depends:
5448 * jquery.effects.core.js
5449 */
5450 (function( $, undefined ) {
5451
5452 $.effects.shake = function(o) {
5453
5454 return this.queue(function() {
5455
5456 // Create element
5457 var el = $(this), props = ['position','top','left'];
5458
5459 // Set options
5460 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5461 var direction = o.options.direction || 'left'; // Default direction
5462 var distance = o.options.distance || 20; // Default distance
5463 var times = o.options.times || 3; // Default # of times
5464 var speed = o.duration || o.options.duration || 140; // Default speed per shake
5465
5466 // Adjust
5467 $.effects.save(el, props); el.show(); // Save & Show
5468 $.effects.createWrapper(el); // Create Wrapper
5469 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5470 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5471
5472 // Animation
5473 var animation = {}, animation1 = {}, animation2 = {};
5474 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
5475 animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
5476 animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
5477
5478 // Animate
5479 el.animate(animation, speed, o.options.easing);
5480 for (var i = 1; i < times; i++) { // Shakes
5481 el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
5482 };
5483 el.animate(animation1, speed, o.options.easing).
5484 animate(animation, speed / 2, o.options.easing, function(){ // Last shake
5485 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5486 if(o.callback) o.callback.apply(this, arguments); // Callback
5487 });
5488 el.queue('fx', function() { el.dequeue(); });
5489 el.dequeue();
5490 });
5491
5492 };
5493
5494 })(jQuery);
5495 /*
5496 * Note: While Microsoft is not the author of this file, Microsoft is
5497 * offering you a license subject to the terms of the Microsoft Software
5498 * License Terms for Microsoft ASP.NET Model View Controller 3.
5499 * Microsoft reserves all other rights. The notices below are provided
5500 * for informational purposes only and are not the license terms under
5501 * which Microsoft distributed this file.
5502 *
5503 * jQuery UI Effects Slide 1.8.7
5504 *
5505 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5506 *
5507 * http://docs.jquery.com/UI/Effects/Slide
5508 *
5509 * Depends:
5510 * jquery.effects.core.js
5511 */
5512 (function( $, undefined ) {
5513
5514 $.effects.slide = function(o) {
5515
5516 return this.queue(function() {
5517
5518 // Create element
5519 var el = $(this), props = ['position','top','left'];
5520
5521 // Set options
5522 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
5523 var direction = o.options.direction || 'left'; // Default Direction
5524
5525 // Adjust
5526 $.effects.save(el, props); el.show(); // Save & Show
5527 $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
5528 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5529 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5530 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
5531 if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
5532
5533 // Animation
5534 var animation = {};
5535 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
5536
5537 // Animate
5538 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5539 if(mode == 'hide') el.hide(); // Hide
5540 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5541 if(o.callback) o.callback.apply(this, arguments); // Callback
5542 el.dequeue();
5543 }});
5544
5545 });
5546
5547 };
5548
5549 })(jQuery);
5550 /*
5551 * Note: While Microsoft is not the author of this file, Microsoft is
5552 * offering you a license subject to the terms of the Microsoft Software
5553 * License Terms for Microsoft ASP.NET Model View Controller 3.
5554 * Microsoft reserves all other rights. The notices below are provided
5555 * for informational purposes only and are not the license terms under
5556 * which Microsoft distributed this file.
5557 *
5558 * jQuery UI Effects Transfer 1.8.7
5559 *
5560 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5561 *
5562 * http://docs.jquery.com/UI/Effects/Transfer
5563 *
5564 * Depends:
5565 * jquery.effects.core.js
5566 */
5567 (function( $, undefined ) {
5568
5569 $.effects.transfer = function(o) {
5570 return this.queue(function() {
5571 var elem = $(this),
5572 target = $(o.options.to),
5573 endPosition = target.offset(),
5574 animation = {
5575 top: endPosition.top,
5576 left: endPosition.left,
5577 height: target.innerHeight(),
5578 width: target.innerWidth()
5579 },
5580 startPosition = elem.offset(),
5581 transfer = $('<div class="ui-effects-transfer"></div>')
5582 .appendTo(document.body)
5583 .addClass(o.options.className)
5584 .css({
5585 top: startPosition.top,
5586 left: startPosition.left,
5587 height: elem.innerHeight(),
5588 width: elem.innerWidth(),
5589 position: 'absolute'
5590 })
5591 .animate(animation, o.duration, o.options.easing, function() {
5592 transfer.remove();
5593 (o.callback && o.callback.apply(elem[0], arguments));
5594 elem.dequeue();
5595 });
5596 });
5597 };
5598
5599 })(jQuery);
5600 /*
5601 * Note: While Microsoft is not the author of this file, Microsoft is
5602 * offering you a license subject to the terms of the Microsoft Software
5603 * License Terms for Microsoft ASP.NET Model View Controller 3.
5604 * Microsoft reserves all other rights. The notices below are provided
5605 * for informational purposes only and are not the license terms under
5606 * which Microsoft distributed this file.
5607 *
5608 * jQuery UI Accordion 1.8.7
5609 *
5610 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5611 *
5612 * http://docs.jquery.com/UI/Accordion
5613 *
5614 * Depends:
5615 * jquery.ui.core.js
5616 * jquery.ui.widget.js
5617 */
5618 (function( $, undefined ) {
5619
5620 $.widget( "ui.accordion", {
5621 options: {
5622 active: 0,
5623 animated: "slide",
5624 autoHeight: true,
5625 clearStyle: false,
5626 collapsible: false,
5627 event: "click",
5628 fillSpace: false,
5629 header: "> li > :first-child,> :not(li):even",
5630 icons: {
5631 header: "ui-icon-triangle-1-e",
5632 headerSelected: "ui-icon-triangle-1-s"
5633 },
5634 navigation: false,
5635 navigationFilter: function() {
5636 return this.href.toLowerCase() === location.href.toLowerCase();
5637 }
5638 },
5639
5640 _create: function() {
5641 var self = this,
5642 options = self.options;
5643
5644 self.running = 0;
5645
5646 self.element
5647 .addClass( "ui-accordion ui-widget ui-helper-reset" )
5648 // in lack of child-selectors in CSS
5649 // we need to mark top-LIs in a UL-accordion for some IE-fix
5650 .children( "li" )
5651 .addClass( "ui-accordion-li-fix" );
5652
5653 self.headers = self.element.find( options.header )
5654 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
5655 .bind( "mouseenter.accordion", function() {
5656 if ( options.disabled ) {
5657 return;
5658 }
5659 $( this ).addClass( "ui-state-hover" );
5660 })
5661 .bind( "mouseleave.accordion", function() {
5662 if ( options.disabled ) {
5663 return;
5664 }
5665 $( this ).removeClass( "ui-state-hover" );
5666 })
5667 .bind( "focus.accordion", function() {
5668 if ( options.disabled ) {
5669 return;
5670 }
5671 $( this ).addClass( "ui-state-focus" );
5672 })
5673 .bind( "blur.accordion", function() {
5674 if ( options.disabled ) {
5675 return;
5676 }
5677 $( this ).removeClass( "ui-state-focus" );
5678 });
5679
5680 self.headers.next()
5681 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
5682
5683 if ( options.navigation ) {
5684 var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
5685 if ( current.length ) {
5686 var header = current.closest( ".ui-accordion-header" );
5687 if ( header.length ) {
5688 // anchor within header
5689 self.active = header;
5690 } else {
5691 // anchor within content
5692 self.active = current.closest( ".ui-accordion-content" ).prev();
5693 }
5694 }
5695 }
5696
5697 self.active = self._findActive( self.active || options.active )
5698 .addClass( "ui-state-default ui-state-active" )
5699 .toggleClass( "ui-corner-all" )
5700 .toggleClass( "ui-corner-top" );
5701 self.active.next().addClass( "ui-accordion-content-active" );
5702
5703 self._createIcons();
5704 self.resize();
5705
5706 // ARIA
5707 self.element.attr( "role", "tablist" );
5708
5709 self.headers
5710 .attr( "role", "tab" )
5711 .bind( "keydown.accordion", function( event ) {
5712 return self._keydown( event );
5713 })
5714 .next()
5715 .attr( "role", "tabpanel" );
5716
5717 self.headers
5718 .not( self.active || "" )
5719 .attr({
5720 "aria-expanded": "false",
5721 tabIndex: -1
5722 })
5723 .next()
5724 .hide();
5725
5726 // make sure at least one header is in the tab order
5727 if ( !self.active.length ) {
5728 self.headers.eq( 0 ).attr( "tabIndex", 0 );
5729 } else {
5730 self.active
5731 .attr({
5732 "aria-expanded": "true",
5733 tabIndex: 0
5734 });
5735 }
5736
5737 // only need links in tab order for Safari
5738 if ( !$.browser.safari ) {
5739 self.headers.find( "a" ).attr( "tabIndex", -1 );
5740 }
5741
5742 if ( options.event ) {
5743 self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
5744 self._clickHandler.call( self, event, this );
5745 event.preventDefault();
5746 });
5747 }
5748 },
5749
5750 _createIcons: function() {
5751 var options = this.options;
5752 if ( options.icons ) {
5753 $( "<span></span>" )
5754 .addClass( "ui-icon " + options.icons.header )
5755 .prependTo( this.headers );
5756 this.active.children( ".ui-icon" )
5757 .toggleClass(options.icons.header)
5758 .toggleClass(options.icons.headerSelected);
5759 this.element.addClass( "ui-accordion-icons" );
5760 }
5761 },
5762
5763 _destroyIcons: function() {
5764 this.headers.children( ".ui-icon" ).remove();
5765 this.element.removeClass( "ui-accordion-icons" );
5766 },
5767
5768 destroy: function() {
5769 var options = this.options;
5770
5771 this.element
5772 .removeClass( "ui-accordion ui-widget ui-helper-reset" )
5773 .removeAttr( "role" );
5774
5775 this.headers
5776 .unbind( ".accordion" )
5777 .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5778 .removeAttr( "role" )
5779 .removeAttr( "aria-expanded" )
5780 .removeAttr( "tabIndex" );
5781
5782 this.headers.find( "a" ).removeAttr( "tabIndex" );
5783 this._destroyIcons();
5784 var contents = this.headers.next()
5785 .css( "display", "" )
5786 .removeAttr( "role" )
5787 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
5788 if ( options.autoHeight || options.fillHeight ) {
5789 contents.css( "height", "" );
5790 }
5791
5792 return $.Widget.prototype.destroy.call( this );
5793 },
5794
5795 _setOption: function( key, value ) {
5796 $.Widget.prototype._setOption.apply( this, arguments );
5797
5798 if ( key == "active" ) {
5799 this.activate( value );
5800 }
5801 if ( key == "icons" ) {
5802 this._destroyIcons();
5803 if ( value ) {
5804 this._createIcons();
5805 }
5806 }
5807 // #5332 - opacity doesn't cascade to positioned elements in IE
5808 // so we need to add the disabled class to the headers and panels
5809 if ( key == "disabled" ) {
5810 this.headers.add(this.headers.next())
5811 [ value ? "addClass" : "removeClass" ](
5812 "ui-accordion-disabled ui-state-disabled" );
5813 }
5814 },
5815
5816 _keydown: function( event ) {
5817 if ( this.options.disabled || event.altKey || event.ctrlKey ) {
5818 return;
5819 }
5820
5821 var keyCode = $.ui.keyCode,
5822 length = this.headers.length,
5823 currentIndex = this.headers.index( event.target ),
5824 toFocus = false;
5825
5826 switch ( event.keyCode ) {
5827 case keyCode.RIGHT:
5828 case keyCode.DOWN:
5829 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5830 break;
5831 case keyCode.LEFT:
5832 case keyCode.UP:
5833 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5834 break;
5835 case keyCode.SPACE:
5836 case keyCode.ENTER:
5837 this._clickHandler( { target: event.target }, event.target );
5838 event.preventDefault();
5839 }
5840
5841 if ( toFocus ) {
5842 $( event.target ).attr( "tabIndex", -1 );
5843 $( toFocus ).attr( "tabIndex", 0 );
5844 toFocus.focus();
5845 return false;
5846 }
5847
5848 return true;
5849 },
5850
5851 resize: function() {
5852 var options = this.options,
5853 maxHeight;
5854
5855 if ( options.fillSpace ) {
5856 if ( $.browser.msie ) {
5857 var defOverflow = this.element.parent().css( "overflow" );
5858 this.element.parent().css( "overflow", "hidden");
5859 }
5860 maxHeight = this.element.parent().height();
5861 if ($.browser.msie) {
5862 this.element.parent().css( "overflow", defOverflow );
5863 }
5864
5865 this.headers.each(function() {
5866 maxHeight -= $( this ).outerHeight( true );
5867 });
5868
5869 this.headers.next()
5870 .each(function() {
5871 $( this ).height( Math.max( 0, maxHeight -
5872 $( this ).innerHeight() + $( this ).height() ) );
5873 })
5874 .css( "overflow", "auto" );
5875 } else if ( options.autoHeight ) {
5876 maxHeight = 0;
5877 this.headers.next()
5878 .each(function() {
5879 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
5880 })
5881 .height( maxHeight );
5882 }
5883
5884 return this;
5885 },
5886
5887 activate: function( index ) {
5888 // TODO this gets called on init, changing the option without an explicit call for that
5889 this.options.active = index;
5890 // call clickHandler with custom event
5891 var active = this._findActive( index )[ 0 ];
5892 this._clickHandler( { target: active }, active );
5893
5894 return this;
5895 },
5896
5897 _findActive: function( selector ) {
5898 return selector
5899 ? typeof selector === "number"
5900 ? this.headers.filter( ":eq(" + selector + ")" )
5901 : this.headers.not( this.headers.not( selector ) )
5902 : selector === false
5903 ? $( [] )
5904 : this.headers.filter( ":eq(0)" );
5905 },
5906
5907 // TODO isn't event.target enough? why the separate target argument?
5908 _clickHandler: function( event, target ) {
5909 var options = this.options;
5910 if ( options.disabled ) {
5911 return;
5912 }
5913
5914 // called only when using activate(false) to close all parts programmatically
5915 if ( !event.target ) {
5916 if ( !options.collapsible ) {
5917 return;
5918 }
5919 this.active
5920 .removeClass( "ui-state-active ui-corner-top" )
5921 .addClass( "ui-state-default ui-corner-all" )
5922 .children( ".ui-icon" )
5923 .removeClass( options.icons.headerSelected )
5924 .addClass( options.icons.header );
5925 this.active.next().addClass( "ui-accordion-content-active" );
5926 var toHide = this.active.next(),
5927 data = {
5928 options: options,
5929 newHeader: $( [] ),
5930 oldHeader: options.active,
5931 newContent: $( [] ),
5932 oldContent: toHide
5933 },
5934 toShow = ( this.active = $( [] ) );
5935 this._toggle( toShow, toHide, data );
5936 return;
5937 }
5938
5939 // get the click target
5940 var clicked = $( event.currentTarget || target ),
5941 clickedIsActive = clicked[0] === this.active[0];
5942
5943 // TODO the option is changed, is that correct?
5944 // TODO if it is correct, shouldn't that happen after determining that the click is valid?
5945 options.active = options.collapsible && clickedIsActive ?
5946 false :
5947 this.headers.index( clicked );
5948
5949 // if animations are still active, or the active header is the target, ignore click
5950 if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
5951 return;
5952 }
5953
5954 // switch classes
5955 this.active
5956 .removeClass( "ui-state-active ui-corner-top" )
5957 .addClass( "ui-state-default ui-corner-all" )
5958 .children( ".ui-icon" )
5959 .removeClass( options.icons.headerSelected )
5960 .addClass( options.icons.header );
5961 if ( !clickedIsActive ) {
5962 clicked
5963 .removeClass( "ui-state-default ui-corner-all" )
5964 .addClass( "ui-state-active ui-corner-top" )
5965 .children( ".ui-icon" )
5966 .removeClass( options.icons.header )
5967 .addClass( options.icons.headerSelected );
5968 clicked
5969 .next()
5970 .addClass( "ui-accordion-content-active" );
5971 }
5972
5973 // find elements to show and hide
5974 var toShow = clicked.next(),
5975 toHide = this.active.next(),
5976 data = {
5977 options: options,
5978 newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
5979 oldHeader: this.active,
5980 newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
5981 oldContent: toHide
5982 },
5983 down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
5984
5985 this.active = clickedIsActive ? $([]) : clicked;
5986 this._toggle( toShow, toHide, data, clickedIsActive, down );
5987
5988 return;
5989 },
5990
5991 _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
5992 var self = this,
5993 options = self.options;
5994
5995 self.toShow = toShow;
5996 self.toHide = toHide;
5997 self.data = data;
5998
5999 var complete = function() {
6000 if ( !self ) {
6001 return;
6002 }
6003 return self._completed.apply( self, arguments );
6004 };
6005
6006 // trigger changestart event
6007 self._trigger( "changestart", null, self.data );
6008
6009 // count elements to animate
6010 self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
6011
6012 if ( options.animated ) {
6013 var animOptions = {};
6014
6015 if ( options.collapsible && clickedIsActive ) {
6016 animOptions = {
6017 toShow: $( [] ),
6018 toHide: toHide,
6019 complete: complete,
6020 down: down,
6021 autoHeight: options.autoHeight || options.fillSpace
6022 };
6023 } else {
6024 animOptions = {
6025 toShow: toShow,
6026 toHide: toHide,
6027 complete: complete,
6028 down: down,
6029 autoHeight: options.autoHeight || options.fillSpace
6030 };
6031 }
6032
6033 if ( !options.proxied ) {
6034 options.proxied = options.animated;
6035 }
6036
6037 if ( !options.proxiedDuration ) {
6038 options.proxiedDuration = options.duration;
6039 }
6040
6041 options.animated = $.isFunction( options.proxied ) ?
6042 options.proxied( animOptions ) :
6043 options.proxied;
6044
6045 options.duration = $.isFunction( options.proxiedDuration ) ?
6046 options.proxiedDuration( animOptions ) :
6047 options.proxiedDuration;
6048
6049 var animations = $.ui.accordion.animations,
6050 duration = options.duration,
6051 easing = options.animated;
6052
6053 if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
6054 easing = "slide";
6055 }
6056 if ( !animations[ easing ] ) {
6057 animations[ easing ] = function( options ) {
6058 this.slide( options, {
6059 easing: easing,
6060 duration: duration || 700
6061 });
6062 };
6063 }
6064
6065 animations[ easing ]( animOptions );
6066 } else {
6067 if ( options.collapsible && clickedIsActive ) {
6068 toShow.toggle();
6069 } else {
6070 toHide.hide();
6071 toShow.show();
6072 }
6073
6074 complete( true );
6075 }
6076
6077 // TODO assert that the blur and focus triggers are really necessary, remove otherwise
6078 toHide.prev()
6079 .attr({
6080 "aria-expanded": "false",
6081 tabIndex: -1
6082 })
6083 .blur();
6084 toShow.prev()
6085 .attr({
6086 "aria-expanded": "true",
6087 tabIndex: 0
6088 })
6089 .focus();
6090 },
6091
6092 _completed: function( cancel ) {
6093 this.running = cancel ? 0 : --this.running;
6094 if ( this.running ) {
6095 return;
6096 }
6097
6098 if ( this.options.clearStyle ) {
6099 this.toShow.add( this.toHide ).css({
6100 height: "",
6101 overflow: ""
6102 });
6103 }
6104
6105 // other classes are removed before the animation; this one needs to stay until completed
6106 this.toHide.removeClass( "ui-accordion-content-active" );
6107
6108 this._trigger( "change", null, this.data );
6109 }
6110 });
6111
6112 $.extend( $.ui.accordion, {
6113 version: "1.8.7",
6114 animations: {
6115 slide: function( options, additions ) {
6116 options = $.extend({
6117 easing: "swing",
6118 duration: 300
6119 }, options, additions );
6120 if ( !options.toHide.size() ) {
6121 options.toShow.animate({
6122 height: "show",
6123 paddingTop: "show",
6124 paddingBottom: "show"
6125 }, options );
6126 return;
6127 }
6128 if ( !options.toShow.size() ) {
6129 options.toHide.animate({
6130 height: "hide",
6131 paddingTop: "hide",
6132 paddingBottom: "hide"
6133 }, options );
6134 return;
6135 }
6136 var overflow = options.toShow.css( "overflow" ),
6137 percentDone = 0,
6138 showProps = {},
6139 hideProps = {},
6140 fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
6141 originalWidth;
6142 // fix width before calculating height of hidden element
6143 var s = options.toShow;
6144 originalWidth = s[0].style.width;
6145 s.width( parseInt( s.parent().width(), 10 )
6146 - parseInt( s.css( "paddingLeft" ), 10 )
6147 - parseInt( s.css( "paddingRight" ), 10 )
6148 - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
6149 - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
6150
6151 $.each( fxAttrs, function( i, prop ) {
6152 hideProps[ prop ] = "hide";
6153
6154 var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
6155 showProps[ prop ] = {
6156 value: parts[ 1 ],
6157 unit: parts[ 2 ] || "px"
6158 };
6159 });
6160 options.toShow.css({ height: 0, overflow: "hidden" }).show();
6161 options.toHide
6162 .filter( ":hidden" )
6163 .each( options.complete )
6164 .end()
6165 .filter( ":visible" )
6166 .animate( hideProps, {
6167 step: function( now, settings ) {
6168 // only calculate the percent when animating height
6169 // IE gets very inconsistent results when animating elements
6170 // with small values, which is common for padding
6171 if ( settings.prop == "height" ) {
6172 percentDone = ( settings.end - settings.start === 0 ) ? 0 :
6173 ( settings.now - settings.start ) / ( settings.end - settings.start );
6174 }
6175
6176 options.toShow[ 0 ].style[ settings.prop ] =
6177 ( percentDone * showProps[ settings.prop ].value )
6178 + showProps[ settings.prop ].unit;
6179 },
6180 duration: options.duration,
6181 easing: options.easing,
6182 complete: function() {
6183 if ( !options.autoHeight ) {
6184 options.toShow.css( "height", "" );
6185 }
6186 options.toShow.css({
6187 width: originalWidth,
6188 overflow: overflow
6189 });
6190 options.complete();
6191 }
6192 });
6193 },
6194 bounceslide: function( options ) {
6195 this.slide( options, {
6196 easing: options.down ? "easeOutBounce" : "swing",
6197 duration: options.down ? 1000 : 200
6198 });
6199 }
6200 }
6201 });
6202
6203 })( jQuery );
6204 /*
6205 * Note: While Microsoft is not the author of this file, Microsoft is
6206 * offering you a license subject to the terms of the Microsoft Software
6207 * License Terms for Microsoft ASP.NET Model View Controller 3.
6208 * Microsoft reserves all other rights. The notices below are provided
6209 * for informational purposes only and are not the license terms under
6210 * which Microsoft distributed this file.
6211 *
6212 * jQuery UI Autocomplete 1.8.7
6213 *
6214 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
6215 *
6216 * http://docs.jquery.com/UI/Autocomplete
6217 *
6218 * Depends:
6219 * jquery.ui.core.js
6220 * jquery.ui.widget.js
6221 * jquery.ui.position.js
6222 */
6223 (function( $, undefined ) {
6224
6225 $.widget( "ui.autocomplete", {
6226 options: {
6227 appendTo: "body",
6228 delay: 300,
6229 minLength: 1,
6230 position: {
6231 my: "left top",
6232 at: "left bottom",
6233 collision: "none"
6234 },
6235 source: null
6236 },
6237 _create: function() {
6238 var self = this,
6239 doc = this.element[ 0 ].ownerDocument,
6240 suppressKeyPress;
6241
6242 this.element
6243 .addClass( "ui-autocomplete-input" )
6244 .attr( "autocomplete", "off" )
6245 // TODO verify these actually work as intended
6246 .attr({
6247 role: "textbox",
6248 "aria-autocomplete": "list",
6249 "aria-haspopup": "true"
6250 })
6251 .bind( "keydown.autocomplete", function( event ) {
6252 if ( self.options.disabled || self.element.attr( "readonly" ) ) {
6253 return;
6254 }
6255
6256 suppressKeyPress = false;
6257 var keyCode = $.ui.keyCode;
6258 switch( event.keyCode ) {
6259 case keyCode.PAGE_UP:
6260 self._move( "previousPage", event );
6261 break;
6262 case keyCode.PAGE_DOWN:
6263 self._move( "nextPage", event );
6264 break;
6265 case keyCode.UP:
6266 self._move( "previous", event );
6267 // prevent moving cursor to beginning of text field in some browsers
6268 event.preventDefault();
6269 break;
6270 case keyCode.DOWN:
6271 self._move( "next", event );
6272 // prevent moving cursor to end of text field in some browsers
6273 event.preventDefault();
6274 break;
6275 case keyCode.ENTER:
6276 case keyCode.NUMPAD_ENTER:
6277 // when menu is open and has focus
6278 if ( self.menu.active ) {
6279 // #6055 - Opera still allows the keypress to occur
6280 // which causes forms to submit
6281 suppressKeyPress = true;
6282 event.preventDefault();
6283 }
6284 //passthrough - ENTER and TAB both select the current element
6285 case keyCode.TAB:
6286 if ( !self.menu.active ) {
6287 return;
6288 }
6289 self.menu.select( event );
6290 break;
6291 case keyCode.ESCAPE:
6292 self.element.val( self.term );
6293 self.close( event );
6294 break;
6295 default:
6296 // keypress is triggered before the input value is changed
6297 clearTimeout( self.searching );
6298 self.searching = setTimeout(function() {
6299 // only search if the value has changed
6300 if ( self.term != self.element.val() ) {
6301 self.selectedItem = null;
6302 self.search( null, event );
6303 }
6304 }, self.options.delay );
6305 break;
6306 }
6307 })
6308 .bind( "keypress.autocomplete", function( event ) {
6309 if ( suppressKeyPress ) {
6310 suppressKeyPress = false;
6311 event.preventDefault();
6312 }
6313 })
6314 .bind( "focus.autocomplete", function() {
6315 if ( self.options.disabled ) {
6316 return;
6317 }
6318
6319 self.selectedItem = null;
6320 self.previous = self.element.val();
6321 })
6322 .bind( "blur.autocomplete", function( event ) {
6323 if ( self.options.disabled ) {
6324 return;
6325 }
6326
6327 clearTimeout( self.searching );
6328 // clicks on the menu (or a button to trigger a search) will cause a blur event
6329 self.closing = setTimeout(function() {
6330 self.close( event );
6331 self._change( event );
6332 }, 150 );
6333 });
6334 this._initSource();
6335 this.response = function() {
6336 return self._response.apply( self, arguments );
6337 };
6338 this.menu = $( "<ul></ul>" )
6339 .addClass( "ui-autocomplete" )
6340 .appendTo( $( this.options.appendTo || "body", doc )[0] )
6341 // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
6342 .mousedown(function( event ) {
6343 // clicking on the scrollbar causes focus to shift to the body
6344 // but we can't detect a mouseup or a click immediately afterward
6345 // so we have to track the next mousedown and close the menu if
6346 // the user clicks somewhere outside of the autocomplete
6347 var menuElement = self.menu.element[ 0 ];
6348 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6349 setTimeout(function() {
6350 $( document ).one( 'mousedown', function( event ) {
6351 if ( event.target !== self.element[ 0 ] &&
6352 event.target !== menuElement &&
6353 !$.ui.contains( menuElement, event.target ) ) {
6354 self.close();
6355 }
6356 });
6357 }, 1 );
6358 }
6359
6360 // use another timeout to make sure the blur-event-handler on the input was already triggered
6361 setTimeout(function() {
6362 clearTimeout( self.closing );
6363 }, 13);
6364 })
6365 .menu({
6366 focus: function( event, ui ) {
6367 var item = ui.item.data( "item.autocomplete" );
6368 if ( false !== self._trigger( "focus", event, { item: item } ) ) {
6369 // use value to match what will end up in the input, if it was a key event
6370 if ( /^key/.test(event.originalEvent.type) ) {
6371 self.element.val( item.value );
6372 }
6373 }
6374 },
6375 selected: function( event, ui ) {
6376 var item = ui.item.data( "item.autocomplete" ),
6377 previous = self.previous;
6378
6379 // only trigger when focus was lost (click on menu)
6380 if ( self.element[0] !== doc.activeElement ) {
6381 self.element.focus();
6382 self.previous = previous;
6383 // #6109 - IE triggers two focus events and the second
6384 // is asynchronous, so we need to reset the previous
6385 // term synchronously and asynchronously :-(
6386 setTimeout(function() {
6387 self.previous = previous;
6388 self.selectedItem = item;
6389 }, 1);
6390 }
6391
6392 if ( false !== self._trigger( "select", event, { item: item } ) ) {
6393 self.element.val( item.value );
6394 }
6395 // reset the term after the select event
6396 // this allows custom select handling to work properly
6397 self.term = self.element.val();
6398
6399 self.close( event );
6400 self.selectedItem = item;
6401 },
6402 blur: function( event, ui ) {
6403 // don't set the value of the text field if it's already correct
6404 // this prevents moving the cursor unnecessarily
6405 if ( self.menu.element.is(":visible") &&
6406 ( self.element.val() !== self.term ) ) {
6407 self.element.val( self.term );
6408 }
6409 }
6410 })
6411 .zIndex( this.element.zIndex() + 1 )
6412 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6413 .css({ top: 0, left: 0 })
6414 .hide()
6415 .data( "menu" );
6416 if ( $.fn.bgiframe ) {
6417 this.menu.element.bgiframe();
6418 }
6419 },
6420
6421 destroy: function() {
6422 this.element
6423 .removeClass( "ui-autocomplete-input" )
6424 .removeAttr( "autocomplete" )
6425 .removeAttr( "role" )
6426 .removeAttr( "aria-autocomplete" )
6427 .removeAttr( "aria-haspopup" );
6428 this.menu.element.remove();
6429 $.Widget.prototype.destroy.call( this );
6430 },
6431
6432 _setOption: function( key, value ) {
6433 $.Widget.prototype._setOption.apply( this, arguments );
6434 if ( key === "source" ) {
6435 this._initSource();
6436 }
6437 if ( key === "appendTo" ) {
6438 this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
6439 }
6440 },
6441
6442 _initSource: function() {
6443 var self = this,
6444 array,
6445 url;
6446 if ( $.isArray(this.options.source) ) {
6447 array = this.options.source;
6448 this.source = function( request, response ) {
6449 response( $.ui.autocomplete.filter(array, request.term) );
6450 };
6451 } else if ( typeof this.options.source === "string" ) {
6452 url = this.options.source;
6453 this.source = function( request, response ) {
6454 if (self.xhr) {
6455 self.xhr.abort();
6456 }
6457 self.xhr = $.ajax({
6458 url: url,
6459 data: request,
6460 dataType: "json",
6461 success: function( data, status, xhr ) {
6462 if ( xhr === self.xhr ) {
6463 response( data );
6464 }
6465 self.xhr = null;
6466 },
6467 error: function( xhr ) {
6468 if ( xhr === self.xhr ) {
6469 response( [] );
6470 }
6471 self.xhr = null;
6472 }
6473 });
6474 };
6475 } else {
6476 this.source = this.options.source;
6477 }
6478 },
6479
6480 search: function( value, event ) {
6481 value = value != null ? value : this.element.val();
6482
6483 // always save the actual value, not the one passed as an argument
6484 this.term = this.element.val();
6485
6486 if ( value.length < this.options.minLength ) {
6487 return this.close( event );
6488 }
6489
6490 clearTimeout( this.closing );
6491 if ( this._trigger( "search", event ) === false ) {
6492 return;
6493 }
6494
6495 return this._search( value );
6496 },
6497
6498 _search: function( value ) {
6499 this.element.addClass( "ui-autocomplete-loading" );
6500
6501 this.source( { term: value }, this.response );
6502 },
6503
6504 _response: function( content ) {
6505 if ( content && content.length ) {
6506 content = this._normalize( content );
6507 this._suggest( content );
6508 this._trigger( "open" );
6509 } else {
6510 this.close();
6511 }
6512 this.element.removeClass( "ui-autocomplete-loading" );
6513 },
6514
6515 close: function( event ) {
6516 clearTimeout( this.closing );
6517 if ( this.menu.element.is(":visible") ) {
6518 this.menu.element.hide();
6519 this.menu.deactivate();
6520 this._trigger( "close", event );
6521 }
6522 },
6523
6524 _change: function( event ) {
6525 if ( this.previous !== this.element.val() ) {
6526 this._trigger( "change", event, { item: this.selectedItem } );
6527 }
6528 },
6529
6530 _normalize: function( items ) {
6531 // assume all items have the right format when the first item is complete
6532 if ( items.length && items[0].label && items[0].value ) {
6533 return items;
6534 }
6535 return $.map( items, function(item) {
6536 if ( typeof item === "string" ) {
6537 return {
6538 label: item,
6539 value: item
6540 };
6541 }
6542 return $.extend({
6543 label: item.label || item.value,
6544 value: item.value || item.label
6545 }, item );
6546 });
6547 },
6548
6549 _suggest: function( items ) {
6550 var ul = this.menu.element
6551 .empty()
6552 .zIndex( this.element.zIndex() + 1 );
6553 this._renderMenu( ul, items );
6554 // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
6555 this.menu.deactivate();
6556 this.menu.refresh();
6557
6558 // size and position menu
6559 ul.show();
6560 this._resizeMenu();
6561 ul.position( $.extend({
6562 of: this.element
6563 }, this.options.position ));
6564 },
6565
6566 _resizeMenu: function() {
6567 var ul = this.menu.element;
6568 ul.outerWidth( Math.max(
6569 ul.width( "" ).outerWidth(),
6570 this.element.outerWidth()
6571 ) );
6572 },
6573
6574 _renderMenu: function( ul, items ) {
6575 var self = this;
6576 $.each( items, function( index, item ) {
6577 self._renderItem( ul, item );
6578 });
6579 },
6580
6581 _renderItem: function( ul, item) {
6582 return $( "<li></li>" )
6583 .data( "item.autocomplete", item )
6584 .append( $( "<a></a>" ).text( item.label ) )
6585 .appendTo( ul );
6586 },
6587
6588 _move: function( direction, event ) {
6589 if ( !this.menu.element.is(":visible") ) {
6590 this.search( null, event );
6591 return;
6592 }
6593 if ( this.menu.first() && /^previous/.test(direction) ||
6594 this.menu.last() && /^next/.test(direction) ) {
6595 this.element.val( this.term );
6596 this.menu.deactivate();
6597 return;
6598 }
6599 this.menu[ direction ]( event );
6600 },
6601
6602 widget: function() {
6603 return this.menu.element;
6604 }
6605 });
6606
6607 $.extend( $.ui.autocomplete, {
6608 escapeRegex: function( value ) {
6609 return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
6610 },
6611 filter: function(array, term) {
6612 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6613 return $.grep( array, function(value) {
6614 return matcher.test( value.label || value.value || value );
6615 });
6616 }
6617 });
6618
6619 }( jQuery ));
6620
6621 /*
6622 * Note: While Microsoft is not the author of this file, Microsoft is
6623 * offering you a license subject to the terms of the Microsoft Software
6624 * License Terms for Microsoft ASP.NET Model View Controller 3.
6625 * Microsoft reserves all other rights. The notices below are provided
6626 * for informational purposes only and are not the license terms under
6627 * which Microsoft distributed this file.
6628 *
6629 * jQuery UI Menu (not officially released)
6630 *
6631 * This widget isn't yet finished and the API is subject to change. We plan to finish
6632 * it for the next release. You're welcome to give it a try anyway and give us feedback,
6633 * as long as you're okay with migrating your code later on. We can help with that, too.
6634 *
6635 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
6636 *
6637 * http://docs.jquery.com/UI/Menu
6638 *
6639 * Depends:
6640 * jquery.ui.core.js
6641 * jquery.ui.widget.js
6642 */
6643 (function($) {
6644
6645 $.widget("ui.menu", {
6646 _create: function() {
6647 var self = this;
6648 this.element
6649 .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
6650 .attr({
6651 role: "listbox",
6652 "aria-activedescendant": "ui-active-menuitem"
6653 })
6654 .click(function( event ) {
6655 if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
6656 return;
6657 }
6658 // temporary
6659 event.preventDefault();
6660 self.select( event );
6661 });
6662 this.refresh();
6663 },
6664
6665 refresh: function() {
6666 var self = this;
6667
6668 // don't refresh list items that are already adapted
6669 var items = this.element.children("li:not(.ui-menu-item):has(a)")
6670 .addClass("ui-menu-item")
6671 .attr("role", "menuitem");
6672
6673 items.children("a")
6674 .addClass("ui-corner-all")
6675 .attr("tabindex", -1)
6676 // mouseenter doesn't work with event delegation
6677 .mouseenter(function( event ) {
6678 self.activate( event, $(this).parent() );
6679 })
6680 .mouseleave(function() {
6681 self.deactivate();
6682 });
6683 },
6684
6685 activate: function( event, item ) {
6686 this.deactivate();
6687 if (this.hasScroll()) {
6688 var offset = item.offset().top - this.element.offset().top,
6689 scroll = this.element.attr("scrollTop"),
6690 elementHeight = this.element.height();
6691 if (offset < 0) {
6692 this.element.attr("scrollTop", scroll + offset);
6693 } else if (offset >= elementHeight) {
6694 this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
6695 }
6696 }
6697 this.active = item.eq(0)
6698 .children("a")
6699 .addClass("ui-state-hover")
6700 .attr("id", "ui-active-menuitem")
6701 .end();
6702 this._trigger("focus", event, { item: item });
6703 },
6704
6705 deactivate: function() {
6706 if (!this.active) { return; }
6707
6708 this.active.children("a")
6709 .removeClass("ui-state-hover")
6710 .removeAttr("id");
6711 this._trigger("blur");
6712 this.active = null;
6713 },
6714
6715 next: function(event) {
6716 this.move("next", ".ui-menu-item:first", event);
6717 },
6718
6719 previous: function(event) {
6720 this.move("prev", ".ui-menu-item:last", event);
6721 },
6722
6723 first: function() {
6724 return this.active && !this.active.prevAll(".ui-menu-item").length;
6725 },
6726
6727 last: function() {
6728 return this.active && !this.active.nextAll(".ui-menu-item").length;
6729 },
6730
6731 move: function(direction, edge, event) {
6732 if (!this.active) {
6733 this.activate(event, this.element.children(edge));
6734 return;
6735 }
6736 var next = this.active[direction + "All"](".ui-menu-item").eq(0);
6737 if (next.length) {
6738 this.activate(event, next);
6739 } else {
6740 this.activate(event, this.element.children(edge));
6741 }
6742 },
6743
6744 // TODO merge with previousPage
6745 nextPage: function(event) {
6746 if (this.hasScroll()) {
6747 // TODO merge with no-scroll-else
6748 if (!this.active || this.last()) {
6749 this.activate(event, this.element.children(".ui-menu-item:first"));
6750 return;
6751 }
6752 var base = this.active.offset().top,
6753 height = this.element.height(),
6754 result = this.element.children(".ui-menu-item").filter(function() {
6755 var close = $(this).offset().top - base - height + $(this).height();
6756 // TODO improve approximation
6757 return close < 10 && close > -10;
6758 });
6759
6760 // TODO try to catch this earlier when scrollTop indicates the last page anyway
6761 if (!result.length) {
6762 result = this.element.children(".ui-menu-item:last");
6763 }
6764 this.activate(event, result);
6765 } else {
6766 this.activate(event, this.element.children(".ui-menu-item")
6767 .filter(!this.active || this.last() ? ":first" : ":last"));
6768 }
6769 },
6770
6771 // TODO merge with nextPage
6772 previousPage: function(event) {
6773 if (this.hasScroll()) {
6774 // TODO merge with no-scroll-else
6775 if (!this.active || this.first()) {
6776 this.activate(event, this.element.children(".ui-menu-item:last"));
6777 return;
6778 }
6779
6780 var base = this.active.offset().top,
6781 height = this.element.height();
6782 result = this.element.children(".ui-menu-item").filter(function() {
6783 var close = $(this).offset().top - base + height - $(this).height();
6784 // TODO improve approximation
6785 return close < 10 && close > -10;
6786 });
6787
6788 // TODO try to catch this earlier when scrollTop indicates the last page anyway
6789 if (!result.length) {
6790 result = this.element.children(".ui-menu-item:first");
6791 }
6792 this.activate(event, result);
6793 } else {
6794 this.activate(event, this.element.children(".ui-menu-item")
6795 .filter(!this.active || this.first() ? ":last" : ":first"));
6796 }
6797 },
6798
6799 hasScroll: function() {
6800 return this.element.height() < this.element.attr("scrollHeight");
6801 },
6802
6803 select: function( event ) {
6804 this._trigger("selected", event, { item: this.active });
6805 }
6806 });
6807
6808 }(jQuery));
6809 /*
6810 * Note: While Microsoft is not the author of this file, Microsoft is
6811 * offering you a license subject to the terms of the Microsoft Software
6812 * License Terms for Microsoft ASP.NET Model View Controller 3.
6813 * Microsoft reserves all other rights. The notices below are provided
6814 * for informational purposes only and are not the license terms under
6815 * which Microsoft distributed this file.
6816 *
6817 * jQuery UI Button 1.8.7
6818 *
6819 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
6820 *
6821 * http://docs.jquery.com/UI/Button
6822 *
6823 * Depends:
6824 * jquery.ui.core.js
6825 * jquery.ui.widget.js
6826 */
6827 (function( $, undefined ) {
6828
6829 var lastActive,
6830 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6831 stateClasses = "ui-state-hover ui-state-active ",
6832 typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
6833 formResetHandler = function( event ) {
6834 $( ":ui-button", event.target.form ).each(function() {
6835 var inst = $( this ).data( "button" );
6836 setTimeout(function() {
6837 inst.refresh();
6838 }, 1 );
6839 });
6840 },
6841 radioGroup = function( radio ) {
6842 var name = radio.name,
6843 form = radio.form,
6844 radios = $( [] );
6845 if ( name ) {
6846 if ( form ) {
6847 radios = $( form ).find( "[name='" + name + "']" );
6848 } else {
6849 radios = $( "[name='" + name + "']", radio.ownerDocument )
6850 .filter(function() {
6851 return !this.form;
6852 });
6853 }
6854 }
6855 return radios;
6856 };
6857
6858 $.widget( "ui.button", {
6859 options: {
6860 disabled: null,
6861 text: true,
6862 label: null,
6863 icons: {
6864 primary: null,
6865 secondary: null
6866 }
6867 },
6868 _create: function() {
6869 this.element.closest( "form" )
6870 .unbind( "reset.button" )
6871 .bind( "reset.button", formResetHandler );
6872
6873 if ( typeof this.options.disabled !== "boolean" ) {
6874 this.options.disabled = this.element.attr( "disabled" );
6875 }
6876
6877 this._determineButtonType();
6878 this.hasTitle = !!this.buttonElement.attr( "title" );
6879
6880 var self = this,
6881 options = this.options,
6882 toggleButton = this.type === "checkbox" || this.type === "radio",
6883 hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
6884 focusClass = "ui-state-focus";
6885
6886 if ( options.label === null ) {
6887 options.label = this.buttonElement.html();
6888 }
6889
6890 if ( this.element.is( ":disabled" ) ) {
6891 options.disabled = true;
6892 }
6893
6894 this.buttonElement
6895 .addClass( baseClasses )
6896 .attr( "role", "button" )
6897 .bind( "mouseenter.button", function() {
6898 if ( options.disabled ) {
6899 return;
6900 }
6901 $( this ).addClass( "ui-state-hover" );
6902 if ( this === lastActive ) {
6903 $( this ).addClass( "ui-state-active" );
6904 }
6905 })
6906 .bind( "mouseleave.button", function() {
6907 if ( options.disabled ) {
6908 return;
6909 }
6910 $( this ).removeClass( hoverClass );
6911 })
6912 .bind( "focus.button", function() {
6913 // no need to check disabled, focus won't be triggered anyway
6914 $( this ).addClass( focusClass );
6915 })
6916 .bind( "blur.button", function() {
6917 $( this ).removeClass( focusClass );
6918 });
6919
6920 if ( toggleButton ) {
6921 this.element.bind( "change.button", function() {
6922 self.refresh();
6923 });
6924 }
6925
6926 if ( this.type === "checkbox" ) {
6927 this.buttonElement.bind( "click.button", function() {
6928 if ( options.disabled ) {
6929 return false;
6930 }
6931 $( this ).toggleClass( "ui-state-active" );
6932 self.buttonElement.attr( "aria-pressed", self.element[0].checked );
6933 });
6934 } else if ( this.type === "radio" ) {
6935 this.buttonElement.bind( "click.button", function() {
6936 if ( options.disabled ) {
6937 return false;
6938 }
6939 $( this ).addClass( "ui-state-active" );
6940 self.buttonElement.attr( "aria-pressed", true );
6941
6942 var radio = self.element[ 0 ];
6943 radioGroup( radio )
6944 .not( radio )
6945 .map(function() {
6946 return $( this ).button( "widget" )[ 0 ];
6947 })
6948 .removeClass( "ui-state-active" )
6949 .attr( "aria-pressed", false );
6950 });
6951 } else {
6952 this.buttonElement
6953 .bind( "mousedown.button", function() {
6954 if ( options.disabled ) {
6955 return false;
6956 }
6957 $( this ).addClass( "ui-state-active" );
6958 lastActive = this;
6959 $( document ).one( "mouseup", function() {
6960 lastActive = null;
6961 });
6962 })
6963 .bind( "mouseup.button", function() {
6964 if ( options.disabled ) {
6965 return false;
6966 }
6967 $( this ).removeClass( "ui-state-active" );
6968 })
6969 .bind( "keydown.button", function(event) {
6970 if ( options.disabled ) {
6971 return false;
6972 }
6973 if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
6974 $( this ).addClass( "ui-state-active" );
6975 }
6976 })
6977 .bind( "keyup.button", function() {
6978 $( this ).removeClass( "ui-state-active" );
6979 });
6980
6981 if ( this.buttonElement.is("a") ) {
6982 this.buttonElement.keyup(function(event) {
6983 if ( event.keyCode === $.ui.keyCode.SPACE ) {
6984 // TODO pass through original event correctly (just as 2nd argument doesn't work)
6985 $( this ).click();
6986 }
6987 });
6988 }
6989 }
6990
6991 // TODO: pull out $.Widget's handling for the disabled option into
6992 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
6993 // be overridden by individual plugins
6994 this._setOption( "disabled", options.disabled );
6995 },
6996
6997 _determineButtonType: function() {
6998
6999 if ( this.element.is(":checkbox") ) {
7000 this.type = "checkbox";
7001 } else {
7002 if ( this.element.is(":radio") ) {
7003 this.type = "radio";
7004 } else {
7005 if ( this.element.is("input") ) {
7006 this.type = "input";
7007 } else {
7008 this.type = "button";
7009 }
7010 }
7011 }
7012
7013 if ( this.type === "checkbox" || this.type === "radio" ) {
7014 // we don't search against the document in case the element
7015 // is disconnected from the DOM
7016 this.buttonElement = this.element.parents().last()
7017 .find( "label[for=" + this.element.attr("id") + "]" );
7018 this.element.addClass( "ui-helper-hidden-accessible" );
7019
7020 var checked = this.element.is( ":checked" );
7021 if ( checked ) {
7022 this.buttonElement.addClass( "ui-state-active" );
7023 }
7024 this.buttonElement.attr( "aria-pressed", checked );
7025 } else {
7026 this.buttonElement = this.element;
7027 }
7028 },
7029
7030 widget: function() {
7031 return this.buttonElement;
7032 },
7033
7034 destroy: function() {
7035 this.element
7036 .removeClass( "ui-helper-hidden-accessible" );
7037 this.buttonElement
7038 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7039 .removeAttr( "role" )
7040 .removeAttr( "aria-pressed" )
7041 .html( this.buttonElement.find(".ui-button-text").html() );
7042
7043 if ( !this.hasTitle ) {
7044 this.buttonElement.removeAttr( "title" );
7045 }
7046
7047 $.Widget.prototype.destroy.call( this );
7048 },
7049
7050 _setOption: function( key, value ) {
7051 $.Widget.prototype._setOption.apply( this, arguments );
7052 if ( key === "disabled" ) {
7053 if ( value ) {
7054 this.element.attr( "disabled", true );
7055 } else {
7056 this.element.removeAttr( "disabled" );
7057 }
7058 }
7059 this._resetButton();
7060 },
7061
7062 refresh: function() {
7063 var isDisabled = this.element.is( ":disabled" );
7064 if ( isDisabled !== this.options.disabled ) {
7065 this._setOption( "disabled", isDisabled );
7066 }
7067 if ( this.type === "radio" ) {
7068 radioGroup( this.element[0] ).each(function() {
7069 if ( $( this ).is( ":checked" ) ) {
7070 $( this ).button( "widget" )
7071 .addClass( "ui-state-active" )
7072 .attr( "aria-pressed", true );
7073 } else {
7074 $( this ).button( "widget" )
7075 .removeClass( "ui-state-active" )
7076 .attr( "aria-pressed", false );
7077 }
7078 });
7079 } else if ( this.type === "checkbox" ) {
7080 if ( this.element.is( ":checked" ) ) {
7081 this.buttonElement
7082 .addClass( "ui-state-active" )
7083 .attr( "aria-pressed", true );
7084 } else {
7085 this.buttonElement
7086 .removeClass( "ui-state-active" )
7087 .attr( "aria-pressed", false );
7088 }
7089 }
7090 },
7091
7092 _resetButton: function() {
7093 if ( this.type === "input" ) {
7094 if ( this.options.label ) {
7095 this.element.val( this.options.label );
7096 }
7097 return;
7098 }
7099 var buttonElement = this.buttonElement.removeClass( typeClasses ),
7100 buttonText = $( "<span></span>" )
7101 .addClass( "ui-button-text" )
7102 .html( this.options.label )
7103 .appendTo( buttonElement.empty() )
7104 .text(),
7105 icons = this.options.icons,
7106 multipleIcons = icons.primary && icons.secondary;
7107 if ( icons.primary || icons.secondary ) {
7108 buttonElement.addClass( "ui-button-text-icon" +
7109 ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7110 if ( icons.primary ) {
7111 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7112 }
7113 if ( icons.secondary ) {
7114 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7115 }
7116 if ( !this.options.text ) {
7117 buttonElement
7118 .addClass( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" )
7119 .removeClass( "ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary" );
7120 if ( !this.hasTitle ) {
7121 buttonElement.attr( "title", buttonText );
7122 }
7123 }
7124 } else {
7125 buttonElement.addClass( "ui-button-text-only" );
7126 }
7127 }
7128 });
7129
7130 $.widget( "ui.buttonset", {
7131 options: {
7132 items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
7133 },
7134
7135 _create: function() {
7136 this.element.addClass( "ui-buttonset" );
7137 },
7138
7139 _init: function() {
7140 this.refresh();
7141 },
7142
7143 _setOption: function( key, value ) {
7144 if ( key === "disabled" ) {
7145 this.buttons.button( "option", key, value );
7146 }
7147
7148 $.Widget.prototype._setOption.apply( this, arguments );
7149 },
7150
7151 refresh: function() {
7152 this.buttons = this.element.find( this.options.items )
7153 .filter( ":ui-button" )
7154 .button( "refresh" )
7155 .end()
7156 .not( ":ui-button" )
7157 .button()
7158 .end()
7159 .map(function() {
7160 return $( this ).button( "widget" )[ 0 ];
7161 })
7162 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7163 .filter( ":first" )
7164 .addClass( "ui-corner-left" )
7165 .end()
7166 .filter( ":last" )
7167 .addClass( "ui-corner-right" )
7168 .end()
7169 .end();
7170 },
7171
7172 destroy: function() {
7173 this.element.removeClass( "ui-buttonset" );
7174 this.buttons
7175 .map(function() {
7176 return $( this ).button( "widget" )[ 0 ];
7177 })
7178 .removeClass( "ui-corner-left ui-corner-right" )
7179 .end()
7180 .button( "destroy" );
7181
7182 $.Widget.prototype.destroy.call( this );
7183 }
7184 });
7185
7186 }( jQuery ) );
7187 /*
7188 * Note: While Microsoft is not the author of this file, Microsoft is
7189 * offering you a license subject to the terms of the Microsoft Software
7190 * License Terms for Microsoft ASP.NET Model View Controller 3.
7191 * Microsoft reserves all other rights. The notices below are provided
7192 * for informational purposes only and are not the license terms under
7193 * which Microsoft distributed this file.
7194 *
7195 * jQuery UI Datepicker 1.8.7
7196 *
7197 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
7198 *
7199 * http://docs.jquery.com/UI/Datepicker
7200 *
7201 * Depends:
7202 * jquery.ui.core.js
7203 */
7204 (function( $, undefined ) {
7205
7206 $.extend($.ui, { datepicker: { version: "1.8.7" } });
7207
7208 var PROP_NAME = 'datepicker';
7209 var dpuuid = new Date().getTime();
7210
7211 /* Date picker manager.
7212 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7213 Settings for (groups of) date pickers are maintained in an instance object,
7214 allowing multiple different settings on the same page. */
7215
7216 function Datepicker() {
7217 this.debug = false; // Change this to true to start debugging
7218 this._curInst = null; // The current instance in use
7219 this._keyEvent = false; // If the last event was a key event
7220 this._disabledInputs = []; // List of date picker inputs that have been disabled
7221 this._datepickerShowing = false; // True if the popup picker is showing , false if not
7222 this._inDialog = false; // True if showing within a "dialog", false if not
7223 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
7224 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
7225 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
7226 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
7227 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
7228 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
7229 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
7230 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
7231 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
7232 this.regional = []; // Available regional settings, indexed by language code
7233 this.regional[''] = { // Default regional settings
7234 closeText: 'Done', // Display text for close link
7235 prevText: 'Prev', // Display text for previous month link
7236 nextText: 'Next', // Display text for next month link
7237 currentText: 'Today', // Display text for current month link
7238 monthNames: ['January','February','March','April','May','June',
7239 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
7240 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
7241 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
7242 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
7243 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
7244 weekHeader: 'Wk', // Column header for week of the year
7245 dateFormat: 'mm/dd/yy', // See format options on parseDate
7246 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7247 isRTL: false, // True if right-to-left language, false if left-to-right
7248 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7249 yearSuffix: '' // Additional text to append to the year in the month headers
7250 };
7251 this._defaults = { // Global defaults for all the date picker instances
7252 showOn: 'focus', // 'focus' for popup on focus,
7253 // 'button' for trigger button, or 'both' for either
7254 showAnim: 'fadeIn', // Name of jQuery animation for popup
7255 showOptions: {}, // Options for enhanced animations
7256 defaultDate: null, // Used when field is blank: actual date,
7257 // +/-number for offset from today, null for today
7258 appendText: '', // Display text following the input box, e.g. showing the format
7259 buttonText: '...', // Text for trigger button
7260 buttonImage: '', // URL for trigger button image
7261 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7262 hideIfNoPrevNext: false, // True to hide next/previous month links
7263 // if not applicable, false to just disable them
7264 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7265 gotoCurrent: false, // True if today link goes back to current selection instead
7266 changeMonth: false, // True if month can be selected directly, false if only prev/next
7267 changeYear: false, // True if year can be selected directly, false if only prev/next
7268 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
7269 // either relative to today's year (-nn:+nn), relative to currently displayed year
7270 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7271 showOtherMonths: false, // True to show dates in other months, false to leave blank
7272 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7273 showWeek: false, // True to show week of the year, false to not show it
7274 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7275 // takes a Date and returns the number of the week for it
7276 shortYearCutoff: '+10', // Short year values < this are in the current century,
7277 // > this are in the previous century,
7278 // string value starting with '+' for current year + value
7279 minDate: null, // The earliest selectable date, or null for no limit
7280 maxDate: null, // The latest selectable date, or null for no limit
7281 duration: 'fast', // Duration of display/closure
7282 beforeShowDay: null, // Function that takes a date and returns an array with
7283 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
7284 // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7285 beforeShow: null, // Function that takes an input field and
7286 // returns a set of custom settings for the date picker
7287 onSelect: null, // Define a callback function when a date is selected
7288 onChangeMonthYear: null, // Define a callback function when the month or year is changed
7289 onClose: null, // Define a callback function when the datepicker is closed
7290 numberOfMonths: 1, // Number of months to show at a time
7291 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7292 stepMonths: 1, // Number of months to step back/forward
7293 stepBigMonths: 12, // Number of months to step back/forward for the big links
7294 altField: '', // Selector for an alternate field to store selected dates into
7295 altFormat: '', // The date format to use for the alternate field
7296 constrainInput: true, // The input is constrained by the current date format
7297 showButtonPanel: false, // True to show button panel, false to not show it
7298 autoSize: false // True to size the input for the date format, false to leave as is
7299 };
7300 $.extend(this._defaults, this.regional['']);
7301 this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>');
7302 }
7303
7304 $.extend(Datepicker.prototype, {
7305 /* Class name added to elements to indicate already configured with a date picker. */
7306 markerClassName: 'hasDatepicker',
7307
7308 /* Debug logging (if enabled). */
7309 log: function () {
7310 if (this.debug)
7311 console.log.apply('', arguments);
7312 },
7313
7314 // TODO rename to "widget" when switching to widget factory
7315 _widgetDatepicker: function() {
7316 return this.dpDiv;
7317 },
7318
7319 /* Override the default settings for all instances of the date picker.
7320 @param settings object - the new settings to use as defaults (anonymous object)
7321 @return the manager object */
7322 setDefaults: function(settings) {
7323 extendRemove(this._defaults, settings || {});
7324 return this;
7325 },
7326
7327 /* Attach the date picker to a jQuery selection.
7328 @param target element - the target input field or division or span
7329 @param settings object - the new settings to use for this date picker instance (anonymous) */
7330 _attachDatepicker: function(target, settings) {
7331 // check for settings on the control itself - in namespace 'date:'
7332 var inlineSettings = null;
7333 for (var attrName in this._defaults) {
7334 var attrValue = target.getAttribute('date:' + attrName);
7335 if (attrValue) {
7336 inlineSettings = inlineSettings || {};
7337 try {
7338 inlineSettings[attrName] = eval(attrValue);
7339 } catch (err) {
7340 inlineSettings[attrName] = attrValue;
7341 }
7342 }
7343 }
7344 var nodeName = target.nodeName.toLowerCase();
7345 var inline = (nodeName == 'div' || nodeName == 'span');
7346 if (!target.id) {
7347 this.uuid += 1;
7348 target.id = 'dp' + this.uuid;
7349 }
7350 var inst = this._newInst($(target), inline);
7351 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
7352 if (nodeName == 'input') {
7353 this._connectDatepicker(target, inst);
7354 } else if (inline) {
7355 this._inlineDatepicker(target, inst);
7356 }
7357 },
7358
7359 /* Create a new instance object. */
7360 _newInst: function(target, inline) {
7361 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
7362 return {id: id, input: target, // associated target
7363 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7364 drawMonth: 0, drawYear: 0, // month being drawn
7365 inline: inline, // is datepicker inline or not
7366 dpDiv: (!inline ? this.dpDiv : // presentation div
7367 $('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))};
7368 },
7369
7370 /* Attach the date picker to an input field. */
7371 _connectDatepicker: function(target, inst) {
7372 var input = $(target);
7373 inst.append = $([]);
7374 inst.trigger = $([]);
7375 if (input.hasClass(this.markerClassName))
7376 return;
7377 this._attachments(input, inst);
7378 input.addClass(this.markerClassName).keydown(this._doKeyDown).
7379 keypress(this._doKeyPress).keyup(this._doKeyUp).
7380 bind("setData.datepicker", function(event, key, value) {
7381 inst.settings[key] = value;
7382 }).bind("getData.datepicker", function(event, key) {
7383 return this._get(inst, key);
7384 });
7385 this._autoSize(inst);
7386 $.data(target, PROP_NAME, inst);
7387 },
7388
7389 /* Make attachments based on settings. */
7390 _attachments: function(input, inst) {
7391 var appendText = this._get(inst, 'appendText');
7392 var isRTL = this._get(inst, 'isRTL');
7393 if (inst.append)
7394 inst.append.remove();
7395 if (appendText) {
7396 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
7397 input[isRTL ? 'before' : 'after'](inst.append);
7398 }
7399 input.unbind('focus', this._showDatepicker);
7400 if (inst.trigger)
7401 inst.trigger.remove();
7402 var showOn = this._get(inst, 'showOn');
7403 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
7404 input.focus(this._showDatepicker);
7405 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
7406 var buttonText = this._get(inst, 'buttonText');
7407 var buttonImage = this._get(inst, 'buttonImage');
7408 inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
7409 $('<img/>').addClass(this._triggerClass).
7410 attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7411 $('<button type="button"></button>').addClass(this._triggerClass).
7412 html(buttonImage == '' ? buttonText : $('<img/>').attr(
7413 { src:buttonImage, alt:buttonText, title:buttonText })));
7414 input[isRTL ? 'before' : 'after'](inst.trigger);
7415 inst.trigger.click(function() {
7416 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
7417 $.datepicker._hideDatepicker();
7418 else
7419 $.datepicker._showDatepicker(input[0]);
7420 return false;
7421 });
7422 }
7423 },
7424
7425 /* Apply the maximum length for the date format. */
7426 _autoSize: function(inst) {
7427 if (this._get(inst, 'autoSize') && !inst.inline) {
7428 var date = new Date(2009, 12 - 1, 20); // Ensure double digits
7429 var dateFormat = this._get(inst, 'dateFormat');
7430 if (dateFormat.match(/[DM]/)) {
7431 var findMax = function(names) {
7432 var max = 0;
7433 var maxI = 0;
7434 for (var i = 0; i < names.length; i++) {
7435 if (names[i].length > max) {
7436 max = names[i].length;
7437 maxI = i;
7438 }
7439 }
7440 return maxI;
7441 };
7442 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7443 'monthNames' : 'monthNamesShort'))));
7444 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7445 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
7446 }
7447 inst.input.attr('size', this._formatDate(inst, date).length);
7448 }
7449 },
7450
7451 /* Attach an inline date picker to a div. */
7452 _inlineDatepicker: function(target, inst) {
7453 var divSpan = $(target);
7454 if (divSpan.hasClass(this.markerClassName))
7455 return;
7456 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
7457 bind("setData.datepicker", function(event, key, value){
7458 inst.settings[key] = value;
7459 }).bind("getData.datepicker", function(event, key){
7460 return this._get(inst, key);
7461 });
7462 $.data(target, PROP_NAME, inst);
7463 this._setDate(inst, this._getDefaultDate(inst), true);
7464 this._updateDatepicker(inst);
7465 this._updateAlternate(inst);
7466 inst.dpDiv.show();
7467 },
7468
7469 /* Pop-up the date picker in a "dialog" box.
7470 @param input element - ignored
7471 @param date string or Date - the initial date to display
7472 @param onSelect function - the function to call when a date is selected
7473 @param settings object - update the dialog date picker instance's settings (anonymous object)
7474 @param pos int[2] - coordinates for the dialog's position within the screen or
7475 event - with x/y coordinates or
7476 leave empty for default (screen centre)
7477 @return the manager object */
7478 _dialogDatepicker: function(input, date, onSelect, settings, pos) {
7479 var inst = this._dialogInst; // internal instance
7480 if (!inst) {
7481 this.uuid += 1;
7482 var id = 'dp' + this.uuid;
7483 this._dialogInput = $('<input type="text" id="' + id +
7484 '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
7485 this._dialogInput.keydown(this._doKeyDown);
7486 $('body').append(this._dialogInput);
7487 inst = this._dialogInst = this._newInst(this._dialogInput, false);
7488 inst.settings = {};
7489 $.data(this._dialogInput[0], PROP_NAME, inst);
7490 }
7491 extendRemove(inst.settings, settings || {});
7492 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
7493 this._dialogInput.val(date);
7494
7495 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7496 if (!this._pos) {
7497 var browserWidth = document.documentElement.clientWidth;
7498 var browserHeight = document.documentElement.clientHeight;
7499 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7500 var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7501 this._pos = // should use actual width/height below
7502 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7503 }
7504
7505 // move input on screen for focus, but hidden behind dialog
7506 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
7507 inst.settings.onSelect = onSelect;
7508 this._inDialog = true;
7509 this.dpDiv.addClass(this._dialogClass);
7510 this._showDatepicker(this._dialogInput[0]);
7511 if ($.blockUI)
7512 $.blockUI(this.dpDiv);
7513 $.data(this._dialogInput[0], PROP_NAME, inst);
7514 return this;
7515 },
7516
7517 /* Detach a datepicker from its control.
7518 @param target element - the target input field or division or span */
7519 _destroyDatepicker: function(target) {
7520 var $target = $(target);
7521 var inst = $.data(target, PROP_NAME);
7522 if (!$target.hasClass(this.markerClassName)) {
7523 return;
7524 }
7525 var nodeName = target.nodeName.toLowerCase();
7526 $.removeData(target, PROP_NAME);
7527 if (nodeName == 'input') {
7528 inst.append.remove();
7529 inst.trigger.remove();
7530 $target.removeClass(this.markerClassName).
7531 unbind('focus', this._showDatepicker).
7532 unbind('keydown', this._doKeyDown).
7533 unbind('keypress', this._doKeyPress).
7534 unbind('keyup', this._doKeyUp);
7535 } else if (nodeName == 'div' || nodeName == 'span')
7536 $target.removeClass(this.markerClassName).empty();
7537 },
7538
7539 /* Enable the date picker to a jQuery selection.
7540 @param target element - the target input field or division or span */
7541 _enableDatepicker: function(target) {
7542 var $target = $(target);
7543 var inst = $.data(target, PROP_NAME);
7544 if (!$target.hasClass(this.markerClassName)) {
7545 return;
7546 }
7547 var nodeName = target.nodeName.toLowerCase();
7548 if (nodeName == 'input') {
7549 target.disabled = false;
7550 inst.trigger.filter('button').
7551 each(function() { this.disabled = false; }).end().
7552 filter('img').css({opacity: '1.0', cursor: ''});
7553 }
7554 else if (nodeName == 'div' || nodeName == 'span') {
7555 var inline = $target.children('.' + this._inlineClass);
7556 inline.children().removeClass('ui-state-disabled');
7557 }
7558 this._disabledInputs = $.map(this._disabledInputs,
7559 function(value) { return (value == target ? null : value); }); // delete entry
7560 },
7561
7562 /* Disable the date picker to a jQuery selection.
7563 @param target element - the target input field or division or span */
7564 _disableDatepicker: function(target) {
7565 var $target = $(target);
7566 var inst = $.data(target, PROP_NAME);
7567 if (!$target.hasClass(this.markerClassName)) {
7568 return;
7569 }
7570 var nodeName = target.nodeName.toLowerCase();
7571 if (nodeName == 'input') {
7572 target.disabled = true;
7573 inst.trigger.filter('button').
7574 each(function() { this.disabled = true; }).end().
7575 filter('img').css({opacity: '0.5', cursor: 'default'});
7576 }
7577 else if (nodeName == 'div' || nodeName == 'span') {
7578 var inline = $target.children('.' + this._inlineClass);
7579 inline.children().addClass('ui-state-disabled');
7580 }
7581 this._disabledInputs = $.map(this._disabledInputs,
7582 function(value) { return (value == target ? null : value); }); // delete entry
7583 this._disabledInputs[this._disabledInputs.length] = target;
7584 },
7585
7586 /* Is the first field in a jQuery collection disabled as a datepicker?
7587 @param target element - the target input field or division or span
7588 @return boolean - true if disabled, false if enabled */
7589 _isDisabledDatepicker: function(target) {
7590 if (!target) {
7591 return false;
7592 }
7593 for (var i = 0; i < this._disabledInputs.length; i++) {
7594 if (this._disabledInputs[i] == target)
7595 return true;
7596 }
7597 return false;
7598 },
7599
7600 /* Retrieve the instance data for the target control.
7601 @param target element - the target input field or division or span
7602 @return object - the associated instance data
7603 @throws error if a jQuery problem getting data */
7604 _getInst: function(target) {
7605 try {
7606 return $.data(target, PROP_NAME);
7607 }
7608 catch (err) {
7609 throw 'Missing instance data for this datepicker';
7610 }
7611 },
7612
7613 /* Update or retrieve the settings for a date picker attached to an input field or division.
7614 @param target element - the target input field or division or span
7615 @param name object - the new settings to update or
7616 string - the name of the setting to change or retrieve,
7617 when retrieving also 'all' for all instance settings or
7618 'defaults' for all global defaults
7619 @param value any - the new value for the setting
7620 (omit if above is an object or to retrieve a value) */
7621 _optionDatepicker: function(target, name, value) {
7622 var inst = this._getInst(target);
7623 if (arguments.length == 2 && typeof name == 'string') {
7624 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
7625 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
7626 this._get(inst, name)) : null));
7627 }
7628 var settings = name || {};
7629 if (typeof name == 'string') {
7630 settings = {};
7631 settings[name] = value;
7632 }
7633 if (inst) {
7634 if (this._curInst == inst) {
7635 this._hideDatepicker();
7636 }
7637 var date = this._getDateDatepicker(target, true);
7638 extendRemove(inst.settings, settings);
7639 this._attachments($(target), inst);
7640 this._autoSize(inst);
7641 this._setDateDatepicker(target, date);
7642 this._updateDatepicker(inst);
7643 }
7644 },
7645
7646 // change method deprecated
7647 _changeDatepicker: function(target, name, value) {
7648 this._optionDatepicker(target, name, value);
7649 },
7650
7651 /* Redraw the date picker attached to an input field or division.
7652 @param target element - the target input field or division or span */
7653 _refreshDatepicker: function(target) {
7654 var inst = this._getInst(target);
7655 if (inst) {
7656 this._updateDatepicker(inst);
7657 }
7658 },
7659
7660 /* Set the dates for a jQuery selection.
7661 @param target element - the target input field or division or span
7662 @param date Date - the new date */
7663 _setDateDatepicker: function(target, date) {
7664 var inst = this._getInst(target);
7665 if (inst) {
7666 this._setDate(inst, date);
7667 this._updateDatepicker(inst);
7668 this._updateAlternate(inst);
7669 }
7670 },
7671
7672 /* Get the date(s) for the first entry in a jQuery selection.
7673 @param target element - the target input field or division or span
7674 @param noDefault boolean - true if no default date is to be used
7675 @return Date - the current date */
7676 _getDateDatepicker: function(target, noDefault) {
7677 var inst = this._getInst(target);
7678 if (inst && !inst.inline)
7679 this._setDateFromField(inst, noDefault);
7680 return (inst ? this._getDate(inst) : null);
7681 },
7682
7683 /* Handle keystrokes. */
7684 _doKeyDown: function(event) {
7685 var inst = $.datepicker._getInst(event.target);
7686 var handled = true;
7687 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
7688 inst._keyEvent = true;
7689 if ($.datepicker._datepickerShowing)
7690 switch (event.keyCode) {
7691 case 9: $.datepicker._hideDatepicker();
7692 handled = false;
7693 break; // hide on tab out
7694 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
7695 $.datepicker._currentClass + ')', inst.dpDiv);
7696 if (sel[0])
7697 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7698 else
7699 $.datepicker._hideDatepicker();
7700 return false; // don't submit the form
7701 break; // select the value on enter
7702 case 27: $.datepicker._hideDatepicker();
7703 break; // hide on escape
7704 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7705 -$.datepicker._get(inst, 'stepBigMonths') :
7706 -$.datepicker._get(inst, 'stepMonths')), 'M');
7707 break; // previous month/year on page up/+ ctrl
7708 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7709 +$.datepicker._get(inst, 'stepBigMonths') :
7710 +$.datepicker._get(inst, 'stepMonths')), 'M');
7711 break; // next month/year on page down/+ ctrl
7712 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
7713 handled = event.ctrlKey || event.metaKey;
7714 break; // clear on ctrl or command +end
7715 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
7716 handled = event.ctrlKey || event.metaKey;
7717 break; // current on ctrl or command +home
7718 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
7719 handled = event.ctrlKey || event.metaKey;
7720 // -1 day on ctrl or command +left
7721 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7722 -$.datepicker._get(inst, 'stepBigMonths') :
7723 -$.datepicker._get(inst, 'stepMonths')), 'M');
7724 // next month/year on alt +left on Mac
7725 break;
7726 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
7727 handled = event.ctrlKey || event.metaKey;
7728 break; // -1 week on ctrl or command +up
7729 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
7730 handled = event.ctrlKey || event.metaKey;
7731 // +1 day on ctrl or command +right
7732 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7733 +$.datepicker._get(inst, 'stepBigMonths') :
7734 +$.datepicker._get(inst, 'stepMonths')), 'M');
7735 // next month/year on alt +right
7736 break;
7737 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
7738 handled = event.ctrlKey || event.metaKey;
7739 break; // +1 week on ctrl or command +down
7740 default: handled = false;
7741 }
7742 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
7743 $.datepicker._showDatepicker(this);
7744 else {
7745 handled = false;
7746 }
7747 if (handled) {
7748 event.preventDefault();
7749 event.stopPropagation();
7750 }
7751 },
7752
7753 /* Filter entered characters - based on date format. */
7754 _doKeyPress: function(event) {
7755 var inst = $.datepicker._getInst(event.target);
7756 if ($.datepicker._get(inst, 'constrainInput')) {
7757 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
7758 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
7759 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
7760 }
7761 },
7762
7763 /* Synchronise manual entry and field/alternate field. */
7764 _doKeyUp: function(event) {
7765 var inst = $.datepicker._getInst(event.target);
7766 if (inst.input.val() != inst.lastVal) {
7767 try {
7768 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7769 (inst.input ? inst.input.val() : null),
7770 $.datepicker._getFormatConfig(inst));
7771 if (date) { // only if valid
7772 $.datepicker._setDateFromField(inst);
7773 $.datepicker._updateAlternate(inst);
7774 $.datepicker._updateDatepicker(inst);
7775 }
7776 }
7777 catch (event) {
7778 $.datepicker.log(event);
7779 }
7780 }
7781 return true;
7782 },
7783
7784 /* Pop-up the date picker for a given input field.
7785 @param input element - the input field attached to the date picker or
7786 event - if triggered by focus */
7787 _showDatepicker: function(input) {
7788 input = input.target || input;
7789 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
7790 input = $('input', input.parentNode)[0];
7791 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
7792 return;
7793 var inst = $.datepicker._getInst(input);
7794 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
7795 $.datepicker._curInst.dpDiv.stop(true, true);
7796 }
7797 var beforeShow = $.datepicker._get(inst, 'beforeShow');
7798 extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
7799 inst.lastVal = null;
7800 $.datepicker._lastInput = input;
7801 $.datepicker._setDateFromField(inst);
7802 if ($.datepicker._inDialog) // hide cursor
7803 input.value = '';
7804 if (!$.datepicker._pos) { // position below input
7805 $.datepicker._pos = $.datepicker._findPos(input);
7806 $.datepicker._pos[1] += input.offsetHeight; // add the height
7807 }
7808 var isFixed = false;
7809 $(input).parents().each(function() {
7810 isFixed |= $(this).css('position') == 'fixed';
7811 return !isFixed;
7812 });
7813 if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
7814 $.datepicker._pos[0] -= document.documentElement.scrollLeft;
7815 $.datepicker._pos[1] -= document.documentElement.scrollTop;
7816 }
7817 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7818 $.datepicker._pos = null;
7819 //to avoid flashes on Firefox
7820 inst.dpDiv.empty();
7821 // determine sizing offscreen
7822 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
7823 $.datepicker._updateDatepicker(inst);
7824 // fix width for dynamic number of date pickers
7825 // and adjust position before showing
7826 offset = $.datepicker._checkOffset(inst, offset, isFixed);
7827 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7828 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
7829 left: offset.left + 'px', top: offset.top + 'px'});
7830 if (!inst.inline) {
7831 var showAnim = $.datepicker._get(inst, 'showAnim');
7832 var duration = $.datepicker._get(inst, 'duration');
7833 var postProcess = function() {
7834 $.datepicker._datepickerShowing = true;
7835 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7836 if( !! cover.length ){
7837 var borders = $.datepicker._getBorders(inst.dpDiv);
7838 cover.css({left: -borders[0], top: -borders[1],
7839 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
7840 }
7841 };
7842 inst.dpDiv.zIndex($(input).zIndex()+1);
7843 if ($.effects && $.effects[showAnim])
7844 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7845 else
7846 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
7847 if (!showAnim || !duration)
7848 postProcess();
7849 if (inst.input.is(':visible') && !inst.input.is(':disabled'))
7850 inst.input.focus();
7851 $.datepicker._curInst = inst;
7852 }
7853 },
7854
7855 /* Generate the date picker content. */
7856 _updateDatepicker: function(inst) {
7857 var self = this;
7858 var borders = $.datepicker._getBorders(inst.dpDiv);
7859 inst.dpDiv.empty().append(this._generateHTML(inst));
7860 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7861 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
7862 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
7863 }
7864 inst.dpDiv.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
7865 .bind('mouseout', function(){
7866 $(this).removeClass('ui-state-hover');
7867 if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
7868 if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
7869 })
7870 .bind('mouseover', function(){
7871 if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) {
7872 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
7873 $(this).addClass('ui-state-hover');
7874 if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
7875 if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
7876 }
7877 })
7878 .end()
7879 .find('.' + this._dayOverClass + ' a')
7880 .trigger('mouseover')
7881 .end();
7882 var numMonths = this._getNumberOfMonths(inst);
7883 var cols = numMonths[1];
7884 var width = 17;
7885 if (cols > 1)
7886 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
7887 else
7888 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
7889 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
7890 'Class']('ui-datepicker-multi');
7891 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
7892 'Class']('ui-datepicker-rtl');
7893 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
7894 inst.input.is(':visible') && !inst.input.is(':disabled'))
7895 inst.input.focus();
7896 // deffered render of the years select (to avoid flashes on Firefox)
7897 if( inst.yearshtml ){
7898 var origyearshtml = inst.yearshtml;
7899 setTimeout(function(){
7900 //assure that inst.yearshtml didn't change.
7901 if( origyearshtml === inst.yearshtml ){
7902 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
7903 }
7904 origyearshtml = inst.yearshtml = null;
7905 }, 0);
7906 }
7907 },
7908
7909 /* Retrieve the size of left and top borders for an element.
7910 @param elem (jQuery object) the element of interest
7911 @return (number[2]) the left and top borders */
7912 _getBorders: function(elem) {
7913 var convert = function(value) {
7914 return {thin: 1, medium: 2, thick: 3}[value] || value;
7915 };
7916 return [parseFloat(convert(elem.css('border-left-width'))),
7917 parseFloat(convert(elem.css('border-top-width')))];
7918 },
7919
7920 /* Check positioning to remain on screen. */
7921 _checkOffset: function(inst, offset, isFixed) {
7922 var dpWidth = inst.dpDiv.outerWidth();
7923 var dpHeight = inst.dpDiv.outerHeight();
7924 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
7925 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
7926 var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
7927 var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
7928
7929 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
7930 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
7931 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7932
7933 // now check if datepicker is showing outside window viewport - move to a better place if so.
7934 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7935 Math.abs(offset.left + dpWidth - viewWidth) : 0);
7936 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7937 Math.abs(dpHeight + inputHeight) : 0);
7938
7939 return offset;
7940 },
7941
7942 /* Find an object's position on the screen. */
7943 _findPos: function(obj) {
7944 var inst = this._getInst(obj);
7945 var isRTL = this._get(inst, 'isRTL');
7946 while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
7947 obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
7948 }
7949 var position = $(obj).offset();
7950 return [position.left, position.top];
7951 },
7952
7953 /* Hide the date picker from view.
7954 @param input element - the input field attached to the date picker */
7955 _hideDatepicker: function(input) {
7956 var inst = this._curInst;
7957 if (!inst || (input && inst != $.data(input, PROP_NAME)))
7958 return;
7959 if (this._datepickerShowing) {
7960 var showAnim = this._get(inst, 'showAnim');
7961 var duration = this._get(inst, 'duration');
7962 var postProcess = function() {
7963 $.datepicker._tidyDialog(inst);
7964 this._curInst = null;
7965 };
7966 if ($.effects && $.effects[showAnim])
7967 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7968 else
7969 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
7970 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
7971 if (!showAnim)
7972 postProcess();
7973 var onClose = this._get(inst, 'onClose');
7974 if (onClose)
7975 onClose.apply((inst.input ? inst.input[0] : null),
7976 [(inst.input ? inst.input.val() : ''), inst]); // trigger custom callback
7977 this._datepickerShowing = false;
7978 this._lastInput = null;
7979 if (this._inDialog) {
7980 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
7981 if ($.blockUI) {
7982 $.unblockUI();
7983 $('body').append(this.dpDiv);
7984 }
7985 }
7986 this._inDialog = false;
7987 }
7988 },
7989
7990 /* Tidy up after a dialog display. */
7991 _tidyDialog: function(inst) {
7992 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
7993 },
7994
7995 /* Close date picker if clicked elsewhere. */
7996 _checkExternalClick: function(event) {
7997 if (!$.datepicker._curInst)
7998 return;
7999 var $target = $(event.target);
8000 if ($target[0].id != $.datepicker._mainDivId &&
8001 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
8002 !$target.hasClass($.datepicker.markerClassName) &&
8003 !$target.hasClass($.datepicker._triggerClass) &&
8004 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
8005 $.datepicker._hideDatepicker();
8006 },
8007
8008 /* Adjust one of the date sub-fields. */
8009 _adjustDate: function(id, offset, period) {
8010 var target = $(id);
8011 var inst = this._getInst(target[0]);
8012 if (this._isDisabledDatepicker(target[0])) {
8013 return;
8014 }
8015 this._adjustInstDate(inst, offset +
8016 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
8017 period);
8018 this._updateDatepicker(inst);
8019 },
8020
8021 /* Action for current link. */
8022 _gotoToday: function(id) {
8023 var target = $(id);
8024 var inst = this._getInst(target[0]);
8025 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
8026 inst.selectedDay = inst.currentDay;
8027 inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8028 inst.drawYear = inst.selectedYear = inst.currentYear;
8029 }
8030 else {
8031 var date = new Date();
8032 inst.selectedDay = date.getDate();
8033 inst.drawMonth = inst.selectedMonth = date.getMonth();
8034 inst.drawYear = inst.selectedYear = date.getFullYear();
8035 }
8036 this._notifyChange(inst);
8037 this._adjustDate(target);
8038 },
8039
8040 /* Action for selecting a new month/year. */
8041 _selectMonthYear: function(id, select, period) {
8042 var target = $(id);
8043 var inst = this._getInst(target[0]);
8044 inst._selectingMonthYear = false;
8045 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
8046 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
8047 parseInt(select.options[select.selectedIndex].value,10);
8048 this._notifyChange(inst);
8049 this._adjustDate(target);
8050 },
8051
8052 /* Restore input focus after not changing month/year. */
8053 _clickMonthYear: function(id) {
8054 var target = $(id);
8055 var inst = this._getInst(target[0]);
8056 if (inst.input && inst._selectingMonthYear) {
8057 setTimeout(function() {
8058 inst.input.focus();
8059 }, 0);
8060 }
8061 inst._selectingMonthYear = !inst._selectingMonthYear;
8062 },
8063
8064 /* Action for selecting a day. */
8065 _selectDay: function(id, month, year, td) {
8066 var target = $(id);
8067 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8068 return;
8069 }
8070 var inst = this._getInst(target[0]);
8071 inst.selectedDay = inst.currentDay = $('a', td).html();
8072 inst.selectedMonth = inst.currentMonth = month;
8073 inst.selectedYear = inst.currentYear = year;
8074 this._selectDate(id, this._formatDate(inst,
8075 inst.currentDay, inst.currentMonth, inst.currentYear));
8076 },
8077
8078 /* Erase the input field and hide the date picker. */
8079 _clearDate: function(id) {
8080 var target = $(id);
8081 var inst = this._getInst(target[0]);
8082 this._selectDate(target, '');
8083 },
8084
8085 /* Update the input field with the selected date. */
8086 _selectDate: function(id, dateStr) {
8087 var target = $(id);
8088 var inst = this._getInst(target[0]);
8089 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8090 if (inst.input)
8091 inst.input.val(dateStr);
8092 this._updateAlternate(inst);
8093 var onSelect = this._get(inst, 'onSelect');
8094 if (onSelect)
8095 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
8096 else if (inst.input)
8097 inst.input.trigger('change'); // fire the change event
8098 if (inst.inline)
8099 this._updateDatepicker(inst);
8100 else {
8101 this._hideDatepicker();
8102 this._lastInput = inst.input[0];
8103 if (typeof(inst.input[0]) != 'object')
8104 inst.input.focus(); // restore focus
8105 this._lastInput = null;
8106 }
8107 },
8108
8109 /* Update any alternate field to synchronise with the main field. */
8110 _updateAlternate: function(inst) {
8111 var altField = this._get(inst, 'altField');
8112 if (altField) { // update alternate field too
8113 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
8114 var date = this._getDate(inst);
8115 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8116 $(altField).each(function() { $(this).val(dateStr); });
8117 }
8118 },
8119
8120 /* Set as beforeShowDay function to prevent selection of weekends.
8121 @param date Date - the date to customise
8122 @return [boolean, string] - is this date selectable?, what is its CSS class? */
8123 noWeekends: function(date) {
8124 var day = date.getDay();
8125 return [(day > 0 && day < 6), ''];
8126 },
8127
8128 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8129 @param date Date - the date to get the week for
8130 @return number - the number of the week within the year that contains this date */
8131 iso8601Week: function(date) {
8132 var checkDate = new Date(date.getTime());
8133 // Find Thursday of this week starting on Monday
8134 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8135 var time = checkDate.getTime();
8136 checkDate.setMonth(0); // Compare with Jan 1
8137 checkDate.setDate(1);
8138 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8139 },
8140
8141 /* Parse a string value into a date object.
8142 See formatDate below for the possible formats.
8143
8144 @param format string - the expected format of the date
8145 @param value string - the date in the above format
8146 @param settings Object - attributes include:
8147 shortYearCutoff number - the cutoff year for determining the century (optional)
8148 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8149 dayNames string[7] - names of the days from Sunday (optional)
8150 monthNamesShort string[12] - abbreviated names of the months (optional)
8151 monthNames string[12] - names of the months (optional)
8152 @return Date - the extracted date value or null if value is blank */
8153 parseDate: function (format, value, settings) {
8154 if (format == null || value == null)
8155 throw 'Invalid arguments';
8156 value = (typeof value == 'object' ? value.toString() : value + '');
8157 if (value == '')
8158 return null;
8159 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
8160 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8161 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8162 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8163 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8164 var year = -1;
8165 var month = -1;
8166 var day = -1;
8167 var doy = -1;
8168 var literal = false;
8169 // Check whether a format character is doubled
8170 var lookAhead = function(match) {
8171 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8172 if (matches)
8173 iFormat++;
8174 return matches;
8175 };
8176 // Extract a number from the string value
8177 var getNumber = function(match) {
8178 var isDoubled = lookAhead(match);
8179 var size = (match == '@' ? 14 : (match == '!' ? 20 :
8180 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
8181 var digits = new RegExp('^\\d{1,' + size + '}');
8182 var num = value.substring(iValue).match(digits);
8183 if (!num)
8184 throw 'Missing number at position ' + iValue;
8185 iValue += num[0].length;
8186 return parseInt(num[0], 10);
8187 };
8188 // Extract a name from the string value and convert to an index
8189 var getName = function(match, shortNames, longNames) {
8190 var names = (lookAhead(match) ? longNames : shortNames);
8191 for (var i = 0; i < names.length; i++) {
8192 if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) {
8193 iValue += names[i].length;
8194 return i + 1;
8195 }
8196 }
8197 throw 'Unknown name at position ' + iValue;
8198 };
8199 // Confirm that a literal character matches the string value
8200 var checkLiteral = function() {
8201 if (value.charAt(iValue) != format.charAt(iFormat))
8202 throw 'Unexpected literal at position ' + iValue;
8203 iValue++;
8204 };
8205 var iValue = 0;
8206 for (var iFormat = 0; iFormat < format.length; iFormat++) {
8207 if (literal)
8208 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8209 literal = false;
8210 else
8211 checkLiteral();
8212 else
8213 switch (format.charAt(iFormat)) {
8214 case 'd':
8215 day = getNumber('d');
8216 break;
8217 case 'D':
8218 getName('D', dayNamesShort, dayNames);
8219 break;
8220 case 'o':
8221 doy = getNumber('o');
8222 break;
8223 case 'm':
8224 month = getNumber('m');
8225 break;
8226 case 'M':
8227 month = getName('M', monthNamesShort, monthNames);
8228 break;
8229 case 'y':
8230 year = getNumber('y');
8231 break;
8232 case '@':
8233 var date = new Date(getNumber('@'));
8234 year = date.getFullYear();
8235 month = date.getMonth() + 1;
8236 day = date.getDate();
8237 break;
8238 case '!':
8239 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
8240 year = date.getFullYear();
8241 month = date.getMonth() + 1;
8242 day = date.getDate();
8243 break;
8244 case "'":
8245 if (lookAhead("'"))
8246 checkLiteral();
8247 else
8248 literal = true;
8249 break;
8250 default:
8251 checkLiteral();
8252 }
8253 }
8254 if (year == -1)
8255 year = new Date().getFullYear();
8256 else if (year < 100)
8257 year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8258 (year <= shortYearCutoff ? 0 : -100);
8259 if (doy > -1) {
8260 month = 1;
8261 day = doy;
8262 do {
8263 var dim = this._getDaysInMonth(year, month - 1);
8264 if (day <= dim)
8265 break;
8266 month++;
8267 day -= dim;
8268 } while (true);
8269 }
8270 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8271 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
8272 throw 'Invalid date'; // E.g. 31/02/*
8273 return date;
8274 },
8275
8276 /* Standard date formats. */
8277 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
8278 COOKIE: 'D, dd M yy',
8279 ISO_8601: 'yy-mm-dd',
8280 RFC_822: 'D, d M y',
8281 RFC_850: 'DD, dd-M-y',
8282 RFC_1036: 'D, d M y',
8283 RFC_1123: 'D, d M yy',
8284 RFC_2822: 'D, d M yy',
8285 RSS: 'D, d M y', // RFC 822
8286 TICKS: '!',
8287 TIMESTAMP: '@',
8288 W3C: 'yy-mm-dd', // ISO 8601
8289
8290 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8291 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8292
8293 /* Format a date object into a string value.
8294 The format can be combinations of the following:
8295 d - day of month (no leading zero)
8296 dd - day of month (two digit)
8297 o - day of year (no leading zeros)
8298 oo - day of year (three digit)
8299 D - day name short
8300 DD - day name long
8301 m - month of year (no leading zero)
8302 mm - month of year (two digit)
8303 M - month name short
8304 MM - month name long
8305 y - year (two digit)
8306 yy - year (four digit)
8307 @ - Unix timestamp (ms since 01/01/1970)
8308 ! - Windows ticks (100ns since 01/01/0001)
8309 '...' - literal text
8310 '' - single quote
8311
8312 @param format string - the desired format of the date
8313 @param date Date - the date value to format
8314 @param settings Object - attributes include:
8315 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8316 dayNames string[7] - names of the days from Sunday (optional)
8317 monthNamesShort string[12] - abbreviated names of the months (optional)
8318 monthNames string[12] - names of the months (optional)
8319 @return string - the date in the above format */
8320 formatDate: function (format, date, settings) {
8321 if (!date)
8322 return '';
8323 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8324 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8325 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8326 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8327 // Check whether a format character is doubled
8328 var lookAhead = function(match) {
8329 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8330 if (matches)
8331 iFormat++;
8332 return matches;
8333 };
8334 // Format a number, with leading zero if necessary
8335 var formatNumber = function(match, value, len) {
8336 var num = '' + value;
8337 if (lookAhead(match))
8338 while (num.length < len)
8339 num = '0' + num;
8340 return num;
8341 };
8342 // Format a name, short or long as requested
8343 var formatName = function(match, value, shortNames, longNames) {
8344 return (lookAhead(match) ? longNames[value] : shortNames[value]);
8345 };
8346 var output = '';
8347 var literal = false;
8348 if (date)
8349 for (var iFormat = 0; iFormat < format.length; iFormat++) {
8350 if (literal)
8351 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8352 literal = false;
8353 else
8354 output += format.charAt(iFormat);
8355 else
8356 switch (format.charAt(iFormat)) {
8357 case 'd':
8358 output += formatNumber('d', date.getDate(), 2);
8359 break;
8360 case 'D':
8361 output += formatName('D', date.getDay(), dayNamesShort, dayNames);
8362 break;
8363 case 'o':
8364 output += formatNumber('o',
8365 (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3);
8366 break;
8367 case 'm':
8368 output += formatNumber('m', date.getMonth() + 1, 2);
8369 break;
8370 case 'M':
8371 output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
8372 break;
8373 case 'y':
8374 output += (lookAhead('y') ? date.getFullYear() :
8375 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
8376 break;
8377 case '@':
8378 output += date.getTime();
8379 break;
8380 case '!':
8381 output += date.getTime() * 10000 + this._ticksTo1970;
8382 break;
8383 case "'":
8384 if (lookAhead("'"))
8385 output += "'";
8386 else
8387 literal = true;
8388 break;
8389 default:
8390 output += format.charAt(iFormat);
8391 }
8392 }
8393 return output;
8394 },
8395
8396 /* Extract all possible characters from the date format. */
8397 _possibleChars: function (format) {
8398 var chars = '';
8399 var literal = false;
8400 // Check whether a format character is doubled
8401 var lookAhead = function(match) {
8402 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8403 if (matches)
8404 iFormat++;
8405 return matches;
8406 };
8407 for (var iFormat = 0; iFormat < format.length; iFormat++)
8408 if (literal)
8409 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8410 literal = false;
8411 else
8412 chars += format.charAt(iFormat);
8413 else
8414 switch (format.charAt(iFormat)) {
8415 case 'd': case 'm': case 'y': case '@':
8416 chars += '0123456789';
8417 break;
8418 case 'D': case 'M':
8419 return null; // Accept anything
8420 case "'":
8421 if (lookAhead("'"))
8422 chars += "'";
8423 else
8424 literal = true;
8425 break;
8426 default:
8427 chars += format.charAt(iFormat);
8428 }
8429 return chars;
8430 },
8431
8432 /* Get a setting value, defaulting if necessary. */
8433 _get: function(inst, name) {
8434 return inst.settings[name] !== undefined ?
8435 inst.settings[name] : this._defaults[name];
8436 },
8437
8438 /* Parse existing date and initialise date picker. */
8439 _setDateFromField: function(inst, noDefault) {
8440 if (inst.input.val() == inst.lastVal) {
8441 return;
8442 }
8443 var dateFormat = this._get(inst, 'dateFormat');
8444 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
8445 var date, defaultDate;
8446 date = defaultDate = this._getDefaultDate(inst);
8447 var settings = this._getFormatConfig(inst);
8448 try {
8449 date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8450 } catch (event) {
8451 this.log(event);
8452 dates = (noDefault ? '' : dates);
8453 }
8454 inst.selectedDay = date.getDate();
8455 inst.drawMonth = inst.selectedMonth = date.getMonth();
8456 inst.drawYear = inst.selectedYear = date.getFullYear();
8457 inst.currentDay = (dates ? date.getDate() : 0);
8458 inst.currentMonth = (dates ? date.getMonth() : 0);
8459 inst.currentYear = (dates ? date.getFullYear() : 0);
8460 this._adjustInstDate(inst);
8461 },
8462
8463 /* Retrieve the default date shown on opening. */
8464 _getDefaultDate: function(inst) {
8465 return this._restrictMinMax(inst,
8466 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
8467 },
8468
8469 /* A date may be specified as an exact value or a relative one. */
8470 _determineDate: function(inst, date, defaultDate) {
8471 var offsetNumeric = function(offset) {
8472 var date = new Date();
8473 date.setDate(date.getDate() + offset);
8474 return date;
8475 };
8476 var offsetString = function(offset) {
8477 try {
8478 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8479 offset, $.datepicker._getFormatConfig(inst));
8480 }
8481 catch (e) {
8482 // Ignore
8483 }
8484 var date = (offset.toLowerCase().match(/^c/) ?
8485 $.datepicker._getDate(inst) : null) || new Date();
8486 var year = date.getFullYear();
8487 var month = date.getMonth();
8488 var day = date.getDate();
8489 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
8490 var matches = pattern.exec(offset);
8491 while (matches) {
8492 switch (matches[2] || 'd') {
8493 case 'd' : case 'D' :
8494 day += parseInt(matches[1],10); break;
8495 case 'w' : case 'W' :
8496 day += parseInt(matches[1],10) * 7; break;
8497 case 'm' : case 'M' :
8498 month += parseInt(matches[1],10);
8499 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8500 break;
8501 case 'y': case 'Y' :
8502 year += parseInt(matches[1],10);
8503 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8504 break;
8505 }
8506 matches = pattern.exec(offset);
8507 }
8508 return new Date(year, month, day);
8509 };
8510 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
8511 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8512 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
8513 if (newDate) {
8514 newDate.setHours(0);
8515 newDate.setMinutes(0);
8516 newDate.setSeconds(0);
8517 newDate.setMilliseconds(0);
8518 }
8519 return this._daylightSavingAdjust(newDate);
8520 },
8521
8522 /* Handle switch to/from daylight saving.
8523 Hours may be non-zero on daylight saving cut-over:
8524 > 12 when midnight changeover, but then cannot generate
8525 midnight datetime, so jump to 1AM, otherwise reset.
8526 @param date (Date) the date to check
8527 @return (Date) the corrected date */
8528 _daylightSavingAdjust: function(date) {
8529 if (!date) return null;
8530 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8531 return date;
8532 },
8533
8534 /* Set the date(s) directly. */
8535 _setDate: function(inst, date, noChange) {
8536 var clear = !date;
8537 var origMonth = inst.selectedMonth;
8538 var origYear = inst.selectedYear;
8539 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8540 inst.selectedDay = inst.currentDay = newDate.getDate();
8541 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8542 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8543 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
8544 this._notifyChange(inst);
8545 this._adjustInstDate(inst);
8546 if (inst.input) {
8547 inst.input.val(clear ? '' : this._formatDate(inst));
8548 }
8549 },
8550
8551 /* Retrieve the date(s) directly. */
8552 _getDate: function(inst) {
8553 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
8554 this._daylightSavingAdjust(new Date(
8555 inst.currentYear, inst.currentMonth, inst.currentDay)));
8556 return startDate;
8557 },
8558
8559 /* Generate the HTML for the current state of the date picker. */
8560 _generateHTML: function(inst) {
8561 var today = new Date();
8562 today = this._daylightSavingAdjust(
8563 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
8564 var isRTL = this._get(inst, 'isRTL');
8565 var showButtonPanel = this._get(inst, 'showButtonPanel');
8566 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
8567 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
8568 var numMonths = this._getNumberOfMonths(inst);
8569 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
8570 var stepMonths = this._get(inst, 'stepMonths');
8571 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
8572 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8573 new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8574 var minDate = this._getMinMaxDate(inst, 'min');
8575 var maxDate = this._getMinMaxDate(inst, 'max');
8576 var drawMonth = inst.drawMonth - showCurrentAtPos;
8577 var drawYear = inst.drawYear;
8578 if (drawMonth < 0) {
8579 drawMonth += 12;
8580 drawYear--;
8581 }
8582 if (maxDate) {
8583 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8584 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8585 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8586 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8587 drawMonth--;
8588 if (drawMonth < 0) {
8589 drawMonth = 11;
8590 drawYear--;
8591 }
8592 }
8593 }
8594 inst.drawMonth = drawMonth;
8595 inst.drawYear = drawYear;
8596 var prevText = this._get(inst, 'prevText');
8597 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8598 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8599 this._getFormatConfig(inst)));
8600 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8601 '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8602 '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
8603 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
8604 (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
8605 var nextText = this._get(inst, 'nextText');
8606 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8607 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8608 this._getFormatConfig(inst)));
8609 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8610 '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8611 '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
8612 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
8613 (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
8614 var currentText = this._get(inst, 'currentText');
8615 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
8616 currentText = (!navigationAsDateFormat ? currentText :
8617 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8618 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8619 '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
8620 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
8621 (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8622 '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
8623 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
8624 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
8625 firstDay = (isNaN(firstDay) ? 0 : firstDay);
8626 var showWeek = this._get(inst, 'showWeek');
8627 var dayNames = this._get(inst, 'dayNames');
8628 var dayNamesShort = this._get(inst, 'dayNamesShort');
8629 var dayNamesMin = this._get(inst, 'dayNamesMin');
8630 var monthNames = this._get(inst, 'monthNames');
8631 var monthNamesShort = this._get(inst, 'monthNamesShort');
8632 var beforeShowDay = this._get(inst, 'beforeShowDay');
8633 var showOtherMonths = this._get(inst, 'showOtherMonths');
8634 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
8635 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
8636 var defaultDate = this._getDefaultDate(inst);
8637 var html = '';
8638 for (var row = 0; row < numMonths[0]; row++) {
8639 var group = '';
8640 for (var col = 0; col < numMonths[1]; col++) {
8641 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8642 var cornerClass = ' ui-corner-all';
8643 var calender = '';
8644 if (isMultiMonth) {
8645 calender += '<div class="ui-datepicker-group';
8646 if (numMonths[1] > 1)
8647 switch (col) {
8648 case 0: calender += ' ui-datepicker-group-first';
8649 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
8650 case numMonths[1]-1: calender += ' ui-datepicker-group-last';
8651 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
8652 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
8653 }
8654 calender += '">';
8655 }
8656 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
8657 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
8658 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
8659 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8660 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8661 '</div><table class="ui-datepicker-calendar"><thead>' +
8662 '<tr>';
8663 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
8664 for (var dow = 0; dow < 7; dow++) { // days of the week
8665 var day = (dow + firstDay) % 7;
8666 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
8667 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
8668 }
8669 calender += thead + '</tr></thead><tbody>';
8670 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8671 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
8672 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8673 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8674 var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
8675 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8676 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8677 calender += '<tr>';
8678 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
8679 this._get(inst, 'calculateWeek')(printDate) + '</td>');
8680 for (var dow = 0; dow < 7; dow++) { // create date picker days
8681 var daySettings = (beforeShowDay ?
8682 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
8683 var otherMonth = (printDate.getMonth() != drawMonth);
8684 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8685 (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8686 tbody += '<td class="' +
8687 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
8688 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
8689 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
8690 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
8691 // or defaultDate is current printedDate and defaultDate is selectedDate
8692 ' ' + this._dayOverClass : '') + // highlight selected day
8693 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
8694 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
8695 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
8696 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
8697 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
8698 (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
8699 inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
8700 (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
8701 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
8702 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
8703 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
8704 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
8705 '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
8706 printDate.setDate(printDate.getDate() + 1);
8707 printDate = this._daylightSavingAdjust(printDate);
8708 }
8709 calender += tbody + '</tr>';
8710 }
8711 drawMonth++;
8712 if (drawMonth > 11) {
8713 drawMonth = 0;
8714 drawYear++;
8715 }
8716 calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
8717 ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
8718 group += calender;
8719 }
8720 html += group;
8721 }
8722 html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
8723 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
8724 inst._keyEvent = false;
8725 return html;
8726 },
8727
8728 /* Generate the month and year header. */
8729 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8730 secondary, monthNames, monthNamesShort) {
8731 var changeMonth = this._get(inst, 'changeMonth');
8732 var changeYear = this._get(inst, 'changeYear');
8733 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
8734 var html = '<div class="ui-datepicker-title">';
8735 var monthHtml = '';
8736 // month selection
8737 if (secondary || !changeMonth)
8738 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
8739 else {
8740 var inMinYear = (minDate && minDate.getFullYear() == drawYear);
8741 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
8742 monthHtml += '<select class="ui-datepicker-month" ' +
8743 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
8744 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
8745 '>';
8746 for (var month = 0; month < 12; month++) {
8747 if ((!inMinYear || month >= minDate.getMonth()) &&
8748 (!inMaxYear || month <= maxDate.getMonth()))
8749 monthHtml += '<option value="' + month + '"' +
8750 (month == drawMonth ? ' selected="selected"' : '') +
8751 '>' + monthNamesShort[month] + '</option>';
8752 }
8753 monthHtml += '</select>';
8754 }
8755 if (!showMonthAfterYear)
8756 html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
8757 // year selection
8758 inst.yearshtml = '';
8759 if (secondary || !changeYear)
8760 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
8761 else {
8762 // determine range of years to display
8763 var years = this._get(inst, 'yearRange').split(':');
8764 var thisYear = new Date().getFullYear();
8765 var determineYear = function(value) {
8766 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8767 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
8768 parseInt(value, 10)));
8769 return (isNaN(year) ? thisYear : year);
8770 };
8771 var year = determineYear(years[0]);
8772 var endYear = Math.max(year, determineYear(years[1] || ''));
8773 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8774 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8775 inst.yearshtml += '<select class="ui-datepicker-year" ' +
8776 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
8777 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
8778 '>';
8779 for (; year <= endYear; year++) {
8780 inst.yearshtml += '<option value="' + year + '"' +
8781 (year == drawYear ? ' selected="selected"' : '') +
8782 '>' + year + '</option>';
8783 }
8784 inst.yearshtml += '</select>';
8785 //when showing there is no need for later update
8786 if( ! $.browser.mozilla ){
8787 html += inst.yearshtml;
8788 inst.yearshtml = null;
8789 } else {
8790 // will be replaced later with inst.yearshtml
8791 html += '<select class="ui-datepicker-year"><option value="' + drawYear + '" selected="selected">' + drawYear + '</option></select>';
8792 }
8793 }
8794 html += this._get(inst, 'yearSuffix');
8795 if (showMonthAfterYear)
8796 html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
8797 html += '</div>'; // Close datepicker_header
8798 return html;
8799 },
8800
8801 /* Adjust one of the date sub-fields. */
8802 _adjustInstDate: function(inst, offset, period) {
8803 var year = inst.drawYear + (period == 'Y' ? offset : 0);
8804 var month = inst.drawMonth + (period == 'M' ? offset : 0);
8805 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
8806 (period == 'D' ? offset : 0);
8807 var date = this._restrictMinMax(inst,
8808 this._daylightSavingAdjust(new Date(year, month, day)));
8809 inst.selectedDay = date.getDate();
8810 inst.drawMonth = inst.selectedMonth = date.getMonth();
8811 inst.drawYear = inst.selectedYear = date.getFullYear();
8812 if (period == 'M' || period == 'Y')
8813 this._notifyChange(inst);
8814 },
8815
8816 /* Ensure a date is within any min/max bounds. */
8817 _restrictMinMax: function(inst, date) {
8818 var minDate = this._getMinMaxDate(inst, 'min');
8819 var maxDate = this._getMinMaxDate(inst, 'max');
8820 var newDate = (minDate && date < minDate ? minDate : date);
8821 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
8822 return newDate;
8823 },
8824
8825 /* Notify change of month/year. */
8826 _notifyChange: function(inst) {
8827 var onChange = this._get(inst, 'onChangeMonthYear');
8828 if (onChange)
8829 onChange.apply((inst.input ? inst.input[0] : null),
8830 [inst.selectedYear, inst.selectedMonth + 1, inst]);
8831 },
8832
8833 /* Determine the number of months to show. */
8834 _getNumberOfMonths: function(inst) {
8835 var numMonths = this._get(inst, 'numberOfMonths');
8836 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
8837 },
8838
8839 /* Determine the current maximum date - ensure no time components are set. */
8840 _getMinMaxDate: function(inst, minMax) {
8841 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
8842 },
8843
8844 /* Find the number of days in a given month. */
8845 _getDaysInMonth: function(year, month) {
8846 return 32 - new Date(year, month, 32).getDate();
8847 },
8848
8849 /* Find the day of the week of the first of a month. */
8850 _getFirstDayOfMonth: function(year, month) {
8851 return new Date(year, month, 1).getDay();
8852 },
8853
8854 /* Determines if we should allow a "next/prev" month display change. */
8855 _canAdjustMonth: function(inst, offset, curYear, curMonth) {
8856 var numMonths = this._getNumberOfMonths(inst);
8857 var date = this._daylightSavingAdjust(new Date(curYear,
8858 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8859 if (offset < 0)
8860 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8861 return this._isInRange(inst, date);
8862 },
8863
8864 /* Is the given date in the accepted range? */
8865 _isInRange: function(inst, date) {
8866 var minDate = this._getMinMaxDate(inst, 'min');
8867 var maxDate = this._getMinMaxDate(inst, 'max');
8868 return ((!minDate || date.getTime() >= minDate.getTime()) &&
8869 (!maxDate || date.getTime() <= maxDate.getTime()));
8870 },
8871
8872 /* Provide the configuration settings for formatting/parsing. */
8873 _getFormatConfig: function(inst) {
8874 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
8875 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8876 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8877 return {shortYearCutoff: shortYearCutoff,
8878 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
8879 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
8880 },
8881
8882 /* Format the given date for display. */
8883 _formatDate: function(inst, day, month, year) {
8884 if (!day) {
8885 inst.currentDay = inst.selectedDay;
8886 inst.currentMonth = inst.selectedMonth;
8887 inst.currentYear = inst.selectedYear;
8888 }
8889 var date = (day ? (typeof day == 'object' ? day :
8890 this._daylightSavingAdjust(new Date(year, month, day))) :
8891 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8892 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
8893 }
8894 });
8895
8896 /* jQuery extend now ignores nulls! */
8897 function extendRemove(target, props) {
8898 $.extend(target, props);
8899 for (var name in props)
8900 if (props[name] == null || props[name] == undefined)
8901 target[name] = props[name];
8902 return target;
8903 };
8904
8905 /* Determine whether an object is an array. */
8906 function isArray(a) {
8907 return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
8908 (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
8909 };
8910
8911 /* Invoke the datepicker functionality.
8912 @param options string - a command, optionally followed by additional parameters or
8913 Object - settings for attaching new datepicker functionality
8914 @return jQuery object */
8915 $.fn.datepicker = function(options){
8916
8917 /* Initialise the date picker. */
8918 if (!$.datepicker.initialized) {
8919 $(document).mousedown($.datepicker._checkExternalClick).
8920 find('body').append($.datepicker.dpDiv);
8921 $.datepicker.initialized = true;
8922 }
8923
8924 var otherArgs = Array.prototype.slice.call(arguments, 1);
8925 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
8926 return $.datepicker['_' + options + 'Datepicker'].
8927 apply($.datepicker, [this[0]].concat(otherArgs));
8928 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
8929 return $.datepicker['_' + options + 'Datepicker'].
8930 apply($.datepicker, [this[0]].concat(otherArgs));
8931 return this.each(function() {
8932 typeof options == 'string' ?
8933 $.datepicker['_' + options + 'Datepicker'].
8934 apply($.datepicker, [this].concat(otherArgs)) :
8935 $.datepicker._attachDatepicker(this, options);
8936 });
8937 };
8938
8939 $.datepicker = new Datepicker(); // singleton instance
8940 $.datepicker.initialized = false;
8941 $.datepicker.uuid = new Date().getTime();
8942 $.datepicker.version = "1.8.7";
8943
8944 // Workaround for #4055
8945 // Add another global to avoid noConflict issues with inline event handlers
8946 window['DP_jQuery_' + dpuuid] = $;
8947
8948 })(jQuery);
8949 /*
8950 * Note: While Microsoft is not the author of this file, Microsoft is
8951 * offering you a license subject to the terms of the Microsoft Software
8952 * License Terms for Microsoft ASP.NET Model View Controller 3.
8953 * Microsoft reserves all other rights. The notices below are provided
8954 * for informational purposes only and are not the license terms under
8955 * which Microsoft distributed this file.
8956 *
8957 * jQuery UI Dialog 1.8.7
8958 *
8959 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
8960 *
8961 * http://docs.jquery.com/UI/Dialog
8962 *
8963 * Depends:
8964 * jquery.ui.core.js
8965 * jquery.ui.widget.js
8966 * jquery.ui.button.js
8967 * jquery.ui.draggable.js
8968 * jquery.ui.mouse.js
8969 * jquery.ui.position.js
8970 * jquery.ui.resizable.js
8971 */
8972 (function( $, undefined ) {
8973
8974 var uiDialogClasses =
8975 'ui-dialog ' +
8976 'ui-widget ' +
8977 'ui-widget-content ' +
8978 'ui-corner-all ',
8979 sizeRelatedOptions = {
8980 buttons: true,
8981 height: true,
8982 maxHeight: true,
8983 maxWidth: true,
8984 minHeight: true,
8985 minWidth: true,
8986 width: true
8987 },
8988 resizableRelatedOptions = {
8989 maxHeight: true,
8990 maxWidth: true,
8991 minHeight: true,
8992 minWidth: true
8993 };
8994
8995 $.widget("ui.dialog", {
8996 options: {
8997 autoOpen: true,
8998 buttons: {},
8999 closeOnEscape: true,
9000 closeText: 'close',
9001 dialogClass: '',
9002 draggable: true,
9003 hide: null,
9004 height: 'auto',
9005 maxHeight: false,
9006 maxWidth: false,
9007 minHeight: 150,
9008 minWidth: 150,
9009 modal: false,
9010 position: {
9011 my: 'center',
9012 at: 'center',
9013 collision: 'fit',
9014 // ensure that the titlebar is never outside the document
9015 using: function(pos) {
9016 var topOffset = $(this).css(pos).offset().top;
9017 if (topOffset < 0) {
9018 $(this).css('top', pos.top - topOffset);
9019 }
9020 }
9021 },
9022 resizable: true,
9023 show: null,
9024 stack: true,
9025 title: '',
9026 width: 300,
9027 zIndex: 1000
9028 },
9029
9030 _create: function() {
9031 this.originalTitle = this.element.attr('title');
9032 // #5742 - .attr() might return a DOMElement
9033 if ( typeof this.originalTitle !== "string" ) {
9034 this.originalTitle = "";
9035 }
9036
9037 this.options.title = this.options.title || this.originalTitle;
9038 var self = this,
9039 options = self.options,
9040
9041 title = options.title || '&#160;',
9042 titleId = $.ui.dialog.getTitleId(self.element),
9043
9044 uiDialog = (self.uiDialog = $('<div></div>'))
9045 .appendTo(document.body)
9046 .hide()
9047 .addClass(uiDialogClasses + options.dialogClass)
9048 .css({
9049 zIndex: options.zIndex
9050 })
9051 // setting tabIndex makes the div focusable
9052 // setting outline to 0 prevents a border on focus in Mozilla
9053 .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
9054 if (options.closeOnEscape && event.keyCode &&
9055 event.keyCode === $.ui.keyCode.ESCAPE) {
9056
9057 self.close(event);
9058 event.preventDefault();
9059 }
9060 })
9061 .attr({
9062 role: 'dialog',
9063 'aria-labelledby': titleId
9064 })
9065 .mousedown(function(event) {
9066 self.moveToTop(false, event);
9067 }),
9068
9069 uiDialogContent = self.element
9070 .show()
9071 .removeAttr('title')
9072 .addClass(
9073 'ui-dialog-content ' +
9074 'ui-widget-content')
9075 .appendTo(uiDialog),
9076
9077 uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
9078 .addClass(
9079 'ui-dialog-titlebar ' +
9080 'ui-widget-header ' +
9081 'ui-corner-all ' +
9082 'ui-helper-clearfix'
9083 )
9084 .prependTo(uiDialog),
9085
9086 uiDialogTitlebarClose = $('<a href="#"></a>')
9087 .addClass(
9088 'ui-dialog-titlebar-close ' +
9089 'ui-corner-all'
9090 )
9091 .attr('role', 'button')
9092 .hover(
9093 function() {
9094 uiDialogTitlebarClose.addClass('ui-state-hover');
9095 },
9096 function() {
9097 uiDialogTitlebarClose.removeClass('ui-state-hover');
9098 }
9099 )
9100 .focus(function() {
9101 uiDialogTitlebarClose.addClass('ui-state-focus');
9102 })
9103 .blur(function() {
9104 uiDialogTitlebarClose.removeClass('ui-state-focus');
9105 })
9106 .click(function(event) {
9107 self.close(event);
9108 return false;
9109 })
9110 .appendTo(uiDialogTitlebar),
9111
9112 uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
9113 .addClass(
9114 'ui-icon ' +
9115 'ui-icon-closethick'
9116 )
9117 .text(options.closeText)
9118 .appendTo(uiDialogTitlebarClose),
9119
9120 uiDialogTitle = $('<span></span>')
9121 .addClass('ui-dialog-title')
9122 .attr('id', titleId)
9123 .html(title)
9124 .prependTo(uiDialogTitlebar);
9125
9126 //handling of deprecated beforeclose (vs beforeClose) option
9127 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
9128 //TODO: remove in 1.9pre
9129 if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
9130 options.beforeClose = options.beforeclose;
9131 }
9132
9133 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
9134
9135 if (options.draggable && $.fn.draggable) {
9136 self._makeDraggable();
9137 }
9138 if (options.resizable && $.fn.resizable) {
9139 self._makeResizable();
9140 }
9141
9142 self._createButtons(options.buttons);
9143 self._isOpen = false;
9144
9145 if ($.fn.bgiframe) {
9146 uiDialog.bgiframe();
9147 }
9148 },
9149
9150 _init: function() {
9151 if ( this.options.autoOpen ) {
9152 this.open();
9153 }
9154 },
9155
9156 destroy: function() {
9157 var self = this;
9158
9159 if (self.overlay) {
9160 self.overlay.destroy();
9161 }
9162 self.uiDialog.hide();
9163 self.element
9164 .unbind('.dialog')
9165 .removeData('dialog')
9166 .removeClass('ui-dialog-content ui-widget-content')
9167 .hide().appendTo('body');
9168 self.uiDialog.remove();
9169
9170 if (self.originalTitle) {
9171 self.element.attr('title', self.originalTitle);
9172 }
9173
9174 return self;
9175 },
9176
9177 widget: function() {
9178 return this.uiDialog;
9179 },
9180
9181 close: function(event) {
9182 var self = this,
9183 maxZ, thisZ;
9184
9185 if (false === self._trigger('beforeClose', event)) {
9186 return;
9187 }
9188
9189 if (self.overlay) {
9190 self.overlay.destroy();
9191 }
9192 self.uiDialog.unbind('keypress.ui-dialog');
9193
9194 self._isOpen = false;
9195
9196 if (self.options.hide) {
9197 self.uiDialog.hide(self.options.hide, function() {
9198 self._trigger('close', event);
9199 });
9200 } else {
9201 self.uiDialog.hide();
9202 self._trigger('close', event);
9203 }
9204
9205 $.ui.dialog.overlay.resize();
9206
9207 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9208 if (self.options.modal) {
9209 maxZ = 0;
9210 $('.ui-dialog').each(function() {
9211 if (this !== self.uiDialog[0]) {
9212 thisZ = $(this).css('z-index');
9213 if(!isNaN(thisZ)) {
9214 maxZ = Math.max(maxZ, thisZ);
9215 }
9216 }
9217 });
9218 $.ui.dialog.maxZ = maxZ;
9219 }
9220
9221 return self;
9222 },
9223
9224 isOpen: function() {
9225 return this._isOpen;
9226 },
9227
9228 // the force parameter allows us to move modal dialogs to their correct
9229 // position on open
9230 moveToTop: function(force, event) {
9231 var self = this,
9232 options = self.options,
9233 saveScroll;
9234
9235 if ((options.modal && !force) ||
9236 (!options.stack && !options.modal)) {
9237 return self._trigger('focus', event);
9238 }
9239
9240 if (options.zIndex > $.ui.dialog.maxZ) {
9241 $.ui.dialog.maxZ = options.zIndex;
9242 }
9243 if (self.overlay) {
9244 $.ui.dialog.maxZ += 1;
9245 self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
9246 }
9247
9248 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
9249 // http://ui.jquery.com/bugs/ticket/3193
9250 saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') };
9251 $.ui.dialog.maxZ += 1;
9252 self.uiDialog.css('z-index', $.ui.dialog.maxZ);
9253 self.element.attr(saveScroll);
9254 self._trigger('focus', event);
9255
9256 return self;
9257 },
9258
9259 open: function() {
9260 if (this._isOpen) { return; }
9261
9262 var self = this,
9263 options = self.options,
9264 uiDialog = self.uiDialog;
9265
9266 self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
9267 self._size();
9268 self._position(options.position);
9269 uiDialog.show(options.show);
9270 self.moveToTop(true);
9271
9272 // prevent tabbing out of modal dialogs
9273 if (options.modal) {
9274 uiDialog.bind('keypress.ui-dialog', function(event) {
9275 if (event.keyCode !== $.ui.keyCode.TAB) {
9276 return;
9277 }
9278
9279 var tabbables = $(':tabbable', this),
9280 first = tabbables.filter(':first'),
9281 last = tabbables.filter(':last');
9282
9283 if (event.target === last[0] && !event.shiftKey) {
9284 first.focus(1);
9285 return false;
9286 } else if (event.target === first[0] && event.shiftKey) {
9287 last.focus(1);
9288 return false;
9289 }
9290 });
9291 }
9292
9293 // set focus to the first tabbable element in the content area or the first button
9294 // if there are no tabbable elements, set focus on the dialog itself
9295 $(self.element.find(':tabbable').get().concat(
9296 uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
9297 uiDialog.get()))).eq(0).focus();
9298
9299 self._isOpen = true;
9300 self._trigger('open');
9301
9302 return self;
9303 },
9304
9305 _createButtons: function(buttons) {
9306 var self = this,
9307 hasButtons = false,
9308 uiDialogButtonPane = $('<div></div>')
9309 .addClass(
9310 'ui-dialog-buttonpane ' +
9311 'ui-widget-content ' +
9312 'ui-helper-clearfix'
9313 ),
9314 uiButtonSet = $( "<div></div>" )
9315 .addClass( "ui-dialog-buttonset" )
9316 .appendTo( uiDialogButtonPane );
9317
9318 // if we already have a button pane, remove it
9319 self.uiDialog.find('.ui-dialog-buttonpane').remove();
9320
9321 if (typeof buttons === 'object' && buttons !== null) {
9322 $.each(buttons, function() {
9323 return !(hasButtons = true);
9324 });
9325 }
9326 if (hasButtons) {
9327 $.each(buttons, function(name, props) {
9328 props = $.isFunction( props ) ?
9329 { click: props, text: name } :
9330 props;
9331 var button = $('<button type="button"></button>')
9332 .attr( props, true )
9333 .unbind('click')
9334 .click(function() {
9335 props.click.apply(self.element[0], arguments);
9336 })
9337 .appendTo(uiButtonSet);
9338 if ($.fn.button) {
9339 button.button();
9340 }
9341 });
9342 uiDialogButtonPane.appendTo(self.uiDialog);
9343 }
9344 },
9345
9346 _makeDraggable: function() {
9347 var self = this,
9348 options = self.options,
9349 doc = $(document),
9350 heightBeforeDrag;
9351
9352 function filteredUi(ui) {
9353 return {
9354 position: ui.position,
9355 offset: ui.offset
9356 };
9357 }
9358
9359 self.uiDialog.draggable({
9360 cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
9361 handle: '.ui-dialog-titlebar',
9362 containment: 'document',
9363 start: function(event, ui) {
9364 heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
9365 $(this).height($(this).height()).addClass("ui-dialog-dragging");
9366 self._trigger('dragStart', event, filteredUi(ui));
9367 },
9368 drag: function(event, ui) {
9369 self._trigger('drag', event, filteredUi(ui));
9370 },
9371 stop: function(event, ui) {
9372 options.position = [ui.position.left - doc.scrollLeft(),
9373 ui.position.top - doc.scrollTop()];
9374 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
9375 self._trigger('dragStop', event, filteredUi(ui));
9376 $.ui.dialog.overlay.resize();
9377 }
9378 });
9379 },
9380
9381 _makeResizable: function(handles) {
9382 handles = (handles === undefined ? this.options.resizable : handles);
9383 var self = this,
9384 options = self.options,
9385 // .ui-resizable has position: relative defined in the stylesheet
9386 // but dialogs have to use absolute or fixed positioning
9387 position = self.uiDialog.css('position'),
9388 resizeHandles = (typeof handles === 'string' ?
9389 handles :
9390 'n,e,s,w,se,sw,ne,nw'
9391 );
9392
9393 function filteredUi(ui) {
9394 return {
9395 originalPosition: ui.originalPosition,
9396 originalSize: ui.originalSize,
9397 position: ui.position,
9398 size: ui.size
9399 };
9400 }
9401
9402 self.uiDialog.resizable({
9403 cancel: '.ui-dialog-content',
9404 containment: 'document',
9405 alsoResize: self.element,
9406 maxWidth: options.maxWidth,
9407 maxHeight: options.maxHeight,
9408 minWidth: options.minWidth,
9409 minHeight: self._minHeight(),
9410 handles: resizeHandles,
9411 start: function(event, ui) {
9412 $(this).addClass("ui-dialog-resizing");
9413 self._trigger('resizeStart', event, filteredUi(ui));
9414 },
9415 resize: function(event, ui) {
9416 self._trigger('resize', event, filteredUi(ui));
9417 },
9418 stop: function(event, ui) {
9419 $(this).removeClass("ui-dialog-resizing");
9420 options.height = $(this).height();
9421 options.width = $(this).width();
9422 self._trigger('resizeStop', event, filteredUi(ui));
9423 $.ui.dialog.overlay.resize();
9424 }
9425 })
9426 .css('position', position)
9427 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
9428 },
9429
9430 _minHeight: function() {
9431 var options = this.options;
9432
9433 if (options.height === 'auto') {
9434 return options.minHeight;
9435 } else {
9436 return Math.min(options.minHeight, options.height);
9437 }
9438 },
9439
9440 _position: function(position) {
9441 var myAt = [],
9442 offset = [0, 0],
9443 isVisible;
9444
9445 if (position) {
9446 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
9447 // if (typeof position == 'string' || $.isArray(position)) {
9448 // myAt = $.isArray(position) ? position : position.split(' ');
9449
9450 if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
9451 myAt = position.split ? position.split(' ') : [position[0], position[1]];
9452 if (myAt.length === 1) {
9453 myAt[1] = myAt[0];
9454 }
9455
9456 $.each(['left', 'top'], function(i, offsetPosition) {
9457 if (+myAt[i] === myAt[i]) {
9458 offset[i] = myAt[i];
9459 myAt[i] = offsetPosition;
9460 }
9461 });
9462
9463 position = {
9464 my: myAt.join(" "),
9465 at: myAt.join(" "),
9466 offset: offset.join(" ")
9467 };
9468 }
9469
9470 position = $.extend({}, $.ui.dialog.prototype.options.position, position);
9471 } else {
9472 position = $.ui.dialog.prototype.options.position;
9473 }
9474
9475 // need to show the dialog to get the actual offset in the position plugin
9476 isVisible = this.uiDialog.is(':visible');
9477 if (!isVisible) {
9478 this.uiDialog.show();
9479 }
9480 this.uiDialog
9481 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
9482 .css({ top: 0, left: 0 })
9483 .position($.extend({ of: window }, position));
9484 if (!isVisible) {
9485 this.uiDialog.hide();
9486 }
9487 },
9488
9489 _setOptions: function( options ) {
9490 var self = this,
9491 resizableOptions = {},
9492 resize = false;
9493
9494 $.each( options, function( key, value ) {
9495 self._setOption( key, value );
9496
9497 if ( key in sizeRelatedOptions ) {
9498 resize = true;
9499 }
9500 if ( key in resizableRelatedOptions ) {
9501 resizableOptions[ key ] = value;
9502 }
9503 });
9504
9505 if ( resize ) {
9506 this._size();
9507 }
9508 if ( this.uiDialog.is( ":data(resizable)" ) ) {
9509 this.uiDialog.resizable( "option", resizableOptions );
9510 }
9511 },
9512
9513 _setOption: function(key, value){
9514 var self = this,
9515 uiDialog = self.uiDialog;
9516
9517 switch (key) {
9518 //handling of deprecated beforeclose (vs beforeClose) option
9519 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
9520 //TODO: remove in 1.9pre
9521 case "beforeclose":
9522 key = "beforeClose";
9523 break;
9524 case "buttons":
9525 self._createButtons(value);
9526 break;
9527 case "closeText":
9528 // ensure that we always pass a string
9529 self.uiDialogTitlebarCloseText.text("" + value);
9530 break;
9531 case "dialogClass":
9532 uiDialog
9533 .removeClass(self.options.dialogClass)
9534 .addClass(uiDialogClasses + value);
9535 break;
9536 case "disabled":
9537 if (value) {
9538 uiDialog.addClass('ui-dialog-disabled');
9539 } else {
9540 uiDialog.removeClass('ui-dialog-disabled');
9541 }
9542 break;
9543 case "draggable":
9544 var isDraggable = uiDialog.is( ":data(draggable)" );
9545 if ( isDraggable && !value ) {
9546 uiDialog.draggable( "destroy" );
9547 }
9548
9549 if ( !isDraggable && value ) {
9550 self._makeDraggable();
9551 }
9552 break;
9553 case "position":
9554 self._position(value);
9555 break;
9556 case "resizable":
9557 // currently resizable, becoming non-resizable
9558 var isResizable = uiDialog.is( ":data(resizable)" );
9559 if (isResizable && !value) {
9560 uiDialog.resizable('destroy');
9561 }
9562
9563 // currently resizable, changing handles
9564 if (isResizable && typeof value === 'string') {
9565 uiDialog.resizable('option', 'handles', value);
9566 }
9567
9568 // currently non-resizable, becoming resizable
9569 if (!isResizable && value !== false) {
9570 self._makeResizable(value);
9571 }
9572 break;
9573 case "title":
9574 // convert whatever was passed in o a string, for html() to not throw up
9575 $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
9576 break;
9577 }
9578
9579 $.Widget.prototype._setOption.apply(self, arguments);
9580 },
9581
9582 _size: function() {
9583 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
9584 * divs will both have width and height set, so we need to reset them
9585 */
9586 var options = this.options,
9587 nonContentHeight,
9588 minContentHeight,
9589 isVisible = this.uiDialog.is( ":visible" );
9590
9591 // reset content sizing
9592 this.element.show().css({
9593 width: 'auto',
9594 minHeight: 0,
9595 height: 0
9596 });
9597
9598 if (options.minWidth > options.width) {
9599 options.width = options.minWidth;
9600 }
9601
9602 // reset wrapper sizing
9603 // determine the height of all the non-content elements
9604 nonContentHeight = this.uiDialog.css({
9605 height: 'auto',
9606 width: options.width
9607 })
9608 .height();
9609 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
9610
9611 if ( options.height === "auto" ) {
9612 // only needed for IE6 support
9613 if ( $.support.minHeight ) {
9614 this.element.css({
9615 minHeight: minContentHeight,
9616 height: "auto"
9617 });
9618 } else {
9619 this.uiDialog.show();
9620 var autoHeight = this.element.css( "height", "auto" ).height();
9621 if ( !isVisible ) {
9622 this.uiDialog.hide();
9623 }
9624 this.element.height( Math.max( autoHeight, minContentHeight ) );
9625 }
9626 } else {
9627 this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
9628 }
9629
9630 if (this.uiDialog.is(':data(resizable)')) {
9631 this.uiDialog.resizable('option', 'minHeight', this._minHeight());
9632 }
9633 }
9634 });
9635
9636 $.extend($.ui.dialog, {
9637 version: "1.8.7",
9638
9639 uuid: 0,
9640 maxZ: 0,
9641
9642 getTitleId: function($el) {
9643 var id = $el.attr('id');
9644 if (!id) {
9645 this.uuid += 1;
9646 id = this.uuid;
9647 }
9648 return 'ui-dialog-title-' + id;
9649 },
9650
9651 overlay: function(dialog) {
9652 this.$el = $.ui.dialog.overlay.create(dialog);
9653 }
9654 });
9655
9656 $.extend($.ui.dialog.overlay, {
9657 instances: [],
9658 // reuse old instances due to IE memory leak with alpha transparency (see #5185)
9659 oldInstances: [],
9660 maxZ: 0,
9661 events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
9662 function(event) { return event + '.dialog-overlay'; }).join(' '),
9663 create: function(dialog) {
9664 if (this.instances.length === 0) {
9665 // prevent use of anchors and inputs
9666 // we use a setTimeout in case the overlay is created from an
9667 // event that we're going to be cancelling (see #2804)
9668 setTimeout(function() {
9669 // handle $(el).dialog().dialog('close') (see #4065)
9670 if ($.ui.dialog.overlay.instances.length) {
9671 $(document).bind($.ui.dialog.overlay.events, function(event) {
9672 // stop events if the z-index of the target is < the z-index of the overlay
9673 // we cannot return true when we don't want to cancel the event (#3523)
9674 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
9675 return false;
9676 }
9677 });
9678 }
9679 }, 1);
9680
9681 // allow closing by pressing the escape key
9682 $(document).bind('keydown.dialog-overlay', function(event) {
9683 if (dialog.options.closeOnEscape && event.keyCode &&
9684 event.keyCode === $.ui.keyCode.ESCAPE) {
9685
9686 dialog.close(event);
9687 event.preventDefault();
9688 }
9689 });
9690
9691 // handle window resize
9692 $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
9693 }
9694
9695 var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
9696 .appendTo(document.body)
9697 .css({
9698 width: this.width(),
9699 height: this.height()
9700 });
9701
9702 if ($.fn.bgiframe) {
9703 $el.bgiframe();
9704 }
9705
9706 this.instances.push($el);
9707 return $el;
9708 },
9709
9710 destroy: function($el) {
9711 var indexOf = $.inArray($el, this.instances);
9712 if (indexOf != -1){
9713 this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
9714 }
9715
9716 if (this.instances.length === 0) {
9717 $([document, window]).unbind('.dialog-overlay');
9718 }
9719
9720 $el.remove();
9721
9722 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9723 var maxZ = 0;
9724 $.each(this.instances, function() {
9725 maxZ = Math.max(maxZ, this.css('z-index'));
9726 });
9727 this.maxZ = maxZ;
9728 },
9729
9730 height: function() {
9731 var scrollHeight,
9732 offsetHeight;
9733 // handle IE 6
9734 if ($.browser.msie && $.browser.version < 7) {
9735 scrollHeight = Math.max(
9736 document.documentElement.scrollHeight,
9737 document.body.scrollHeight
9738 );
9739 offsetHeight = Math.max(
9740 document.documentElement.offsetHeight,
9741 document.body.offsetHeight
9742 );
9743
9744 if (scrollHeight < offsetHeight) {
9745 return $(window).height() + 'px';
9746 } else {
9747 return scrollHeight + 'px';
9748 }
9749 // handle "good" browsers
9750 } else {
9751 return $(document).height() + 'px';
9752 }
9753 },
9754
9755 width: function() {
9756 var scrollWidth,
9757 offsetWidth;
9758 // handle IE 6
9759 if ($.browser.msie && $.browser.version < 7) {
9760 scrollWidth = Math.max(
9761 document.documentElement.scrollWidth,
9762 document.body.scrollWidth
9763 );
9764 offsetWidth = Math.max(
9765 document.documentElement.offsetWidth,
9766 document.body.offsetWidth
9767 );
9768
9769 if (scrollWidth < offsetWidth) {
9770 return $(window).width() + 'px';
9771 } else {
9772 return scrollWidth + 'px';
9773 }
9774 // handle "good" browsers
9775 } else {
9776 return $(document).width() + 'px';
9777 }
9778 },
9779
9780 resize: function() {
9781 /* If the dialog is draggable and the user drags it past the
9782 * right edge of the window, the document becomes wider so we
9783 * need to stretch the overlay. If the user then drags the
9784 * dialog back to the left, the document will become narrower,
9785 * so we need to shrink the overlay to the appropriate size.
9786 * This is handled by shrinking the overlay before setting it
9787 * to the full document size.
9788 */
9789 var $overlays = $([]);
9790 $.each($.ui.dialog.overlay.instances, function() {
9791 $overlays = $overlays.add(this);
9792 });
9793
9794 $overlays.css({
9795 width: 0,
9796 height: 0
9797 }).css({
9798 width: $.ui.dialog.overlay.width(),
9799 height: $.ui.dialog.overlay.height()
9800 });
9801 }
9802 });
9803
9804 $.extend($.ui.dialog.overlay.prototype, {
9805 destroy: function() {
9806 $.ui.dialog.overlay.destroy(this.$el);
9807 }
9808 });
9809
9810 }(jQuery));
9811 /*
9812 * Note: While Microsoft is not the author of this file, Microsoft is
9813 * offering you a license subject to the terms of the Microsoft Software
9814 * License Terms for Microsoft ASP.NET Model View Controller 3.
9815 * Microsoft reserves all other rights. The notices below are provided
9816 * for informational purposes only and are not the license terms under
9817 * which Microsoft distributed this file.
9818 *
9819 * jQuery UI Position 1.8.7
9820 *
9821 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
9822 *
9823 * http://docs.jquery.com/UI/Position
9824 */
9825 (function( $, undefined ) {
9826
9827 $.ui = $.ui || {};
9828
9829 var horizontalPositions = /left|center|right/,
9830 verticalPositions = /top|center|bottom/,
9831 center = "center",
9832 _position = $.fn.position,
9833 _offset = $.fn.offset;
9834
9835 $.fn.position = function( options ) {
9836 if ( !options || !options.of ) {
9837 return _position.apply( this, arguments );
9838 }
9839
9840 // make a copy, we don't want to modify arguments
9841 options = $.extend( {}, options );
9842
9843 var target = $( options.of ),
9844 targetElem = target[0],
9845 collision = ( options.collision || "flip" ).split( " " ),
9846 offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
9847 targetWidth,
9848 targetHeight,
9849 basePosition;
9850
9851 if ( targetElem.nodeType === 9 ) {
9852 targetWidth = target.width();
9853 targetHeight = target.height();
9854 basePosition = { top: 0, left: 0 };
9855 // TODO: use $.isWindow() in 1.9
9856 } else if ( targetElem.setTimeout ) {
9857 targetWidth = target.width();
9858 targetHeight = target.height();
9859 basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
9860 } else if ( targetElem.preventDefault ) {
9861 // force left top to allow flipping
9862 options.at = "left top";
9863 targetWidth = targetHeight = 0;
9864 basePosition = { top: options.of.pageY, left: options.of.pageX };
9865 } else {
9866 targetWidth = target.outerWidth();
9867 targetHeight = target.outerHeight();
9868 basePosition = target.offset();
9869 }
9870
9871 // force my and at to have valid horizontal and veritcal positions
9872 // if a value is missing or invalid, it will be converted to center
9873 $.each( [ "my", "at" ], function() {
9874 var pos = ( options[this] || "" ).split( " " );
9875 if ( pos.length === 1) {
9876 pos = horizontalPositions.test( pos[0] ) ?
9877 pos.concat( [center] ) :
9878 verticalPositions.test( pos[0] ) ?
9879 [ center ].concat( pos ) :
9880 [ center, center ];
9881 }
9882 pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
9883 pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
9884 options[ this ] = pos;
9885 });
9886
9887 // normalize collision option
9888 if ( collision.length === 1 ) {
9889 collision[ 1 ] = collision[ 0 ];
9890 }
9891
9892 // normalize offset option
9893 offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
9894 if ( offset.length === 1 ) {
9895 offset[ 1 ] = offset[ 0 ];
9896 }
9897 offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
9898
9899 if ( options.at[0] === "right" ) {
9900 basePosition.left += targetWidth;
9901 } else if (options.at[0] === center ) {
9902 basePosition.left += targetWidth / 2;
9903 }
9904
9905 if ( options.at[1] === "bottom" ) {
9906 basePosition.top += targetHeight;
9907 } else if ( options.at[1] === center ) {
9908 basePosition.top += targetHeight / 2;
9909 }
9910
9911 basePosition.left += offset[ 0 ];
9912 basePosition.top += offset[ 1 ];
9913
9914 return this.each(function() {
9915 var elem = $( this ),
9916 elemWidth = elem.outerWidth(),
9917 elemHeight = elem.outerHeight(),
9918 marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
9919 marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
9920 collisionWidth = elemWidth + marginLeft +
9921 parseInt( $.curCSS( this, "marginRight", true ) ) || 0,
9922 collisionHeight = elemHeight + marginTop +
9923 parseInt( $.curCSS( this, "marginBottom", true ) ) || 0,
9924 position = $.extend( {}, basePosition ),
9925 collisionPosition;
9926
9927 if ( options.my[0] === "right" ) {
9928 position.left -= elemWidth;
9929 } else if ( options.my[0] === center ) {
9930 position.left -= elemWidth / 2;
9931 }
9932
9933 if ( options.my[1] === "bottom" ) {
9934 position.top -= elemHeight;
9935 } else if ( options.my[1] === center ) {
9936 position.top -= elemHeight / 2;
9937 }
9938
9939 // prevent fractions (see #5280)
9940 position.left = Math.round( position.left );
9941 position.top = Math.round( position.top );
9942
9943 collisionPosition = {
9944 left: position.left - marginLeft,
9945 top: position.top - marginTop
9946 };
9947
9948 $.each( [ "left", "top" ], function( i, dir ) {
9949 if ( $.ui.position[ collision[i] ] ) {
9950 $.ui.position[ collision[i] ][ dir ]( position, {
9951 targetWidth: targetWidth,
9952 targetHeight: targetHeight,
9953 elemWidth: elemWidth,
9954 elemHeight: elemHeight,
9955 collisionPosition: collisionPosition,
9956 collisionWidth: collisionWidth,
9957 collisionHeight: collisionHeight,
9958 offset: offset,
9959 my: options.my,
9960 at: options.at
9961 });
9962 }
9963 });
9964
9965 if ( $.fn.bgiframe ) {
9966 elem.bgiframe();
9967 }
9968 elem.offset( $.extend( position, { using: options.using } ) );
9969 });
9970 };
9971
9972 $.ui.position = {
9973 fit: {
9974 left: function( position, data ) {
9975 var win = $( window ),
9976 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
9977 position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
9978 },
9979 top: function( position, data ) {
9980 var win = $( window ),
9981 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
9982 position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
9983 }
9984 },
9985
9986 flip: {
9987 left: function( position, data ) {
9988 if ( data.at[0] === center ) {
9989 return;
9990 }
9991 var win = $( window ),
9992 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
9993 myOffset = data.my[ 0 ] === "left" ?
9994 -data.elemWidth :
9995 data.my[ 0 ] === "right" ?
9996 data.elemWidth :
9997 0,
9998 atOffset = data.at[ 0 ] === "left" ?
9999 data.targetWidth :
10000 -data.targetWidth,
10001 offset = -2 * data.offset[ 0 ];
10002 position.left += data.collisionPosition.left < 0 ?
10003 myOffset + atOffset + offset :
10004 over > 0 ?
10005 myOffset + atOffset + offset :
10006 0;
10007 },
10008 top: function( position, data ) {
10009 if ( data.at[1] === center ) {
10010 return;
10011 }
10012 var win = $( window ),
10013 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
10014 myOffset = data.my[ 1 ] === "top" ?
10015 -data.elemHeight :
10016 data.my[ 1 ] === "bottom" ?
10017 data.elemHeight :
10018 0,
10019 atOffset = data.at[ 1 ] === "top" ?
10020 data.targetHeight :
10021 -data.targetHeight,
10022 offset = -2 * data.offset[ 1 ];
10023 position.top += data.collisionPosition.top < 0 ?
10024 myOffset + atOffset + offset :
10025 over > 0 ?
10026 myOffset + atOffset + offset :
10027 0;
10028 }
10029 }
10030 };
10031
10032 // offset setter from jQuery 1.4
10033 if ( !$.offset.setOffset ) {
10034 $.offset.setOffset = function( elem, options ) {
10035 // set position first, in-case top/left are set even on static elem
10036 if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
10037 elem.style.position = "relative";
10038 }
10039 var curElem = $( elem ),
10040 curOffset = curElem.offset(),
10041 curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
10042 curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
10043 props = {
10044 top: (options.top - curOffset.top) + curTop,
10045 left: (options.left - curOffset.left) + curLeft
10046 };
10047
10048 if ( 'using' in options ) {
10049 options.using.call( elem, props );
10050 } else {
10051 curElem.css( props );
10052 }
10053 };
10054
10055 $.fn.offset = function( options ) {
10056 var elem = this[ 0 ];
10057 if ( !elem || !elem.ownerDocument ) { return null; }
10058 if ( options ) {
10059 return this.each(function() {
10060 $.offset.setOffset( this, options );
10061 });
10062 }
10063 return _offset.call( this );
10064 };
10065 }
10066
10067 }( jQuery ));
10068 /*
10069 * Note: While Microsoft is not the author of this file, Microsoft is
10070 * offering you a license subject to the terms of the Microsoft Software
10071 * License Terms for Microsoft ASP.NET Model View Controller 3.
10072 * Microsoft reserves all other rights. The notices below are provided
10073 * for informational purposes only and are not the license terms under
10074 * which Microsoft distributed this file.
10075 *
10076 * jQuery UI Progressbar 1.8.7
10077 *
10078 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
10079 *
10080 * http://docs.jquery.com/UI/Progressbar
10081 *
10082 * Depends:
10083 * jquery.ui.core.js
10084 * jquery.ui.widget.js
10085 */
10086 (function( $, undefined ) {
10087
10088 $.widget( "ui.progressbar", {
10089 options: {
10090 value: 0,
10091 max: 100
10092 },
10093
10094 min: 0,
10095
10096 _create: function() {
10097 this.element
10098 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10099 .attr({
10100 role: "progressbar",
10101 "aria-valuemin": this.min,
10102 "aria-valuemax": this.options.max,
10103 "aria-valuenow": this._value()
10104 });
10105
10106 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10107 .appendTo( this.element );
10108
10109 this.oldValue = this._value();
10110 this._refreshValue();
10111 },
10112
10113 destroy: function() {
10114 this.element
10115 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10116 .removeAttr( "role" )
10117 .removeAttr( "aria-valuemin" )
10118 .removeAttr( "aria-valuemax" )
10119 .removeAttr( "aria-valuenow" );
10120
10121 this.valueDiv.remove();
10122
10123 $.Widget.prototype.destroy.apply( this, arguments );
10124 },
10125
10126 value: function( newValue ) {
10127 if ( newValue === undefined ) {
10128 return this._value();
10129 }
10130
10131 this._setOption( "value", newValue );
10132 return this;
10133 },
10134
10135 _setOption: function( key, value ) {
10136 if ( key === "value" ) {
10137 this.options.value = value;
10138 this._refreshValue();
10139 if ( this._value() === this.options.max ) {
10140 this._trigger( "complete" );
10141 }
10142 }
10143
10144 $.Widget.prototype._setOption.apply( this, arguments );
10145 },
10146
10147 _value: function() {
10148 var val = this.options.value;
10149 // normalize invalid value
10150 if ( typeof val !== "number" ) {
10151 val = 0;
10152 }
10153 return Math.min( this.options.max, Math.max( this.min, val ) );
10154 },
10155
10156 _percentage: function() {
10157 return 100 * this._value() / this.options.max;
10158 },
10159
10160 _refreshValue: function() {
10161 var value = this.value();
10162 var percentage = this._percentage();
10163
10164 if ( this.oldValue !== value ) {
10165 this.oldValue = value;
10166 this._trigger( "change" );
10167 }
10168
10169 this.valueDiv
10170 .toggleClass( "ui-corner-right", value === this.options.max )
10171 .width( percentage.toFixed(0) + "%" );
10172 this.element.attr( "aria-valuenow", value );
10173 }
10174 });
10175
10176 $.extend( $.ui.progressbar, {
10177 version: "1.8.7"
10178 });
10179
10180 })( jQuery );
10181 /*
10182 * Note: While Microsoft is not the author of this file, Microsoft is
10183 * offering you a license subject to the terms of the Microsoft Software
10184 * License Terms for Microsoft ASP.NET Model View Controller 3.
10185 * Microsoft reserves all other rights. The notices below are provided
10186 * for informational purposes only and are not the license terms under
10187 * which Microsoft distributed this file.
10188 *
10189 * jQuery UI Slider 1.8.7
10190 *
10191 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
10192 *
10193 * http://docs.jquery.com/UI/Slider
10194 *
10195 * Depends:
10196 * jquery.ui.core.js
10197 * jquery.ui.mouse.js
10198 * jquery.ui.widget.js
10199 */
10200 (function( $, undefined ) {
10201
10202 // number of pages in a slider
10203 // (how many times can you page up/down to go through the whole range)
10204 var numPages = 5;
10205
10206 $.widget( "ui.slider", $.ui.mouse, {
10207
10208 widgetEventPrefix: "slide",
10209
10210 options: {
10211 animate: false,
10212 distance: 0,
10213 max: 100,
10214 min: 0,
10215 orientation: "horizontal",
10216 range: false,
10217 step: 1,
10218 value: 0,
10219 values: null
10220 },
10221
10222 _create: function() {
10223 var self = this,
10224 o = this.options;
10225
10226 this._keySliding = false;
10227 this._mouseSliding = false;
10228 this._animateOff = true;
10229 this._handleIndex = null;
10230 this._detectOrientation();
10231 this._mouseInit();
10232
10233 this.element
10234 .addClass( "ui-slider" +
10235 " ui-slider-" + this.orientation +
10236 " ui-widget" +
10237 " ui-widget-content" +
10238 " ui-corner-all" );
10239
10240 if ( o.disabled ) {
10241 this.element.addClass( "ui-slider-disabled ui-disabled" );
10242 }
10243
10244 this.range = $([]);
10245
10246 if ( o.range ) {
10247 if ( o.range === true ) {
10248 this.range = $( "<div></div>" );
10249 if ( !o.values ) {
10250 o.values = [ this._valueMin(), this._valueMin() ];
10251 }
10252 if ( o.values.length && o.values.length !== 2 ) {
10253 o.values = [ o.values[0], o.values[0] ];
10254 }
10255 } else {
10256 this.range = $( "<div></div>" );
10257 }
10258
10259 this.range
10260 .appendTo( this.element )
10261 .addClass( "ui-slider-range" );
10262
10263 if ( o.range === "min" || o.range === "max" ) {
10264 this.range.addClass( "ui-slider-range-" + o.range );
10265 }
10266
10267 // note: this isn't the most fittingly semantic framework class for this element,
10268 // but worked best visually with a variety of themes
10269 this.range.addClass( "ui-widget-header" );
10270 }
10271
10272 if ( $( ".ui-slider-handle", this.element ).length === 0 ) {
10273 $( "<a href='#'></a>" )
10274 .appendTo( this.element )
10275 .addClass( "ui-slider-handle" );
10276 }
10277
10278 if ( o.values && o.values.length ) {
10279 while ( $(".ui-slider-handle", this.element).length < o.values.length ) {
10280 $( "<a href='#'></a>" )
10281 .appendTo( this.element )
10282 .addClass( "ui-slider-handle" );
10283 }
10284 }
10285
10286 this.handles = $( ".ui-slider-handle", this.element )
10287 .addClass( "ui-state-default" +
10288 " ui-corner-all" );
10289
10290 this.handle = this.handles.eq( 0 );
10291
10292 this.handles.add( this.range ).filter( "a" )
10293 .click(function( event ) {
10294 event.preventDefault();
10295 })
10296 .hover(function() {
10297 if ( !o.disabled ) {
10298 $( this ).addClass( "ui-state-hover" );
10299 }
10300 }, function() {
10301 $( this ).removeClass( "ui-state-hover" );
10302 })
10303 .focus(function() {
10304 if ( !o.disabled ) {
10305 $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
10306 $( this ).addClass( "ui-state-focus" );
10307 } else {
10308 $( this ).blur();
10309 }
10310 })
10311 .blur(function() {
10312 $( this ).removeClass( "ui-state-focus" );
10313 });
10314
10315 this.handles.each(function( i ) {
10316 $( this ).data( "index.ui-slider-handle", i );
10317 });
10318
10319 this.handles
10320 .keydown(function( event ) {
10321 var ret = true,
10322 index = $( this ).data( "index.ui-slider-handle" ),
10323 allowed,
10324 curVal,
10325 newVal,
10326 step;
10327
10328 if ( self.options.disabled ) {
10329 return;
10330 }
10331
10332 switch ( event.keyCode ) {
10333 case $.ui.keyCode.HOME:
10334 case $.ui.keyCode.END:
10335 case $.ui.keyCode.PAGE_UP:
10336 case $.ui.keyCode.PAGE_DOWN:
10337 case $.ui.keyCode.UP:
10338 case $.ui.keyCode.RIGHT:
10339 case $.ui.keyCode.DOWN:
10340 case $.ui.keyCode.LEFT:
10341 ret = false;
10342 if ( !self._keySliding ) {
10343 self._keySliding = true;
10344 $( this ).addClass( "ui-state-active" );
10345 allowed = self._start( event, index );
10346 if ( allowed === false ) {
10347 return;
10348 }
10349 }
10350 break;
10351 }
10352
10353 step = self.options.step;
10354 if ( self.options.values && self.options.values.length ) {
10355 curVal = newVal = self.values( index );
10356 } else {
10357 curVal = newVal = self.value();
10358 }
10359
10360 switch ( event.keyCode ) {
10361 case $.ui.keyCode.HOME:
10362 newVal = self._valueMin();
10363 break;
10364 case $.ui.keyCode.END:
10365 newVal = self._valueMax();
10366 break;
10367 case $.ui.keyCode.PAGE_UP:
10368 newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
10369 break;
10370 case $.ui.keyCode.PAGE_DOWN:
10371 newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
10372 break;
10373 case $.ui.keyCode.UP:
10374 case $.ui.keyCode.RIGHT:
10375 if ( curVal === self._valueMax() ) {
10376 return;
10377 }
10378 newVal = self._trimAlignValue( curVal + step );
10379 break;
10380 case $.ui.keyCode.DOWN:
10381 case $.ui.keyCode.LEFT:
10382 if ( curVal === self._valueMin() ) {
10383 return;
10384 }
10385 newVal = self._trimAlignValue( curVal - step );
10386 break;
10387 }
10388
10389 self._slide( event, index, newVal );
10390
10391 return ret;
10392
10393 })
10394 .keyup(function( event ) {
10395 var index = $( this ).data( "index.ui-slider-handle" );
10396
10397 if ( self._keySliding ) {
10398 self._keySliding = false;
10399 self._stop( event, index );
10400 self._change( event, index );
10401 $( this ).removeClass( "ui-state-active" );
10402 }
10403
10404 });
10405
10406 this._refreshValue();
10407
10408 this._animateOff = false;
10409 },
10410
10411 destroy: function() {
10412 this.handles.remove();
10413 this.range.remove();
10414
10415 this.element
10416 .removeClass( "ui-slider" +
10417 " ui-slider-horizontal" +
10418 " ui-slider-vertical" +
10419 " ui-slider-disabled" +
10420 " ui-widget" +
10421 " ui-widget-content" +
10422 " ui-corner-all" )
10423 .removeData( "slider" )
10424 .unbind( ".slider" );
10425
10426 this._mouseDestroy();
10427
10428 return this;
10429 },
10430
10431 _mouseCapture: function( event ) {
10432 var o = this.options,
10433 position,
10434 normValue,
10435 distance,
10436 closestHandle,
10437 self,
10438 index,
10439 allowed,
10440 offset,
10441 mouseOverHandle;
10442
10443 if ( o.disabled ) {
10444 return false;
10445 }
10446
10447 this.elementSize = {
10448 width: this.element.outerWidth(),
10449 height: this.element.outerHeight()
10450 };
10451 this.elementOffset = this.element.offset();
10452
10453 position = { x: event.pageX, y: event.pageY };
10454 normValue = this._normValueFromMouse( position );
10455 distance = this._valueMax() - this._valueMin() + 1;
10456 self = this;
10457 this.handles.each(function( i ) {
10458 var thisDistance = Math.abs( normValue - self.values(i) );
10459 if ( distance > thisDistance ) {
10460 distance = thisDistance;
10461 closestHandle = $( this );
10462 index = i;
10463 }
10464 });
10465
10466 // workaround for bug #3736 (if both handles of a range are at 0,
10467 // the first is always used as the one with least distance,
10468 // and moving it is obviously prevented by preventing negative ranges)
10469 if( o.range === true && this.values(1) === o.min ) {
10470 index += 1;
10471 closestHandle = $( this.handles[index] );
10472 }
10473
10474 allowed = this._start( event, index );
10475 if ( allowed === false ) {
10476 return false;
10477 }
10478 this._mouseSliding = true;
10479
10480 self._handleIndex = index;
10481
10482 closestHandle
10483 .addClass( "ui-state-active" )
10484 .focus();
10485
10486 offset = closestHandle.offset();
10487 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
10488 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10489 left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10490 top: event.pageY - offset.top -
10491 ( closestHandle.height() / 2 ) -
10492 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10493 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10494 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10495 };
10496
10497 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10498 this._slide( event, index, normValue );
10499 }
10500 this._animateOff = true;
10501 return true;
10502 },
10503
10504 _mouseStart: function( event ) {
10505 return true;
10506 },
10507
10508 _mouseDrag: function( event ) {
10509 var position = { x: event.pageX, y: event.pageY },
10510 normValue = this._normValueFromMouse( position );
10511
10512 this._slide( event, this._handleIndex, normValue );
10513
10514 return false;
10515 },
10516
10517 _mouseStop: function( event ) {
10518 this.handles.removeClass( "ui-state-active" );
10519 this._mouseSliding = false;
10520
10521 this._stop( event, this._handleIndex );
10522 this._change( event, this._handleIndex );
10523
10524 this._handleIndex = null;
10525 this._clickOffset = null;
10526 this._animateOff = false;
10527
10528 return false;
10529 },
10530
10531 _detectOrientation: function() {
10532 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10533 },
10534
10535 _normValueFromMouse: function( position ) {
10536 var pixelTotal,
10537 pixelMouse,
10538 percentMouse,
10539 valueTotal,
10540 valueMouse;
10541
10542 if ( this.orientation === "horizontal" ) {
10543 pixelTotal = this.elementSize.width;
10544 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10545 } else {
10546 pixelTotal = this.elementSize.height;
10547 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10548 }
10549
10550 percentMouse = ( pixelMouse / pixelTotal );
10551 if ( percentMouse > 1 ) {
10552 percentMouse = 1;
10553 }
10554 if ( percentMouse < 0 ) {
10555 percentMouse = 0;
10556 }
10557 if ( this.orientation === "vertical" ) {
10558 percentMouse = 1 - percentMouse;
10559 }
10560
10561 valueTotal = this._valueMax() - this._valueMin();
10562 valueMouse = this._valueMin() + percentMouse * valueTotal;
10563
10564 return this._trimAlignValue( valueMouse );
10565 },
10566
10567 _start: function( event, index ) {
10568 var uiHash = {
10569 handle: this.handles[ index ],
10570 value: this.value()
10571 };
10572 if ( this.options.values && this.options.values.length ) {
10573 uiHash.value = this.values( index );
10574 uiHash.values = this.values();
10575 }
10576 return this._trigger( "start", event, uiHash );
10577 },
10578
10579 _slide: function( event, index, newVal ) {
10580 var otherVal,
10581 newValues,
10582 allowed;
10583
10584 if ( this.options.values && this.options.values.length ) {
10585 otherVal = this.values( index ? 0 : 1 );
10586
10587 if ( ( this.options.values.length === 2 && this.options.range === true ) &&
10588 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10589 ) {
10590 newVal = otherVal;
10591 }
10592
10593 if ( newVal !== this.values( index ) ) {
10594 newValues = this.values();
10595 newValues[ index ] = newVal;
10596 // A slide can be canceled by returning false from the slide callback
10597 allowed = this._trigger( "slide", event, {
10598 handle: this.handles[ index ],
10599 value: newVal,
10600 values: newValues
10601 } );
10602 otherVal = this.values( index ? 0 : 1 );
10603 if ( allowed !== false ) {
10604 this.values( index, newVal, true );
10605 }
10606 }
10607 } else {
10608 if ( newVal !== this.value() ) {
10609 // A slide can be canceled by returning false from the slide callback
10610 allowed = this._trigger( "slide", event, {
10611 handle: this.handles[ index ],
10612 value: newVal
10613 } );
10614 if ( allowed !== false ) {
10615 this.value( newVal );
10616 }
10617 }
10618 }
10619 },
10620
10621 _stop: function( event, index ) {
10622 var uiHash = {
10623 handle: this.handles[ index ],
10624 value: this.value()
10625 };
10626 if ( this.options.values && this.options.values.length ) {
10627 uiHash.value = this.values( index );
10628 uiHash.values = this.values();
10629 }
10630
10631 this._trigger( "stop", event, uiHash );
10632 },
10633
10634 _change: function( event, index ) {
10635 if ( !this._keySliding && !this._mouseSliding ) {
10636 var uiHash = {
10637 handle: this.handles[ index ],
10638 value: this.value()
10639 };
10640 if ( this.options.values && this.options.values.length ) {
10641 uiHash.value = this.values( index );
10642 uiHash.values = this.values();
10643 }
10644
10645 this._trigger( "change", event, uiHash );
10646 }
10647 },
10648
10649 value: function( newValue ) {
10650 if ( arguments.length ) {
10651 this.options.value = this._trimAlignValue( newValue );
10652 this._refreshValue();
10653 this._change( null, 0 );
10654 }
10655
10656 return this._value();
10657 },
10658
10659 values: function( index, newValue ) {
10660 var vals,
10661 newValues,
10662 i;
10663
10664 if ( arguments.length > 1 ) {
10665 this.options.values[ index ] = this._trimAlignValue( newValue );
10666 this._refreshValue();
10667 this._change( null, index );
10668 }
10669
10670 if ( arguments.length ) {
10671 if ( $.isArray( arguments[ 0 ] ) ) {
10672 vals = this.options.values;
10673 newValues = arguments[ 0 ];
10674 for ( i = 0; i < vals.length; i += 1 ) {
10675 vals[ i ] = this._trimAlignValue( newValues[ i ] );
10676 this._change( null, i );
10677 }
10678 this._refreshValue();
10679 } else {
10680 if ( this.options.values && this.options.values.length ) {
10681 return this._values( index );
10682 } else {
10683 return this.value();
10684 }
10685 }
10686 } else {
10687 return this._values();
10688 }
10689 },
10690
10691 _setOption: function( key, value ) {
10692 var i,
10693 valsLength = 0;
10694
10695 if ( $.isArray( this.options.values ) ) {
10696 valsLength = this.options.values.length;
10697 }
10698
10699 $.Widget.prototype._setOption.apply( this, arguments );
10700
10701 switch ( key ) {
10702 case "disabled":
10703 if ( value ) {
10704 this.handles.filter( ".ui-state-focus" ).blur();
10705 this.handles.removeClass( "ui-state-hover" );
10706 this.handles.attr( "disabled", "disabled" );
10707 this.element.addClass( "ui-disabled" );
10708 } else {
10709 this.handles.removeAttr( "disabled" );
10710 this.element.removeClass( "ui-disabled" );
10711 }
10712 break;
10713 case "orientation":
10714 this._detectOrientation();
10715 this.element
10716 .removeClass( "ui-slider-horizontal ui-slider-vertical" )
10717 .addClass( "ui-slider-" + this.orientation );
10718 this._refreshValue();
10719 break;
10720 case "value":
10721 this._animateOff = true;
10722 this._refreshValue();
10723 this._change( null, 0 );
10724 this._animateOff = false;
10725 break;
10726 case "values":
10727 this._animateOff = true;
10728 this._refreshValue();
10729 for ( i = 0; i < valsLength; i += 1 ) {
10730 this._change( null, i );
10731 }
10732 this._animateOff = false;
10733 break;
10734 }
10735 },
10736
10737 //internal value getter
10738 // _value() returns value trimmed by min and max, aligned by step
10739 _value: function() {
10740 var val = this.options.value;
10741 val = this._trimAlignValue( val );
10742
10743 return val;
10744 },
10745
10746 //internal values getter
10747 // _values() returns array of values trimmed by min and max, aligned by step
10748 // _values( index ) returns single value trimmed by min and max, aligned by step
10749 _values: function( index ) {
10750 var val,
10751 vals,
10752 i;
10753
10754 if ( arguments.length ) {
10755 val = this.options.values[ index ];
10756 val = this._trimAlignValue( val );
10757
10758 return val;
10759 } else {
10760 // .slice() creates a copy of the array
10761 // this copy gets trimmed by min and max and then returned
10762 vals = this.options.values.slice();
10763 for ( i = 0; i < vals.length; i+= 1) {
10764 vals[ i ] = this._trimAlignValue( vals[ i ] );
10765 }
10766
10767 return vals;
10768 }
10769 },
10770
10771 // returns the step-aligned value that val is closest to, between (inclusive) min and max
10772 _trimAlignValue: function( val ) {
10773 if ( val <= this._valueMin() ) {
10774 return this._valueMin();
10775 }
10776 if ( val >= this._valueMax() ) {
10777 return this._valueMax();
10778 }
10779 var step = ( this.options.step > 0 ) ? this.options.step : 1,
10780 valModStep = (val - this._valueMin()) % step;
10781 alignValue = val - valModStep;
10782
10783 if ( Math.abs(valModStep) * 2 >= step ) {
10784 alignValue += ( valModStep > 0 ) ? step : ( -step );
10785 }
10786
10787 // Since JavaScript has problems with large floats, round
10788 // the final value to 5 digits after the decimal point (see #4124)
10789 return parseFloat( alignValue.toFixed(5) );
10790 },
10791
10792 _valueMin: function() {
10793 return this.options.min;
10794 },
10795
10796 _valueMax: function() {
10797 return this.options.max;
10798 },
10799
10800 _refreshValue: function() {
10801 var oRange = this.options.range,
10802 o = this.options,
10803 self = this,
10804 animate = ( !this._animateOff ) ? o.animate : false,
10805 valPercent,
10806 _set = {},
10807 lastValPercent,
10808 value,
10809 valueMin,
10810 valueMax;
10811
10812 if ( this.options.values && this.options.values.length ) {
10813 this.handles.each(function( i, j ) {
10814 valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
10815 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10816 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10817 if ( self.options.range === true ) {
10818 if ( self.orientation === "horizontal" ) {
10819 if ( i === 0 ) {
10820 self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10821 }
10822 if ( i === 1 ) {
10823 self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10824 }
10825 } else {
10826 if ( i === 0 ) {
10827 self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10828 }
10829 if ( i === 1 ) {
10830 self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10831 }
10832 }
10833 }
10834 lastValPercent = valPercent;
10835 });
10836 } else {
10837 value = this.value();
10838 valueMin = this._valueMin();
10839 valueMax = this._valueMax();
10840 valPercent = ( valueMax !== valueMin ) ?
10841 ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10842 0;
10843 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10844 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10845
10846 if ( oRange === "min" && this.orientation === "horizontal" ) {
10847 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10848 }
10849 if ( oRange === "max" && this.orientation === "horizontal" ) {
10850 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10851 }
10852 if ( oRange === "min" && this.orientation === "vertical" ) {
10853 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10854 }
10855 if ( oRange === "max" && this.orientation === "vertical" ) {
10856 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10857 }
10858 }
10859 }
10860
10861 });
10862
10863 $.extend( $.ui.slider, {
10864 version: "1.8.7"
10865 });
10866
10867 }(jQuery));
10868 /*
10869 * Note: While Microsoft is not the author of this file, Microsoft is
10870 * offering you a license subject to the terms of the Microsoft Software
10871 * License Terms for Microsoft ASP.NET Model View Controller 3.
10872 * Microsoft reserves all other rights. The notices below are provided
10873 * for informational purposes only and are not the license terms under
10874 * which Microsoft distributed this file.
10875 *
10876 * jQuery UI Tabs 1.8.7
10877 *
10878 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
10879 *
10880 * http://docs.jquery.com/UI/Tabs
10881 *
10882 * Depends:
10883 * jquery.ui.core.js
10884 * jquery.ui.widget.js
10885 */
10886 (function( $, undefined ) {
10887
10888 var tabId = 0,
10889 listId = 0;
10890
10891 function getNextTabId() {
10892 return ++tabId;
10893 }
10894
10895 function getNextListId() {
10896 return ++listId;
10897 }
10898
10899 $.widget( "ui.tabs", {
10900 options: {
10901 add: null,
10902 ajaxOptions: null,
10903 cache: false,
10904 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
10905 collapsible: false,
10906 disable: null,
10907 disabled: [],
10908 enable: null,
10909 event: "click",
10910 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
10911 idPrefix: "ui-tabs-",
10912 load: null,
10913 panelTemplate: "<div></div>",
10914 remove: null,
10915 select: null,
10916 show: null,
10917 spinner: "<em>Loading&#8230;</em>",
10918 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
10919 },
10920
10921 _create: function() {
10922 this._tabify( true );
10923 },
10924
10925 _setOption: function( key, value ) {
10926 if ( key == "selected" ) {
10927 if (this.options.collapsible && value == this.options.selected ) {
10928 return;
10929 }
10930 this.select( value );
10931 } else {
10932 this.options[ key ] = value;
10933 this._tabify();
10934 }
10935 },
10936
10937 _tabId: function( a ) {
10938 return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
10939 this.options.idPrefix + getNextTabId();
10940 },
10941
10942 _sanitizeSelector: function( hash ) {
10943 // we need this because an id may contain a ":"
10944 return hash.replace( /:/g, "\\:" );
10945 },
10946
10947 _cookie: function() {
10948 var cookie = this.cookie ||
10949 ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
10950 return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
10951 },
10952
10953 _ui: function( tab, panel ) {
10954 return {
10955 tab: tab,
10956 panel: panel,
10957 index: this.anchors.index( tab )
10958 };
10959 },
10960
10961 _cleanup: function() {
10962 // restore all former loading tabs labels
10963 this.lis.filter( ".ui-state-processing" )
10964 .removeClass( "ui-state-processing" )
10965 .find( "span:data(label.tabs)" )
10966 .each(function() {
10967 var el = $( this );
10968 el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
10969 });
10970 },
10971
10972 _tabify: function( init ) {
10973 var self = this,
10974 o = this.options,
10975 fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
10976
10977 this.list = this.element.find( "ol,ul" ).eq( 0 );
10978 this.lis = $( " > li:has(a[href])", this.list );
10979 this.anchors = this.lis.map(function() {
10980 return $( "a", this )[ 0 ];
10981 });
10982 this.panels = $( [] );
10983
10984 this.anchors.each(function( i, a ) {
10985 var href = $( a ).attr( "href" );
10986 // For dynamically created HTML that contains a hash as href IE < 8 expands
10987 // such href to the full page url with hash and then misinterprets tab as ajax.
10988 // Same consideration applies for an added tab with a fragment identifier
10989 // since a[href=#fragment-identifier] does unexpectedly not match.
10990 // Thus normalize href attribute...
10991 var hrefBase = href.split( "#" )[ 0 ],
10992 baseEl;
10993 if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
10994 ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
10995 href = a.hash;
10996 a.href = href;
10997 }
10998
10999 // inline tab
11000 if ( fragmentId.test( href ) ) {
11001 self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
11002 // remote tab
11003 // prevent loading the page itself if href is just "#"
11004 } else if ( href && href !== "#" ) {
11005 // required for restore on destroy
11006 $.data( a, "href.tabs", href );
11007
11008 // TODO until #3808 is fixed strip fragment identifier from url
11009 // (IE fails to load from such url)
11010 $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
11011
11012 var id = self._tabId( a );
11013 a.href = "#" + id;
11014 var $panel = self.element.find( "#" + id );
11015 if ( !$panel.length ) {
11016 $panel = $( o.panelTemplate )
11017 .attr( "id", id )
11018 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11019 .insertAfter( self.panels[ i - 1 ] || self.list );
11020 $panel.data( "destroy.tabs", true );
11021 }
11022 self.panels = self.panels.add( $panel );
11023 // invalid tab href
11024 } else {
11025 o.disabled.push( i );
11026 }
11027 });
11028
11029 // initialization from scratch
11030 if ( init ) {
11031 // attach necessary classes for styling
11032 this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
11033 this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
11034 this.lis.addClass( "ui-state-default ui-corner-top" );
11035 this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
11036
11037 // Selected tab
11038 // use "selected" option or try to retrieve:
11039 // 1. from fragment identifier in url
11040 // 2. from cookie
11041 // 3. from selected class attribute on <li>
11042 if ( o.selected === undefined ) {
11043 if ( location.hash ) {
11044 this.anchors.each(function( i, a ) {
11045 if ( a.hash == location.hash ) {
11046 o.selected = i;
11047 return false;
11048 }
11049 });
11050 }
11051 if ( typeof o.selected !== "number" && o.cookie ) {
11052 o.selected = parseInt( self._cookie(), 10 );
11053 }
11054 if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
11055 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
11056 }
11057 o.selected = o.selected || ( this.lis.length ? 0 : -1 );
11058 } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
11059 o.selected = -1;
11060 }
11061
11062 // sanity check - default to first tab...
11063 o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
11064 ? o.selected
11065 : 0;
11066
11067 // Take disabling tabs via class attribute from HTML
11068 // into account and update option properly.
11069 // A selected tab cannot become disabled.
11070 o.disabled = $.unique( o.disabled.concat(
11071 $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
11072 return self.lis.index( n );
11073 })
11074 ) ).sort();
11075
11076 if ( $.inArray( o.selected, o.disabled ) != -1 ) {
11077 o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
11078 }
11079
11080 // highlight selected tab
11081 this.panels.addClass( "ui-tabs-hide" );
11082 this.lis.removeClass( "ui-tabs-selected ui-state-active" );
11083 // check for length avoids error when initializing empty list
11084 if ( o.selected >= 0 && this.anchors.length ) {
11085 self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
11086 this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
11087
11088 // seems to be expected behavior that the show callback is fired
11089 self.element.queue( "tabs", function() {
11090 self._trigger( "show", null,
11091 self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ) ) );
11092 });
11093
11094 this.load( o.selected );
11095 }
11096
11097 // clean up to avoid memory leaks in certain versions of IE 6
11098 // TODO: namespace this event
11099 $( window ).bind( "unload", function() {
11100 self.lis.add( self.anchors ).unbind( ".tabs" );
11101 self.lis = self.anchors = self.panels = null;
11102 });
11103 // update selected after add/remove
11104 } else {
11105 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
11106 }
11107
11108 // update collapsible
11109 // TODO: use .toggleClass()
11110 this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
11111
11112 // set or update cookie after init and add/remove respectively
11113 if ( o.cookie ) {
11114 this._cookie( o.selected, o.cookie );
11115 }
11116
11117 // disable tabs
11118 for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
11119 $( li )[ $.inArray( i, o.disabled ) != -1 &&
11120 // TODO: use .toggleClass()
11121 !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
11122 }
11123
11124 // reset cache if switching from cached to not cached
11125 if ( o.cache === false ) {
11126 this.anchors.removeData( "cache.tabs" );
11127 }
11128
11129 // remove all handlers before, tabify may run on existing tabs after add or option change
11130 this.lis.add( this.anchors ).unbind( ".tabs" );
11131
11132 if ( o.event !== "mouseover" ) {
11133 var addState = function( state, el ) {
11134 if ( el.is( ":not(.ui-state-disabled)" ) ) {
11135 el.addClass( "ui-state-" + state );
11136 }
11137 };
11138 var removeState = function( state, el ) {
11139 el.removeClass( "ui-state-" + state );
11140 };
11141 this.lis.bind( "mouseover.tabs" , function() {
11142 addState( "hover", $( this ) );
11143 });
11144 this.lis.bind( "mouseout.tabs", function() {
11145 removeState( "hover", $( this ) );
11146 });
11147 this.anchors.bind( "focus.tabs", function() {
11148 addState( "focus", $( this ).closest( "li" ) );
11149 });
11150 this.anchors.bind( "blur.tabs", function() {
11151 removeState( "focus", $( this ).closest( "li" ) );
11152 });
11153 }
11154
11155 // set up animations
11156 var hideFx, showFx;
11157 if ( o.fx ) {
11158 if ( $.isArray( o.fx ) ) {
11159 hideFx = o.fx[ 0 ];
11160 showFx = o.fx[ 1 ];
11161 } else {
11162 hideFx = showFx = o.fx;
11163 }
11164 }
11165
11166 // Reset certain styles left over from animation
11167 // and prevent IE's ClearType bug...
11168 function resetStyle( $el, fx ) {
11169 $el.css( "display", "" );
11170 if ( !$.support.opacity && fx.opacity ) {
11171 $el[ 0 ].style.removeAttribute( "filter" );
11172 }
11173 }
11174
11175 // Show a tab...
11176 var showTab = showFx
11177 ? function( clicked, $show ) {
11178 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
11179 $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
11180 .animate( showFx, showFx.duration || "normal", function() {
11181 resetStyle( $show, showFx );
11182 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
11183 });
11184 }
11185 : function( clicked, $show ) {
11186 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
11187 $show.removeClass( "ui-tabs-hide" );
11188 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
11189 };
11190
11191 // Hide a tab, $show is optional...
11192 var hideTab = hideFx
11193 ? function( clicked, $hide ) {
11194 $hide.animate( hideFx, hideFx.duration || "normal", function() {
11195 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
11196 $hide.addClass( "ui-tabs-hide" );
11197 resetStyle( $hide, hideFx );
11198 self.element.dequeue( "tabs" );
11199 });
11200 }
11201 : function( clicked, $hide, $show ) {
11202 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
11203 $hide.addClass( "ui-tabs-hide" );
11204 self.element.dequeue( "tabs" );
11205 };
11206
11207 // attach tab event handler, unbind to avoid duplicates from former tabifying...
11208 this.anchors.bind( o.event + ".tabs", function() {
11209 var el = this,
11210 $li = $(el).closest( "li" ),
11211 $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
11212 $show = self.element.find( self._sanitizeSelector( el.hash ) );
11213
11214 // If tab is already selected and not collapsible or tab disabled or
11215 // or is already loading or click callback returns false stop here.
11216 // Check if click handler returns false last so that it is not executed
11217 // for a disabled or loading tab!
11218 if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
11219 $li.hasClass( "ui-state-disabled" ) ||
11220 $li.hasClass( "ui-state-processing" ) ||
11221 self.panels.filter( ":animated" ).length ||
11222 self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
11223 this.blur();
11224 return false;
11225 }
11226
11227 o.selected = self.anchors.index( this );
11228
11229 self.abort();
11230
11231 // if tab may be closed
11232 if ( o.collapsible ) {
11233 if ( $li.hasClass( "ui-tabs-selected" ) ) {
11234 o.selected = -1;
11235
11236 if ( o.cookie ) {
11237 self._cookie( o.selected, o.cookie );
11238 }
11239
11240 self.element.queue( "tabs", function() {
11241 hideTab( el, $hide );
11242 }).dequeue( "tabs" );
11243
11244 this.blur();
11245 return false;
11246 } else if ( !$hide.length ) {
11247 if ( o.cookie ) {
11248 self._cookie( o.selected, o.cookie );
11249 }
11250
11251 self.element.queue( "tabs", function() {
11252 showTab( el, $show );
11253 });
11254
11255 // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
11256 self.load( self.anchors.index( this ) );
11257
11258 this.blur();
11259 return false;
11260 }
11261 }
11262
11263 if ( o.cookie ) {
11264 self._cookie( o.selected, o.cookie );
11265 }
11266
11267 // show new tab
11268 if ( $show.length ) {
11269 if ( $hide.length ) {
11270 self.element.queue( "tabs", function() {
11271 hideTab( el, $hide );
11272 });
11273 }
11274 self.element.queue( "tabs", function() {
11275 showTab( el, $show );
11276 });
11277
11278 self.load( self.anchors.index( this ) );
11279 } else {
11280 throw "jQuery UI Tabs: Mismatching fragment identifier.";
11281 }
11282
11283 // Prevent IE from keeping other link focussed when using the back button
11284 // and remove dotted border from clicked link. This is controlled via CSS
11285 // in modern browsers; blur() removes focus from address bar in Firefox
11286 // which can become a usability and annoying problem with tabs('rotate').
11287 if ( $.browser.msie ) {
11288 this.blur();
11289 }
11290 });
11291
11292 // disable click in any case
11293 this.anchors.bind( "click.tabs", function(){
11294 return false;
11295 });
11296 },
11297
11298 _getIndex: function( index ) {
11299 // meta-function to give users option to provide a href string instead of a numerical index.
11300 // also sanitizes numerical indexes to valid values.
11301 if ( typeof index == "string" ) {
11302 index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
11303 }
11304
11305 return index;
11306 },
11307
11308 destroy: function() {
11309 var o = this.options;
11310
11311 this.abort();
11312
11313 this.element
11314 .unbind( ".tabs" )
11315 .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
11316 .removeData( "tabs" );
11317
11318 this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
11319
11320 this.anchors.each(function() {
11321 var href = $.data( this, "href.tabs" );
11322 if ( href ) {
11323 this.href = href;
11324 }
11325 var $this = $( this ).unbind( ".tabs" );
11326 $.each( [ "href", "load", "cache" ], function( i, prefix ) {
11327 $this.removeData( prefix + ".tabs" );
11328 });
11329 });
11330
11331 this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
11332 if ( $.data( this, "destroy.tabs" ) ) {
11333 $( this ).remove();
11334 } else {
11335 $( this ).removeClass([
11336 "ui-state-default",
11337 "ui-corner-top",
11338 "ui-tabs-selected",
11339 "ui-state-active",
11340 "ui-state-hover",
11341 "ui-state-focus",
11342 "ui-state-disabled",
11343 "ui-tabs-panel",
11344 "ui-widget-content",
11345 "ui-corner-bottom",
11346 "ui-tabs-hide"
11347 ].join( " " ) );
11348 }
11349 });
11350
11351 if ( o.cookie ) {
11352 this._cookie( null, o.cookie );
11353 }
11354
11355 return this;
11356 },
11357
11358 add: function( url, label, index ) {
11359 if ( index === undefined ) {
11360 index = this.anchors.length;
11361 }
11362
11363 var self = this,
11364 o = this.options,
11365 $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
11366 id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
11367
11368 $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
11369
11370 // try to find an existing element before creating a new one
11371 var $panel = self.element.find( "#" + id );
11372 if ( !$panel.length ) {
11373 $panel = $( o.panelTemplate )
11374 .attr( "id", id )
11375 .data( "destroy.tabs", true );
11376 }
11377 $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
11378
11379 if ( index >= this.lis.length ) {
11380 $li.appendTo( this.list );
11381 $panel.appendTo( this.list[ 0 ].parentNode );
11382 } else {
11383 $li.insertBefore( this.lis[ index ] );
11384 $panel.insertBefore( this.panels[ index ] );
11385 }
11386
11387 o.disabled = $.map( o.disabled, function( n, i ) {
11388 return n >= index ? ++n : n;
11389 });
11390
11391 this._tabify();
11392
11393 if ( this.anchors.length == 1 ) {
11394 o.selected = 0;
11395 $li.addClass( "ui-tabs-selected ui-state-active" );
11396 $panel.removeClass( "ui-tabs-hide" );
11397 this.element.queue( "tabs", function() {
11398 self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
11399 });
11400
11401 this.load( 0 );
11402 }
11403
11404 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11405 return this;
11406 },
11407
11408 remove: function( index ) {
11409 index = this._getIndex( index );
11410 var o = this.options,
11411 $li = this.lis.eq( index ).remove(),
11412 $panel = this.panels.eq( index ).remove();
11413
11414 // If selected tab was removed focus tab to the right or
11415 // in case the last tab was removed the tab to the left.
11416 if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
11417 this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
11418 }
11419
11420 o.disabled = $.map(
11421 $.grep( o.disabled, function(n, i) {
11422 return n != index;
11423 }),
11424 function( n, i ) {
11425 return n >= index ? --n : n;
11426 });
11427
11428 this._tabify();
11429
11430 this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
11431 return this;
11432 },
11433
11434 enable: function( index ) {
11435 index = this._getIndex( index );
11436 var o = this.options;
11437 if ( $.inArray( index, o.disabled ) == -1 ) {
11438 return;
11439 }
11440
11441 this.lis.eq( index ).removeClass( "ui-state-disabled" );
11442 o.disabled = $.grep( o.disabled, function( n, i ) {
11443 return n != index;
11444 });
11445
11446 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11447 return this;
11448 },
11449
11450 disable: function( index ) {
11451 index = this._getIndex( index );
11452 var self = this, o = this.options;
11453 // cannot disable already selected tab
11454 if ( index != o.selected ) {
11455 this.lis.eq( index ).addClass( "ui-state-disabled" );
11456
11457 o.disabled.push( index );
11458 o.disabled.sort();
11459
11460 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11461 }
11462
11463 return this;
11464 },
11465
11466 select: function( index ) {
11467 index = this._getIndex( index );
11468 if ( index == -1 ) {
11469 if ( this.options.collapsible && this.options.selected != -1 ) {
11470 index = this.options.selected;
11471 } else {
11472 return this;
11473 }
11474 }
11475 this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
11476 return this;
11477 },
11478
11479 load: function( index ) {
11480 index = this._getIndex( index );
11481 var self = this,
11482 o = this.options,
11483 a = this.anchors.eq( index )[ 0 ],
11484 url = $.data( a, "load.tabs" );
11485
11486 this.abort();
11487
11488 // not remote or from cache
11489 if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
11490 this.element.dequeue( "tabs" );
11491 return;
11492 }
11493
11494 // load remote from here on
11495 this.lis.eq( index ).addClass( "ui-state-processing" );
11496
11497 if ( o.spinner ) {
11498 var span = $( "span", a );
11499 span.data( "label.tabs", span.html() ).html( o.spinner );
11500 }
11501
11502 this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
11503 url: url,
11504 success: function( r, s ) {
11505 self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
11506
11507 // take care of tab labels
11508 self._cleanup();
11509
11510 if ( o.cache ) {
11511 $.data( a, "cache.tabs", true );
11512 }
11513
11514 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
11515 try {
11516 o.ajaxOptions.success( r, s );
11517 }
11518 catch ( e ) {}
11519 },
11520 error: function( xhr, s, e ) {
11521 // take care of tab labels
11522 self._cleanup();
11523
11524 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
11525 try {
11526 // Passing index avoid a race condition when this method is
11527 // called after the user has selected another tab.
11528 // Pass the anchor that initiated this request allows
11529 // loadError to manipulate the tab content panel via $(a.hash)
11530 o.ajaxOptions.error( xhr, s, index, a );
11531 }
11532 catch ( e ) {}
11533 }
11534 } ) );
11535
11536 // last, so that load event is fired before show...
11537 self.element.dequeue( "tabs" );
11538
11539 return this;
11540 },
11541
11542 abort: function() {
11543 // stop possibly running animations
11544 this.element.queue( [] );
11545 this.panels.stop( false, true );
11546
11547 // "tabs" queue must not contain more than two elements,
11548 // which are the callbacks for the latest clicked tab...
11549 this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
11550
11551 // terminate pending requests from other tabs
11552 if ( this.xhr ) {
11553 this.xhr.abort();
11554 delete this.xhr;
11555 }
11556
11557 // take care of tab labels
11558 this._cleanup();
11559 return this;
11560 },
11561
11562 url: function( index, url ) {
11563 this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
11564 return this;
11565 },
11566
11567 length: function() {
11568 return this.anchors.length;
11569 }
11570 });
11571
11572 $.extend( $.ui.tabs, {
11573 version: "1.8.7"
11574 });
11575
11576 /*
11577 * Tabs Extensions
11578 */
11579
11580 /*
11581 * Rotate
11582 */
11583 $.extend( $.ui.tabs.prototype, {
11584 rotation: null,
11585 rotate: function( ms, continuing ) {
11586 var self = this,
11587 o = this.options;
11588
11589 var rotate = self._rotate || ( self._rotate = function( e ) {
11590 clearTimeout( self.rotation );
11591 self.rotation = setTimeout(function() {
11592 var t = o.selected;
11593 self.select( ++t < self.anchors.length ? t : 0 );
11594 }, ms );
11595
11596 if ( e ) {
11597 e.stopPropagation();
11598 }
11599 });
11600
11601 var stop = self._unrotate || ( self._unrotate = !continuing
11602 ? function(e) {
11603 if (e.clientX) { // in case of a true click
11604 self.rotate(null);
11605 }
11606 }
11607 : function( e ) {
11608 t = o.selected;
11609 rotate();
11610 });
11611
11612 // start rotation
11613 if ( ms ) {
11614 this.element.bind( "tabsshow", rotate );
11615 this.anchors.bind( o.event + ".tabs", stop );
11616 rotate();
11617 // stop rotation
11618 } else {
11619 clearTimeout( self.rotation );
11620 this.element.unbind( "tabsshow", rotate );
11621 this.anchors.unbind( o.event + ".tabs", stop );
11622 delete this._rotate;
11623 delete this._unrotate;
11624 }
11625
11626 return this;
11627 }
11628 });
11629
11630 })( jQuery );