1// source --> https://www.clickteam.com/wp-content/themes/clickteam/js/jquery-ui.js 2/*! jQuery UI - v1.10.2 - 2013-03-14 3* http://jqueryui.com 4* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js 5* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11// $.ui might exist from components with no dependencies, e.g., $.ui.position 12$.ui = $.ui || {}; 13 14$.extend( $.ui, { 15 version: "1.10.2", 16 17 keyCode: { 18 BACKSPACE: 8, 19 COMMA: 188, 20 DELETE: 46, 21 DOWN: 40, 22 END: 35, 23 ENTER: 13, 24 ESCAPE: 27, 25 HOME: 36, 26 LEFT: 37, 27 NUMPAD_ADD: 107, 28 NUMPAD_DECIMAL: 110, 29 NUMPAD_DIVIDE: 111, 30 NUMPAD_ENTER: 108, 31 NUMPAD_MULTIPLY: 106, 32 NUMPAD_SUBTRACT: 109, 33 PAGE_DOWN: 34, 34 PAGE_UP: 33, 35 PERIOD: 190, 36 RIGHT: 39, 37 SPACE: 32, 38 TAB: 9, 39 UP: 38 40 } 41}); 42 43// plugins 44$.fn.extend({ 45 focus: (function( orig ) { 46 return function( delay, fn ) { 47 return typeof delay === "number" ? 48 this.each(function() { 49 var elem = this; 50 setTimeout(function() { 51 $( elem ).focus(); 52 if ( fn ) { 53 fn.call( elem ); 54 } 55 }, delay ); 56 }) : 57 orig.apply( this, arguments ); 58 }; 59 })( $.fn.focus ), 60 61 scrollParent: function() { 62 var scrollParent; 63 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 64 scrollParent = this.parents().filter(function() { 65 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 66 }).eq(0); 67 } else { 68 scrollParent = this.parents().filter(function() { 69 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 70 }).eq(0); 71 } 72 73 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 74 }, 75 76 zIndex: function( zIndex ) { 77 if ( zIndex !== undefined ) { 78 return this.css( "zIndex", zIndex ); 79 } 80 81 if ( this.length ) { 82 var elem = $( this[ 0 ] ), position, value; 83 while ( elem.length && elem[ 0 ] !== document ) { 84 // Ignore z-index if position is set to a value where z-index is ignored by the browser 85 // This makes behavior of this function consistent across browsers 86 // WebKit always returns auto if the element is positioned 87 position = elem.css( "position" ); 88 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 89 // IE returns 0 when zIndex is not specified 90 // other browsers return a string 91 // we ignore the case of nested elements with an explicit value of 0 92 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 93 value = parseInt( elem.css( "zIndex" ), 10 ); 94 if ( !isNaN( value ) && value !== 0 ) { 95 return value; 96 } 97 } 98 elem = elem.parent(); 99 } 100 } 101 102 return 0; 103 }, 104 105 uniqueId: function() { 106 return this.each(function() { 107 if ( !this.id ) { 108 this.id = "ui-id-" + (++uuid); 109 } 110 }); 111 }, 112 113 removeUniqueId: function() { 114 return this.each(function() { 115 if ( runiqueId.test( this.id ) ) { 116 $( this ).removeAttr( "id" ); 117 } 118 }); 119 } 120}); 121 122// selectors 123function focusable( element, isTabIndexNotNaN ) { 124 var map, mapName, img, 125 nodeName = element.nodeName.toLowerCase(); 126 if ( "area" === nodeName ) { 127 map = element.parentNode; 128 mapName = map.name; 129 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 130 return false;
vendor: 24,146 bytes, lines 131-997
131 } 132 img = $( "img[usemap=#" + mapName + "]" )[0]; 133 return !!img && visible( img ); 134 } 135 return ( /input|select|textarea|button|object/.test( nodeName ) ? 136 !element.disabled : 137 "a" === nodeName ? 138 element.href || isTabIndexNotNaN : 139 isTabIndexNotNaN) && 140 // the element and all of its ancestors must be visible 141 visible( element ); 142} 143 144function visible( element ) { 145 return $.expr.filters.visible( element ) && 146 !$( element ).parents().addBack().filter(function() { 147 return $.css( this, "visibility" ) === "hidden"; 148 }).length; 149} 150 151$.extend( $.expr[ ":" ], { 152 data: $.expr.createPseudo ? 153 $.expr.createPseudo(function( dataName ) { 154 return function( elem ) { 155 return !!$.data( elem, dataName ); 156 }; 157 }) : 158 // support: jQuery <1.8 159 function( elem, i, match ) { 160 return !!$.data( elem, match[ 3 ] ); 161 }, 162 163 focusable: function( element ) { 164 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 165 }, 166 167 tabbable: function( element ) { 168 var tabIndex = $.attr( element, "tabindex" ), 169 isTabIndexNaN = isNaN( tabIndex ); 170 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 171 } 172}); 173 174// support: jQuery <1.8 175if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 176 $.each( [ "Width", "Height" ], function( i, name ) { 177 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 178 type = name.toLowerCase(), 179 orig = { 180 innerWidth: $.fn.innerWidth, 181 innerHeight: $.fn.innerHeight, 182 outerWidth: $.fn.outerWidth, 183 outerHeight: $.fn.outerHeight 184 }; 185 186 function reduce( elem, size, border, margin ) { 187 $.each( side, function() { 188 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 189 if ( border ) { 190 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 191 } 192 if ( margin ) { 193 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 194 } 195 }); 196 return size; 197 } 198 199 $.fn[ "inner" + name ] = function( size ) { 200 if ( size === undefined ) { 201 return orig[ "inner" + name ].call( this ); 202 } 203 204 return this.each(function() { 205 $( this ).css( type, reduce( this, size ) + "px" ); 206 }); 207 }; 208 209 $.fn[ "outer" + name] = function( size, margin ) { 210 if ( typeof size !== "number" ) { 211 return orig[ "outer" + name ].call( this, size ); 212 } 213 214 return this.each(function() { 215 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 216 }); 217 }; 218 }); 219} 220 221// support: jQuery <1.8 222if ( !$.fn.addBack ) { 223 $.fn.addBack = function( selector ) { 224 return this.add( selector == null ? 225 this.prevObject : this.prevObject.filter( selector ) 226 ); 227 }; 228} 229 230// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 231if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 232 $.fn.removeData = (function( removeData ) { 233 return function( key ) { 234 if ( arguments.length ) { 235 return removeData.call( this, $.camelCase( key ) ); 236 } else { 237 return removeData.call( this ); 238 } 239 }; 240 })( $.fn.removeData ); 241} 242 243 244 245 246 247// deprecated 248$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 249 250$.support.selectstart = "onselectstart" in document.createElement( "div" ); 251$.fn.extend({ 252 disableSelection: function() { 253 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 254 ".ui-disableSelection", function( event ) { 255 event.preventDefault(); 256 }); 257 }, 258 259 enableSelection: function() { 260 return this.unbind( ".ui-disableSelection" ); 261 } 262}); 263 264$.extend( $.ui, { 265 // $.ui.plugin is deprecated. Use the proxy pattern instead. 266 plugin: { 267 add: function( module, option, set ) { 268 var i, 269 proto = $.ui[ module ].prototype; 270 for ( i in set ) { 271 proto.plugins[ i ] = proto.plugins[ i ] || []; 272 proto.plugins[ i ].push( [ option, set[ i ] ] ); 273 } 274 }, 275 call: function( instance, name, args ) { 276 var i, 277 set = instance.plugins[ name ]; 278 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 279 return; 280 } 281 282 for ( i = 0; i < set.length; i++ ) { 283 if ( instance.options[ set[ i ][ 0 ] ] ) { 284 set[ i ][ 1 ].apply( instance.element, args ); 285 } 286 } 287 } 288 }, 289 290 // only used by resizable 291 hasScroll: function( el, a ) { 292 293 //If overflow is hidden, the element might have extra content, but the user wants to hide it 294 if ( $( el ).css( "overflow" ) === "hidden") { 295 return false; 296 } 297 298 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 299 has = false; 300 301 if ( el[ scroll ] > 0 ) { 302 return true; 303 } 304 305 // TODO: determine which cases actually cause this to happen 306 // if the element doesn't have the scroll set, see if it's possible to 307 // set the scroll 308 el[ scroll ] = 1; 309 has = ( el[ scroll ] > 0 ); 310 el[ scroll ] = 0; 311 return has; 312 } 313}); 314 315})( jQuery ); 316 317(function( $, undefined ) { 318 319var uuid = 0, 320 slice = Array.prototype.slice, 321 _cleanData = $.cleanData; 322$.cleanData = function( elems ) { 323 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 324 try { 325 $( elem ).triggerHandler( "remove" ); 326 // http://bugs.jquery.com/ticket/8235 327 } catch( e ) {} 328 } 329 _cleanData( elems ); 330}; 331 332$.widget = function( name, base, prototype ) { 333 var fullName, existingConstructor, constructor, basePrototype, 334 // proxiedPrototype allows the provided prototype to remain unmodified 335 // so that it can be used as a mixin for multiple widgets (#8876) 336 proxiedPrototype = {}, 337 namespace = name.split( "." )[ 0 ]; 338 339 name = name.split( "." )[ 1 ]; 340 fullName = namespace + "-" + name; 341 342 if ( !prototype ) { 343 prototype = base; 344 base = $.Widget; 345 } 346 347 // create selector for plugin 348 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 349 return !!$.data( elem, fullName ); 350 }; 351 352 $[ namespace ] = $[ namespace ] || {}; 353 existingConstructor = $[ namespace ][ name ]; 354 constructor = $[ namespace ][ name ] = function( options, element ) { 355 // allow instantiation without "new" keyword 356 if ( !this._createWidget ) { 357 return new constructor( options, element ); 358 } 359 360 // allow instantiation without initializing for simple inheritance 361 // must use "new" keyword (the code above always passes args) 362 if ( arguments.length ) { 363 this._createWidget( options, element ); 364 } 365 }; 366 // extend with the existing constructor to carry over any static properties 367 $.extend( constructor, existingConstructor, { 368 version: prototype.version, 369 // copy the object used to create the prototype in case we need to 370 // redefine the widget later 371 _proto: $.extend( {}, prototype ), 372 // track widgets that inherit from this widget in case this widget is 373 // redefined after a widget inherits from it 374 _childConstructors: [] 375 }); 376 377 basePrototype = new base(); 378 // we need to make the options hash a property directly on the new instance 379 // otherwise we'll modify the options hash on the prototype that we're 380 // inheriting from 381 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 382 $.each( prototype, function( prop, value ) { 383 if ( !$.isFunction( value ) ) { 384 proxiedPrototype[ prop ] = value; 385 return; 386 } 387 proxiedPrototype[ prop ] = (function() { 388 var _super = function() { 389 return base.prototype[ prop ].apply( this, arguments ); 390 }, 391 _superApply = function( args ) { 392 return base.prototype[ prop ].apply( this, args ); 393 }; 394 return function() { 395 var __super = this._super, 396 __superApply = this._superApply, 397 returnValue; 398 399 this._super = _super; 400 this._superApply = _superApply; 401 402 returnValue = value.apply( this, arguments ); 403 404 this._super = __super; 405 this._superApply = __superApply; 406 407 return returnValue; 408 }; 409 })(); 410 }); 411 constructor.prototype = $.widget.extend( basePrototype, { 412 // TODO: remove support for widgetEventPrefix 413 // always use the name + a colon as the prefix, e.g., draggable:start 414 // don't prefix for widgets that aren't DOM-based 415 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 416 }, proxiedPrototype, { 417 constructor: constructor, 418 namespace: namespace, 419 widgetName: name, 420 widgetFullName: fullName 421 }); 422 423 // If this widget is being redefined then we need to find all widgets that 424 // are inheriting from it and redefine all of them so that they inherit from 425 // the new version of this widget. We're essentially trying to replace one 426 // level in the prototype chain. 427 if ( existingConstructor ) { 428 $.each( existingConstructor._childConstructors, function( i, child ) { 429 var childPrototype = child.prototype; 430 431 // redefine the child widget using the same prototype that was 432 // originally used, but inherit from the new version of the base 433 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 434 }); 435 // remove the list of existing child constructors from the old constructor 436 // so the old child constructors can be garbage collected 437 delete existingConstructor._childConstructors; 438 } else { 439 base._childConstructors.push( constructor ); 440 } 441 442 $.widget.bridge( name, constructor ); 443}; 444 445$.widget.extend = function( target ) { 446 var input = slice.call( arguments, 1 ), 447 inputIndex = 0, 448 inputLength = input.length, 449 key, 450 value; 451 for ( ; inputIndex < inputLength; inputIndex++ ) { 452 for ( key in input[ inputIndex ] ) { 453 value = input[ inputIndex ][ key ]; 454 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 455 // Clone objects 456 if ( $.isPlainObject( value ) ) { 457 target[ key ] = $.isPlainObject( target[ key ] ) ? 458 $.widget.extend( {}, target[ key ], value ) : 459 // Don't extend strings, arrays, etc. with objects 460 $.widget.extend( {}, value ); 461 // Copy everything else by reference 462 } else { 463 target[ key ] = value; 464 } 465 } 466 } 467 } 468 return target; 469}; 470 471$.widget.bridge = function( name, object ) { 472 var fullName = object.prototype.widgetFullName || name; 473 $.fn[ name ] = function( options ) { 474 var isMethodCall = typeof options === "string", 475 args = slice.call( arguments, 1 ), 476 returnValue = this; 477 478 // allow multiple hashes to be passed on init 479 options = !isMethodCall && args.length ? 480 $.widget.extend.apply( null, [ options ].concat(args) ) : 481 options; 482 483 if ( isMethodCall ) { 484 this.each(function() { 485 var methodValue, 486 instance = $.data( this, fullName ); 487 if ( !instance ) { 488 return $.error( "cannot call methods on " + name + " prior to initialization; " + 489 "attempted to call method '" + options + "'" ); 490 } 491 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 492 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 493 } 494 methodValue = instance[ options ].apply( instance, args ); 495 if ( methodValue !== instance && methodValue !== undefined ) { 496 returnValue = methodValue && methodValue.jquery ? 497 returnValue.pushStack( methodValue.get() ) : 498 methodValue; 499 return false; 500 } 501 }); 502 } else { 503 this.each(function() { 504 var instance = $.data( this, fullName ); 505 if ( instance ) { 506 instance.option( options || {} )._init(); 507 } else { 508 $.data( this, fullName, new object( options, this ) ); 509 } 510 }); 511 } 512 513 return returnValue; 514 }; 515}; 516 517$.Widget = function( /* options, element */ ) {}; 518$.Widget._childConstructors = []; 519 520$.Widget.prototype = { 521 widgetName: "widget", 522 widgetEventPrefix: "", 523 defaultElement: "<div>", 524 options: { 525 disabled: false, 526 527 // callbacks 528 create: null 529 }, 530 _createWidget: function( options, element ) { 531 element = $( element || this.defaultElement || this )[ 0 ]; 532 this.element = $( element ); 533 this.uuid = uuid++; 534 this.eventNamespace = "." + this.widgetName + this.uuid; 535 this.options = $.widget.extend( {}, 536 this.options, 537 this._getCreateOptions(), 538 options ); 539 540 this.bindings = $(); 541 this.hoverable = $(); 542 this.focusable = $(); 543 544 if ( element !== this ) { 545 $.data( element, this.widgetFullName, this ); 546 this._on( true, this.element, { 547 remove: function( event ) { 548 if ( event.target === element ) { 549 this.destroy(); 550 } 551 } 552 }); 553 this.document = $( element.style ? 554 // element within the document 555 element.ownerDocument : 556 // element is window or document 557 element.document || element ); 558 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 559 } 560 561 this._create(); 562 this._trigger( "create", null, this._getCreateEventData() ); 563 this._init(); 564 }, 565 _getCreateOptions: $.noop, 566 _getCreateEventData: $.noop, 567 _create: $.noop, 568 _init: $.noop, 569 570 destroy: function() { 571 this._destroy(); 572 // we can probably remove the unbind calls in 2.0 573 // all event bindings should go through this._on() 574 this.element 575 .unbind( this.eventNamespace ) 576 // 1.9 BC for #7810 577 // TODO remove dual storage 578 .removeData( this.widgetName ) 579 .removeData( this.widgetFullName ) 580 // support: jquery <1.6.3 581 // http://bugs.jquery.com/ticket/9413 582 .removeData( $.camelCase( this.widgetFullName ) ); 583 this.widget() 584 .unbind( this.eventNamespace ) 585 .removeAttr( "aria-disabled" ) 586 .removeClass( 587 this.widgetFullName + "-disabled " + 588 "ui-state-disabled" ); 589 590 // clean up events and states 591 this.bindings.unbind( this.eventNamespace ); 592 this.hoverable.removeClass( "ui-state-hover" ); 593 this.focusable.removeClass( "ui-state-focus" ); 594 }, 595 _destroy: $.noop, 596 597 widget: function() { 598 return this.element; 599 }, 600 601 option: function( key, value ) { 602 var options = key, 603 parts, 604 curOption, 605 i; 606 607 if ( arguments.length === 0 ) { 608 // don't return a reference to the internal hash 609 return $.widget.extend( {}, this.options ); 610 } 611 612 if ( typeof key === "string" ) { 613 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 614 options = {}; 615 parts = key.split( "." ); 616 key = parts.shift(); 617 if ( parts.length ) { 618 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 619 for ( i = 0; i < parts.length - 1; i++ ) { 620 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 621 curOption = curOption[ parts[ i ] ]; 622 } 623 key = parts.pop(); 624 if ( value === undefined ) { 625 return curOption[ key ] === undefined ? null : curOption[ key ]; 626 } 627 curOption[ key ] = value; 628 } else { 629 if ( value === undefined ) { 630 return this.options[ key ] === undefined ? null : this.options[ key ]; 631 } 632 options[ key ] = value; 633 } 634 } 635 636 this._setOptions( options ); 637 638 return this; 639 }, 640 _setOptions: function( options ) { 641 var key; 642 643 for ( key in options ) { 644 this._setOption( key, options[ key ] ); 645 } 646 647 return this; 648 }, 649 _setOption: function( key, value ) { 650 this.options[ key ] = value; 651 652 if ( key === "disabled" ) { 653 this.widget() 654 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 655 .attr( "aria-disabled", value ); 656 this.hoverable.removeClass( "ui-state-hover" ); 657 this.focusable.removeClass( "ui-state-focus" ); 658 } 659 660 return this; 661 }, 662 663 enable: function() { 664 return this._setOption( "disabled", false ); 665 }, 666 disable: function() { 667 return this._setOption( "disabled", true ); 668 }, 669 670 _on: function( suppressDisabledCheck, element, handlers ) { 671 var delegateElement, 672 instance = this; 673 674 // no suppressDisabledCheck flag, shuffle arguments 675 if ( typeof suppressDisabledCheck !== "boolean" ) { 676 handlers = element; 677 element = suppressDisabledCheck; 678 suppressDisabledCheck = false; 679 } 680 681 // no element argument, shuffle and use this.element 682 if ( !handlers ) { 683 handlers = element; 684 element = this.element; 685 delegateElement = this.widget(); 686 } else { 687 // accept selectors, DOM elements 688 element = delegateElement = $( element ); 689 this.bindings = this.bindings.add( element ); 690 } 691 692 $.each( handlers, function( event, handler ) { 693 function handlerProxy() { 694 // allow widgets to customize the disabled handling 695 // - disabled as an array instead of boolean 696 // - disabled class as method for disabling individual parts 697 if ( !suppressDisabledCheck && 698 ( instance.options.disabled === true || 699 $( this ).hasClass( "ui-state-disabled" ) ) ) { 700 return; 701 } 702 return ( typeof handler === "string" ? instance[ handler ] : handler ) 703 .apply( instance, arguments ); 704 } 705 706 // copy the guid so direct unbinding works 707 if ( typeof handler !== "string" ) { 708 handlerProxy.guid = handler.guid = 709 handler.guid || handlerProxy.guid || $.guid++; 710 } 711 712 var match = event.match( /^(\w+)\s*(.*)$/ ), 713 eventName = match[1] + instance.eventNamespace, 714 selector = match[2]; 715 if ( selector ) { 716 delegateElement.delegate( selector, eventName, handlerProxy ); 717 } else { 718 element.bind( eventName, handlerProxy ); 719 } 720 }); 721 }, 722 723 _off: function( element, eventName ) { 724 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 725 element.unbind( eventName ).undelegate( eventName ); 726 }, 727 728 _delay: function( handler, delay ) { 729 function handlerProxy() { 730 return ( typeof handler === "string" ? instance[ handler ] : handler ) 731 .apply( instance, arguments ); 732 } 733 var instance = this; 734 return setTimeout( handlerProxy, delay || 0 ); 735 }, 736 737 _hoverable: function( element ) { 738 this.hoverable = this.hoverable.add( element ); 739 this._on( element, { 740 mouseenter: function( event ) { 741 $( event.currentTarget ).addClass( "ui-state-hover" ); 742 }, 743 mouseleave: function( event ) { 744 $( event.currentTarget ).removeClass( "ui-state-hover" ); 745 } 746 }); 747 }, 748 749 _focusable: function( element ) { 750 this.focusable = this.focusable.add( element ); 751 this._on( element, { 752 focusin: function( event ) { 753 $( event.currentTarget ).addClass( "ui-state-focus" ); 754 }, 755 focusout: function( event ) { 756 $( event.currentTarget ).removeClass( "ui-state-focus" ); 757 } 758 }); 759 }, 760 761 _trigger: function( type, event, data ) { 762 var prop, orig, 763 callback = this.options[ type ]; 764 765 data = data || {}; 766 event = $.Event( event ); 767 event.type = ( type === this.widgetEventPrefix ? 768 type : 769 this.widgetEventPrefix + type ).toLowerCase(); 770 // the original event may come from any element 771 // so we need to reset the target on the new event 772 event.target = this.element[ 0 ]; 773 774 // copy original event properties over to the new event 775 orig = event.originalEvent; 776 if ( orig ) { 777 for ( prop in orig ) { 778 if ( !( prop in event ) ) { 779 event[ prop ] = orig[ prop ]; 780 } 781 } 782 } 783 784 this.element.trigger( event, data ); 785 return !( $.isFunction( callback ) && 786 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 787 event.isDefaultPrevented() ); 788 } 789}; 790 791$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 792 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 793 if ( typeof options === "string" ) { 794 options = { effect: options }; 795 } 796 var hasOptions, 797 effectName = !options ? 798 method : 799 options === true || typeof options === "number" ? 800 defaultEffect : 801 options.effect || defaultEffect; 802 options = options || {}; 803 if ( typeof options === "number" ) { 804 options = { duration: options }; 805 } 806 hasOptions = !$.isEmptyObject( options ); 807 options.complete = callback; 808 if ( options.delay ) { 809 element.delay( options.delay ); 810 } 811 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 812 element[ method ]( options ); 813 } else if ( effectName !== method && element[ effectName ] ) { 814 element[ effectName ]( options.duration, options.easing, callback ); 815 } else { 816 element.queue(function( next ) { 817 $( this )[ method ](); 818 if ( callback ) { 819 callback.call( element[ 0 ] ); 820 } 821 next(); 822 }); 823 } 824 }; 825}); 826 827})( jQuery ); 828 829(function( $, undefined ) { 830 831var mouseHandled = false; 832$( document ).mouseup( function() { 833 mouseHandled = false; 834}); 835 836$.widget("ui.mouse", { 837 version: "1.10.2", 838 options: { 839 cancel: "input,textarea,button,select,option", 840 distance: 1, 841 delay: 0 842 }, 843 _mouseInit: function() { 844 var that = this; 845 846 this.element 847 .bind("mousedown."+this.widgetName, function(event) { 848 return that._mouseDown(event); 849 }) 850 .bind("click."+this.widgetName, function(event) { 851 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 852 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 853 event.stopImmediatePropagation(); 854 return false; 855 } 856 }); 857 858 this.started = false; 859 }, 860 861 // TODO: make sure destroying one instance of mouse doesn't mess with 862 // other instances of mouse 863 _mouseDestroy: function() { 864 this.element.unbind("."+this.widgetName); 865 if ( this._mouseMoveDelegate ) { 866 $(document) 867 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 868 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 869 } 870 }, 871 872 _mouseDown: function(event) { 873 // don't let more than one widget handle mouseStart 874 if( mouseHandled ) { return; } 875 876 // we may have missed mouseup (out of window) 877 (this._mouseStarted && this._mouseUp(event)); 878 879 this._mouseDownEvent = event; 880 881 var that = this, 882 btnIsLeft = (event.which === 1), 883 // event.target.nodeName works around a bug in IE 8 with 884 // disabled inputs (#7620) 885 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 886 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 887 return true; 888 } 889 890 this.mouseDelayMet = !this.options.delay; 891 if (!this.mouseDelayMet) { 892 this._mouseDelayTimer = setTimeout(function() { 893 that.mouseDelayMet = true; 894 }, this.options.delay); 895 } 896 897 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 898 this._mouseStarted = (this._mouseStart(event) !== false); 899 if (!this._mouseStarted) { 900 event.preventDefault(); 901 return true; 902 } 903 } 904 905 // Click event may never have fired (Gecko & Opera) 906 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 907 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 908 } 909 910 // these delegates are required to keep context 911 this._mouseMoveDelegate = function(event) { 912 return that._mouseMove(event); 913 }; 914 this._mouseUpDelegate = function(event) { 915 return that._mouseUp(event); 916 }; 917 $(document) 918 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 919 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 920 921 event.preventDefault(); 922 923 mouseHandled = true; 924 return true; 925 }, 926 927 _mouseMove: function(event) { 928 // IE mouseup check - mouseup happened when mouse was out of window 929 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 930 return this._mouseUp(event); 931 } 932 933 if (this._mouseStarted) { 934 this._mouseDrag(event); 935 return event.preventDefault(); 936 } 937 938 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 939 this._mouseStarted = 940 (this._mouseStart(this._mouseDownEvent, event) !== false); 941 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 942 } 943 944 return !this._mouseStarted; 945 }, 946 947 _mouseUp: function(event) { 948 $(document) 949 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 950 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 951 952 if (this._mouseStarted) { 953 this._mouseStarted = false; 954 955 if (event.target === this._mouseDownEvent.target) { 956 $.data(event.target, this.widgetName + ".preventClickEvent", true); 957 } 958 959 this._mouseStop(event); 960 } 961 962 return false; 963 }, 964 965 _mouseDistanceMet: function(event) { 966 return (Math.max( 967 Math.abs(this._mouseDownEvent.pageX - event.pageX), 968 Math.abs(this._mouseDownEvent.pageY - event.pageY) 969 ) >= this.options.distance 970 ); 971 }, 972 973 _mouseDelayMet: function(/* event */) { 974 return this.mouseDelayMet; 975 }, 976 977 // These are placeholder methods, to be overriden by extending plugin 978 _mouseStart: function(/* event */) {}, 979 _mouseDrag: function(/* event */) {}, 980 _mouseStop: function(/* event */) {}, 981 _mouseCapture: function(/* event */) { return true; } 982}); 983 984})(jQuery); 985 986(function( $, undefined ) { 987 988$.widget("ui.draggable", $.ui.mouse, { 989 version: "1.10.2", 990 widgetEventPrefix: "drag", 991 options: { 992 addClasses: true, 993 appendTo: "parent", 994 axis: false, 995 connectToSortable: false, 996 containment: false, 997 cursor: "auto",
998 cursorAt: false, 999 grid: false, 1000 handle: false, 1001 helper: "original", 1002 iframeFix: false, 1003 opacity: false, 1004 refreshPositions: false, 1005 revert: false, 1006 revertDuration: 500, 1007 scope: "default", 1008 scroll: true, 1009 scrollSensitivity: 20, 1010 scrollSpeed: 20, 1011 snap: false, 1012 snapMode: "both", 1013 snapTolerance: 20, 1014 stack: false, 1015 zIndex: false, 1016 1017 // callbacks 1018 drag: null, 1019 start: null, 1020 stop: null 1021 }, 1022 _create: function() { 1023 1024 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 1025 this.element[0].style.position = "relative"; 1026 } 1027 if (this.options.addClasses){ 1028 this.element.addClass("ui-draggable"); 1029 } 1030 if (this.options.disabled){ 1031 this.element.addClass("ui-draggable-disabled"); 1032 } 1033 1034 this._mouseInit(); 1035 1036 }, 1037 1038 _destroy: function() { 1039 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1040 this._mouseDestroy(); 1041 }, 1042 1043 _mouseCapture: function(event) { 1044 1045 var o = this.options; 1046 1047 // among others, prevent a drag on a resizable-handle 1048 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 1049 return false; 1050 } 1051 1052 //Quit if we're not on a valid handle 1053 this.handle = this._getHandle(event); 1054 if (!this.handle) { 1055 return false; 1056 } 1057 1058 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1059 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 1060 .css({ 1061 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1062 position: "absolute", opacity: "0.001", zIndex: 1000 1063 }) 1064 .css($(this).offset()) 1065 .appendTo("body"); 1066 }); 1067 1068 return true; 1069 1070 }, 1071 1072 _mouseStart: function(event) { 1073 1074 var o = this.options; 1075 1076 //Create and append the visible helper 1077 this.helper = this._createHelper(event); 1078 1079 this.helper.addClass("ui-draggable-dragging"); 1080 1081 //Cache the helper size 1082 this._cacheHelperProportions(); 1083 1084 //If ddmanager is used for droppables, set the global draggable 1085 if($.ui.ddmanager) { 1086 $.ui.ddmanager.current = this; 1087 } 1088 1089 /* 1090 * - Position generation - 1091 * This block generates everything position related - it's the core of draggables. 1092 */ 1093 1094 //Cache the margins of the original element 1095 this._cacheMargins(); 1096 1097 //Store the helper's css position 1098 this.cssPosition = this.helper.css("position"); 1099 this.scrollParent = this.helper.scrollParent(); 1100 1101 //The element's absolute position on the page minus margins 1102 this.offset = this.positionAbs = this.element.offset(); 1103 this.offset = { 1104 top: this.offset.top - this.margins.top, 1105 left: this.offset.left - this.margins.left 1106 }; 1107 1108 $.extend(this.offset, { 1109 click: { //Where the click happened, relative to the element 1110 left: event.pageX - this.offset.left, 1111 top: event.pageY - this.offset.top 1112 }, 1113 parent: this._getParentOffset(), 1114 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1115 }); 1116 1117 //Generate the original position 1118 this.originalPosition = this.position = this._generatePosition(event); 1119 this.originalPageX = event.pageX; 1120 this.originalPageY = event.pageY; 1121 1122 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 1123 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1124 1125 //Set a containment if given in the options 1126 if(o.containment) { 1127 this._setContainment(); 1128 } 1129 1130 //Trigger event + callbacks 1131 if(this._trigger("start", event) === false) { 1132 this._clear(); 1133 return false; 1134 } 1135 1136 //Recache the helper size 1137 this._cacheHelperProportions(); 1138 1139 //Prepare the droppable offsets 1140 if ($.ui.ddmanager && !o.dropBehaviour) { 1141 $.ui.ddmanager.prepareOffsets(this, event); 1142 } 1143 1144 1145 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1146 1147 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1148 if ( $.ui.ddmanager ) { 1149 $.ui.ddmanager.dragStart(this, event); 1150 } 1151 1152 return true; 1153 }, 1154 1155 _mouseDrag: function(event, noPropagation) { 1156 1157 //Compute the helpers position 1158 this.position = this._generatePosition(event); 1159 this.positionAbs = this._convertPositionTo("absolute"); 1160 1161 //Call plugins and callbacks and use the resulting position if something is returned 1162 if (!noPropagation) { 1163 var ui = this._uiHash(); 1164 if(this._trigger("drag", event, ui) === false) { 1165 this._mouseUp({}); 1166 return false;
1167 } 1168 this.position = ui.position; 1169 } 1170 1171 if(!this.options.axis || this.options.axis !== "y") { 1172 this.helper[0].style.left = this.position.left+"px"; 1173 } 1174 if(!this.options.axis || this.options.axis !== "x") { 1175 this.helper[0].style.top = this.position.top+"px"; 1176 } 1177 if($.ui.ddmanager) { 1178 $.ui.ddmanager.drag(this, event); 1179 } 1180 1181 return false; 1182 }, 1183 1184 _mouseStop: function(event) { 1185 1186 //If we are using droppables, inform the manager about the drop 1187 var element, 1188 that = this, 1189 elementInDom = false, 1190 dropped = false; 1191 if ($.ui.ddmanager && !this.options.dropBehaviour) { 1192 dropped = $.ui.ddmanager.drop(this, event); 1193 } 1194 1195 //if a drop comes from outside (a sortable) 1196 if(this.dropped) { 1197 dropped = this.dropped; 1198 this.dropped = false; 1199 } 1200 1201 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1202 element = this.element[0]; 1203 while ( element && (element = element.parentNode) ) { 1204 if (element === document ) { 1205 elementInDom = true; 1206 } 1207 } 1208 if ( !elementInDom && this.options.helper === "original" ) { 1209 return false; 1210 } 1211 1212 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))) { 1213 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1214 if(that._trigger("stop", event) !== false) { 1215 that._clear(); 1216 } 1217 }); 1218 } else { 1219 if(this._trigger("stop", event) !== false) { 1220 this._clear(); 1221 } 1222 } 1223 1224 return false; 1225 }, 1226 1227 _mouseUp: function(event) { 1228 //Remove frame helpers 1229 $("div.ui-draggable-iframeFix").each(function() { 1230 this.parentNode.removeChild(this); 1231 }); 1232 1233 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1234 if( $.ui.ddmanager ) { 1235 $.ui.ddmanager.dragStop(this, event); 1236 } 1237 1238 return $.ui.mouse.prototype._mouseUp.call(this, event); 1239 }, 1240 1241 cancel: function() { 1242 1243 if(this.helper.is(".ui-draggable-dragging")) { 1244 this._mouseUp({}); 1245 } else { 1246 this._clear(); 1247 } 1248 1249 return this; 1250 1251 }, 1252 1253 _getHandle: function(event) { 1254 return this.options.handle ? 1255 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 1256 true; 1257 }, 1258 1259 _createHelper: function(event) { 1260 1261 var o = this.options, 1262 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 1263 1264 if(!helper.parents("body").length) { 1265 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1266 } 1267 1268 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1269 helper.css("position", "absolute"); 1270 } 1271 1272 return helper; 1273 1274 }, 1275 1276 _adjustOffsetFromHelper: function(obj) { 1277 if (typeof obj === "string") { 1278 obj = obj.split(" "); 1279 } 1280 if ($.isArray(obj)) { 1281 obj = {left: +obj[0], top: +obj[1] || 0}; 1282 } 1283 if ("left" in obj) { 1284 this.offset.click.left = obj.left + this.margins.left; 1285 } 1286 if ("right" in obj) { 1287 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1288 } 1289 if ("top" in obj) { 1290 this.offset.click.top = obj.top + this.margins.top; 1291 } 1292 if ("bottom" in obj) { 1293 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1294 } 1295 }, 1296 1297 _getParentOffset: function() { 1298 1299 //Get the offsetParent and cache its position 1300 this.offsetParent = this.helper.offsetParent(); 1301 var po = this.offsetParent.offset(); 1302 1303 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1304 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1305 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1306 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1307 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1308 po.left += this.scrollParent.scrollLeft(); 1309 po.top += this.scrollParent.scrollTop(); 1310 } 1311 1312 //This needs to be actually done for all browsers, since pageX/pageY includes this information 1313 //Ugly IE fix 1314 if((this.offsetParent[0] === document.body) || 1315 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 1316 po = { top: 0, left: 0 }; 1317 } 1318 1319 return { 1320 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
vendor: 1,408 bytes, lines 1320-1367
132010) || 0), 1321 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1322 }; 1323 1324 }, 1325 1326 _getRelativeOffset: function() { 1327 1328 if(this.cssPosition === "relative") { 1329 var p = this.element.position(); 1330 return { 1331 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1332 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1333 }; 1334 } else { 1335 return { top: 0, left: 0 }; 1336 } 1337 1338 }, 1339 1340 _cacheMargins: function() { 1341 this.margins = { 1342 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1343 top: (parseInt(this.element.css("marginTop"),10) || 0), 1344 right: (parseInt(this.element.css("marginRight"),10) || 0), 1345 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1346 }; 1347 }, 1348 1349 _cacheHelperProportions: function() { 1350 this.helperProportions = { 1351 width: this.helper.outerWidth(), 1352 height: this.helper.outerHeight() 1353 }; 1354 }, 1355 1356 _setContainment: function() { 1357 1358 var over, c, ce, 1359 o = this.options; 1360 1361 if(o.containment === "parent") { 1362 o.containment = this.helper[0].parentNode; 1363 } 1364 if(o.containment === "document" || o.containment === "window") { 1365 this.containment = [ 1366 o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1367 o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
vendor: 6,292 bytes, lines 1368-1500
1368 (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 1369 (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 1370 ]; 1371 } 1372 1373 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) { 1374 c = $(o.containment); 1375 ce = c[0]; 1376 1377 if(!ce) { 1378 return; 1379 } 1380 1381 over = ($(ce).css("overflow") !== "hidden"); 1382 1383 this.containment = [ 1384 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), 1385 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), 1386 (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderRightWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right, 1387 (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderBottomWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom 1388 ]; 1389 this.relative_container = c; 1390 1391 } else if(o.containment.constructor === Array) { 1392 this.containment = o.containment; 1393 } 1394 1395 }, 1396 1397 _convertPositionTo: function(d, pos) { 1398 1399 if(!pos) { 1400 pos = this.position; 1401 } 1402 1403 var mod = d === "absolute" ? 1 : -1, 1404 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 1405 1406 return { 1407 top: ( 1408 pos.top + // The absolute mouse position 1409 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1410 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 1411 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 1412 ), 1413 left: ( 1414 pos.left + // The absolute mouse position 1415 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1416 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 1417 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 1418 ) 1419 }; 1420 1421 }, 1422 1423 _generatePosition: function(event) { 1424 1425 var containment, co, top, left, 1426 o = this.options, 1427 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 1428 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName), 1429 pageX = event.pageX, 1430 pageY = event.pageY; 1431 1432 /* 1433 * - Position constraining - 1434 * Constrain the position to a mix of grid, containment. 1435 */ 1436 1437 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 1438 if(this.containment) { 1439 if (this.relative_container){ 1440 co = this.relative_container.offset(); 1441 containment = [ this.containment[0] + co.left, 1442 this.containment[1] + co.top, 1443 this.containment[2] + co.left, 1444 this.containment[3] + co.top ]; 1445 } 1446 else { 1447 containment = this.containment; 1448 } 1449 1450 if(event.pageX - this.offset.click.left < containment[0]) { 1451 pageX = containment[0] + this.offset.click.left; 1452 } 1453 if(event.pageY - this.offset.click.top < containment[1]) { 1454 pageY = containment[1] + this.offset.click.top; 1455 } 1456 if(event.pageX - this.offset.click.left > containment[2]) { 1457 pageX = containment[2] + this.offset.click.left; 1458 } 1459 if(event.pageY - this.offset.click.top > containment[3]) { 1460 pageY = containment[3] + this.offset.click.top; 1461 } 1462 } 1463 1464 if(o.grid) { 1465 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1466 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1467 pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; 1468 1469 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1470 pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; 1471 } 1472 1473 } 1474 1475 return { 1476 top: ( 1477 pageY - // The absolute mouse position 1478 this.offset.click.top - // Click offset (relative to the element) 1479 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 1480 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 1481 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 1482 ), 1483 left: ( 1484 pageX - // The absolute mouse position 1485 this.offset.click.left - // Click offset (relative to the element) 1486 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 1487 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 1488 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 1489 ) 1490 }; 1491 1492 }, 1493 1494 _clear: function() { 1495 this.helper.removeClass("ui-draggable-dragging"); 1496 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 1497 this.helper.remove(); 1498 } 1499 this.helper = null; 1500 this.cancelHelperRemoval = false;
1501 }, 1502 1503 // From now on bulk stuff - mainly helpers 1504 1505 _trigger: function(type, event, ui) { 1506 ui = ui || this._uiHash(); 1507 $.ui.plugin.call(this, type, [event, ui]); 1508 //The absolute position has to be recalculated after plugins 1509 if(type === "drag") { 1510 this.positionAbs = this._convertPositionTo("absolute"); 1511 } 1512 return $.Widget.prototype._trigger.call(this, type, event, ui); 1513 }, 1514 1515 plugins: {}, 1516 1517 _uiHash: function() { 1518 return { 1519 helper: this.helper, 1520 position: this.position, 1521 originalPosition: this.originalPosition, 1522 offset: this.positionAbs 1523 }; 1524 } 1525 1526}); 1527 1528$.ui.plugin.add("draggable", "connectToSortable", { 1529 start: function(event, ui) { 1530 1531 var inst = $(this).data("ui-draggable"), o = inst.options, 1532 uiSortable = $.extend({}, ui, { item: inst.element }); 1533 inst.sortables = []; 1534 $(o.connectToSortable).each(function() { 1535 var sortable = $.data(this, "ui-sortable"); 1536 if (sortable && !sortable.options.disabled) { 1537 inst.sortables.push({ 1538 instance: sortable, 1539 shouldRevert: sortable.options.revert 1540 }); 1541 sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). 1542 sortable._trigger("activate", event, uiSortable); 1543 } 1544 }); 1545 1546 }, 1547 stop: function(event, ui) { 1548 1549 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 1550 var inst = $(this).data("ui-draggable"), 1551 uiSortable = $.extend({}, ui, { item: inst.element }); 1552 1553 $.each(inst.sortables, function() { 1554 if(this.instance.isOver) { 1555 1556 this.instance.isOver = 0; 1557 1558 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 1559 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 1560 1561 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 1562 if(this.shouldRevert) { 1563 this.instance.options.revert = this.shouldRevert; 1564 } 1565 1566 //Trigger the stop of the sortable 1567 this.instance._mouseStop(event); 1568 1569 this.instance.options.helper = this.instance.options._helper; 1570 1571 //If the helper has been the original item, restore properties in the sortable 1572 if(inst.options.helper === "original") { 1573 this.instance.currentItem.css({ top: "auto", left: "auto" }); 1574 } 1575 1576 } else { 1577 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 1578 this.instance._trigger("deactivate", event, uiSortable); 1579 } 1580 1581 }); 1582 1583 }, 1584 drag: function(event, ui) { 1585 1586 var inst = $(this).data("ui-draggable"), that = this; 1587 1588 $.each(inst.sortables, function() { 1589 1590 var innermostIntersecting = false, 1591 thisSortable = this; 1592 1593 //Copy over some variables to allow calling the sortable's native _intersectsWith 1594 this.instance.positionAbs = inst.positionAbs; 1595 this.instance.helperProportions = inst.helperProportions; 1596 this.instance.offset.click = inst.offset.click; 1597 1598 if(this.instance._intersectsWith(this.instance.containerCache)) { 1599 innermostIntersecting = true; 1600 $.each(inst.sortables, function () { 1601 this.instance.positionAbs = inst.positionAbs; 1602 this.instance.helperProportions = inst.helperProportions; 1603 this.instance.offset.click = inst.offset.click; 1604 if (this !== thisSortable && 1605 this.instance._intersectsWith(this.instance.containerCache) && 1606 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 1607 ) { 1608 innermostIntersecting = false; 1609 } 1610 return innermostIntersecting; 1611 }); 1612 } 1613 1614 1615 if(innermostIntersecting) { 1616 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 1617 if(!this.instance.isOver) { 1618 1619 this.instance.isOver = 1; 1620 //Now we fake the start of dragging for the sortable instance, 1621 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 1622 //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) 1623 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 1624 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 1625 this.instance.options.helper = function() { return ui.helper[0]; }; 1626 1627 event.target = this.instance.currentItem[0]; 1628 this.instance._mouseCapture(event, true); 1629 this.instance._mouseStart(event, true, true); 1630
1631 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 1632 this.instance.offset.click.top = inst.offset.click.top; 1633 this.instance.offset.click.left = inst.offset.click.left; 1634 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 1635 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 1636 1637 inst._trigger("toSortable", event); 1638 inst.dropped = this.instance.element; //draggable revert needs that 1639 //hack so receive/update callbacks work (mostly) 1640 inst.currentItem = inst.element; 1641 this.instance.fromOutside = inst; 1642 1643 } 1644 1645 //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 1646 if(this.instance.currentItem) { 1647 this.instance._mouseDrag(event); 1648 } 1649 1650 } else { 1651 1652 //If it doesn't intersect with the sortable, and it intersected before, 1653 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 1654 if(this.instance.isOver) { 1655 1656 this.instance.isOver = 0; 1657 this.instance.cancelHelperRemoval = true; 1658 1659 //Prevent reverting on this forced stop 1660 this.instance.options.revert = false; 1661 1662 // The out event needs to be triggered independently 1663 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 1664 1665 this.instance._mouseStop(event, true); 1666 this.instance.options.helper = this.instance.options._helper; 1667 1668 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 1669 this.instance.currentItem.remove(); 1670 if(this.instance.placeholder) { 1671 this.instance.placeholder.remove(); 1672 } 1673 1674 inst._trigger("fromSortable", event); 1675 inst.dropped = false; //draggable revert needs that 1676 } 1677 1678 } 1679 1680 }); 1681 1682 } 1683}); 1684 1685$.ui.plugin.add("draggable", "cursor", { 1686 start: function() { 1687 var t = $("body"), o = $(this).data("ui-draggable").options; 1688 if (t.css("cursor")) { 1689 o._cursor = t.css("cursor"); 1690 } 1691 t.css("cursor", o.cursor); 1692 }, 1693 stop: function() { 1694 var o = $(this).data("ui-draggable").options; 1695 if (o._cursor) { 1696 $("body").css("cursor", o._cursor); 1697 } 1698 } 1699}); 1700 1701$.ui.plugin.add("draggable", "opacity", { 1702 start: function(event, ui) { 1703 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1704 if(t.css("opacity")) { 1705 o._opacity = t.css("opacity"); 1706 } 1707 t.css("opacity", o.opacity); 1708 }, 1709 stop: function(event, ui) { 1710 var o = $(this).data("ui-draggable").options; 1711 if(o._opacity) { 1712 $(ui.helper).css("opacity", o._opacity); 1713 } 1714 } 1715}); 1716 1717$.ui.plugin.add("draggable", "scroll", { 1718 start: function() { 1719 var i = $(this).data("ui-draggable"); 1720 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1721 i.overflowOffset = i.scrollParent.offset(); 1722 } 1723 }, 1724 drag: function( event ) { 1725 1726 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 1727 1728 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1729 1730 if(!o.axis || o.axis !== "x") { 1731 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 1732 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 1733 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 1734 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 1735 } 1736 } 1737 1738 if(!o.axis || o.axis !== "y") { 1739 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 1740 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 1741 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 1742 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 1743 } 1744 } 1745 1746 } else { 1747 1748 if(!o.axis || o.axis !== "x") { 1749 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 1750 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 1751 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 1752 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 1753 } 1754 } 1755 1756 if(!o.axis || o.axis !== "y") { 1757 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 1758 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 1759 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 1760 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 1761 } 1762 } 1763 1764 } 1765 1766 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 1767 $.ui.ddmanager.prepareOffsets(i, event); 1768 } 1769 1770 } 1771}); 1772 1773$.ui.plugin.add("draggable", "snap", { 1774 start: function() { 1775 1776 var i = $(this).data("ui-draggable"), 1777 o = i.options; 1778 1779 i.snapElements = []; 1780 1781 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 1782 var $t = $(this), 1783 $o = $t.offset(); 1784 if(this !== i.element[0]) { 1785 i.snapElements.push({ 1786 item: this, 1787 width: $t.outerWidth(), height: $t.outerHeight(), 1788 top: $o.top, left: $o.left 1789 }); 1790 } 1791 }); 1792 1793 }, 1794 drag: function(event, ui) { 1795 1796 var ts, bs, ls, rs, l, r, t, b, i, first, 1797 inst = $(this).data("ui-draggable"), 1798 o = inst.options, 1799 d = o.snapTolerance, 1800 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 1801 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 1802 1803 for (i = inst.snapElements.length - 1; i >= 0; i--){ 1804 1805 l = inst.snapElements[i].left; 1806 r = l + inst.snapElements[i].width; 1807 t = inst.snapElements[i].top; 1808 b = t + inst.snapElements[i].height; 1809 1810 //Yes, I know, this is insane ;) 1811 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))) { 1812 if(inst.snapElements[i].snapping) { 1813 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1814 } 1815 inst.snapElements[i].snapping = false;
vendor: 5,789 bytes, lines 1816-2035
1816 continue; 1817 } 1818 1819 if(o.snapMode !== "inner") { 1820 ts = Math.abs(t - y2) <= d; 1821 bs = Math.abs(b - y1) <= d; 1822 ls = Math.abs(l - x2) <= d; 1823 rs = Math.abs(r - x1) <= d; 1824 if(ts) { 1825 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1826 } 1827 if(bs) { 1828 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 1829 } 1830 if(ls) { 1831 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 1832 } 1833 if(rs) { 1834 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 1835 } 1836 } 1837 1838 first = (ts || bs || ls || rs); 1839 1840 if(o.snapMode !== "outer") { 1841 ts = Math.abs(t - y1) <= d; 1842 bs = Math.abs(b - y2) <= d; 1843 ls = Math.abs(l - x1) <= d; 1844 rs = Math.abs(r - x2) <= d; 1845 if(ts) { 1846 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 1847 } 1848 if(bs) { 1849 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1850 } 1851 if(ls) { 1852 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 1853 } 1854 if(rs) { 1855 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 1856 } 1857 } 1858 1859 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 1860 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1861 } 1862 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 1863 1864 } 1865 1866 } 1867}); 1868 1869$.ui.plugin.add("draggable", "stack", { 1870 start: function() { 1871 var min, 1872 o = this.data("ui-draggable").options, 1873 group = $.makeArray($(o.stack)).sort(function(a,b) { 1874 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 1875 }); 1876 1877 if (!group.length) { return; } 1878 1879 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 1880 $(group).each(function(i) { 1881 $(this).css("zIndex", min + i); 1882 }); 1883 this.css("zIndex", (min + group.length)); 1884 } 1885}); 1886 1887$.ui.plugin.add("draggable", "zIndex", { 1888 start: function(event, ui) { 1889 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1890 if(t.css("zIndex")) { 1891 o._zIndex = t.css("zIndex"); 1892 } 1893 t.css("zIndex", o.zIndex); 1894 }, 1895 stop: function(event, ui) { 1896 var o = $(this).data("ui-draggable").options; 1897 if(o._zIndex) { 1898 $(ui.helper).css("zIndex", o._zIndex); 1899 } 1900 } 1901}); 1902 1903})(jQuery); 1904 1905(function( $, undefined ) { 1906 1907function isOverAxis( x, reference, size ) { 1908 return ( x > reference ) && ( x < ( reference + size ) ); 1909} 1910 1911$.widget("ui.droppable", { 1912 version: "1.10.2", 1913 widgetEventPrefix: "drop", 1914 options: { 1915 accept: "*", 1916 activeClass: false, 1917 addClasses: true, 1918 greedy: false, 1919 hoverClass: false, 1920 scope: "default", 1921 tolerance: "intersect", 1922 1923 // callbacks 1924 activate: null, 1925 deactivate: null, 1926 drop: null, 1927 out: null, 1928 over: null 1929 }, 1930 _create: function() { 1931 1932 var o = this.options, 1933 accept = o.accept; 1934 1935 this.isover = false; 1936 this.isout = true; 1937 1938 this.accept = $.isFunction(accept) ? accept : function(d) { 1939 return d.is(accept); 1940 }; 1941 1942 //Store the droppable's proportions 1943 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 1944 1945 // Add the reference and positions to the manager 1946 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 1947 $.ui.ddmanager.droppables[o.scope].push(this); 1948 1949 (o.addClasses && this.element.addClass("ui-droppable")); 1950 1951 }, 1952 1953 _destroy: function() { 1954 var i = 0, 1955 drop = $.ui.ddmanager.droppables[this.options.scope]; 1956 1957 for ( ; i < drop.length; i++ ) { 1958 if ( drop[i] === this ) { 1959 drop.splice(i, 1); 1960 } 1961 } 1962 1963 this.element.removeClass("ui-droppable ui-droppable-disabled"); 1964 }, 1965 1966 _setOption: function(key, value) { 1967 1968 if(key === "accept") { 1969 this.accept = $.isFunction(value) ? value : function(d) { 1970 return d.is(value); 1971 }; 1972 } 1973 $.Widget.prototype._setOption.apply(this, arguments); 1974 }, 1975 1976 _activate: function(event) { 1977 var draggable = $.ui.ddmanager.current; 1978 if(this.options.activeClass) { 1979 this.element.addClass(this.options.activeClass); 1980 } 1981 if(draggable){ 1982 this._trigger("activate", event, this.ui(draggable)); 1983 } 1984 }, 1985 1986 _deactivate: function(event) { 1987 var draggable = $.ui.ddmanager.current; 1988 if(this.options.activeClass) { 1989 this.element.removeClass(this.options.activeClass); 1990 } 1991 if(draggable){ 1992 this._trigger("deactivate", event, this.ui(draggable)); 1993 } 1994 }, 1995 1996 _over: function(event) { 1997 1998 var draggable = $.ui.ddmanager.current; 1999 2000 // Bail if draggable and droppable are same element 2001 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2002 return; 2003 } 2004 2005 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2006 if(this.options.hoverClass) { 2007 this.element.addClass(this.options.hoverClass); 2008 } 2009 this._trigger("over", event, this.ui(draggable)); 2010 } 2011 2012 }, 2013 2014 _out: function(event) { 2015 2016 var draggable = $.ui.ddmanager.current; 2017 2018 // Bail if draggable and droppable are same element 2019 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2020 return; 2021 } 2022 2023 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2024 if(this.options.hoverClass) { 2025 this.element.removeClass(this.options.hoverClass); 2026 } 2027 this._trigger("out", event, this.ui(draggable)); 2028 } 2029 2030 }, 2031 2032 _drop: function(event,custom) { 2033 2034 var draggable = custom || $.ui.ddmanager.current, 2035 childrenIntersection = false;
2036 2037 // Bail if draggable and droppable are same element 2038 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2039 return false; 2040 } 2041 2042 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 2043 var inst = $.data(this, "ui-droppable"); 2044 if( 2045 inst.options.greedy && 2046 !inst.options.disabled && 2047 inst.options.scope === draggable.options.scope && 2048 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 2049 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2050 ) { childrenIntersection = true; return false; } 2051 }); 2052 if(childrenIntersection) { 2053 return false; 2054 } 2055 2056 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2057 if(this.options.activeClass) { 2058 this.element.removeClass(this.options.activeClass); 2059 } 2060 if(this.options.hoverClass) { 2061 this.element.removeClass(this.options.hoverClass); 2062 } 2063 this._trigger("drop", event, this.ui(draggable)); 2064 return this.element; 2065 } 2066 2067 return false; 2068 2069 }, 2070 2071 ui: function(c) { 2072 return { 2073 draggable: (c.currentItem || c.element), 2074 helper: c.helper, 2075 position: c.position, 2076 offset: c.positionAbs 2077 }; 2078 } 2079 2080}); 2081 2082$.ui.intersect = function(draggable, droppable, toleranceMode) { 2083 2084 if (!droppable.offset) { 2085 return false; 2086 } 2087 2088 var draggableLeft, draggableTop, 2089 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 2090 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, 2091 l = droppable.offset.left, r = l + droppable.proportions.width, 2092 t = droppable.offset.top, b = t + droppable.proportions.height; 2093 2094 switch (toleranceMode) { 2095 case "fit": 2096 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 2097 case "intersect": 2098 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half 2099 x2 - (draggable.helperProportions.width / 2) < r && // Left Half 2100 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half 2101 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 2102 case "pointer": 2103 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 2104 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 2105 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); 2106 case "touch": 2107 return ( 2108 (y1 >= t && y1 <= b) || // Top edge touching 2109 (y2 >= t && y2 <= b) || // Bottom edge touching 2110 (y1 < t && y2 > b) // Surrounded vertically 2111 ) && ( 2112 (x1 >= l && x1 <= r) || // Left edge touching 2113 (x2 >= l && x2 <= r) || // Right edge touching 2114 (x1 < l && x2 > r) // Surrounded horizontally 2115 ); 2116 default: 2117 return false; 2118 } 2119 2120}; 2121 2122/* 2123 This manager tracks offsets of draggables and droppables 2124*/ 2125$.ui.ddmanager = { 2126 current: null, 2127 droppables: { "default": [] }, 2128 prepareOffsets: function(t, event) { 2129 2130 var i, j, 2131 m = $.ui.ddmanager.droppables[t.options.scope] || [], 2132 type = event ? event.type : null, // workaround for #2317 2133 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 2134 2135 droppablesLoop: for (i = 0; i < m.length; i++) { 2136 2137 //No disabled and non-accepted 2138 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 2139 continue; 2140 } 2141 2142 // Filter out elements in the current dragged item 2143 for (j=0; j < list.length; j++) { 2144 if(list[j] === m[i].element[0]) { 2145 m[i].proportions.height = 0; 2146 continue droppablesLoop; 2147 } 2148 } 2149 2150 m[i].visible = m[i].element.css("display") !== "none"; 2151 if(!m[i].visible) { 2152 continue; 2153 } 2154 2155 //Activate the droppable if used directly from draggables 2156 if(type === "mousedown") { 2157 m[i]._activate.call(m[i], event); 2158 } 2159 2160 m[i].offset = m[i].element.offset(); 2161 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2162 2163 } 2164 2165 }, 2166 drop: function(draggable, event) { 2167 2168 var dropped = false;
vendor: 22,518 bytes, lines 2169-2958
2169 // Create a copy of the droppables in case the list changes during the drop (#9116) 2170 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { 2171 2172 if(!this.options) { 2173 return; 2174 } 2175 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 2176 dropped = this._drop.call(this, event) || dropped; 2177 } 2178 2179 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2180 this.isout = true; 2181 this.isover = false; 2182 this._deactivate.call(this, event); 2183 } 2184 2185 }); 2186 return dropped; 2187 2188 }, 2189 dragStart: function( draggable, event ) { 2190 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2191 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2192 if( !draggable.options.refreshPositions ) { 2193 $.ui.ddmanager.prepareOffsets( draggable, event ); 2194 } 2195 }); 2196 }, 2197 drag: function(draggable, event) { 2198 2199 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2200 if(draggable.options.refreshPositions) { 2201 $.ui.ddmanager.prepareOffsets(draggable, event); 2202 } 2203 2204 //Run through all droppables and check their positions based on specific tolerance options 2205 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2206 2207 if(this.options.disabled || this.greedyChild || !this.visible) { 2208 return; 2209 } 2210 2211 var parentInstance, scope, parent, 2212 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 2213 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 2214 if(!c) { 2215 return; 2216 } 2217 2218 if (this.options.greedy) { 2219 // find droppable parents with same scope 2220 scope = this.options.scope; 2221 parent = this.element.parents(":data(ui-droppable)").filter(function () { 2222 return $.data(this, "ui-droppable").options.scope === scope; 2223 }); 2224 2225 if (parent.length) { 2226 parentInstance = $.data(parent[0], "ui-droppable"); 2227 parentInstance.greedyChild = (c === "isover"); 2228 } 2229 } 2230 2231 // we just moved into a greedy child 2232 if (parentInstance && c === "isover") { 2233 parentInstance.isover = false; 2234 parentInstance.isout = true; 2235 parentInstance._out.call(parentInstance, event); 2236 } 2237 2238 this[c] = true; 2239 this[c === "isout" ? "isover" : "isout"] = false; 2240 this[c === "isover" ? "_over" : "_out"].call(this, event); 2241 2242 // we just moved out of a greedy child 2243 if (parentInstance && c === "isout") { 2244 parentInstance.isout = false; 2245 parentInstance.isover = true; 2246 parentInstance._over.call(parentInstance, event); 2247 } 2248 }); 2249 2250 }, 2251 dragStop: function( draggable, event ) { 2252 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2253 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2254 if( !draggable.options.refreshPositions ) { 2255 $.ui.ddmanager.prepareOffsets( draggable, event ); 2256 } 2257 } 2258}; 2259 2260})(jQuery); 2261 2262(function( $, undefined ) { 2263 2264function num(v) { 2265 return parseInt(v, 10) || 0; 2266} 2267 2268function isNumber(value) { 2269 return !isNaN(parseInt(value, 10)); 2270} 2271 2272$.widget("ui.resizable", $.ui.mouse, { 2273 version: "1.10.2", 2274 widgetEventPrefix: "resize", 2275 options: { 2276 alsoResize: false, 2277 animate: false, 2278 animateDuration: "slow", 2279 animateEasing: "swing", 2280 aspectRatio: false, 2281 autoHide: false, 2282 containment: false, 2283 ghost: false, 2284 grid: false, 2285 handles: "e,s,se", 2286 helper: false, 2287 maxHeight: null, 2288 maxWidth: null, 2289 minHeight: 10, 2290 minWidth: 10, 2291 // See #7960 2292 zIndex: 90, 2293 2294 // callbacks 2295 resize: null, 2296 start: null, 2297 stop: null 2298 }, 2299 _create: function() { 2300 2301 var n, i, handle, axis, hname, 2302 that = this, 2303 o = this.options; 2304 this.element.addClass("ui-resizable"); 2305 2306 $.extend(this, { 2307 _aspectRatio: !!(o.aspectRatio), 2308 aspectRatio: o.aspectRatio, 2309 originalElement: this.element, 2310 _proportionallyResizeElements: [], 2311 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 2312 }); 2313 2314 //Wrap the element if it cannot hold child nodes 2315 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2316 2317 //Create a wrapper element and set the wrapper to the new current internal element 2318 this.element.wrap( 2319 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 2320 position: this.element.css("position"), 2321 width: this.element.outerWidth(), 2322 height: this.element.outerHeight(), 2323 top: this.element.css("top"), 2324 left: this.element.css("left") 2325 }) 2326 ); 2327 2328 //Overwrite the original this.element 2329 this.element = this.element.parent().data( 2330 "ui-resizable", this.element.data("ui-resizable") 2331 ); 2332 2333 this.elementIsWrapper = true; 2334 2335 //Move margins to the wrapper 2336 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2337 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2338 2339 //Prevent Safari textarea resize 2340 this.originalResizeStyle = this.originalElement.css("resize"); 2341 this.originalElement.css("resize", "none"); 2342 2343 //Push the actual element to our proportionallyResize internal array 2344 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 2345 2346 // avoid IE jump (hard set the margin) 2347 this.originalElement.css({ margin: this.originalElement.css("margin") }); 2348 2349 // fix handlers offset 2350 this._proportionallyResize(); 2351 2352 } 2353 2354 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" }); 2355 if(this.handles.constructor === String) { 2356 2357 if ( this.handles === "all") { 2358 this.handles = "n,e,s,w,se,sw,ne,nw"; 2359 } 2360 2361 n = this.handles.split(","); 2362 this.handles = {}; 2363 2364 for(i = 0; i < n.length; i++) { 2365 2366 handle = $.trim(n[i]); 2367 hname = "ui-resizable-"+handle; 2368 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 2369 2370 // Apply zIndex to all handles - see #7960 2371 axis.css({ zIndex: o.zIndex }); 2372 2373 //TODO : What's going on here? 2374 if ("se" === handle) { 2375 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 2376 } 2377 2378 //Insert into internal handles object and append to element 2379 this.handles[handle] = ".ui-resizable-"+handle; 2380 this.element.append(axis); 2381 } 2382 2383 } 2384 2385 this._renderAxis = function(target) { 2386 2387 var i, axis, padPos, padWrapper; 2388 2389 target = target || this.element; 2390 2391 for(i in this.handles) { 2392 2393 if(this.handles[i].constructor === String) { 2394 this.handles[i] = $(this.handles[i], this.element).show(); 2395 } 2396 2397 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2398 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2399 2400 axis = $(this.handles[i], this.element); 2401 2402 //Checking the correct pad and border 2403 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2404 2405 //The padding type i have to apply... 2406 padPos = [ "padding", 2407 /ne|nw|n/.test(i) ? "Top" : 2408 /se|sw|s/.test(i) ? "Bottom" : 2409 /^e$/.test(i) ? "Right" : "Left" ].join(""); 2410 2411 target.css(padPos, padWrapper); 2412 2413 this._proportionallyResize(); 2414 2415 } 2416 2417 //TODO: What's that good for? There's not anything to be executed left 2418 if(!$(this.handles[i]).length) { 2419 continue; 2420 } 2421 } 2422 }; 2423 2424 //TODO: make renderAxis a prototype function 2425 this._renderAxis(this.element); 2426 2427 this._handles = $(".ui-resizable-handle", this.element) 2428 .disableSelection(); 2429 2430 //Matching axis name 2431 this._handles.mouseover(function() { 2432 if (!that.resizing) { 2433 if (this.className) { 2434 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2435 } 2436 //Axis, default = se 2437 that.axis = axis && axis[1] ? axis[1] : "se"; 2438 } 2439 }); 2440 2441 //If we want to auto hide the elements 2442 if (o.autoHide) { 2443 this._handles.hide(); 2444 $(this.element) 2445 .addClass("ui-resizable-autohide") 2446 .mouseenter(function() { 2447 if (o.disabled) { 2448 return; 2449 } 2450 $(this).removeClass("ui-resizable-autohide"); 2451 that._handles.show(); 2452 }) 2453 .mouseleave(function(){ 2454 if (o.disabled) { 2455 return; 2456 } 2457 if (!that.resizing) { 2458 $(this).addClass("ui-resizable-autohide"); 2459 that._handles.hide(); 2460 } 2461 }); 2462 } 2463 2464 //Initialize the mouse interaction 2465 this._mouseInit(); 2466 2467 }, 2468 2469 _destroy: function() { 2470 2471 this._mouseDestroy(); 2472 2473 var wrapper, 2474 _destroy = function(exp) { 2475 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2476 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 2477 }; 2478 2479 //TODO: Unwrap at same DOM position 2480 if (this.elementIsWrapper) { 2481 _destroy(this.element); 2482 wrapper = this.element; 2483 this.originalElement.css({ 2484 position: wrapper.css("position"), 2485 width: wrapper.outerWidth(), 2486 height: wrapper.outerHeight(), 2487 top: wrapper.css("top"), 2488 left: wrapper.css("left") 2489 }).insertAfter( wrapper ); 2490 wrapper.remove(); 2491 } 2492 2493 this.originalElement.css("resize", this.originalResizeStyle); 2494 _destroy(this.originalElement); 2495 2496 return this; 2497 }, 2498 2499 _mouseCapture: function(event) { 2500 var i, handle, 2501 capture = false; 2502 2503 for (i in this.handles) { 2504 handle = $(this.handles[i])[0]; 2505 if (handle === event.target || $.contains(handle, event.target)) { 2506 capture = true; 2507 } 2508 } 2509 2510 return !this.options.disabled && capture; 2511 }, 2512 2513 _mouseStart: function(event) { 2514 2515 var curleft, curtop, cursor, 2516 o = this.options, 2517 iniPos = this.element.position(), 2518 el = this.element; 2519 2520 this.resizing = true; 2521 2522 // bugfix for http://dev.jquery.com/ticket/1749 2523 if ( (/absolute/).test( el.css("position") ) ) { 2524 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 2525 } else if (el.is(".ui-draggable")) { 2526 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 2527 } 2528 2529 this._renderProxy(); 2530 2531 curleft = num(this.helper.css("left")); 2532 curtop = num(this.helper.css("top")); 2533 2534 if (o.containment) { 2535 curleft += $(o.containment).scrollLeft() || 0; 2536 curtop += $(o.containment).scrollTop() || 0; 2537 } 2538 2539 //Store needed variables 2540 this.offset = this.helper.offset(); 2541 this.position = { left: curleft, top: curtop }; 2542 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2543 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2544 this.originalPosition = { left: curleft, top: curtop }; 2545 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 2546 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2547 2548 //Aspect Ratio 2549 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 2550 2551 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 2552 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 2553 2554 el.addClass("ui-resizable-resizing"); 2555 this._propagate("start", event); 2556 return true; 2557 }, 2558 2559 _mouseDrag: function(event) { 2560 2561 //Increase performance, avoid regex 2562 var data, 2563 el = this.helper, props = {}, 2564 smp = this.originalMousePosition, 2565 a = this.axis, 2566 prevTop = this.position.top, 2567 prevLeft = this.position.left, 2568 prevWidth = this.size.width, 2569 prevHeight = this.size.height, 2570 dx = (event.pageX-smp.left)||0, 2571 dy = (event.pageY-smp.top)||0, 2572 trigger = this._change[a]; 2573 2574 if (!trigger) { 2575 return false; 2576 } 2577 2578 // Calculate the attrs that will be change 2579 data = trigger.apply(this, [event, dx, dy]); 2580 2581 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 2582 this._updateVirtualBoundaries(event.shiftKey); 2583 if (this._aspectRatio || event.shiftKey) { 2584 data = this._updateRatio(data, event); 2585 } 2586 2587 data = this._respectSize(data, event); 2588 2589 this._updateCache(data); 2590 2591 // plugins callbacks need to be called first 2592 this._propagate("resize", event); 2593 2594 if (this.position.top !== prevTop) { 2595 props.top = this.position.top + "px"; 2596 } 2597 if (this.position.left !== prevLeft) { 2598 props.left = this.position.left + "px"; 2599 } 2600 if (this.size.width !== prevWidth) { 2601 props.width = this.size.width + "px"; 2602 } 2603 if (this.size.height !== prevHeight) { 2604 props.height = this.size.height + "px"; 2605 } 2606 el.css(props); 2607 2608 if (!this._helper && this._proportionallyResizeElements.length) { 2609 this._proportionallyResize(); 2610 } 2611 2612 // Call the user callback if the element was resized 2613 if ( ! $.isEmptyObject(props) ) { 2614 this._trigger("resize", event, this.ui()); 2615 } 2616 2617 return false; 2618 }, 2619 2620 _mouseStop: function(event) { 2621 2622 this.resizing = false; 2623 var pr, ista, soffseth, soffsetw, s, left, top, 2624 o = this.options, that = this; 2625 2626 if(this._helper) { 2627 2628 pr = this._proportionallyResizeElements; 2629 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 2630 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 2631 soffsetw = ista ? 0 : that.sizeDiff.width; 2632 2633 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 2634 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 2635 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2636 2637 if (!o.animate) { 2638 this.element.css($.extend(s, { top: top, left: left })); 2639 } 2640 2641 that.helper.height(that.size.height); 2642 that.helper.width(that.size.width); 2643 2644 if (this._helper && !o.animate) { 2645 this._proportionallyResize(); 2646 } 2647 } 2648 2649 $("body").css("cursor", "auto"); 2650 2651 this.element.removeClass("ui-resizable-resizing"); 2652 2653 this._propagate("stop", event); 2654 2655 if (this._helper) { 2656 this.helper.remove(); 2657 } 2658 2659 return false; 2660 2661 }, 2662 2663 _updateVirtualBoundaries: function(forceAspectRatio) { 2664 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 2665 o = this.options; 2666 2667 b = { 2668 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 2669 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 2670 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 2671 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 2672 }; 2673 2674 if(this._aspectRatio || forceAspectRatio) { 2675 // We want to create an enclosing box whose aspect ration is the requested one 2676 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 2677 pMinWidth = b.minHeight * this.aspectRatio; 2678 pMinHeight = b.minWidth / this.aspectRatio; 2679 pMaxWidth = b.maxHeight * this.aspectRatio; 2680 pMaxHeight = b.maxWidth / this.aspectRatio; 2681 2682 if(pMinWidth > b.minWidth) { 2683 b.minWidth = pMinWidth; 2684 } 2685 if(pMinHeight > b.minHeight) { 2686 b.minHeight = pMinHeight; 2687 } 2688 if(pMaxWidth < b.maxWidth) { 2689 b.maxWidth = pMaxWidth; 2690 } 2691 if(pMaxHeight < b.maxHeight) { 2692 b.maxHeight = pMaxHeight; 2693 } 2694 } 2695 this._vBoundaries = b; 2696 }, 2697 2698 _updateCache: function(data) { 2699 this.offset = this.helper.offset(); 2700 if (isNumber(data.left)) { 2701 this.position.left = data.left; 2702 } 2703 if (isNumber(data.top)) { 2704 this.position.top = data.top; 2705 } 2706 if (isNumber(data.height)) { 2707 this.size.height = data.height; 2708 } 2709 if (isNumber(data.width)) { 2710 this.size.width = data.width; 2711 } 2712 }, 2713 2714 _updateRatio: function( data ) { 2715 2716 var cpos = this.position, 2717 csize = this.size, 2718 a = this.axis; 2719 2720 if (isNumber(data.height)) { 2721 data.width = (data.height * this.aspectRatio); 2722 } else if (isNumber(data.width)) { 2723 data.height = (data.width / this.aspectRatio); 2724 } 2725 2726 if (a === "sw") { 2727 data.left = cpos.left + (csize.width - data.width); 2728 data.top = null; 2729 } 2730 if (a === "nw") { 2731 data.top = cpos.top + (csize.height - data.height); 2732 data.left = cpos.left + (csize.width - data.width); 2733 } 2734 2735 return data; 2736 }, 2737 2738 _respectSize: function( data ) { 2739 2740 var o = this._vBoundaries, 2741 a = this.axis, 2742 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 2743 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 2744 dw = this.originalPosition.left + this.originalSize.width, 2745 dh = this.position.top + this.size.height, 2746 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 2747 if (isminw) { 2748 data.width = o.minWidth; 2749 } 2750 if (isminh) { 2751 data.height = o.minHeight; 2752 } 2753 if (ismaxw) { 2754 data.width = o.maxWidth; 2755 } 2756 if (ismaxh) { 2757 data.height = o.maxHeight; 2758 } 2759 2760 if (isminw && cw) { 2761 data.left = dw - o.minWidth; 2762 } 2763 if (ismaxw && cw) { 2764 data.left = dw - o.maxWidth; 2765 } 2766 if (isminh && ch) { 2767 data.top = dh - o.minHeight; 2768 } 2769 if (ismaxh && ch) { 2770 data.top = dh - o.maxHeight; 2771 } 2772 2773 // fixing jump error on top/left - bug #2330 2774 if (!data.width && !data.height && !data.left && data.top) { 2775 data.top = null; 2776 } else if (!data.width && !data.height && !data.top && data.left) { 2777 data.left = null; 2778 } 2779 2780 return data; 2781 }, 2782 2783 _proportionallyResize: function() { 2784 2785 if (!this._proportionallyResizeElements.length) { 2786 return; 2787 } 2788 2789 var i, j, borders, paddings, prel, 2790 element = this.helper || this.element; 2791 2792 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 2793 2794 prel = this._proportionallyResizeElements[i]; 2795 2796 if (!this.borderDif) { 2797 this.borderDif = []; 2798 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 2799 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 2800 2801 for ( j = 0; j < borders.length; j++ ) { 2802 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 2803 } 2804 } 2805 2806 prel.css({ 2807 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 2808 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 2809 }); 2810 2811 } 2812 2813 }, 2814 2815 _renderProxy: function() { 2816 2817 var el = this.element, o = this.options; 2818 this.elementOffset = el.offset(); 2819 2820 if(this._helper) { 2821 2822 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 2823 2824 this.helper.addClass(this._helper).css({ 2825 width: this.element.outerWidth() - 1, 2826 height: this.element.outerHeight() - 1, 2827 position: "absolute", 2828 left: this.elementOffset.left +"px", 2829 top: this.elementOffset.top +"px", 2830 zIndex: ++o.zIndex //TODO: Don't modify option 2831 }); 2832 2833 this.helper 2834 .appendTo("body") 2835 .disableSelection(); 2836 2837 } else { 2838 this.helper = this.element; 2839 } 2840 2841 }, 2842 2843 _change: { 2844 e: function(event, dx) { 2845 return { width: this.originalSize.width + dx }; 2846 }, 2847 w: function(event, dx) { 2848 var cs = this.originalSize, sp = this.originalPosition; 2849 return { left: sp.left + dx, width: cs.width - dx }; 2850 }, 2851 n: function(event, dx, dy) { 2852 var cs = this.originalSize, sp = this.originalPosition; 2853 return { top: sp.top + dy, height: cs.height - dy }; 2854 }, 2855 s: function(event, dx, dy) { 2856 return { height: this.originalSize.height + dy }; 2857 }, 2858 se: function(event, dx, dy) { 2859 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2860 }, 2861 sw: function(event, dx, dy) { 2862 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2863 }, 2864 ne: function(event, dx, dy) { 2865 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2866 }, 2867 nw: function(event, dx, dy) { 2868 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2869 } 2870 }, 2871 2872 _propagate: function(n, event) { 2873 $.ui.plugin.call(this, n, [event, this.ui()]); 2874 (n !== "resize" && this._trigger(n, event, this.ui())); 2875 }, 2876 2877 plugins: {}, 2878 2879 ui: function() { 2880 return { 2881 originalElement: this.originalElement, 2882 element: this.element, 2883 helper: this.helper, 2884 position: this.position, 2885 size: this.size, 2886 originalSize: this.originalSize, 2887 originalPosition: this.originalPosition 2888 }; 2889 } 2890 2891}); 2892 2893/* 2894 * Resizable Extensions 2895 */ 2896 2897$.ui.plugin.add("resizable", "animate", { 2898 2899 stop: function( event ) { 2900 var that = $(this).data("ui-resizable"), 2901 o = that.options, 2902 pr = that._proportionallyResizeElements, 2903 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2904 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2905 soffsetw = ista ? 0 : that.sizeDiff.width, 2906 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 2907 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 2908 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2909 2910 that.element.animate( 2911 $.extend(style, top && left ? { top: top, left: left } : {}), { 2912 duration: o.animateDuration, 2913 easing: o.animateEasing, 2914 step: function() { 2915 2916 var data = { 2917 width: parseInt(that.element.css("width"), 10), 2918 height: parseInt(that.element.css("height"), 10), 2919 top: parseInt(that.element.css("top"), 10), 2920 left: parseInt(that.element.css("left"), 10) 2921 }; 2922 2923 if (pr && pr.length) { 2924 $(pr[0]).css({ width: data.width, height: data.height }); 2925 } 2926 2927 // propagating resize, and updating values for each animation step 2928 that._updateCache(data); 2929 that._propagate("resize", event); 2930 2931 } 2932 } 2933 ); 2934 } 2935 2936}); 2937 2938$.ui.plugin.add("resizable", "containment", { 2939 2940 start: function() { 2941 var element, p, co, ch, cw, width, height, 2942 that = $(this).data("ui-resizable"), 2943 o = that.options, 2944 el = that.element, 2945 oc = o.containment, 2946 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 2947 2948 if (!ce) { 2949 return; 2950 } 2951 2952 that.containerElement = $(ce); 2953 2954 if (/document/.test(oc) || oc === document) { 2955 that.containerOffset = { left: 0, top: 0 }; 2956 that.containerPosition = { left: 0, top: 0 }; 2957 2958 that.parentData = {
2959 element: $(document), left: 0, top: 0, 2960 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 2961 }; 2962 } 2963 2964 // i'm a node, so compute top, left, right, bottom 2965 else { 2966 element = $(ce); 2967 p = []; 2968 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 2969 2970 that.containerOffset = element.offset(); 2971 that.containerPosition = element.position(); 2972 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 2973 2974 co = that.containerOffset; 2975 ch = that.containerSize.height; 2976 cw = that.containerSize.width; 2977 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 2978 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 2979 2980 that.parentData = { 2981 element: ce, left: co.left, top: co.top, width: width, height: height 2982 }; 2983 } 2984 }, 2985 2986 resize: function( event ) { 2987 var woset, hoset, isParent, isOffsetRelative, 2988 that = $(this).data("ui-resizable"), 2989 o = that.options, 2990 co = that.containerOffset, cp = that.position, 2991 pRatio = that._aspectRatio || event.shiftKey, 2992 cop = { top:0, left:0 }, ce = that.containerElement; 2993 2994 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 2995 cop = co; 2996 } 2997 2998 if (cp.left < (that._helper ? co.left : 0)) { 2999 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 3000 if (pRatio) { 3001 that.size.height = that.size.width / that.aspectRatio; 3002 } 3003 that.position.left = o.helper ? co.left : 0; 3004 } 3005 3006 if (cp.top < (that._helper ? co.top : 0)) { 3007 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3008 if (pRatio) { 3009 that.size.width = that.size.height * that.aspectRatio; 3010 } 3011 that.position.top = that._helper ? co.top : 0; 3012 } 3013 3014 that.offset.left = that.parentData.left+that.position.left; 3015 that.offset.top = that.parentData.top+that.position.top; 3016 3017 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 3018 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3019 3020 isParent = that.containerElement.get(0) === that.element.parent().get(0); 3021 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 3022 3023 if(isParent && isOffsetRelative) { 3024 woset -= that.parentData.left; 3025 } 3026 3027 if (woset + that.size.width >= that.parentData.width) { 3028 that.size.width = that.parentData.width - woset; 3029 if (pRatio) { 3030 that.size.height = that.size.width / that.aspectRatio; 3031 } 3032 } 3033 3034 if (hoset + that.size.height >= that.parentData.height) { 3035 that.size.height = that.parentData.height - hoset; 3036 if (pRatio) { 3037 that.size.width = that.size.height * that.aspectRatio; 3038 } 3039 } 3040 }, 3041 3042 stop: function(){ 3043 var that = $(this).data("ui-resizable"), 3044 o = that.options, 3045 co = that.containerOffset, 3046 cop = that.containerPosition, 3047 ce = that.containerElement, 3048 helper = $(that.helper), 3049 ho = helper.offset(), 3050 w = helper.outerWidth() - that.sizeDiff.width, 3051 h = helper.outerHeight() - that.sizeDiff.height; 3052 3053 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 3054 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3055 } 3056 3057 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 3058 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3059 } 3060 3061 } 3062}); 3063 3064$.ui.plugin.add("resizable", "alsoResize", { 3065 3066 start: function () { 3067 var that = $(this).data("ui-resizable"), 3068 o = that.options, 3069 _store = function (exp) { 3070 $(exp).each(function() { 3071 var el = $(this); 3072 el.data("ui-resizable-alsoresize", { 3073 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3074 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 3075 }); 3076 }); 3077 }; 3078 3079 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 3080 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3081 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3082 }else{ 3083 _store(o.alsoResize); 3084 } 3085 }, 3086 3087 resize: function (event, ui) { 3088 var that = $(this).data("ui-resizable"), 3089 o = that.options, 3090 os = that.originalSize, 3091 op = that.originalPosition, 3092 delta = { 3093 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3094 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3095 }, 3096 3097 _alsoResize = function (exp, c) { 3098 $(exp).each(function() { 3099 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 3100 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 3101
vendor: 32,517 bytes, lines 3102-4254
3102 $.each(css, function (i, prop) { 3103 var sum = (start[prop]||0) + (delta[prop]||0); 3104 if (sum && sum >= 0) { 3105 style[prop] = sum || null; 3106 } 3107 }); 3108 3109 el.css(style); 3110 }); 3111 }; 3112 3113 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 3114 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3115 }else{ 3116 _alsoResize(o.alsoResize); 3117 } 3118 }, 3119 3120 stop: function () { 3121 $(this).removeData("resizable-alsoresize"); 3122 } 3123}); 3124 3125$.ui.plugin.add("resizable", "ghost", { 3126 3127 start: function() { 3128 3129 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 3130 3131 that.ghost = that.originalElement.clone(); 3132 that.ghost 3133 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3134 .addClass("ui-resizable-ghost") 3135 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 3136 3137 that.ghost.appendTo(that.helper); 3138 3139 }, 3140 3141 resize: function(){ 3142 var that = $(this).data("ui-resizable"); 3143 if (that.ghost) { 3144 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 3145 } 3146 }, 3147 3148 stop: function() { 3149 var that = $(this).data("ui-resizable"); 3150 if (that.ghost && that.helper) { 3151 that.helper.get(0).removeChild(that.ghost.get(0)); 3152 } 3153 } 3154 3155}); 3156 3157$.ui.plugin.add("resizable", "grid", { 3158 3159 resize: function() { 3160 var that = $(this).data("ui-resizable"), 3161 o = that.options, 3162 cs = that.size, 3163 os = that.originalSize, 3164 op = that.originalPosition, 3165 a = that.axis, 3166 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 3167 gridX = (grid[0]||1), 3168 gridY = (grid[1]||1), 3169 ox = Math.round((cs.width - os.width) / gridX) * gridX, 3170 oy = Math.round((cs.height - os.height) / gridY) * gridY, 3171 newWidth = os.width + ox, 3172 newHeight = os.height + oy, 3173 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 3174 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 3175 isMinWidth = o.minWidth && (o.minWidth > newWidth), 3176 isMinHeight = o.minHeight && (o.minHeight > newHeight); 3177 3178 o.grid = grid; 3179 3180 if (isMinWidth) { 3181 newWidth = newWidth + gridX; 3182 } 3183 if (isMinHeight) { 3184 newHeight = newHeight + gridY; 3185 } 3186 if (isMaxWidth) { 3187 newWidth = newWidth - gridX; 3188 } 3189 if (isMaxHeight) { 3190 newHeight = newHeight - gridY; 3191 } 3192 3193 if (/^(se|s|e)$/.test(a)) { 3194 that.size.width = newWidth; 3195 that.size.height = newHeight; 3196 } else if (/^(ne)$/.test(a)) { 3197 that.size.width = newWidth; 3198 that.size.height = newHeight; 3199 that.position.top = op.top - oy; 3200 } else if (/^(sw)$/.test(a)) { 3201 that.size.width = newWidth; 3202 that.size.height = newHeight; 3203 that.position.left = op.left - ox; 3204 } else { 3205 that.size.width = newWidth; 3206 that.size.height = newHeight; 3207 that.position.top = op.top - oy; 3208 that.position.left = op.left - ox; 3209 } 3210 } 3211 3212}); 3213 3214})(jQuery); 3215 3216(function( $, undefined ) { 3217 3218$.widget("ui.selectable", $.ui.mouse, { 3219 version: "1.10.2", 3220 options: { 3221 appendTo: "body", 3222 autoRefresh: true, 3223 distance: 0, 3224 filter: "*", 3225 tolerance: "touch", 3226 3227 // callbacks 3228 selected: null, 3229 selecting: null, 3230 start: null, 3231 stop: null, 3232 unselected: null, 3233 unselecting: null 3234 }, 3235 _create: function() { 3236 var selectees, 3237 that = this; 3238 3239 this.element.addClass("ui-selectable"); 3240 3241 this.dragged = false; 3242 3243 // cache selectee children based on filter 3244 this.refresh = function() { 3245 selectees = $(that.options.filter, that.element[0]); 3246 selectees.addClass("ui-selectee"); 3247 selectees.each(function() { 3248 var $this = $(this), 3249 pos = $this.offset(); 3250 $.data(this, "selectable-item", { 3251 element: this, 3252 $element: $this, 3253 left: pos.left, 3254 top: pos.top, 3255 right: pos.left + $this.outerWidth(), 3256 bottom: pos.top + $this.outerHeight(), 3257 startselected: false, 3258 selected: $this.hasClass("ui-selected"), 3259 selecting: $this.hasClass("ui-selecting"), 3260 unselecting: $this.hasClass("ui-unselecting") 3261 }); 3262 }); 3263 }; 3264 this.refresh(); 3265 3266 this.selectees = selectees.addClass("ui-selectee"); 3267 3268 this._mouseInit(); 3269 3270 this.helper = $("<div class='ui-selectable-helper'></div>"); 3271 }, 3272 3273 _destroy: function() { 3274 this.selectees 3275 .removeClass("ui-selectee") 3276 .removeData("selectable-item"); 3277 this.element 3278 .removeClass("ui-selectable ui-selectable-disabled"); 3279 this._mouseDestroy(); 3280 }, 3281 3282 _mouseStart: function(event) { 3283 var that = this, 3284 options = this.options; 3285 3286 this.opos = [event.pageX, event.pageY]; 3287 3288 if (this.options.disabled) { 3289 return; 3290 } 3291 3292 this.selectees = $(options.filter, this.element[0]); 3293 3294 this._trigger("start", event); 3295 3296 $(options.appendTo).append(this.helper); 3297 // position helper (lasso) 3298 this.helper.css({ 3299 "left": event.pageX, 3300 "top": event.pageY, 3301 "width": 0, 3302 "height": 0 3303 }); 3304 3305 if (options.autoRefresh) { 3306 this.refresh(); 3307 } 3308 3309 this.selectees.filter(".ui-selected").each(function() { 3310 var selectee = $.data(this, "selectable-item"); 3311 selectee.startselected = true; 3312 if (!event.metaKey && !event.ctrlKey) { 3313 selectee.$element.removeClass("ui-selected"); 3314 selectee.selected = false; 3315 selectee.$element.addClass("ui-unselecting"); 3316 selectee.unselecting = true; 3317 // selectable UNSELECTING callback 3318 that._trigger("unselecting", event, { 3319 unselecting: selectee.element 3320 }); 3321 } 3322 }); 3323 3324 $(event.target).parents().addBack().each(function() { 3325 var doSelect, 3326 selectee = $.data(this, "selectable-item"); 3327 if (selectee) { 3328 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 3329 selectee.$element 3330 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3331 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3332 selectee.unselecting = !doSelect; 3333 selectee.selecting = doSelect; 3334 selectee.selected = doSelect; 3335 // selectable (UN)SELECTING callback 3336 if (doSelect) { 3337 that._trigger("selecting", event, { 3338 selecting: selectee.element 3339 }); 3340 } else { 3341 that._trigger("unselecting", event, { 3342 unselecting: selectee.element 3343 }); 3344 } 3345 return false; 3346 } 3347 }); 3348 3349 }, 3350 3351 _mouseDrag: function(event) { 3352 3353 this.dragged = true; 3354 3355 if (this.options.disabled) { 3356 return; 3357 } 3358 3359 var tmp, 3360 that = this, 3361 options = this.options, 3362 x1 = this.opos[0], 3363 y1 = this.opos[1], 3364 x2 = event.pageX, 3365 y2 = event.pageY; 3366 3367 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 3368 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 3369 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3370 3371 this.selectees.each(function() { 3372 var selectee = $.data(this, "selectable-item"), 3373 hit = false; 3374 3375 //prevent helper from being selected if appendTo: selectable 3376 if (!selectee || selectee.element === that.element[0]) { 3377 return; 3378 } 3379 3380 if (options.tolerance === "touch") { 3381 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3382 } else if (options.tolerance === "fit") { 3383 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3384 } 3385 3386 if (hit) { 3387 // SELECT 3388 if (selectee.selected) { 3389 selectee.$element.removeClass("ui-selected"); 3390 selectee.selected = false; 3391 } 3392 if (selectee.unselecting) { 3393 selectee.$element.removeClass("ui-unselecting"); 3394 selectee.unselecting = false; 3395 } 3396 if (!selectee.selecting) { 3397 selectee.$element.addClass("ui-selecting"); 3398 selectee.selecting = true; 3399 // selectable SELECTING callback 3400 that._trigger("selecting", event, { 3401 selecting: selectee.element 3402 }); 3403 } 3404 } else { 3405 // UNSELECT 3406 if (selectee.selecting) { 3407 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3408 selectee.$element.removeClass("ui-selecting"); 3409 selectee.selecting = false; 3410 selectee.$element.addClass("ui-selected"); 3411 selectee.selected = true; 3412 } else { 3413 selectee.$element.removeClass("ui-selecting"); 3414 selectee.selecting = false; 3415 if (selectee.startselected) { 3416 selectee.$element.addClass("ui-unselecting"); 3417 selectee.unselecting = true; 3418 } 3419 // selectable UNSELECTING callback 3420 that._trigger("unselecting", event, { 3421 unselecting: selectee.element 3422 }); 3423 } 3424 } 3425 if (selectee.selected) { 3426 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3427 selectee.$element.removeClass("ui-selected"); 3428 selectee.selected = false; 3429 3430 selectee.$element.addClass("ui-unselecting"); 3431 selectee.unselecting = true; 3432 // selectable UNSELECTING callback 3433 that._trigger("unselecting", event, { 3434 unselecting: selectee.element 3435 }); 3436 } 3437 } 3438 } 3439 }); 3440 3441 return false; 3442 }, 3443 3444 _mouseStop: function(event) { 3445 var that = this; 3446 3447 this.dragged = false; 3448 3449 $(".ui-unselecting", this.element[0]).each(function() { 3450 var selectee = $.data(this, "selectable-item"); 3451 selectee.$element.removeClass("ui-unselecting"); 3452 selectee.unselecting = false; 3453 selectee.startselected = false; 3454 that._trigger("unselected", event, { 3455 unselected: selectee.element 3456 }); 3457 }); 3458 $(".ui-selecting", this.element[0]).each(function() { 3459 var selectee = $.data(this, "selectable-item"); 3460 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 3461 selectee.selecting = false; 3462 selectee.selected = true; 3463 selectee.startselected = true; 3464 that._trigger("selected", event, { 3465 selected: selectee.element 3466 }); 3467 }); 3468 this._trigger("stop", event); 3469 3470 this.helper.remove(); 3471 3472 return false; 3473 } 3474 3475}); 3476 3477})(jQuery); 3478 3479(function( $, undefined ) { 3480 3481/*jshint loopfunc: true */ 3482 3483function isOverAxis( x, reference, size ) { 3484 return ( x > reference ) && ( x < ( reference + size ) ); 3485} 3486 3487function isFloating(item) { 3488 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 3489} 3490 3491$.widget("ui.sortable", $.ui.mouse, { 3492 version: "1.10.2", 3493 widgetEventPrefix: "sort", 3494 ready: false, 3495 options: { 3496 appendTo: "parent", 3497 axis: false, 3498 connectWith: false, 3499 containment: false, 3500 cursor: "auto", 3501 cursorAt: false, 3502 dropOnEmpty: true, 3503 forcePlaceholderSize: false, 3504 forceHelperSize: false, 3505 grid: false, 3506 handle: false, 3507 helper: "original", 3508 items: "> *", 3509 opacity: false, 3510 placeholder: false, 3511 revert: false, 3512 scroll: true, 3513 scrollSensitivity: 20, 3514 scrollSpeed: 20, 3515 scope: "default", 3516 tolerance: "intersect", 3517 zIndex: 1000, 3518 3519 // callbacks 3520 activate: null, 3521 beforeStop: null, 3522 change: null, 3523 deactivate: null, 3524 out: null, 3525 over: null, 3526 receive: null, 3527 remove: null, 3528 sort: null, 3529 start: null, 3530 stop: null, 3531 update: null 3532 }, 3533 _create: function() { 3534 3535 var o = this.options; 3536 this.containerCache = {}; 3537 this.element.addClass("ui-sortable"); 3538 3539 //Get the items 3540 this.refresh(); 3541 3542 //Let's determine if the items are being displayed horizontally 3543 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; 3544 3545 //Let's determine the parent's offset 3546 this.offset = this.element.offset(); 3547 3548 //Initialize mouse events for interaction 3549 this._mouseInit(); 3550 3551 //We're ready to go 3552 this.ready = true; 3553 3554 }, 3555 3556 _destroy: function() { 3557 this.element 3558 .removeClass("ui-sortable ui-sortable-disabled"); 3559 this._mouseDestroy(); 3560 3561 for ( var i = this.items.length - 1; i >= 0; i-- ) { 3562 this.items[i].item.removeData(this.widgetName + "-item"); 3563 } 3564 3565 return this; 3566 }, 3567 3568 _setOption: function(key, value){ 3569 if ( key === "disabled" ) { 3570 this.options[ key ] = value; 3571 3572 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 3573 } else { 3574 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 3575 $.Widget.prototype._setOption.apply(this, arguments); 3576 } 3577 }, 3578 3579 _mouseCapture: function(event, overrideHandle) { 3580 var currentItem = null, 3581 validHandle = false, 3582 that = this; 3583 3584 if (this.reverting) { 3585 return false; 3586 } 3587 3588 if(this.options.disabled || this.options.type === "static") { 3589 return false; 3590 } 3591 3592 //We have to refresh the items data once first 3593 this._refreshItems(event); 3594 3595 //Find out if the clicked node (or one of its parents) is a actual item in this.items 3596 $(event.target).parents().each(function() { 3597 if($.data(this, that.widgetName + "-item") === that) { 3598 currentItem = $(this); 3599 return false; 3600 } 3601 }); 3602 if($.data(event.target, that.widgetName + "-item") === that) { 3603 currentItem = $(event.target); 3604 } 3605 3606 if(!currentItem) { 3607 return false; 3608 } 3609 if(this.options.handle && !overrideHandle) { 3610 $(this.options.handle, currentItem).find("*").addBack().each(function() { 3611 if(this === event.target) { 3612 validHandle = true; 3613 } 3614 }); 3615 if(!validHandle) { 3616 return false; 3617 } 3618 } 3619 3620 this.currentItem = currentItem; 3621 this._removeCurrentsFromItems(); 3622 return true; 3623 3624 }, 3625 3626 _mouseStart: function(event, overrideHandle, noActivation) { 3627 3628 var i, body, 3629 o = this.options; 3630 3631 this.currentContainer = this; 3632 3633 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 3634 this.refreshPositions(); 3635 3636 //Create and append the visible helper 3637 this.helper = this._createHelper(event); 3638 3639 //Cache the helper size 3640 this._cacheHelperProportions(); 3641 3642 /* 3643 * - Position generation - 3644 * This block generates everything position related - it's the core of draggables. 3645 */ 3646 3647 //Cache the margins of the original element 3648 this._cacheMargins(); 3649 3650 //Get the next scrolling parent 3651 this.scrollParent = this.helper.scrollParent(); 3652 3653 //The element's absolute position on the page minus margins 3654 this.offset = this.currentItem.offset(); 3655 this.offset = { 3656 top: this.offset.top - this.margins.top, 3657 left: this.offset.left - this.margins.left 3658 }; 3659 3660 $.extend(this.offset, { 3661 click: { //Where the click happened, relative to the element 3662 left: event.pageX - this.offset.left, 3663 top: event.pageY - this.offset.top 3664 }, 3665 parent: this._getParentOffset(), 3666 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3667 }); 3668 3669 // Only after we got the offset, we can change the helper's position to absolute 3670 // TODO: Still need to figure out a way to make relative sorting possible 3671 this.helper.css("position", "absolute"); 3672 this.cssPosition = this.helper.css("position"); 3673 3674 //Generate the original position 3675 this.originalPosition = this._generatePosition(event); 3676 this.originalPageX = event.pageX; 3677 this.originalPageY = event.pageY; 3678 3679 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 3680 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 3681 3682 //Cache the former DOM position 3683 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 3684 3685 //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 3686 if(this.helper[0] !== this.currentItem[0]) { 3687 this.currentItem.hide(); 3688 } 3689 3690 //Create the placeholder 3691 this._createPlaceholder(); 3692 3693 //Set a containment if given in the options 3694 if(o.containment) { 3695 this._setContainment(); 3696 } 3697 3698 if( o.cursor && o.cursor !== "auto" ) { // cursor option 3699 body = this.document.find( "body" ); 3700 3701 // support: IE 3702 this.storedCursor = body.css( "cursor" ); 3703 body.css( "cursor", o.cursor ); 3704 3705 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 3706 } 3707 3708 if(o.opacity) { // opacity option 3709 if (this.helper.css("opacity")) { 3710 this._storedOpacity = this.helper.css("opacity"); 3711 } 3712 this.helper.css("opacity", o.opacity); 3713 } 3714 3715 if(o.zIndex) { // zIndex option 3716 if (this.helper.css("zIndex")) { 3717 this._storedZIndex = this.helper.css("zIndex"); 3718 } 3719 this.helper.css("zIndex", o.zIndex); 3720 } 3721 3722 //Prepare scrolling 3723 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3724 this.overflowOffset = this.scrollParent.offset(); 3725 } 3726 3727 //Call callbacks 3728 this._trigger("start", event, this._uiHash()); 3729 3730 //Recache the helper size 3731 if(!this._preserveHelperProportions) { 3732 this._cacheHelperProportions(); 3733 } 3734 3735 3736 //Post "activate" events to possible containers 3737 if( !noActivation ) { 3738 for ( i = this.containers.length - 1; i >= 0; i-- ) { 3739 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 3740 } 3741 } 3742 3743 //Prepare possible droppables 3744 if($.ui.ddmanager) { 3745 $.ui.ddmanager.current = this; 3746 } 3747 3748 if ($.ui.ddmanager && !o.dropBehaviour) { 3749 $.ui.ddmanager.prepareOffsets(this, event); 3750 } 3751 3752 this.dragging = true; 3753 3754 this.helper.addClass("ui-sortable-helper"); 3755 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3756 return true; 3757 3758 }, 3759 3760 _mouseDrag: function(event) { 3761 var i, item, itemElement, intersection, 3762 o = this.options, 3763 scrolled = false; 3764 3765 //Compute the helpers position 3766 this.position = this._generatePosition(event); 3767 this.positionAbs = this._convertPositionTo("absolute"); 3768 3769 if (!this.lastPositionAbs) { 3770 this.lastPositionAbs = this.positionAbs; 3771 } 3772 3773 //Do scrolling 3774 if(this.options.scroll) { 3775 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3776 3777 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 3778 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 3779 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 3780 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 3781 } 3782 3783 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 3784 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 3785 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 3786 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 3787 } 3788 3789 } else { 3790 3791 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 3792 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3793 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 3794 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3795 } 3796 3797 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 3798 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3799 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 3800 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3801 } 3802 3803 } 3804 3805 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 3806 $.ui.ddmanager.prepareOffsets(this, event); 3807 } 3808 } 3809 3810 //Regenerate the absolute position used for position checks 3811 this.positionAbs = this._convertPositionTo("absolute"); 3812 3813 //Set the helper position 3814 if(!this.options.axis || this.options.axis !== "y") { 3815 this.helper[0].style.left = this.position.left+"px"; 3816 } 3817 if(!this.options.axis || this.options.axis !== "x") { 3818 this.helper[0].style.top = this.position.top+"px"; 3819 } 3820 3821 //Rearrange 3822 for (i = this.items.length - 1; i >= 0; i--) { 3823 3824 //Cache variables and intersection, continue if no intersection 3825 item = this.items[i]; 3826 itemElement = item.item[0]; 3827 intersection = this._intersectsWithPointer(item); 3828 if (!intersection) { 3829 continue; 3830 } 3831 3832 // Only put the placeholder inside the current Container, skip all 3833 // items form other containers. This works because when moving 3834 // an item from one container to another the 3835 // currentContainer is switched before the placeholder is moved. 3836 // 3837 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 3838 // beetween the outer and inner container. 3839 if (item.instance !== this.currentContainer) { 3840 continue; 3841 } 3842 3843 // cannot intersect with itself 3844 // no useless actions that have been done before 3845 // no action if the item moved is the parent of the item checked 3846 if (itemElement !== this.currentItem[0] && 3847 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 3848 !$.contains(this.placeholder[0], itemElement) && 3849 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 3850 ) { 3851 3852 this.direction = intersection === 1 ? "down" : "up"; 3853 3854 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 3855 this._rearrange(event, item); 3856 } else { 3857 break; 3858 } 3859 3860 this._trigger("change", event, this._uiHash()); 3861 break; 3862 } 3863 } 3864 3865 //Post events to containers 3866 this._contactContainers(event); 3867 3868 //Interconnect with droppables 3869 if($.ui.ddmanager) { 3870 $.ui.ddmanager.drag(this, event); 3871 } 3872 3873 //Call callbacks 3874 this._trigger("sort", event, this._uiHash()); 3875 3876 this.lastPositionAbs = this.positionAbs; 3877 return false; 3878 3879 }, 3880 3881 _mouseStop: function(event, noPropagation) { 3882 3883 if(!event) { 3884 return; 3885 } 3886 3887 //If we are using droppables, inform the manager about the drop 3888 if ($.ui.ddmanager && !this.options.dropBehaviour) { 3889 $.ui.ddmanager.drop(this, event); 3890 } 3891 3892 if(this.options.revert) { 3893 var that = this, 3894 cur = this.placeholder.offset(), 3895 axis = this.options.axis, 3896 animation = {}; 3897 3898 if ( !axis || axis === "x" ) { 3899 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 3900 } 3901 if ( !axis || axis === "y" ) { 3902 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 3903 } 3904 this.reverting = true; 3905 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 3906 that._clear(event); 3907 }); 3908 } else { 3909 this._clear(event, noPropagation); 3910 } 3911 3912 return false; 3913 3914 }, 3915 3916 cancel: function() { 3917 3918 if(this.dragging) { 3919 3920 this._mouseUp({ target: null }); 3921 3922 if(this.options.helper === "original") { 3923 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 3924 } else { 3925 this.currentItem.show(); 3926 } 3927 3928 //Post deactivating events to containers 3929 for (var i = this.containers.length - 1; i >= 0; i--){ 3930 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 3931 if(this.containers[i].containerCache.over) { 3932 this.containers[i]._trigger("out", null, this._uiHash(this)); 3933 this.containers[i].containerCache.over = 0; 3934 } 3935 } 3936 3937 } 3938 3939 if (this.placeholder) { 3940 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 3941 if(this.placeholder[0].parentNode) { 3942 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 3943 } 3944 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 3945 this.helper.remove(); 3946 } 3947 3948 $.extend(this, { 3949 helper: null, 3950 dragging: false, 3951 reverting: false, 3952 _noFinalSort: null 3953 }); 3954 3955 if(this.domPosition.prev) { 3956 $(this.domPosition.prev).after(this.currentItem); 3957 } else { 3958 $(this.domPosition.parent).prepend(this.currentItem); 3959 } 3960 } 3961 3962 return this; 3963 3964 }, 3965 3966 serialize: function(o) { 3967 3968 var items = this._getItemsAsjQuery(o && o.connected), 3969 str = []; 3970 o = o || {}; 3971 3972 $(items).each(function() { 3973 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 3974 if (res) { 3975 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 3976 } 3977 }); 3978 3979 if(!str.length && o.key) { 3980 str.push(o.key + "="); 3981 } 3982 3983 return str.join("&"); 3984 3985 }, 3986 3987 toArray: function(o) { 3988 3989 var items = this._getItemsAsjQuery(o && o.connected), 3990 ret = []; 3991 3992 o = o || {}; 3993 3994 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 3995 return ret; 3996 3997 }, 3998 3999 /* Be careful with the following core functions */ 4000 _intersectsWith: function(item) { 4001 4002 var x1 = this.positionAbs.left, 4003 x2 = x1 + this.helperProportions.width, 4004 y1 = this.positionAbs.top, 4005 y2 = y1 + this.helperProportions.height, 4006 l = item.left, 4007 r = l + item.width, 4008 t = item.top, 4009 b = t + item.height, 4010 dyClick = this.offset.click.top, 4011 dxClick = this.offset.click.left, 4012 isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 4013 4014 if ( this.options.tolerance === "pointer" || 4015 this.options.forcePointerForContainers || 4016 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 4017 ) { 4018 return isOverElement; 4019 } else { 4020 4021 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 4022 x2 - (this.helperProportions.width / 2) < r && // Left Half 4023 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 4024 y2 - (this.helperProportions.height / 2) < b ); // Top Half 4025 4026 } 4027 }, 4028 4029 _intersectsWithPointer: function(item) { 4030 4031 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4032 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4033 isOverElement = isOverElementHeight && isOverElementWidth, 4034 verticalDirection = this._getDragVerticalDirection(), 4035 horizontalDirection = this._getDragHorizontalDirection(); 4036 4037 if (!isOverElement) { 4038 return false; 4039 } 4040 4041 return this.floating ? 4042 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 4043 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 4044 4045 }, 4046 4047 _intersectsWithSides: function(item) { 4048 4049 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4050 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4051 verticalDirection = this._getDragVerticalDirection(), 4052 horizontalDirection = this._getDragHorizontalDirection(); 4053 4054 if (this.floating && horizontalDirection) { 4055 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 4056 } else { 4057 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 4058 } 4059 4060 }, 4061 4062 _getDragVerticalDirection: function() { 4063 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4064 return delta !== 0 && (delta > 0 ? "down" : "up"); 4065 }, 4066 4067 _getDragHorizontalDirection: function() { 4068 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4069 return delta !== 0 && (delta > 0 ? "right" : "left"); 4070 }, 4071 4072 refresh: function(event) { 4073 this._refreshItems(event); 4074 this.refreshPositions(); 4075 return this; 4076 }, 4077 4078 _connectWith: function() { 4079 var options = this.options; 4080 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 4081 }, 4082 4083 _getItemsAsjQuery: function(connected) { 4084 4085 var i, j, cur, inst, 4086 items = [], 4087 queries = [], 4088 connectWith = this._connectWith(); 4089 4090 if(connectWith && connected) { 4091 for (i = connectWith.length - 1; i >= 0; i--){ 4092 cur = $(connectWith[i]); 4093 for ( j = cur.length - 1; j >= 0; j--){ 4094 inst = $.data(cur[j], this.widgetFullName); 4095 if(inst && inst !== this && !inst.options.disabled) { 4096 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]); 4097 } 4098 } 4099 } 4100 } 4101 4102 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]); 4103 4104 for (i = queries.length - 1; i >= 0; i--){ 4105 queries[i][0].each(function() { 4106 items.push(this); 4107 }); 4108 } 4109 4110 return $(items); 4111 4112 }, 4113 4114 _removeCurrentsFromItems: function() { 4115 4116 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4117 4118 this.items = $.grep(this.items, function (item) { 4119 for (var j=0; j < list.length; j++) { 4120 if(list[j] === item.item[0]) { 4121 return false; 4122 } 4123 } 4124 return true; 4125 }); 4126 4127 }, 4128 4129 _refreshItems: function(event) { 4130 4131 this.items = []; 4132 this.containers = [this]; 4133 4134 var i, j, cur, inst, targetData, _queries, item, queriesLength, 4135 items = this.items, 4136 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 4137 connectWith = this._connectWith(); 4138 4139 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4140 for (i = connectWith.length - 1; i >= 0; i--){ 4141 cur = $(connectWith[i]); 4142 for (j = cur.length - 1; j >= 0; j--){ 4143 inst = $.data(cur[j], this.widgetFullName); 4144 if(inst && inst !== this && !inst.options.disabled) { 4145 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4146 this.containers.push(inst); 4147 } 4148 } 4149 } 4150 } 4151 4152 for (i = queries.length - 1; i >= 0; i--) { 4153 targetData = queries[i][1]; 4154 _queries = queries[i][0]; 4155 4156 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4157 item = $(_queries[j]); 4158 4159 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 4160 4161 items.push({ 4162 item: item, 4163 instance: targetData, 4164 width: 0, height: 0, 4165 left: 0, top: 0 4166 }); 4167 } 4168 } 4169 4170 }, 4171 4172 refreshPositions: function(fast) { 4173 4174 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4175 if(this.offsetParent && this.helper) { 4176 this.offset.parent = this._getParentOffset(); 4177 } 4178 4179 var i, item, t, p; 4180 4181 for (i = this.items.length - 1; i >= 0; i--){ 4182 item = this.items[i]; 4183 4184 //We ignore calculating positions of all connected containers when we're not over them 4185 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 4186 continue; 4187 } 4188 4189 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4190 4191 if (!fast) { 4192 item.width = t.outerWidth(); 4193 item.height = t.outerHeight(); 4194 } 4195 4196 p = t.offset(); 4197 item.left = p.left; 4198 item.top = p.top; 4199 } 4200 4201 if(this.options.custom && this.options.custom.refreshContainers) { 4202 this.options.custom.refreshContainers.call(this); 4203 } else { 4204 for (i = this.containers.length - 1; i >= 0; i--){ 4205 p = this.containers[i].element.offset(); 4206 this.containers[i].containerCache.left = p.left; 4207 this.containers[i].containerCache.top = p.top; 4208 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 4209 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4210 } 4211 } 4212 4213 return this; 4214 }, 4215 4216 _createPlaceholder: function(that) { 4217 that = that || this; 4218 var className, 4219 o = that.options; 4220 4221 if(!o.placeholder || o.placeholder.constructor === String) { 4222 className = o.placeholder; 4223 o.placeholder = { 4224 element: function() { 4225 4226 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 4227 element = $( that.document[0].createElement( nodeName ) ) 4228 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4229 .removeClass("ui-sortable-helper"); 4230 4231 if ( nodeName === "tr" ) { 4232 // Use a high colspan to force the td to expand the full 4233 // width of the table (browsers are smart enough to 4234 // handle this properly) 4235 element.append( "<td colspan='99'> </td>" ); 4236 } else if ( nodeName === "img" ) { 4237 element.attr( "src", that.currentItem.attr( "src" ) ); 4238 } 4239 4240 if ( !className ) { 4241 element.css( "visibility", "hidden" ); 4242 } 4243 4244 return element; 4245 }, 4246 update: function(container, p) { 4247 4248 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4249 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4250 if(className && !o.forcePlaceholderSize) { 4251 return; 4252 } 4253 4254 //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
4255 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 4256 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 4257 } 4258 }; 4259 } 4260 4261 //Create the placeholder 4262 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4263 4264 //Append it after the actual current item 4265 that.currentItem.after(that.placeholder); 4266 4267 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4268 o.placeholder.update(that, that.placeholder); 4269 4270 }, 4271 4272 _contactContainers: function(event) { 4273 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, 4274 innermostContainer = null, 4275 innermostIndex = null; 4276 4277 // get innermost container that intersects with item 4278 for (i = this.containers.length - 1; i >= 0; i--) { 4279 4280 // never consider a container that's located within the item itself 4281 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 4282 continue; 4283 } 4284 4285 if(this._intersectsWith(this.containers[i].containerCache)) { 4286 4287 // if we've already found a container and it's more "inner" than this, then continue 4288 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 4289 continue; 4290 } 4291 4292 innermostContainer = this.containers[i]; 4293 innermostIndex = i; 4294 4295 } else { 4296 // container doesn't intersect. trigger "out" event if necessary 4297 if(this.containers[i].containerCache.over) { 4298 this.containers[i]._trigger("out", event, this._uiHash(this)); 4299 this.containers[i].containerCache.over = 0; 4300 } 4301 } 4302 4303 } 4304 4305 // if no intersecting containers found, return 4306 if(!innermostContainer) { 4307 return; 4308 } 4309 4310 // move the item into the container if it's not there already 4311 if(this.containers.length === 1) { 4312 if (!this.containers[innermostIndex].containerCache.over) { 4313 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4314 this.containers[innermostIndex].containerCache.over = 1; 4315 } 4316 } else { 4317 4318 //When entering a new container, we will find the item with the least distance and append our item near it 4319 dist = 10000; 4320 itemWithLeastDistance = null; 4321 floating = innermostContainer.floating || isFloating(this.currentItem); 4322 posProperty = floating ? "left" : "top"; 4323 sizeProperty = floating ? "width" : "height"; 4324 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 4325 for (j = this.items.length - 1; j >= 0; j--) { 4326 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 4327 continue; 4328 } 4329 if(this.items[j].item[0] === this.currentItem[0]) { 4330 continue; 4331 } 4332 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { 4333 continue; 4334 } 4335 cur = this.items[j].item.offset()[posProperty]; 4336 nearBottom = false; 4337 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 4338 nearBottom = true; 4339 cur += this.items[j][sizeProperty]; 4340 } 4341 4342 if(Math.abs(cur - base) < dist) { 4343 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 4344 this.direction = nearBottom ? "up": "down"; 4345 } 4346 } 4347 4348 //Check if dropOnEmpty is enabled 4349 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 4350 return; 4351 } 4352 4353 if(this.currentContainer === this.containers[innermostIndex]) { 4354 return; 4355 } 4356 4357 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 4358 this._trigger("change", event, this._uiHash()); 4359 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 4360 this.currentContainer = this.containers[innermostIndex]; 4361 4362 //Update the placeholder 4363 this.options.placeholder.update(this.currentContainer, this.placeholder); 4364 4365 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4366 this.containers[innermostIndex].containerCache.over = 1; 4367 } 4368 4369 4370 }, 4371 4372 _createHelper: function(event) { 4373 4374 var o = this.options, 4375 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 4376 4377 //Add the helper to the DOM if that didn't happen already 4378 if(!helper.parents("body").length) { 4379 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 4380 } 4381 4382 if(helper[0] === this.currentItem[0]) { 4383 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
vendor: 4,379 bytes, lines 4383-4500
4383: this.currentItem.css("left") }; 4384 } 4385 4386 if(!helper[0].style.width || o.forceHelperSize) { 4387 helper.width(this.currentItem.width()); 4388 } 4389 if(!helper[0].style.height || o.forceHelperSize) { 4390 helper.height(this.currentItem.height()); 4391 } 4392 4393 return helper; 4394 4395 }, 4396 4397 _adjustOffsetFromHelper: function(obj) { 4398 if (typeof obj === "string") { 4399 obj = obj.split(" "); 4400 } 4401 if ($.isArray(obj)) { 4402 obj = {left: +obj[0], top: +obj[1] || 0}; 4403 } 4404 if ("left" in obj) { 4405 this.offset.click.left = obj.left + this.margins.left; 4406 } 4407 if ("right" in obj) { 4408 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4409 } 4410 if ("top" in obj) { 4411 this.offset.click.top = obj.top + this.margins.top; 4412 } 4413 if ("bottom" in obj) { 4414 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4415 } 4416 }, 4417 4418 _getParentOffset: function() { 4419 4420 4421 //Get the offsetParent and cache its position 4422 this.offsetParent = this.helper.offsetParent(); 4423 var po = this.offsetParent.offset(); 4424 4425 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4426 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4427 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4428 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4429 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4430 po.left += this.scrollParent.scrollLeft(); 4431 po.top += this.scrollParent.scrollTop(); 4432 } 4433 4434 // This needs to be actually done for all browsers, since pageX/pageY includes this information 4435 // with an ugly IE fix 4436 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 4437 po = { top: 0, left: 0 }; 4438 } 4439 4440 return { 4441 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4442 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4443 }; 4444 4445 }, 4446 4447 _getRelativeOffset: function() { 4448 4449 if(this.cssPosition === "relative") { 4450 var p = this.currentItem.position(); 4451 return { 4452 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4453 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4454 }; 4455 } else { 4456 return { top: 0, left: 0 }; 4457 } 4458 4459 }, 4460 4461 _cacheMargins: function() { 4462 this.margins = { 4463 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 4464 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 4465 }; 4466 }, 4467 4468 _cacheHelperProportions: function() { 4469 this.helperProportions = { 4470 width: this.helper.outerWidth(), 4471 height: this.helper.outerHeight() 4472 }; 4473 }, 4474 4475 _setContainment: function() { 4476 4477 var ce, co, over, 4478 o = this.options; 4479 if(o.containment === "parent") { 4480 o.containment = this.helper[0].parentNode; 4481 } 4482 if(o.containment === "document" || o.containment === "window") { 4483 this.containment = [ 4484 0 - this.offset.relative.left - this.offset.parent.left, 4485 0 - this.offset.relative.top - this.offset.parent.top, 4486 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 4487 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4488 ]; 4489 } 4490 4491 if(!(/^(document|window|parent)$/).test(o.containment)) { 4492 ce = $(o.containment)[0]; 4493 co = $(o.containment).offset(); 4494 over = ($(ce).css("overflow") !== "hidden"); 4495 4496 this.containment = [ 4497 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 4498 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 4499 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, 4500 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
vendor: 5,508 bytes, lines 4500-4612
450010) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 4501 ]; 4502 } 4503 4504 }, 4505 4506 _convertPositionTo: function(d, pos) { 4507 4508 if(!pos) { 4509 pos = this.position; 4510 } 4511 var mod = d === "absolute" ? 1 : -1, 4512 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 4513 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 4514 4515 return { 4516 top: ( 4517 pos.top + // The absolute mouse position 4518 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4519 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 4520 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4521 ), 4522 left: ( 4523 pos.left + // The absolute mouse position 4524 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4525 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 4526 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4527 ) 4528 }; 4529 4530 }, 4531 4532 _generatePosition: function(event) { 4533 4534 var top, left, 4535 o = this.options, 4536 pageX = event.pageX, 4537 pageY = event.pageY, 4538 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 4539 4540 // This is another very weird special case that only happens for relative elements: 4541 // 1. If the css position is relative 4542 // 2. and the scroll parent is the document or similar to the offset parent 4543 // we have to refresh the relative offset during the scroll so there are no jumps 4544 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 4545 this.offset.relative = this._getRelativeOffset(); 4546 } 4547 4548 /* 4549 * - Position constraining - 4550 * Constrain the position to a mix of grid, containment. 4551 */ 4552 4553 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 4554 4555 if(this.containment) { 4556 if(event.pageX - this.offset.click.left < this.containment[0]) { 4557 pageX = this.containment[0] + this.offset.click.left; 4558 } 4559 if(event.pageY - this.offset.click.top < this.containment[1]) { 4560 pageY = this.containment[1] + this.offset.click.top; 4561 } 4562 if(event.pageX - this.offset.click.left > this.containment[2]) { 4563 pageX = this.containment[2] + this.offset.click.left; 4564 } 4565 if(event.pageY - this.offset.click.top > this.containment[3]) { 4566 pageY = this.containment[3] + this.offset.click.top; 4567 } 4568 } 4569 4570 if(o.grid) { 4571 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 4572 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; 4573 4574 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 4575 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; 4576 } 4577 4578 } 4579 4580 return { 4581 top: ( 4582 pageY - // The absolute mouse position 4583 this.offset.click.top - // Click offset (relative to the element) 4584 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 4585 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 4586 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 4587 ), 4588 left: ( 4589 pageX - // The absolute mouse position 4590 this.offset.click.left - // Click offset (relative to the element) 4591 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 4592 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 4593 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 4594 ) 4595 }; 4596 4597 }, 4598 4599 _rearrange: function(event, i, a, hardRefresh) { 4600 4601 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)); 4602 4603 //Various things done here to improve the performance: 4604 // 1. we create a setTimeout, that calls refreshPositions 4605 // 2. on the instance, we have a counter variable, that get's higher after every append 4606 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 4607 // 4. this lets only the last addition to the timeout stack through 4608 this.counter = this.counter ? ++this.counter : 1; 4609 var counter = this.counter; 4610 4611 this._delay(function() { 4612 if(counter === this.counter) {
vendor: 3,331 bytes, lines 4613-4696
4613 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 4614 } 4615 }); 4616 4617 }, 4618 4619 _clear: function(event, noPropagation) { 4620 4621 this.reverting = false; 4622 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 4623 // everything else normalized again 4624 var i, 4625 delayedTriggers = []; 4626 4627 // We first have to update the dom position of the actual currentItem 4628 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 4629 if(!this._noFinalSort && this.currentItem.parent().length) { 4630 this.placeholder.before(this.currentItem); 4631 } 4632 this._noFinalSort = null; 4633 4634 if(this.helper[0] === this.currentItem[0]) { 4635 for(i in this._storedCSS) { 4636 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 4637 this._storedCSS[i] = ""; 4638 } 4639 } 4640 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4641 } else { 4642 this.currentItem.show(); 4643 } 4644 4645 if(this.fromOutside && !noPropagation) { 4646 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 4647 } 4648 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 4649 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 4650 } 4651 4652 // Check if the items Container has Changed and trigger appropriate 4653 // events. 4654 if (this !== this.currentContainer) { 4655 if(!noPropagation) { 4656 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 4657 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4658 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4659 } 4660 } 4661 4662 4663 //Post events to containers 4664 for (i = this.containers.length - 1; i >= 0; i--){ 4665 if(!noPropagation) { 4666 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4667 } 4668 if(this.containers[i].containerCache.over) { 4669 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4670 this.containers[i].containerCache.over = 0; 4671 } 4672 } 4673 4674 //Do what was originally in plugins 4675 if ( this.storedCursor ) { 4676 this.document.find( "body" ).css( "cursor", this.storedCursor ); 4677 this.storedStylesheet.remove(); 4678 } 4679 if(this._storedOpacity) { 4680 this.helper.css("opacity", this._storedOpacity); 4681 } 4682 if(this._storedZIndex) { 4683 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 4684 } 4685 4686 this.dragging = false; 4687 if(this.cancelHelperRemoval) { 4688 if(!noPropagation) { 4689 this._trigger("beforeStop", event, this._uiHash()); 4690 for (i=0; i < delayedTriggers.length; i++) { 4691 delayedTriggers[i].call(this, event); 4692 } //Trigger all delayed events 4693 this._trigger("stop", event, this._uiHash()); 4694 } 4695 4696 this.fromOutside = false;
vendor: 77,820 bytes, lines 4697-7636
4697 return false; 4698 } 4699 4700 if(!noPropagation) { 4701 this._trigger("beforeStop", event, this._uiHash()); 4702 } 4703 4704 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4705 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4706 4707 if(this.helper[0] !== this.currentItem[0]) { 4708 this.helper.remove(); 4709 } 4710 this.helper = null; 4711 4712 if(!noPropagation) { 4713 for (i=0; i < delayedTriggers.length; i++) { 4714 delayedTriggers[i].call(this, event); 4715 } //Trigger all delayed events 4716 this._trigger("stop", event, this._uiHash()); 4717 } 4718 4719 this.fromOutside = false; 4720 return true; 4721 4722 }, 4723 4724 _trigger: function() { 4725 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 4726 this.cancel(); 4727 } 4728 }, 4729 4730 _uiHash: function(_inst) { 4731 var inst = _inst || this; 4732 return { 4733 helper: inst.helper, 4734 placeholder: inst.placeholder || $([]), 4735 position: inst.position, 4736 originalPosition: inst.originalPosition, 4737 offset: inst.positionAbs, 4738 item: inst.currentItem, 4739 sender: _inst ? _inst.element : null 4740 }; 4741 } 4742 4743}); 4744 4745})(jQuery); 4746 4747(function($, undefined) { 4748 4749var dataSpace = "ui-effects-"; 4750 4751$.effects = { 4752 effect: {} 4753}; 4754 4755/*! 4756 * jQuery Color Animations v2.1.2 4757 * https://github.com/jquery/jquery-color 4758 * 4759 * Copyright 2013 jQuery Foundation and other contributors 4760 * Released under the MIT license. 4761 * http://jquery.org/license 4762 * 4763 * Date: Wed Jan 16 08:47:09 2013 -0600 4764 */ 4765(function( jQuery, undefined ) { 4766 4767 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 4768 4769 // plusequals test for += 100 -= 100 4770 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 4771 // a set of RE's that can match strings and generate color tuples. 4772 stringParsers = [{ 4773 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4774 parse: function( execResult ) { 4775 return [ 4776 execResult[ 1 ], 4777 execResult[ 2 ], 4778 execResult[ 3 ], 4779 execResult[ 4 ] 4780 ]; 4781 } 4782 }, { 4783 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4784 parse: function( execResult ) { 4785 return [ 4786 execResult[ 1 ] * 2.55, 4787 execResult[ 2 ] * 2.55, 4788 execResult[ 3 ] * 2.55, 4789 execResult[ 4 ] 4790 ]; 4791 } 4792 }, { 4793 // this regex ignores A-F because it's compared against an already lowercased string 4794 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 4795 parse: function( execResult ) { 4796 return [ 4797 parseInt( execResult[ 1 ], 16 ), 4798 parseInt( execResult[ 2 ], 16 ), 4799 parseInt( execResult[ 3 ], 16 ) 4800 ]; 4801 } 4802 }, { 4803 // this regex ignores A-F because it's compared against an already lowercased string 4804 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 4805 parse: function( execResult ) { 4806 return [ 4807 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 4808 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 4809 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 4810 ]; 4811 } 4812 }, { 4813 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4814 space: "hsla", 4815 parse: function( execResult ) { 4816 return [ 4817 execResult[ 1 ], 4818 execResult[ 2 ] / 100, 4819 execResult[ 3 ] / 100, 4820 execResult[ 4 ] 4821 ]; 4822 } 4823 }], 4824 4825 // jQuery.Color( ) 4826 color = jQuery.Color = function( color, green, blue, alpha ) { 4827 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 4828 }, 4829 spaces = { 4830 rgba: { 4831 props: { 4832 red: { 4833 idx: 0, 4834 type: "byte" 4835 }, 4836 green: { 4837 idx: 1, 4838 type: "byte" 4839 }, 4840 blue: { 4841 idx: 2, 4842 type: "byte" 4843 } 4844 } 4845 }, 4846 4847 hsla: { 4848 props: { 4849 hue: { 4850 idx: 0, 4851 type: "degrees" 4852 }, 4853 saturation: { 4854 idx: 1, 4855 type: "percent" 4856 }, 4857 lightness: { 4858 idx: 2, 4859 type: "percent" 4860 } 4861 } 4862 } 4863 }, 4864 propTypes = { 4865 "byte": { 4866 floor: true, 4867 max: 255 4868 }, 4869 "percent": { 4870 max: 1 4871 }, 4872 "degrees": { 4873 mod: 360, 4874 floor: true 4875 } 4876 }, 4877 support = color.support = {}, 4878 4879 // element for support tests 4880 supportElem = jQuery( "<p>" )[ 0 ], 4881 4882 // colors = jQuery.Color.names 4883 colors, 4884 4885 // local aliases of functions called often 4886 each = jQuery.each; 4887 4888// determine rgba support immediately 4889supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 4890support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 4891 4892// define cache name and alpha properties 4893// for rgba and hsla spaces 4894each( spaces, function( spaceName, space ) { 4895 space.cache = "_" + spaceName; 4896 space.props.alpha = { 4897 idx: 3, 4898 type: "percent", 4899 def: 1 4900 }; 4901}); 4902 4903function clamp( value, prop, allowEmpty ) { 4904 var type = propTypes[ prop.type ] || {}; 4905 4906 if ( value == null ) { 4907 return (allowEmpty || !prop.def) ? null : prop.def; 4908 } 4909 4910 // ~~ is an short way of doing floor for positive numbers 4911 value = type.floor ? ~~value : parseFloat( value ); 4912 4913 // IE will pass in empty strings as value for alpha, 4914 // which will hit this case 4915 if ( isNaN( value ) ) { 4916 return prop.def; 4917 } 4918 4919 if ( type.mod ) { 4920 // we add mod before modding to make sure that negatives values 4921 // get converted properly: -10 -> 350 4922 return (value + type.mod) % type.mod; 4923 } 4924 4925 // for now all property types without mod have min and max 4926 return 0 > value ? 0 : type.max < value ? type.max : value; 4927} 4928 4929function stringParse( string ) { 4930 var inst = color(), 4931 rgba = inst._rgba = []; 4932 4933 string = string.toLowerCase(); 4934 4935 each( stringParsers, function( i, parser ) { 4936 var parsed, 4937 match = parser.re.exec( string ), 4938 values = match && parser.parse( match ), 4939 spaceName = parser.space || "rgba"; 4940 4941 if ( values ) { 4942 parsed = inst[ spaceName ]( values ); 4943 4944 // if this was an rgba parse the assignment might happen twice 4945 // oh well.... 4946 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 4947 rgba = inst._rgba = parsed._rgba; 4948 4949 // exit each( stringParsers ) here because we matched 4950 return false; 4951 } 4952 }); 4953 4954 // Found a stringParser that handled it 4955 if ( rgba.length ) { 4956 4957 // if this came from a parsed string, force "transparent" when alpha is 0 4958 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 4959 if ( rgba.join() === "0,0,0,0" ) { 4960 jQuery.extend( rgba, colors.transparent ); 4961 } 4962 return inst; 4963 } 4964 4965 // named colors 4966 return colors[ string ]; 4967} 4968 4969color.fn = jQuery.extend( color.prototype, { 4970 parse: function( red, green, blue, alpha ) { 4971 if ( red === undefined ) { 4972 this._rgba = [ null, null, null, null ]; 4973 return this; 4974 } 4975 if ( red.jquery || red.nodeType ) { 4976 red = jQuery( red ).css( green ); 4977 green = undefined; 4978 } 4979 4980 var inst = this, 4981 type = jQuery.type( red ), 4982 rgba = this._rgba = []; 4983 4984 // more than 1 argument specified - assume ( red, green, blue, alpha ) 4985 if ( green !== undefined ) { 4986 red = [ red, green, blue, alpha ]; 4987 type = "array"; 4988 } 4989 4990 if ( type === "string" ) { 4991 return this.parse( stringParse( red ) || colors._default ); 4992 } 4993 4994 if ( type === "array" ) { 4995 each( spaces.rgba.props, function( key, prop ) { 4996 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 4997 }); 4998 return this; 4999 } 5000 5001 if ( type === "object" ) { 5002 if ( red instanceof color ) { 5003 each( spaces, function( spaceName, space ) { 5004 if ( red[ space.cache ] ) { 5005 inst[ space.cache ] = red[ space.cache ].slice(); 5006 } 5007 }); 5008 } else { 5009 each( spaces, function( spaceName, space ) { 5010 var cache = space.cache; 5011 each( space.props, function( key, prop ) { 5012 5013 // if the cache doesn't exist, and we know how to convert 5014 if ( !inst[ cache ] && space.to ) { 5015 5016 // if the value was null, we don't need to copy it 5017 // if the key was alpha, we don't need to copy it either 5018 if ( key === "alpha" || red[ key ] == null ) { 5019 return; 5020 } 5021 inst[ cache ] = space.to( inst._rgba ); 5022 } 5023 5024 // this is the only case where we allow nulls for ALL properties. 5025 // call clamp with alwaysAllowEmpty 5026 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 5027 }); 5028 5029 // everything defined but alpha? 5030 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 5031 // use the default of 1 5032 inst[ cache ][ 3 ] = 1; 5033 if ( space.from ) { 5034 inst._rgba = space.from( inst[ cache ] ); 5035 } 5036 } 5037 }); 5038 } 5039 return this; 5040 } 5041 }, 5042 is: function( compare ) { 5043 var is = color( compare ), 5044 same = true, 5045 inst = this; 5046 5047 each( spaces, function( _, space ) { 5048 var localCache, 5049 isCache = is[ space.cache ]; 5050 if (isCache) { 5051 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 5052 each( space.props, function( _, prop ) { 5053 if ( isCache[ prop.idx ] != null ) { 5054 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 5055 return same; 5056 } 5057 }); 5058 } 5059 return same; 5060 }); 5061 return same; 5062 }, 5063 _space: function() { 5064 var used = [], 5065 inst = this; 5066 each( spaces, function( spaceName, space ) { 5067 if ( inst[ space.cache ] ) { 5068 used.push( spaceName ); 5069 } 5070 }); 5071 return used.pop(); 5072 }, 5073 transition: function( other, distance ) { 5074 var end = color( other ), 5075 spaceName = end._space(), 5076 space = spaces[ spaceName ], 5077 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 5078 start = startColor[ space.cache ] || space.to( startColor._rgba ), 5079 result = start.slice(); 5080 5081 end = end[ space.cache ]; 5082 each( space.props, function( key, prop ) { 5083 var index = prop.idx, 5084 startValue = start[ index ], 5085 endValue = end[ index ], 5086 type = propTypes[ prop.type ] || {}; 5087 5088 // if null, don't override start value 5089 if ( endValue === null ) { 5090 return; 5091 } 5092 // if null - use end 5093 if ( startValue === null ) { 5094 result[ index ] = endValue; 5095 } else { 5096 if ( type.mod ) { 5097 if ( endValue - startValue > type.mod / 2 ) { 5098 startValue += type.mod; 5099 } else if ( startValue - endValue > type.mod / 2 ) { 5100 startValue -= type.mod; 5101 } 5102 } 5103 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 5104 } 5105 }); 5106 return this[ spaceName ]( result ); 5107 }, 5108 blend: function( opaque ) { 5109 // if we are already opaque - return ourself 5110 if ( this._rgba[ 3 ] === 1 ) { 5111 return this; 5112 } 5113 5114 var rgb = this._rgba.slice(), 5115 a = rgb.pop(), 5116 blend = color( opaque )._rgba; 5117 5118 return color( jQuery.map( rgb, function( v, i ) { 5119 return ( 1 - a ) * blend[ i ] + a * v; 5120 })); 5121 }, 5122 toRgbaString: function() { 5123 var prefix = "rgba(", 5124 rgba = jQuery.map( this._rgba, function( v, i ) { 5125 return v == null ? ( i > 2 ? 1 : 0 ) : v; 5126 }); 5127 5128 if ( rgba[ 3 ] === 1 ) { 5129 rgba.pop(); 5130 prefix = "rgb("; 5131 } 5132 5133 return prefix + rgba.join() + ")"; 5134 }, 5135 toHslaString: function() { 5136 var prefix = "hsla(", 5137 hsla = jQuery.map( this.hsla(), function( v, i ) { 5138 if ( v == null ) { 5139 v = i > 2 ? 1 : 0; 5140 } 5141 5142 // catch 1 and 2 5143 if ( i && i < 3 ) { 5144 v = Math.round( v * 100 ) + "%"; 5145 } 5146 return v; 5147 }); 5148 5149 if ( hsla[ 3 ] === 1 ) { 5150 hsla.pop(); 5151 prefix = "hsl("; 5152 } 5153 return prefix + hsla.join() + ")"; 5154 }, 5155 toHexString: function( includeAlpha ) { 5156 var rgba = this._rgba.slice(), 5157 alpha = rgba.pop(); 5158 5159 if ( includeAlpha ) { 5160 rgba.push( ~~( alpha * 255 ) ); 5161 } 5162 5163 return "#" + jQuery.map( rgba, function( v ) { 5164 5165 // default to 0 when nulls exist 5166 v = ( v || 0 ).toString( 16 ); 5167 return v.length === 1 ? "0" + v : v; 5168 }).join(""); 5169 }, 5170 toString: function() { 5171 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 5172 } 5173}); 5174color.fn.parse.prototype = color.fn; 5175 5176// hsla conversions adapted from: 5177// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 5178 5179function hue2rgb( p, q, h ) { 5180 h = ( h + 1 ) % 1; 5181 if ( h * 6 < 1 ) { 5182 return p + (q - p) * h * 6; 5183 } 5184 if ( h * 2 < 1) { 5185 return q; 5186 } 5187 if ( h * 3 < 2 ) { 5188 return p + (q - p) * ((2/3) - h) * 6; 5189 } 5190 return p; 5191} 5192 5193spaces.hsla.to = function ( rgba ) { 5194 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 5195 return [ null, null, null, rgba[ 3 ] ]; 5196 } 5197 var r = rgba[ 0 ] / 255, 5198 g = rgba[ 1 ] / 255, 5199 b = rgba[ 2 ] / 255, 5200 a = rgba[ 3 ], 5201 max = Math.max( r, g, b ), 5202 min = Math.min( r, g, b ), 5203 diff = max - min, 5204 add = max + min, 5205 l = add * 0.5, 5206 h, s; 5207 5208 if ( min === max ) { 5209 h = 0; 5210 } else if ( r === max ) { 5211 h = ( 60 * ( g - b ) / diff ) + 360; 5212 } else if ( g === max ) { 5213 h = ( 60 * ( b - r ) / diff ) + 120; 5214 } else { 5215 h = ( 60 * ( r - g ) / diff ) + 240; 5216 } 5217 5218 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 5219 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 5220 if ( diff === 0 ) { 5221 s = 0; 5222 } else if ( l <= 0.5 ) { 5223 s = diff / add; 5224 } else { 5225 s = diff / ( 2 - add ); 5226 } 5227 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 5228}; 5229 5230spaces.hsla.from = function ( hsla ) { 5231 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 5232 return [ null, null, null, hsla[ 3 ] ]; 5233 } 5234 var h = hsla[ 0 ] / 360, 5235 s = hsla[ 1 ], 5236 l = hsla[ 2 ], 5237 a = hsla[ 3 ], 5238 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 5239 p = 2 * l - q; 5240 5241 return [ 5242 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 5243 Math.round( hue2rgb( p, q, h ) * 255 ), 5244 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 5245 a 5246 ]; 5247}; 5248 5249 5250each( spaces, function( spaceName, space ) { 5251 var props = space.props, 5252 cache = space.cache, 5253 to = space.to, 5254 from = space.from; 5255 5256 // makes rgba() and hsla() 5257 color.fn[ spaceName ] = function( value ) { 5258 5259 // generate a cache for this space if it doesn't exist 5260 if ( to && !this[ cache ] ) { 5261 this[ cache ] = to( this._rgba ); 5262 } 5263 if ( value === undefined ) { 5264 return this[ cache ].slice(); 5265 } 5266 5267 var ret, 5268 type = jQuery.type( value ), 5269 arr = ( type === "array" || type === "object" ) ? value : arguments, 5270 local = this[ cache ].slice(); 5271 5272 each( props, function( key, prop ) { 5273 var val = arr[ type === "object" ? key : prop.idx ]; 5274 if ( val == null ) { 5275 val = local[ prop.idx ]; 5276 } 5277 local[ prop.idx ] = clamp( val, prop ); 5278 }); 5279 5280 if ( from ) { 5281 ret = color( from( local ) ); 5282 ret[ cache ] = local; 5283 return ret; 5284 } else { 5285 return color( local ); 5286 } 5287 }; 5288 5289 // makes red() green() blue() alpha() hue() saturation() lightness() 5290 each( props, function( key, prop ) { 5291 // alpha is included in more than one space 5292 if ( color.fn[ key ] ) { 5293 return; 5294 } 5295 color.fn[ key ] = function( value ) { 5296 var vtype = jQuery.type( value ), 5297 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 5298 local = this[ fn ](), 5299 cur = local[ prop.idx ], 5300 match; 5301 5302 if ( vtype === "undefined" ) { 5303 return cur; 5304 } 5305 5306 if ( vtype === "function" ) { 5307 value = value.call( this, cur ); 5308 vtype = jQuery.type( value ); 5309 } 5310 if ( value == null && prop.empty ) { 5311 return this; 5312 } 5313 if ( vtype === "string" ) { 5314 match = rplusequals.exec( value ); 5315 if ( match ) { 5316 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 5317 } 5318 } 5319 local[ prop.idx ] = value; 5320 return this[ fn ]( local ); 5321 }; 5322 }); 5323}); 5324 5325// add cssHook and .fx.step function for each named hook. 5326// accept a space separated string of properties 5327color.hook = function( hook ) { 5328 var hooks = hook.split( " " ); 5329 each( hooks, function( i, hook ) { 5330 jQuery.cssHooks[ hook ] = { 5331 set: function( elem, value ) { 5332 var parsed, curElem, 5333 backgroundColor = ""; 5334 5335 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 5336 value = color( parsed || value ); 5337 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 5338 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 5339 while ( 5340 (backgroundColor === "" || backgroundColor === "transparent") && 5341 curElem && curElem.style 5342 ) { 5343 try { 5344 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 5345 curElem = curElem.parentNode; 5346 } catch ( e ) { 5347 } 5348 } 5349 5350 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 5351 backgroundColor : 5352 "_default" ); 5353 } 5354 5355 value = value.toRgbaString(); 5356 } 5357 try { 5358 elem.style[ hook ] = value; 5359 } catch( e ) { 5360 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 5361 } 5362 } 5363 }; 5364 jQuery.fx.step[ hook ] = function( fx ) { 5365 if ( !fx.colorInit ) { 5366 fx.start = color( fx.elem, hook ); 5367 fx.end = color( fx.end ); 5368 fx.colorInit = true; 5369 } 5370 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 5371 }; 5372 }); 5373 5374}; 5375 5376color.hook( stepHooks ); 5377 5378jQuery.cssHooks.borderColor = { 5379 expand: function( value ) { 5380 var expanded = {}; 5381 5382 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 5383 expanded[ "border" + part + "Color" ] = value; 5384 }); 5385 return expanded; 5386 } 5387}; 5388 5389// Basic color names only. 5390// Usage of any of the other color names requires adding yourself or including 5391// jquery.color.svg-names.js. 5392colors = jQuery.Color.names = { 5393 // 4.1. Basic color keywords 5394 aqua: "#00ffff", 5395 black: "#000000", 5396 blue: "#0000ff", 5397 fuchsia: "#ff00ff", 5398 gray: "#808080", 5399 green: "#008000", 5400 lime: "#00ff00", 5401 maroon: "#800000", 5402 navy: "#000080", 5403 olive: "#808000", 5404 purple: "#800080", 5405 red: "#ff0000", 5406 silver: "#c0c0c0", 5407 teal: "#008080", 5408 white: "#ffffff", 5409 yellow: "#ffff00", 5410 5411 // 4.2.3. "transparent" color keyword 5412 transparent: [ null, null, null, 0 ], 5413 5414 _default: "#ffffff" 5415}; 5416 5417})( jQuery ); 5418 5419 5420/******************************************************************************/ 5421/****************************** CLASS ANIMATIONS ******************************/ 5422/******************************************************************************/ 5423(function() { 5424 5425var classAnimationActions = [ "add", "remove", "toggle" ], 5426 shorthandStyles = { 5427 border: 1, 5428 borderBottom: 1, 5429 borderColor: 1, 5430 borderLeft: 1, 5431 borderRight: 1, 5432 borderTop: 1, 5433 borderWidth: 1, 5434 margin: 1, 5435 padding: 1 5436 }; 5437 5438$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 5439 $.fx.step[ prop ] = function( fx ) { 5440 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 5441 jQuery.style( fx.elem, prop, fx.end ); 5442 fx.setAttr = true; 5443 } 5444 }; 5445}); 5446 5447function getElementStyles( elem ) { 5448 var key, len, 5449 style = elem.ownerDocument.defaultView ? 5450 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 5451 elem.currentStyle, 5452 styles = {}; 5453 5454 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 5455 len = style.length; 5456 while ( len-- ) { 5457 key = style[ len ]; 5458 if ( typeof style[ key ] === "string" ) { 5459 styles[ $.camelCase( key ) ] = style[ key ]; 5460 } 5461 } 5462 // support: Opera, IE <9 5463 } else { 5464 for ( key in style ) { 5465 if ( typeof style[ key ] === "string" ) { 5466 styles[ key ] = style[ key ]; 5467 } 5468 } 5469 } 5470 5471 return styles; 5472} 5473 5474 5475function styleDifference( oldStyle, newStyle ) { 5476 var diff = {}, 5477 name, value; 5478 5479 for ( name in newStyle ) { 5480 value = newStyle[ name ]; 5481 if ( oldStyle[ name ] !== value ) { 5482 if ( !shorthandStyles[ name ] ) { 5483 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 5484 diff[ name ] = value; 5485 } 5486 } 5487 } 5488 } 5489 5490 return diff; 5491} 5492 5493// support: jQuery <1.8 5494if ( !$.fn.addBack ) { 5495 $.fn.addBack = function( selector ) { 5496 return this.add( selector == null ? 5497 this.prevObject : this.prevObject.filter( selector ) 5498 ); 5499 }; 5500} 5501 5502$.effects.animateClass = function( value, duration, easing, callback ) { 5503 var o = $.speed( duration, easing, callback ); 5504 5505 return this.queue( function() { 5506 var animated = $( this ), 5507 baseClass = animated.attr( "class" ) || "", 5508 applyClassChange, 5509 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 5510 5511 // map the animated objects to store the original styles. 5512 allAnimations = allAnimations.map(function() { 5513 var el = $( this ); 5514 return { 5515 el: el, 5516 start: getElementStyles( this ) 5517 }; 5518 }); 5519 5520 // apply class change 5521 applyClassChange = function() { 5522 $.each( classAnimationActions, function(i, action) { 5523 if ( value[ action ] ) { 5524 animated[ action + "Class" ]( value[ action ] ); 5525 } 5526 }); 5527 }; 5528 applyClassChange(); 5529 5530 // map all animated objects again - calculate new styles and diff 5531 allAnimations = allAnimations.map(function() { 5532 this.end = getElementStyles( this.el[ 0 ] ); 5533 this.diff = styleDifference( this.start, this.end ); 5534 return this; 5535 }); 5536 5537 // apply original class 5538 animated.attr( "class", baseClass ); 5539 5540 // map all animated objects again - this time collecting a promise 5541 allAnimations = allAnimations.map(function() { 5542 var styleInfo = this, 5543 dfd = $.Deferred(), 5544 opts = $.extend({}, o, { 5545 queue: false, 5546 complete: function() { 5547 dfd.resolve( styleInfo ); 5548 } 5549 }); 5550 5551 this.el.animate( this.diff, opts ); 5552 return dfd.promise(); 5553 }); 5554 5555 // once all animations have completed: 5556 $.when.apply( $, allAnimations.get() ).done(function() { 5557 5558 // set the final class 5559 applyClassChange(); 5560 5561 // for each animated element, 5562 // clear all css properties that were animated 5563 $.each( arguments, function() { 5564 var el = this.el; 5565 $.each( this.diff, function(key) { 5566 el.css( key, "" ); 5567 }); 5568 }); 5569 5570 // this is guarnteed to be there if you use jQuery.speed() 5571 // it also handles dequeuing the next anim... 5572 o.complete.call( animated[ 0 ] ); 5573 }); 5574 }); 5575}; 5576 5577$.fn.extend({ 5578 addClass: (function( orig ) { 5579 return function( classNames, speed, easing, callback ) { 5580 return speed ? 5581 $.effects.animateClass.call( this, 5582 { add: classNames }, speed, easing, callback ) : 5583 orig.apply( this, arguments ); 5584 }; 5585 })( $.fn.addClass ), 5586 5587 removeClass: (function( orig ) { 5588 return function( classNames, speed, easing, callback ) { 5589 return arguments.length > 1 ? 5590 $.effects.animateClass.call( this, 5591 { remove: classNames }, speed, easing, callback ) : 5592 orig.apply( this, arguments ); 5593 }; 5594 })( $.fn.removeClass ), 5595 5596 toggleClass: (function( orig ) { 5597 return function( classNames, force, speed, easing, callback ) { 5598 if ( typeof force === "boolean" || force === undefined ) { 5599 if ( !speed ) { 5600 // without speed parameter 5601 return orig.apply( this, arguments ); 5602 } else { 5603 return $.effects.animateClass.call( this, 5604 (force ? { add: classNames } : { remove: classNames }), 5605 speed, easing, callback ); 5606 } 5607 } else { 5608 // without force parameter 5609 return $.effects.animateClass.call( this, 5610 { toggle: classNames }, force, speed, easing ); 5611 } 5612 }; 5613 })( $.fn.toggleClass ), 5614 5615 switchClass: function( remove, add, speed, easing, callback) { 5616 return $.effects.animateClass.call( this, { 5617 add: add, 5618 remove: remove 5619 }, speed, easing, callback ); 5620 } 5621}); 5622 5623})(); 5624 5625/******************************************************************************/ 5626/*********************************** EFFECTS **********************************/ 5627/******************************************************************************/ 5628 5629(function() { 5630 5631$.extend( $.effects, { 5632 version: "1.10.2", 5633 5634 // Saves a set of properties in a data storage 5635 save: function( element, set ) { 5636 for( var i=0; i < set.length; i++ ) { 5637 if ( set[ i ] !== null ) { 5638 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 5639 } 5640 } 5641 }, 5642 5643 // Restores a set of previously saved properties from a data storage 5644 restore: function( element, set ) { 5645 var val, i; 5646 for( i=0; i < set.length; i++ ) { 5647 if ( set[ i ] !== null ) { 5648 val = element.data( dataSpace + set[ i ] ); 5649 // support: jQuery 1.6.2 5650 // http://bugs.jquery.com/ticket/9917 5651 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 5652 // We can't differentiate between "" and 0 here, so we just assume 5653 // empty string since it's likely to be a more common value... 5654 if ( val === undefined ) { 5655 val = ""; 5656 } 5657 element.css( set[ i ], val ); 5658 } 5659 } 5660 }, 5661 5662 setMode: function( el, mode ) { 5663 if (mode === "toggle") { 5664 mode = el.is( ":hidden" ) ? "show" : "hide"; 5665 } 5666 return mode; 5667 }, 5668 5669 // Translates a [top,left] array into a baseline value 5670 // this should be a little more flexible in the future to handle a string & hash 5671 getBaseline: function( origin, original ) { 5672 var y, x; 5673 switch ( origin[ 0 ] ) { 5674 case "top": y = 0; break; 5675 case "middle": y = 0.5; break; 5676 case "bottom": y = 1; break; 5677 default: y = origin[ 0 ] / original.height; 5678 } 5679 switch ( origin[ 1 ] ) { 5680 case "left": x = 0; break; 5681 case "center": x = 0.5; break; 5682 case "right": x = 1; break; 5683 default: x = origin[ 1 ] / original.width; 5684 } 5685 return { 5686 x: x, 5687 y: y 5688 }; 5689 }, 5690 5691 // Wraps the element around a wrapper that copies position properties 5692 createWrapper: function( element ) { 5693 5694 // if the element is already wrapped, return it 5695 if ( element.parent().is( ".ui-effects-wrapper" )) { 5696 return element.parent(); 5697 } 5698 5699 // wrap the element 5700 var props = { 5701 width: element.outerWidth(true), 5702 height: element.outerHeight(true), 5703 "float": element.css( "float" ) 5704 }, 5705 wrapper = $( "<div></div>" ) 5706 .addClass( "ui-effects-wrapper" ) 5707 .css({ 5708 fontSize: "100%", 5709 background: "transparent", 5710 border: "none", 5711 margin: 0, 5712 padding: 0 5713 }), 5714 // Store the size in case width/height are defined in % - Fixes #5245 5715 size = { 5716 width: element.width(), 5717 height: element.height() 5718 }, 5719 active = document.activeElement; 5720 5721 // support: Firefox 5722 // Firefox incorrectly exposes anonymous content 5723 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 5724 try { 5725 active.id; 5726 } catch( e ) { 5727 active = document.body; 5728 } 5729 5730 element.wrap( wrapper ); 5731 5732 // Fixes #7595 - Elements lose focus when wrapped. 5733 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5734 $( active ).focus(); 5735 } 5736 5737 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 5738 5739 // transfer positioning properties to the wrapper 5740 if ( element.css( "position" ) === "static" ) { 5741 wrapper.css({ position: "relative" }); 5742 element.css({ position: "relative" }); 5743 } else { 5744 $.extend( props, { 5745 position: element.css( "position" ), 5746 zIndex: element.css( "z-index" ) 5747 }); 5748 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 5749 props[ pos ] = element.css( pos ); 5750 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 5751 props[ pos ] = "auto"; 5752 } 5753 }); 5754 element.css({ 5755 position: "relative", 5756 top: 0, 5757 left: 0, 5758 right: "auto", 5759 bottom: "auto" 5760 }); 5761 } 5762 element.css(size); 5763 5764 return wrapper.css( props ).show(); 5765 }, 5766 5767 removeWrapper: function( element ) { 5768 var active = document.activeElement; 5769 5770 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 5771 element.parent().replaceWith( element ); 5772 5773 // Fixes #7595 - Elements lose focus when wrapped. 5774 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5775 $( active ).focus(); 5776 } 5777 } 5778 5779 5780 return element; 5781 }, 5782 5783 setTransition: function( element, list, factor, value ) { 5784 value = value || {}; 5785 $.each( list, function( i, x ) { 5786 var unit = element.cssUnit( x ); 5787 if ( unit[ 0 ] > 0 ) { 5788 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 5789 } 5790 }); 5791 return value; 5792 } 5793}); 5794 5795// return an effect options object for the given parameters: 5796function _normalizeArguments( effect, options, speed, callback ) { 5797 5798 // allow passing all options as the first parameter 5799 if ( $.isPlainObject( effect ) ) { 5800 options = effect; 5801 effect = effect.effect; 5802 } 5803 5804 // convert to an object 5805 effect = { effect: effect }; 5806 5807 // catch (effect, null, ...) 5808 if ( options == null ) { 5809 options = {}; 5810 } 5811 5812 // catch (effect, callback) 5813 if ( $.isFunction( options ) ) { 5814 callback = options; 5815 speed = null; 5816 options = {}; 5817 } 5818 5819 // catch (effect, speed, ?) 5820 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 5821 callback = speed; 5822 speed = options; 5823 options = {}; 5824 } 5825 5826 // catch (effect, options, callback) 5827 if ( $.isFunction( speed ) ) { 5828 callback = speed; 5829 speed = null; 5830 } 5831 5832 // add options to effect 5833 if ( options ) { 5834 $.extend( effect, options ); 5835 } 5836 5837 speed = speed || options.duration; 5838 effect.duration = $.fx.off ? 0 : 5839 typeof speed === "number" ? speed : 5840 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 5841 $.fx.speeds._default; 5842 5843 effect.complete = callback || options.complete; 5844 5845 return effect; 5846} 5847 5848function standardAnimationOption( option ) { 5849 // Valid standard speeds (nothing, number, named speed) 5850 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 5851 return true; 5852 } 5853 5854 // Invalid strings - treat as "normal" speed 5855 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 5856 return true; 5857 } 5858 5859 // Complete callback 5860 if ( $.isFunction( option ) ) { 5861 return true; 5862 } 5863 5864 // Options hash (but not naming an effect) 5865 if ( typeof option === "object" && !option.effect ) { 5866 return true; 5867 } 5868 5869 // Didn't match any standard API 5870 return false; 5871} 5872 5873$.fn.extend({ 5874 effect: function( /* effect, options, speed, callback */ ) { 5875 var args = _normalizeArguments.apply( this, arguments ), 5876 mode = args.mode, 5877 queue = args.queue, 5878 effectMethod = $.effects.effect[ args.effect ]; 5879 5880 if ( $.fx.off || !effectMethod ) { 5881 // delegate to the original method (e.g., .show()) if possible 5882 if ( mode ) { 5883 return this[ mode ]( args.duration, args.complete ); 5884 } else { 5885 return this.each( function() { 5886 if ( args.complete ) { 5887 args.complete.call( this ); 5888 } 5889 }); 5890 } 5891 } 5892 5893 function run( next ) { 5894 var elem = $( this ), 5895 complete = args.complete, 5896 mode = args.mode; 5897 5898 function done() { 5899 if ( $.isFunction( complete ) ) { 5900 complete.call( elem[0] ); 5901 } 5902 if ( $.isFunction( next ) ) { 5903 next(); 5904 } 5905 } 5906 5907 // If the element already has the correct final state, delegate to 5908 // the core methods so the internal tracking of "olddisplay" works. 5909 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 5910 elem[ mode ](); 5911 done(); 5912 } else { 5913 effectMethod.call( elem[0], args, done ); 5914 } 5915 } 5916 5917 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 5918 }, 5919 5920 show: (function( orig ) { 5921 return function( option ) { 5922 if ( standardAnimationOption( option ) ) { 5923 return orig.apply( this, arguments ); 5924 } else { 5925 var args = _normalizeArguments.apply( this, arguments ); 5926 args.mode = "show"; 5927 return this.effect.call( this, args ); 5928 } 5929 }; 5930 })( $.fn.show ), 5931 5932 hide: (function( orig ) { 5933 return function( option ) { 5934 if ( standardAnimationOption( option ) ) { 5935 return orig.apply( this, arguments ); 5936 } else { 5937 var args = _normalizeArguments.apply( this, arguments ); 5938 args.mode = "hide"; 5939 return this.effect.call( this, args ); 5940 } 5941 }; 5942 })( $.fn.hide ), 5943 5944 toggle: (function( orig ) { 5945 return function( option ) { 5946 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 5947 return orig.apply( this, arguments ); 5948 } else { 5949 var args = _normalizeArguments.apply( this, arguments ); 5950 args.mode = "toggle"; 5951 return this.effect.call( this, args ); 5952 } 5953 }; 5954 })( $.fn.toggle ), 5955 5956 // helper functions 5957 cssUnit: function(key) { 5958 var style = this.css( key ), 5959 val = []; 5960 5961 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 5962 if ( style.indexOf( unit ) > 0 ) { 5963 val = [ parseFloat( style ), unit ]; 5964 } 5965 }); 5966 return val; 5967 } 5968}); 5969 5970})(); 5971 5972/******************************************************************************/ 5973/*********************************** EASING ***********************************/ 5974/******************************************************************************/ 5975 5976(function() { 5977 5978// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 5979 5980var baseEasings = {}; 5981 5982$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 5983 baseEasings[ name ] = function( p ) { 5984 return Math.pow( p, i + 2 ); 5985 }; 5986}); 5987 5988$.extend( baseEasings, { 5989 Sine: function ( p ) { 5990 return 1 - Math.cos( p * Math.PI / 2 ); 5991 }, 5992 Circ: function ( p ) { 5993 return 1 - Math.sqrt( 1 - p * p ); 5994 }, 5995 Elastic: function( p ) { 5996 return p === 0 || p === 1 ? p : 5997 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 5998 }, 5999 Back: function( p ) { 6000 return p * p * ( 3 * p - 2 ); 6001 }, 6002 Bounce: function ( p ) { 6003 var pow2, 6004 bounce = 4; 6005 6006 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 6007 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 6008 } 6009}); 6010 6011$.each( baseEasings, function( name, easeIn ) { 6012 $.easing[ "easeIn" + name ] = easeIn; 6013 $.easing[ "easeOut" + name ] = function( p ) { 6014 return 1 - easeIn( 1 - p ); 6015 }; 6016 $.easing[ "easeInOut" + name ] = function( p ) { 6017 return p < 0.5 ? 6018 easeIn( p * 2 ) / 2 : 6019 1 - easeIn( p * -2 + 2 ) / 2; 6020 }; 6021}); 6022 6023})(); 6024 6025})(jQuery); 6026 6027(function( $, undefined ) { 6028 6029var uid = 0, 6030 hideProps = {}, 6031 showProps = {}; 6032 6033hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 6034 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 6035showProps.height = showProps.paddingTop = showProps.paddingBottom = 6036 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 6037 6038$.widget( "ui.accordion", { 6039 version: "1.10.2", 6040 options: { 6041 active: 0, 6042 animate: {}, 6043 collapsible: false, 6044 event: "click", 6045 header: "> li > :first-child,> :not(li):even", 6046 heightStyle: "auto", 6047 icons: { 6048 activeHeader: "ui-icon-triangle-1-s", 6049 header: "ui-icon-triangle-1-e" 6050 }, 6051 6052 // callbacks 6053 activate: null, 6054 beforeActivate: null 6055 }, 6056 6057 _create: function() { 6058 var options = this.options; 6059 this.prevShow = this.prevHide = $(); 6060 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 6061 // ARIA 6062 .attr( "role", "tablist" ); 6063 6064 // don't allow collapsible: false and active: false / null 6065 if ( !options.collapsible && (options.active === false || options.active == null) ) { 6066 options.active = 0; 6067 } 6068 6069 this._processPanels(); 6070 // handle negative values 6071 if ( options.active < 0 ) { 6072 options.active += this.headers.length; 6073 } 6074 this._refresh(); 6075 }, 6076 6077 _getCreateEventData: function() { 6078 return { 6079 header: this.active, 6080 panel: !this.active.length ? $() : this.active.next(), 6081 content: !this.active.length ? $() : this.active.next() 6082 }; 6083 }, 6084 6085 _createIcons: function() { 6086 var icons = this.options.icons; 6087 if ( icons ) { 6088 $( "<span>" ) 6089 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 6090 .prependTo( this.headers ); 6091 this.active.children( ".ui-accordion-header-icon" ) 6092 .removeClass( icons.header ) 6093 .addClass( icons.activeHeader ); 6094 this.headers.addClass( "ui-accordion-icons" ); 6095 } 6096 }, 6097 6098 _destroyIcons: function() { 6099 this.headers 6100 .removeClass( "ui-accordion-icons" ) 6101 .children( ".ui-accordion-header-icon" ) 6102 .remove(); 6103 }, 6104 6105 _destroy: function() { 6106 var contents; 6107 6108 // clean up main element 6109 this.element 6110 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 6111 .removeAttr( "role" ); 6112 6113 // clean up headers 6114 this.headers 6115 .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) 6116 .removeAttr( "role" ) 6117 .removeAttr( "aria-selected" ) 6118 .removeAttr( "aria-controls" ) 6119 .removeAttr( "tabIndex" ) 6120 .each(function() { 6121 if ( /^ui-accordion/.test( this.id ) ) { 6122 this.removeAttribute( "id" ); 6123 } 6124 }); 6125 this._destroyIcons(); 6126 6127 // clean up content panels 6128 contents = this.headers.next() 6129 .css( "display", "" ) 6130 .removeAttr( "role" ) 6131 .removeAttr( "aria-expanded" ) 6132 .removeAttr( "aria-hidden" ) 6133 .removeAttr( "aria-labelledby" ) 6134 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 6135 .each(function() { 6136 if ( /^ui-accordion/.test( this.id ) ) { 6137 this.removeAttribute( "id" ); 6138 } 6139 }); 6140 if ( this.options.heightStyle !== "content" ) { 6141 contents.css( "height", "" ); 6142 } 6143 }, 6144 6145 _setOption: function( key, value ) { 6146 if ( key === "active" ) { 6147 // _activate() will handle invalid values and update this.options 6148 this._activate( value ); 6149 return; 6150 } 6151 6152 if ( key === "event" ) { 6153 if ( this.options.event ) { 6154 this._off( this.headers, this.options.event ); 6155 } 6156 this._setupEvents( value ); 6157 } 6158 6159 this._super( key, value ); 6160 6161 // setting collapsible: false while collapsed; open first panel 6162 if ( key === "collapsible" && !value && this.options.active === false ) { 6163 this._activate( 0 ); 6164 } 6165 6166 if ( key === "icons" ) { 6167 this._destroyIcons(); 6168 if ( value ) { 6169 this._createIcons(); 6170 } 6171 } 6172 6173 // #5332 - opacity doesn't cascade to positioned elements in IE 6174 // so we need to add the disabled class to the headers and panels 6175 if ( key === "disabled" ) { 6176 this.headers.add( this.headers.next() ) 6177 .toggleClass( "ui-state-disabled", !!value ); 6178 } 6179 }, 6180 6181 _keydown: function( event ) { 6182 /*jshint maxcomplexity:15*/ 6183 if ( event.altKey || event.ctrlKey ) { 6184 return; 6185 } 6186 6187 var keyCode = $.ui.keyCode, 6188 length = this.headers.length, 6189 currentIndex = this.headers.index( event.target ), 6190 toFocus = false; 6191 6192 switch ( event.keyCode ) { 6193 case keyCode.RIGHT: 6194 case keyCode.DOWN: 6195 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 6196 break; 6197 case keyCode.LEFT: 6198 case keyCode.UP: 6199 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 6200 break; 6201 case keyCode.SPACE: 6202 case keyCode.ENTER: 6203 this._eventHandler( event ); 6204 break; 6205 case keyCode.HOME: 6206 toFocus = this.headers[ 0 ]; 6207 break; 6208 case keyCode.END: 6209 toFocus = this.headers[ length - 1 ]; 6210 break; 6211 } 6212 6213 if ( toFocus ) { 6214 $( event.target ).attr( "tabIndex", -1 ); 6215 $( toFocus ).attr( "tabIndex", 0 ); 6216 toFocus.focus(); 6217 event.preventDefault(); 6218 } 6219 }, 6220 6221 _panelKeyDown : function( event ) { 6222 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 6223 $( event.currentTarget ).prev().focus(); 6224 } 6225 }, 6226 6227 refresh: function() { 6228 var options = this.options; 6229 this._processPanels(); 6230 6231 // was collapsed or no panel 6232 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 6233 options.active = false; 6234 this.active = $(); 6235 // active false only when collapsible is true 6236 } if ( options.active === false ) { 6237 this._activate( 0 ); 6238 // was active, but active panel is gone 6239 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 6240 // all remaining panel are disabled 6241 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 6242 options.active = false; 6243 this.active = $(); 6244 // activate previous panel 6245 } else { 6246 this._activate( Math.max( 0, options.active - 1 ) ); 6247 } 6248 // was active, active panel still exists 6249 } else { 6250 // make sure active index is correct 6251 options.active = this.headers.index( this.active ); 6252 } 6253 6254 this._destroyIcons(); 6255 6256 this._refresh(); 6257 }, 6258 6259 _processPanels: function() { 6260 this.headers = this.element.find( this.options.header ) 6261 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 6262 6263 this.headers.next() 6264 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 6265 .filter(":not(.ui-accordion-content-active)") 6266 .hide(); 6267 }, 6268 6269 _refresh: function() { 6270 var maxHeight, 6271 options = this.options, 6272 heightStyle = options.heightStyle, 6273 parent = this.element.parent(), 6274 accordionId = this.accordionId = "ui-accordion-" + 6275 (this.element.attr( "id" ) || ++uid); 6276 6277 this.active = this._findActive( options.active ) 6278 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 6279 .removeClass( "ui-corner-all" ); 6280 this.active.next() 6281 .addClass( "ui-accordion-content-active" ) 6282 .show(); 6283 6284 this.headers 6285 .attr( "role", "tab" ) 6286 .each(function( i ) { 6287 var header = $( this ), 6288 headerId = header.attr( "id" ), 6289 panel = header.next(), 6290 panelId = panel.attr( "id" ); 6291 if ( !headerId ) { 6292 headerId = accordionId + "-header-" + i; 6293 header.attr( "id", headerId ); 6294 } 6295 if ( !panelId ) { 6296 panelId = accordionId + "-panel-" + i; 6297 panel.attr( "id", panelId ); 6298 } 6299 header.attr( "aria-controls", panelId ); 6300 panel.attr( "aria-labelledby", headerId ); 6301 }) 6302 .next() 6303 .attr( "role", "tabpanel" ); 6304 6305 this.headers 6306 .not( this.active ) 6307 .attr({ 6308 "aria-selected": "false", 6309 tabIndex: -1 6310 }) 6311 .next() 6312 .attr({ 6313 "aria-expanded": "false", 6314 "aria-hidden": "true" 6315 }) 6316 .hide(); 6317 6318 // make sure at least one header is in the tab order 6319 if ( !this.active.length ) { 6320 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 6321 } else { 6322 this.active.attr({ 6323 "aria-selected": "true", 6324 tabIndex: 0 6325 }) 6326 .next() 6327 .attr({ 6328 "aria-expanded": "true", 6329 "aria-hidden": "false" 6330 }); 6331 } 6332 6333 this._createIcons(); 6334 6335 this._setupEvents( options.event ); 6336 6337 if ( heightStyle === "fill" ) { 6338 maxHeight = parent.height(); 6339 this.element.siblings( ":visible" ).each(function() { 6340 var elem = $( this ), 6341 position = elem.css( "position" ); 6342 6343 if ( position === "absolute" || position === "fixed" ) { 6344 return; 6345 } 6346 maxHeight -= elem.outerHeight( true ); 6347 }); 6348 6349 this.headers.each(function() { 6350 maxHeight -= $( this ).outerHeight( true ); 6351 }); 6352 6353 this.headers.next() 6354 .each(function() { 6355 $( this ).height( Math.max( 0, maxHeight - 6356 $( this ).innerHeight() + $( this ).height() ) ); 6357 }) 6358 .css( "overflow", "auto" ); 6359 } else if ( heightStyle === "auto" ) { 6360 maxHeight = 0; 6361 this.headers.next() 6362 .each(function() { 6363 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 6364 }) 6365 .height( maxHeight ); 6366 } 6367 }, 6368 6369 _activate: function( index ) { 6370 var active = this._findActive( index )[ 0 ]; 6371 6372 // trying to activate the already active panel 6373 if ( active === this.active[ 0 ] ) { 6374 return; 6375 } 6376 6377 // trying to collapse, simulate a click on the currently active header 6378 active = active || this.active[ 0 ]; 6379 6380 this._eventHandler({ 6381 target: active, 6382 currentTarget: active, 6383 preventDefault: $.noop 6384 }); 6385 }, 6386 6387 _findActive: function( selector ) { 6388 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 6389 }, 6390 6391 _setupEvents: function( event ) { 6392 var events = { 6393 keydown: "_keydown" 6394 }; 6395 if ( event ) { 6396 $.each( event.split(" "), function( index, eventName ) { 6397 events[ eventName ] = "_eventHandler"; 6398 }); 6399 } 6400 6401 this._off( this.headers.add( this.headers.next() ) ); 6402 this._on( this.headers, events ); 6403 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 6404 this._hoverable( this.headers ); 6405 this._focusable( this.headers ); 6406 }, 6407 6408 _eventHandler: function( event ) { 6409 var options = this.options, 6410 active = this.active, 6411 clicked = $( event.currentTarget ), 6412 clickedIsActive = clicked[ 0 ] === active[ 0 ], 6413 collapsing = clickedIsActive && options.collapsible, 6414 toShow = collapsing ? $() : clicked.next(), 6415 toHide = active.next(), 6416 eventData = { 6417 oldHeader: active, 6418 oldPanel: toHide, 6419 newHeader: collapsing ? $() : clicked, 6420 newPanel: toShow 6421 }; 6422 6423 event.preventDefault(); 6424 6425 if ( 6426 // click on active header, but not collapsible 6427 ( clickedIsActive && !options.collapsible ) || 6428 // allow canceling activation 6429 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 6430 return; 6431 } 6432 6433 options.active = collapsing ? false : this.headers.index( clicked ); 6434 6435 // when the call to ._toggle() comes after the class changes 6436 // it causes a very odd bug in IE 8 (see #6720) 6437 this.active = clickedIsActive ? $() : clicked; 6438 this._toggle( eventData ); 6439 6440 // switch classes 6441 // corner classes on the previously active header stay after the animation 6442 active.removeClass( "ui-accordion-header-active ui-state-active" ); 6443 if ( options.icons ) { 6444 active.children( ".ui-accordion-header-icon" ) 6445 .removeClass( options.icons.activeHeader ) 6446 .addClass( options.icons.header ); 6447 } 6448 6449 if ( !clickedIsActive ) { 6450 clicked 6451 .removeClass( "ui-corner-all" ) 6452 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 6453 if ( options.icons ) { 6454 clicked.children( ".ui-accordion-header-icon" ) 6455 .removeClass( options.icons.header ) 6456 .addClass( options.icons.activeHeader ); 6457 } 6458 6459 clicked 6460 .next() 6461 .addClass( "ui-accordion-content-active" ); 6462 } 6463 }, 6464 6465 _toggle: function( data ) { 6466 var toShow = data.newPanel, 6467 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 6468 6469 // handle activating a panel during the animation for another activation 6470 this.prevShow.add( this.prevHide ).stop( true, true ); 6471 this.prevShow = toShow; 6472 this.prevHide = toHide; 6473 6474 if ( this.options.animate ) { 6475 this._animate( toShow, toHide, data ); 6476 } else { 6477 toHide.hide(); 6478 toShow.show(); 6479 this._toggleComplete( data ); 6480 } 6481 6482 toHide.attr({ 6483 "aria-expanded": "false", 6484 "aria-hidden": "true" 6485 }); 6486 toHide.prev().attr( "aria-selected", "false" ); 6487 // if we're switching panels, remove the old header from the tab order 6488 // if we're opening from collapsed state, remove the previous header from the tab order 6489 // if we're collapsing, then keep the collapsing header in the tab order 6490 if ( toShow.length && toHide.length ) { 6491 toHide.prev().attr( "tabIndex", -1 ); 6492 } else if ( toShow.length ) { 6493 this.headers.filter(function() { 6494 return $( this ).attr( "tabIndex" ) === 0; 6495 }) 6496 .attr( "tabIndex", -1 ); 6497 } 6498 6499 toShow 6500 .attr({ 6501 "aria-expanded": "true", 6502 "aria-hidden": "false" 6503 }) 6504 .prev() 6505 .attr({ 6506 "aria-selected": "true", 6507 tabIndex: 0 6508 }); 6509 }, 6510 6511 _animate: function( toShow, toHide, data ) { 6512 var total, easing, duration, 6513 that = this, 6514 adjust = 0, 6515 down = toShow.length && 6516 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 6517 animate = this.options.animate || {}, 6518 options = down && animate.down || animate, 6519 complete = function() { 6520 that._toggleComplete( data ); 6521 }; 6522 6523 if ( typeof options === "number" ) { 6524 duration = options; 6525 } 6526 if ( typeof options === "string" ) { 6527 easing = options; 6528 } 6529 // fall back from options to animation in case of partial down settings 6530 easing = easing || options.easing || animate.easing; 6531 duration = duration || options.duration || animate.duration; 6532 6533 if ( !toHide.length ) { 6534 return toShow.animate( showProps, duration, easing, complete ); 6535 } 6536 if ( !toShow.length ) { 6537 return toHide.animate( hideProps, duration, easing, complete ); 6538 } 6539 6540 total = toShow.show().outerHeight(); 6541 toHide.animate( hideProps, { 6542 duration: duration, 6543 easing: easing, 6544 step: function( now, fx ) { 6545 fx.now = Math.round( now ); 6546 } 6547 }); 6548 toShow 6549 .hide() 6550 .animate( showProps, { 6551 duration: duration, 6552 easing: easing, 6553 complete: complete, 6554 step: function( now, fx ) { 6555 fx.now = Math.round( now ); 6556 if ( fx.prop !== "height" ) { 6557 adjust += fx.now; 6558 } else if ( that.options.heightStyle !== "content" ) { 6559 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 6560 adjust = 0; 6561 } 6562 } 6563 }); 6564 }, 6565 6566 _toggleComplete: function( data ) { 6567 var toHide = data.oldPanel; 6568 6569 toHide 6570 .removeClass( "ui-accordion-content-active" ) 6571 .prev() 6572 .removeClass( "ui-corner-top" ) 6573 .addClass( "ui-corner-all" ); 6574 6575 // Work around for rendering bug in IE (#5421) 6576 if ( toHide.length ) { 6577 toHide.parent()[0].className = toHide.parent()[0].className; 6578 } 6579 6580 this._trigger( "activate", null, data ); 6581 } 6582}); 6583 6584})( jQuery ); 6585 6586(function( $, undefined ) { 6587 6588// used to prevent race conditions with remote data sources 6589var requestIndex = 0; 6590 6591$.widget( "ui.autocomplete", { 6592 version: "1.10.2", 6593 defaultElement: "<input>", 6594 options: { 6595 appendTo: null, 6596 autoFocus: false, 6597 delay: 300, 6598 minLength: 1, 6599 position: { 6600 my: "left top", 6601 at: "left bottom", 6602 collision: "none" 6603 }, 6604 source: null, 6605 6606 // callbacks 6607 change: null, 6608 close: null, 6609 focus: null, 6610 open: null, 6611 response: null, 6612 search: null, 6613 select: null 6614 }, 6615 6616 pending: 0, 6617 6618 _create: function() { 6619 // Some browsers only repeat keydown events, not keypress events, 6620 // so we use the suppressKeyPress flag to determine if we've already 6621 // handled the keydown event. #7269 6622 // Unfortunately the code for & in keypress is the same as the up arrow, 6623 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 6624 // events when we know the keydown event was used to modify the 6625 // search term. #7799 6626 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 6627 nodeName = this.element[0].nodeName.toLowerCase(), 6628 isTextarea = nodeName === "textarea", 6629 isInput = nodeName === "input"; 6630 6631 this.isMultiLine = 6632 // Textareas are always multi-line 6633 isTextarea ? true : 6634 // Inputs are always single-line, even if inside a contentEditable element 6635 // IE also treats inputs as contentEditable 6636 isInput ? false : 6637 // All other element types are determined by whether or not they're contentEditable 6638 this.element.prop( "isContentEditable" ); 6639 6640 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 6641 this.isNewMenu = true; 6642 6643 this.element 6644 .addClass( "ui-autocomplete-input" ) 6645 .attr( "autocomplete", "off" ); 6646 6647 this._on( this.element, { 6648 keydown: function( event ) { 6649 /*jshint maxcomplexity:15*/ 6650 if ( this.element.prop( "readOnly" ) ) { 6651 suppressKeyPress = true; 6652 suppressInput = true; 6653 suppressKeyPressRepeat = true; 6654 return; 6655 } 6656 6657 suppressKeyPress = false; 6658 suppressInput = false; 6659 suppressKeyPressRepeat = false; 6660 var keyCode = $.ui.keyCode; 6661 switch( event.keyCode ) { 6662 case keyCode.PAGE_UP: 6663 suppressKeyPress = true; 6664 this._move( "previousPage", event ); 6665 break; 6666 case keyCode.PAGE_DOWN: 6667 suppressKeyPress = true; 6668 this._move( "nextPage", event ); 6669 break; 6670 case keyCode.UP: 6671 suppressKeyPress = true; 6672 this._keyEvent( "previous", event ); 6673 break; 6674 case keyCode.DOWN: 6675 suppressKeyPress = true; 6676 this._keyEvent( "next", event ); 6677 break; 6678 case keyCode.ENTER: 6679 case keyCode.NUMPAD_ENTER: 6680 // when menu is open and has focus 6681 if ( this.menu.active ) { 6682 // #6055 - Opera still allows the keypress to occur 6683 // which causes forms to submit 6684 suppressKeyPress = true; 6685 event.preventDefault(); 6686 this.menu.select( event ); 6687 } 6688 break; 6689 case keyCode.TAB: 6690 if ( this.menu.active ) { 6691 this.menu.select( event ); 6692 } 6693 break; 6694 case keyCode.ESCAPE: 6695 if ( this.menu.element.is( ":visible" ) ) { 6696 this._value( this.term ); 6697 this.close( event ); 6698 // Different browsers have different default behavior for escape 6699 // Single press can mean undo or clear 6700 // Double press in IE means clear the whole form 6701 event.preventDefault(); 6702 } 6703 break; 6704 default: 6705 suppressKeyPressRepeat = true; 6706 // search timeout should be triggered before the input value is changed 6707 this._searchTimeout( event ); 6708 break; 6709 } 6710 }, 6711 keypress: function( event ) { 6712 if ( suppressKeyPress ) { 6713 suppressKeyPress = false; 6714 event.preventDefault(); 6715 return; 6716 } 6717 if ( suppressKeyPressRepeat ) { 6718 return; 6719 } 6720 6721 // replicate some key handlers to allow them to repeat in Firefox and Opera 6722 var keyCode = $.ui.keyCode; 6723 switch( event.keyCode ) { 6724 case keyCode.PAGE_UP: 6725 this._move( "previousPage", event ); 6726 break; 6727 case keyCode.PAGE_DOWN: 6728 this._move( "nextPage", event ); 6729 break; 6730 case keyCode.UP: 6731 this._keyEvent( "previous", event ); 6732 break; 6733 case keyCode.DOWN: 6734 this._keyEvent( "next", event ); 6735 break; 6736 } 6737 }, 6738 input: function( event ) { 6739 if ( suppressInput ) { 6740 suppressInput = false; 6741 event.preventDefault(); 6742 return; 6743 } 6744 this._searchTimeout( event ); 6745 }, 6746 focus: function() { 6747 this.selectedItem = null; 6748 this.previous = this._value(); 6749 }, 6750 blur: function( event ) { 6751 if ( this.cancelBlur ) { 6752 delete this.cancelBlur; 6753 return; 6754 } 6755 6756 clearTimeout( this.searching ); 6757 this.close( event ); 6758 this._change( event ); 6759 } 6760 }); 6761 6762 this._initSource(); 6763 this.menu = $( "<ul>" ) 6764 .addClass( "ui-autocomplete ui-front" ) 6765 .appendTo( this._appendTo() ) 6766 .menu({ 6767 // custom key handling for now 6768 input: $(), 6769 // disable ARIA support, the live region takes care of that 6770 role: null 6771 }) 6772 .hide() 6773 .data( "ui-menu" ); 6774 6775 this._on( this.menu.element, { 6776 mousedown: function( event ) { 6777 // prevent moving focus out of the text field 6778 event.preventDefault(); 6779 6780 // IE doesn't prevent moving focus even with event.preventDefault() 6781 // so we set a flag to know when we should ignore the blur event 6782 this.cancelBlur = true; 6783 this._delay(function() { 6784 delete this.cancelBlur; 6785 }); 6786 6787 // clicking on the scrollbar causes focus to shift to the body 6788 // but we can't detect a mouseup or a click immediately afterward 6789 // so we have to track the next mousedown and close the menu if 6790 // the user clicks somewhere outside of the autocomplete 6791 var menuElement = this.menu.element[ 0 ]; 6792 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 6793 this._delay(function() { 6794 var that = this; 6795 this.document.one( "mousedown", function( event ) { 6796 if ( event.target !== that.element[ 0 ] && 6797 event.target !== menuElement && 6798 !$.contains( menuElement, event.target ) ) { 6799 that.close(); 6800 } 6801 }); 6802 }); 6803 } 6804 }, 6805 menufocus: function( event, ui ) { 6806 // support: Firefox 6807 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 6808 if ( this.isNewMenu ) { 6809 this.isNewMenu = false; 6810 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 6811 this.menu.blur(); 6812 6813 this.document.one( "mousemove", function() { 6814 $( event.target ).trigger( event.originalEvent ); 6815 }); 6816 6817 return; 6818 } 6819 } 6820 6821 var item = ui.item.data( "ui-autocomplete-item" ); 6822 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6823 // use value to match what will end up in the input, if it was a key event 6824 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6825 this._value( item.value ); 6826 } 6827 } else { 6828 // Normally the input is populated with the item's value as the 6829 // menu is navigated, causing screen readers to notice a change and 6830 // announce the item. Since the focus event was canceled, this doesn't 6831 // happen, so we update the live region so that screen readers can 6832 // still notice the change and announce it. 6833 this.liveRegion.text( item.value ); 6834 } 6835 }, 6836 menuselect: function( event, ui ) { 6837 var item = ui.item.data( "ui-autocomplete-item" ), 6838 previous = this.previous; 6839 6840 // only trigger when focus was lost (click on menu) 6841 if ( this.element[0] !== this.document[0].activeElement ) { 6842 this.element.focus(); 6843 this.previous = previous; 6844 // #6109 - IE triggers two focus events and the second 6845 // is asynchronous, so we need to reset the previous 6846 // term synchronously and asynchronously :-( 6847 this._delay(function() { 6848 this.previous = previous; 6849 this.selectedItem = item; 6850 }); 6851 } 6852 6853 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6854 this._value( item.value ); 6855 } 6856 // reset the term after the select event 6857 // this allows custom select handling to work properly 6858 this.term = this._value(); 6859 6860 this.close( event ); 6861 this.selectedItem = item; 6862 } 6863 }); 6864 6865 this.liveRegion = $( "<span>", { 6866 role: "status", 6867 "aria-live": "polite" 6868 }) 6869 .addClass( "ui-helper-hidden-accessible" ) 6870 .insertAfter( this.element ); 6871 6872 // turning off autocomplete prevents the browser from remembering the 6873 // value when navigating through history, so we re-enable autocomplete 6874 // if the page is unloaded before the widget is destroyed. #7790 6875 this._on( this.window, { 6876 beforeunload: function() { 6877 this.element.removeAttr( "autocomplete" ); 6878 } 6879 }); 6880 }, 6881 6882 _destroy: function() { 6883 clearTimeout( this.searching ); 6884 this.element 6885 .removeClass( "ui-autocomplete-input" ) 6886 .removeAttr( "autocomplete" ); 6887 this.menu.element.remove(); 6888 this.liveRegion.remove(); 6889 }, 6890 6891 _setOption: function( key, value ) { 6892 this._super( key, value ); 6893 if ( key === "source" ) { 6894 this._initSource(); 6895 } 6896 if ( key === "appendTo" ) { 6897 this.menu.element.appendTo( this._appendTo() ); 6898 } 6899 if ( key === "disabled" && value && this.xhr ) { 6900 this.xhr.abort(); 6901 } 6902 }, 6903 6904 _appendTo: function() { 6905 var element = this.options.appendTo; 6906 6907 if ( element ) { 6908 element = element.jquery || element.nodeType ? 6909 $( element ) : 6910 this.document.find( element ).eq( 0 ); 6911 } 6912 6913 if ( !element ) { 6914 element = this.element.closest( ".ui-front" ); 6915 } 6916 6917 if ( !element.length ) { 6918 element = this.document[0].body; 6919 } 6920 6921 return element; 6922 }, 6923 6924 _initSource: function() { 6925 var array, url, 6926 that = this; 6927 if ( $.isArray(this.options.source) ) { 6928 array = this.options.source; 6929 this.source = function( request, response ) { 6930 response( $.ui.autocomplete.filter( array, request.term ) ); 6931 }; 6932 } else if ( typeof this.options.source === "string" ) { 6933 url = this.options.source; 6934 this.source = function( request, response ) { 6935 if ( that.xhr ) { 6936 that.xhr.abort(); 6937 } 6938 that.xhr = $.ajax({ 6939 url: url, 6940 data: request, 6941 dataType: "json", 6942 success: function( data ) { 6943 response( data ); 6944 }, 6945 error: function() { 6946 response( [] ); 6947 } 6948 }); 6949 }; 6950 } else { 6951 this.source = this.options.source; 6952 } 6953 }, 6954 6955 _searchTimeout: function( event ) { 6956 clearTimeout( this.searching ); 6957 this.searching = this._delay(function() { 6958 // only search if the value has changed 6959 if ( this.term !== this._value() ) { 6960 this.selectedItem = null; 6961 this.search( null, event ); 6962 } 6963 }, this.options.delay ); 6964 }, 6965 6966 search: function( value, event ) { 6967 value = value != null ? value : this._value(); 6968 6969 // always save the actual value, not the one passed as an argument 6970 this.term = this._value(); 6971 6972 if ( value.length < this.options.minLength ) { 6973 return this.close( event ); 6974 } 6975 6976 if ( this._trigger( "search", event ) === false ) { 6977 return; 6978 } 6979 6980 return this._search( value ); 6981 }, 6982 6983 _search: function( value ) { 6984 this.pending++; 6985 this.element.addClass( "ui-autocomplete-loading" ); 6986 this.cancelSearch = false; 6987 6988 this.source( { term: value }, this._response() ); 6989 }, 6990 6991 _response: function() { 6992 var that = this, 6993 index = ++requestIndex; 6994 6995 return function( content ) { 6996 if ( index === requestIndex ) { 6997 that.__response( content ); 6998 } 6999 7000 that.pending--; 7001 if ( !that.pending ) { 7002 that.element.removeClass( "ui-autocomplete-loading" ); 7003 } 7004 }; 7005 }, 7006 7007 __response: function( content ) { 7008 if ( content ) { 7009 content = this._normalize( content ); 7010 } 7011 this._trigger( "response", null, { content: content } ); 7012 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 7013 this._suggest( content ); 7014 this._trigger( "open" ); 7015 } else { 7016 // use ._close() instead of .close() so we don't cancel future searches 7017 this._close(); 7018 } 7019 }, 7020 7021 close: function( event ) { 7022 this.cancelSearch = true; 7023 this._close( event ); 7024 }, 7025 7026 _close: function( event ) { 7027 if ( this.menu.element.is( ":visible" ) ) { 7028 this.menu.element.hide(); 7029 this.menu.blur(); 7030 this.isNewMenu = true; 7031 this._trigger( "close", event ); 7032 } 7033 }, 7034 7035 _change: function( event ) { 7036 if ( this.previous !== this._value() ) { 7037 this._trigger( "change", event, { item: this.selectedItem } ); 7038 } 7039 }, 7040 7041 _normalize: function( items ) { 7042 // assume all items have the right format when the first item is complete 7043 if ( items.length && items[0].label && items[0].value ) { 7044 return items; 7045 } 7046 return $.map( items, function( item ) { 7047 if ( typeof item === "string" ) { 7048 return { 7049 label: item, 7050 value: item 7051 }; 7052 } 7053 return $.extend({ 7054 label: item.label || item.value, 7055 value: item.value || item.label 7056 }, item ); 7057 }); 7058 }, 7059 7060 _suggest: function( items ) { 7061 var ul = this.menu.element.empty(); 7062 this._renderMenu( ul, items ); 7063 this.isNewMenu = true; 7064 this.menu.refresh(); 7065 7066 // size and position menu 7067 ul.show(); 7068 this._resizeMenu(); 7069 ul.position( $.extend({ 7070 of: this.element 7071 }, this.options.position )); 7072 7073 if ( this.options.autoFocus ) { 7074 this.menu.next(); 7075 } 7076 }, 7077 7078 _resizeMenu: function() { 7079 var ul = this.menu.element; 7080 ul.outerWidth( Math.max( 7081 // Firefox wraps long text (possibly a rounding bug) 7082 // so we add 1px to avoid the wrapping (#7513) 7083 ul.width( "" ).outerWidth() + 1, 7084 this.element.outerWidth() 7085 ) ); 7086 }, 7087 7088 _renderMenu: function( ul, items ) { 7089 var that = this; 7090 $.each( items, function( index, item ) { 7091 that._renderItemData( ul, item ); 7092 }); 7093 }, 7094 7095 _renderItemData: function( ul, item ) { 7096 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 7097 }, 7098 7099 _renderItem: function( ul, item ) { 7100 return $( "<li>" ) 7101 .append( $( "<a>" ).text( item.label ) ) 7102 .appendTo( ul ); 7103 }, 7104 7105 _move: function( direction, event ) { 7106 if ( !this.menu.element.is( ":visible" ) ) { 7107 this.search( null, event ); 7108 return; 7109 } 7110 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 7111 this.menu.isLastItem() && /^next/.test( direction ) ) { 7112 this._value( this.term ); 7113 this.menu.blur(); 7114 return; 7115 } 7116 this.menu[ direction ]( event ); 7117 }, 7118 7119 widget: function() { 7120 return this.menu.element; 7121 }, 7122 7123 _value: function() { 7124 return this.valueMethod.apply( this.element, arguments ); 7125 }, 7126 7127 _keyEvent: function( keyEvent, event ) { 7128 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 7129 this._move( keyEvent, event ); 7130 7131 // prevents moving cursor to beginning/end of the text field in some browsers 7132 event.preventDefault(); 7133 } 7134 } 7135}); 7136 7137$.extend( $.ui.autocomplete, { 7138 escapeRegex: function( value ) { 7139 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 7140 }, 7141 filter: function(array, term) { 7142 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 7143 return $.grep( array, function(value) { 7144 return matcher.test( value.label || value.value || value ); 7145 }); 7146 } 7147}); 7148 7149 7150// live region extension, adding a `messages` option 7151// NOTE: This is an experimental API. We are still investigating 7152// a full solution for string manipulation and internationalization. 7153$.widget( "ui.autocomplete", $.ui.autocomplete, { 7154 options: { 7155 messages: { 7156 noResults: "No search results.", 7157 results: function( amount ) { 7158 return amount + ( amount > 1 ? " results are" : " result is" ) + 7159 " available, use up and down arrow keys to navigate."; 7160 } 7161 } 7162 }, 7163 7164 __response: function( content ) { 7165 var message; 7166 this._superApply( arguments ); 7167 if ( this.options.disabled || this.cancelSearch ) { 7168 return; 7169 } 7170 if ( content && content.length ) { 7171 message = this.options.messages.results( content.length ); 7172 } else { 7173 message = this.options.messages.noResults; 7174 } 7175 this.liveRegion.text( message ); 7176 } 7177}); 7178 7179}( jQuery )); 7180 7181(function( $, undefined ) { 7182 7183var lastActive, startXPos, startYPos, clickDragged, 7184 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 7185 stateClasses = "ui-state-hover ui-state-active ", 7186 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", 7187 formResetHandler = function() { 7188 var buttons = $( this ).find( ":ui-button" ); 7189 setTimeout(function() { 7190 buttons.button( "refresh" ); 7191 }, 1 ); 7192 }, 7193 radioGroup = function( radio ) { 7194 var name = radio.name, 7195 form = radio.form, 7196 radios = $( [] ); 7197 if ( name ) { 7198 name = name.replace( /'/g, "\\'" ); 7199 if ( form ) { 7200 radios = $( form ).find( "[name='" + name + "']" ); 7201 } else { 7202 radios = $( "[name='" + name + "']", radio.ownerDocument ) 7203 .filter(function() { 7204 return !this.form; 7205 }); 7206 } 7207 } 7208 return radios; 7209 }; 7210 7211$.widget( "ui.button", { 7212 version: "1.10.2", 7213 defaultElement: "<button>", 7214 options: { 7215 disabled: null, 7216 text: true, 7217 label: null, 7218 icons: { 7219 primary: null, 7220 secondary: null 7221 } 7222 }, 7223 _create: function() { 7224 this.element.closest( "form" ) 7225 .unbind( "reset" + this.eventNamespace ) 7226 .bind( "reset" + this.eventNamespace, formResetHandler ); 7227 7228 if ( typeof this.options.disabled !== "boolean" ) { 7229 this.options.disabled = !!this.element.prop( "disabled" ); 7230 } else { 7231 this.element.prop( "disabled", this.options.disabled ); 7232 } 7233 7234 this._determineButtonType(); 7235 this.hasTitle = !!this.buttonElement.attr( "title" ); 7236 7237 var that = this, 7238 options = this.options, 7239 toggleButton = this.type === "checkbox" || this.type === "radio", 7240 activeClass = !toggleButton ? "ui-state-active" : "", 7241 focusClass = "ui-state-focus"; 7242 7243 if ( options.label === null ) { 7244 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 7245 } 7246 7247 this._hoverable( this.buttonElement ); 7248 7249 this.buttonElement 7250 .addClass( baseClasses ) 7251 .attr( "role", "button" ) 7252 .bind( "mouseenter" + this.eventNamespace, function() { 7253 if ( options.disabled ) { 7254 return; 7255 } 7256 if ( this === lastActive ) { 7257 $( this ).addClass( "ui-state-active" ); 7258 } 7259 }) 7260 .bind( "mouseleave" + this.eventNamespace, function() { 7261 if ( options.disabled ) { 7262 return; 7263 } 7264 $( this ).removeClass( activeClass ); 7265 }) 7266 .bind( "click" + this.eventNamespace, function( event ) { 7267 if ( options.disabled ) { 7268 event.preventDefault(); 7269 event.stopImmediatePropagation(); 7270 } 7271 }); 7272 7273 this.element 7274 .bind( "focus" + this.eventNamespace, function() { 7275 // no need to check disabled, focus won't be triggered anyway 7276 that.buttonElement.addClass( focusClass ); 7277 }) 7278 .bind( "blur" + this.eventNamespace, function() { 7279 that.buttonElement.removeClass( focusClass ); 7280 }); 7281 7282 if ( toggleButton ) { 7283 this.element.bind( "change" + this.eventNamespace, function() { 7284 if ( clickDragged ) { 7285 return; 7286 } 7287 that.refresh(); 7288 }); 7289 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 7290 // prevents issue where button state changes but checkbox/radio checked state 7291 // does not in Firefox (see ticket #6970) 7292 this.buttonElement 7293 .bind( "mousedown" + this.eventNamespace, function( event ) { 7294 if ( options.disabled ) { 7295 return; 7296 } 7297 clickDragged = false; 7298 startXPos = event.pageX; 7299 startYPos = event.pageY; 7300 }) 7301 .bind( "mouseup" + this.eventNamespace, function( event ) { 7302 if ( options.disabled ) { 7303 return; 7304 } 7305 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 7306 clickDragged = true; 7307 } 7308 }); 7309 } 7310 7311 if ( this.type === "checkbox" ) { 7312 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7313 if ( options.disabled || clickDragged ) { 7314 return false; 7315 } 7316 }); 7317 } else if ( this.type === "radio" ) { 7318 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7319 if ( options.disabled || clickDragged ) { 7320 return false; 7321 } 7322 $( this ).addClass( "ui-state-active" ); 7323 that.buttonElement.attr( "aria-pressed", "true" ); 7324 7325 var radio = that.element[ 0 ]; 7326 radioGroup( radio ) 7327 .not( radio ) 7328 .map(function() { 7329 return $( this ).button( "widget" )[ 0 ]; 7330 }) 7331 .removeClass( "ui-state-active" ) 7332 .attr( "aria-pressed", "false" ); 7333 }); 7334 } else { 7335 this.buttonElement 7336 .bind( "mousedown" + this.eventNamespace, function() { 7337 if ( options.disabled ) { 7338 return false; 7339 } 7340 $( this ).addClass( "ui-state-active" ); 7341 lastActive = this; 7342 that.document.one( "mouseup", function() { 7343 lastActive = null; 7344 }); 7345 }) 7346 .bind( "mouseup" + this.eventNamespace, function() { 7347 if ( options.disabled ) { 7348 return false; 7349 } 7350 $( this ).removeClass( "ui-state-active" ); 7351 }) 7352 .bind( "keydown" + this.eventNamespace, function(event) { 7353 if ( options.disabled ) { 7354 return false; 7355 } 7356 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 7357 $( this ).addClass( "ui-state-active" ); 7358 } 7359 }) 7360 // see #8559, we bind to blur here in case the button element loses 7361 // focus between keydown and keyup, it would be left in an "active" state 7362 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 7363 $( this ).removeClass( "ui-state-active" ); 7364 }); 7365 7366 if ( this.buttonElement.is("a") ) { 7367 this.buttonElement.keyup(function(event) { 7368 if ( event.keyCode === $.ui.keyCode.SPACE ) { 7369 // TODO pass through original event correctly (just as 2nd argument doesn't work) 7370 $( this ).click(); 7371 } 7372 }); 7373 } 7374 } 7375 7376 // TODO: pull out $.Widget's handling for the disabled option into 7377 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 7378 // be overridden by individual plugins 7379 this._setOption( "disabled", options.disabled ); 7380 this._resetButton(); 7381 }, 7382 7383 _determineButtonType: function() { 7384 var ancestor, labelSelector, checked; 7385 7386 if ( this.element.is("[type=checkbox]") ) { 7387 this.type = "checkbox"; 7388 } else if ( this.element.is("[type=radio]") ) { 7389 this.type = "radio"; 7390 } else if ( this.element.is("input") ) { 7391 this.type = "input"; 7392 } else { 7393 this.type = "button"; 7394 } 7395 7396 if ( this.type === "checkbox" || this.type === "radio" ) { 7397 // we don't search against the document in case the element 7398 // is disconnected from the DOM 7399 ancestor = this.element.parents().last(); 7400 labelSelector = "label[for='" + this.element.attr("id") + "']"; 7401 this.buttonElement = ancestor.find( labelSelector ); 7402 if ( !this.buttonElement.length ) { 7403 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 7404 this.buttonElement = ancestor.filter( labelSelector ); 7405 if ( !this.buttonElement.length ) { 7406 this.buttonElement = ancestor.find( labelSelector ); 7407 } 7408 } 7409 this.element.addClass( "ui-helper-hidden-accessible" ); 7410 7411 checked = this.element.is( ":checked" ); 7412 if ( checked ) { 7413 this.buttonElement.addClass( "ui-state-active" ); 7414 } 7415 this.buttonElement.prop( "aria-pressed", checked ); 7416 } else { 7417 this.buttonElement = this.element; 7418 } 7419 }, 7420 7421 widget: function() { 7422 return this.buttonElement; 7423 }, 7424 7425 _destroy: function() { 7426 this.element 7427 .removeClass( "ui-helper-hidden-accessible" ); 7428 this.buttonElement 7429 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 7430 .removeAttr( "role" ) 7431 .removeAttr( "aria-pressed" ) 7432 .html( this.buttonElement.find(".ui-button-text").html() ); 7433 7434 if ( !this.hasTitle ) { 7435 this.buttonElement.removeAttr( "title" ); 7436 } 7437 }, 7438 7439 _setOption: function( key, value ) { 7440 this._super( key, value ); 7441 if ( key === "disabled" ) { 7442 if ( value ) { 7443 this.element.prop( "disabled", true ); 7444 } else { 7445 this.element.prop( "disabled", false ); 7446 } 7447 return; 7448 } 7449 this._resetButton(); 7450 }, 7451 7452 refresh: function() { 7453 //See #8237 & #8828 7454 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 7455 7456 if ( isDisabled !== this.options.disabled ) { 7457 this._setOption( "disabled", isDisabled ); 7458 } 7459 if ( this.type === "radio" ) { 7460 radioGroup( this.element[0] ).each(function() { 7461 if ( $( this ).is( ":checked" ) ) { 7462 $( this ).button( "widget" ) 7463 .addClass( "ui-state-active" ) 7464 .attr( "aria-pressed", "true" ); 7465 } else { 7466 $( this ).button( "widget" ) 7467 .removeClass( "ui-state-active" ) 7468 .attr( "aria-pressed", "false" ); 7469 } 7470 }); 7471 } else if ( this.type === "checkbox" ) { 7472 if ( this.element.is( ":checked" ) ) { 7473 this.buttonElement 7474 .addClass( "ui-state-active" ) 7475 .attr( "aria-pressed", "true" ); 7476 } else { 7477 this.buttonElement 7478 .removeClass( "ui-state-active" ) 7479 .attr( "aria-pressed", "false" ); 7480 } 7481 } 7482 }, 7483 7484 _resetButton: function() { 7485 if ( this.type === "input" ) { 7486 if ( this.options.label ) { 7487 this.element.val( this.options.label ); 7488 } 7489 return; 7490 } 7491 var buttonElement = this.buttonElement.removeClass( typeClasses ), 7492 buttonText = $( "<span></span>", this.document[0] ) 7493 .addClass( "ui-button-text" ) 7494 .html( this.options.label ) 7495 .appendTo( buttonElement.empty() ) 7496 .text(), 7497 icons = this.options.icons, 7498 multipleIcons = icons.primary && icons.secondary, 7499 buttonClasses = []; 7500 7501 if ( icons.primary || icons.secondary ) { 7502 if ( this.options.text ) { 7503 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 7504 } 7505 7506 if ( icons.primary ) { 7507 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 7508 } 7509 7510 if ( icons.secondary ) { 7511 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 7512 } 7513 7514 if ( !this.options.text ) { 7515 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 7516 7517 if ( !this.hasTitle ) { 7518 buttonElement.attr( "title", $.trim( buttonText ) ); 7519 } 7520 } 7521 } else { 7522 buttonClasses.push( "ui-button-text-only" ); 7523 } 7524 buttonElement.addClass( buttonClasses.join( " " ) ); 7525 } 7526}); 7527 7528$.widget( "ui.buttonset", { 7529 version: "1.10.2", 7530 options: { 7531 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 7532 }, 7533 7534 _create: function() { 7535 this.element.addClass( "ui-buttonset" ); 7536 }, 7537 7538 _init: function() { 7539 this.refresh(); 7540 }, 7541 7542 _setOption: function( key, value ) { 7543 if ( key === "disabled" ) { 7544 this.buttons.button( "option", key, value ); 7545 } 7546 7547 this._super( key, value ); 7548 }, 7549 7550 refresh: function() { 7551 var rtl = this.element.css( "direction" ) === "rtl"; 7552 7553 this.buttons = this.element.find( this.options.items ) 7554 .filter( ":ui-button" ) 7555 .button( "refresh" ) 7556 .end() 7557 .not( ":ui-button" ) 7558 .button() 7559 .end() 7560 .map(function() { 7561 return $( this ).button( "widget" )[ 0 ]; 7562 }) 7563 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 7564 .filter( ":first" ) 7565 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 7566 .end() 7567 .filter( ":last" ) 7568 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 7569 .end() 7570 .end(); 7571 }, 7572 7573 _destroy: function() { 7574 this.element.removeClass( "ui-buttonset" ); 7575 this.buttons 7576 .map(function() { 7577 return $( this ).button( "widget" )[ 0 ]; 7578 }) 7579 .removeClass( "ui-corner-left ui-corner-right" ) 7580 .end() 7581 .button( "destroy" ); 7582 } 7583}); 7584 7585}( jQuery ) ); 7586 7587(function( $, undefined ) { 7588 7589$.extend($.ui, { datepicker: { version: "1.10.2" } }); 7590 7591var PROP_NAME = "datepicker", 7592 dpuuid = new Date().getTime(), 7593 instActive; 7594 7595/* Date picker manager. 7596 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7597 Settings for (groups of) date pickers are maintained in an instance object, 7598 allowing multiple different settings on the same page. */ 7599 7600function Datepicker() { 7601 this._curInst = null; // The current instance in use 7602 this._keyEvent = false; // If the last event was a key event 7603 this._disabledInputs = []; // List of date picker inputs that have been disabled 7604 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7605 this._inDialog = false; // True if showing within a "dialog", false if not 7606 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 7607 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 7608 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 7609 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 7610 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 7611 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 7612 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 7613 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 7614 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 7615 this.regional = []; // Available regional settings, indexed by language code 7616 this.regional[""] = { // Default regional settings 7617 closeText: "Done", // Display text for close link 7618 prevText: "Prev", // Display text for previous month link 7619 nextText: "Next", // Display text for next month link 7620 currentText: "Today", // Display text for current month link 7621 monthNames: ["January","February","March","April","May","June", 7622 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 7623 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 7624 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 7625 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 7626 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 7627 weekHeader: "Wk", // Column header for week of the year 7628 dateFormat: "mm/dd/yy", // See format options on parseDate 7629 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7630 isRTL: false, // True if right-to-left language, false if left-to-right 7631 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7632 yearSuffix: "" // Additional text to append to the year in the month headers 7633 }; 7634 this._defaults = { // Global defaults for all the date picker instances 7635 showOn: "focus", // "focus" for popup on focus, 7636 // "button" for trigger button, or "both" for either
vendor: 6,360 bytes, lines 7637-7766
7637 showAnim: "fadeIn", // Name of jQuery animation for popup 7638 showOptions: {}, // Options for enhanced animations 7639 defaultDate: null, // Used when field is blank: actual date, 7640 // +/-number for offset from today, null for today 7641 appendText: "", // Display text following the input box, e.g. showing the format 7642 buttonText: "...", // Text for trigger button 7643 buttonImage: "", // URL for trigger button image 7644 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7645 hideIfNoPrevNext: false, // True to hide next/previous month links 7646 // if not applicable, false to just disable them 7647 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7648 gotoCurrent: false, // True if today link goes back to current selection instead 7649 changeMonth: false, // True if month can be selected directly, false if only prev/next 7650 changeYear: false, // True if year can be selected directly, false if only prev/next 7651 yearRange: "c-10:c+10", // Range of years to display in drop-down, 7652 // either relative to today's year (-nn:+nn), relative to currently displayed year 7653 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7654 showOtherMonths: false, // True to show dates in other months, false to leave blank 7655 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7656 showWeek: false, // True to show week of the year, false to not show it 7657 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7658 // takes a Date and returns the number of the week for it 7659 shortYearCutoff: "+10", // Short year values < this are in the current century, 7660 // > this are in the previous century, 7661 // string value starting with "+" for current year + value 7662 minDate: null, // The earliest selectable date, or null for no limit 7663 maxDate: null, // The latest selectable date, or null for no limit 7664 duration: "fast", // Duration of display/closure 7665 beforeShowDay: null, // Function that takes a date and returns an array with 7666 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 7667 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7668 beforeShow: null, // Function that takes an input field and 7669 // returns a set of custom settings for the date picker 7670 onSelect: null, // Define a callback function when a date is selected 7671 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7672 onClose: null, // Define a callback function when the datepicker is closed 7673 numberOfMonths: 1, // Number of months to show at a time 7674 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7675 stepMonths: 1, // Number of months to step back/forward 7676 stepBigMonths: 12, // Number of months to step back/forward for the big links 7677 altField: "", // Selector for an alternate field to store selected dates into 7678 altFormat: "", // The date format to use for the alternate field 7679 constrainInput: true, // The input is constrained by the current date format 7680 showButtonPanel: false, // True to show button panel, false to not show it 7681 autoSize: false, // True to size the input for the date format, false to leave as is 7682 disabled: false // The initial disabled state 7683 }; 7684 $.extend(this._defaults, this.regional[""]); 7685 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 7686} 7687 7688$.extend(Datepicker.prototype, { 7689 /* Class name added to elements to indicate already configured with a date picker. */ 7690 markerClassName: "hasDatepicker", 7691 7692 //Keep track of the maximum number of rows displayed (see #7043) 7693 maxRows: 4, 7694 7695 // TODO rename to "widget" when switching to widget factory 7696 _widgetDatepicker: function() { 7697 return this.dpDiv; 7698 }, 7699 7700 /* Override the default settings for all instances of the date picker. 7701 * @param settings object - the new settings to use as defaults (anonymous object) 7702 * @return the manager object 7703 */ 7704 setDefaults: function(settings) { 7705 extendRemove(this._defaults, settings || {}); 7706 return this; 7707 }, 7708 7709 /* Attach the date picker to a jQuery selection. 7710 * @param target element - the target input field or division or span 7711 * @param settings object - the new settings to use for this date picker instance (anonymous) 7712 */ 7713 _attachDatepicker: function(target, settings) { 7714 var nodeName, inline, inst; 7715 nodeName = target.nodeName.toLowerCase(); 7716 inline = (nodeName === "div" || nodeName === "span"); 7717 if (!target.id) { 7718 this.uuid += 1; 7719 target.id = "dp" + this.uuid; 7720 } 7721 inst = this._newInst($(target), inline); 7722 inst.settings = $.extend({}, settings || {}); 7723 if (nodeName === "input") { 7724 this._connectDatepicker(target, inst); 7725 } else if (inline) { 7726 this._inlineDatepicker(target, inst); 7727 } 7728 }, 7729 7730 /* Create a new instance object. */ 7731 _newInst: function(target, inline) { 7732 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 7733 return {id: id, input: target, // associated target 7734 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 7735 drawMonth: 0, drawYear: 0, // month being drawn 7736 inline: inline, // is datepicker inline or not 7737 dpDiv: (!inline ? this.dpDiv : // presentation div 7738 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 7739 }, 7740 7741 /* Attach the date picker to an input field. */ 7742 _connectDatepicker: function(target, inst) { 7743 var input = $(target); 7744 inst.append = $([]); 7745 inst.trigger = $([]); 7746 if (input.hasClass(this.markerClassName)) { 7747 return; 7748 } 7749 this._attachments(input, inst); 7750 input.addClass(this.markerClassName).keydown(this._doKeyDown). 7751 keypress(this._doKeyPress).keyup(this._doKeyUp); 7752 this._autoSize(inst); 7753 $.data(target, PROP_NAME, inst); 7754 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 7755 if( inst.settings.disabled ) { 7756 this._disableDatepicker( target ); 7757 } 7758 }, 7759 7760 /* Make attachments based on settings. */ 7761 _attachments: function(input, inst) { 7762 var showOn, buttonText, buttonImage, 7763 appendText = this._get(inst, "appendText"), 7764 isRTL = this._get(inst, "isRTL"); 7765 7766 if (inst.append) {
vendor: 5,777 bytes, lines 7767-7922
7767 inst.append.remove(); 7768 } 7769 if (appendText) { 7770 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 7771 input[isRTL ? "before" : "after"](inst.append); 7772 } 7773 7774 input.unbind("focus", this._showDatepicker); 7775 7776 if (inst.trigger) { 7777 inst.trigger.remove(); 7778 } 7779 7780 showOn = this._get(inst, "showOn"); 7781 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 7782 input.focus(this._showDatepicker); 7783 } 7784 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 7785 buttonText = this._get(inst, "buttonText"); 7786 buttonImage = this._get(inst, "buttonImage"); 7787 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 7788 $("<img/>").addClass(this._triggerClass). 7789 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 7790 $("<button type='button'></button>").addClass(this._triggerClass). 7791 html(!buttonImage ? buttonText : $("<img/>").attr( 7792 { src:buttonImage, alt:buttonText, title:buttonText }))); 7793 input[isRTL ? "before" : "after"](inst.trigger); 7794 inst.trigger.click(function() { 7795 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 7796 $.datepicker._hideDatepicker(); 7797 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 7798 $.datepicker._hideDatepicker(); 7799 $.datepicker._showDatepicker(input[0]); 7800 } else { 7801 $.datepicker._showDatepicker(input[0]); 7802 } 7803 return false; 7804 }); 7805 } 7806 }, 7807 7808 /* Apply the maximum length for the date format. */ 7809 _autoSize: function(inst) { 7810 if (this._get(inst, "autoSize") && !inst.inline) { 7811 var findMax, max, maxI, i, 7812 date = new Date(2009, 12 - 1, 20), // Ensure double digits 7813 dateFormat = this._get(inst, "dateFormat"); 7814 7815 if (dateFormat.match(/[DM]/)) { 7816 findMax = function(names) { 7817 max = 0; 7818 maxI = 0; 7819 for (i = 0; i < names.length; i++) { 7820 if (names[i].length > max) { 7821 max = names[i].length; 7822 maxI = i; 7823 } 7824 } 7825 return maxI; 7826 }; 7827 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7828 "monthNames" : "monthNamesShort")))); 7829 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7830 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 7831 } 7832 inst.input.attr("size", this._formatDate(inst, date).length); 7833 } 7834 }, 7835 7836 /* Attach an inline date picker to a div. */ 7837 _inlineDatepicker: function(target, inst) { 7838 var divSpan = $(target); 7839 if (divSpan.hasClass(this.markerClassName)) { 7840 return; 7841 } 7842 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 7843 $.data(target, PROP_NAME, inst); 7844 this._setDate(inst, this._getDefaultDate(inst), true); 7845 this._updateDatepicker(inst); 7846 this._updateAlternate(inst); 7847 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7848 if( inst.settings.disabled ) { 7849 this._disableDatepicker( target ); 7850 } 7851 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7852 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7853 inst.dpDiv.css( "display", "block" ); 7854 }, 7855 7856 /* Pop-up the date picker in a "dialog" box. 7857 * @param input element - ignored 7858 * @param date string or Date - the initial date to display 7859 * @param onSelect function - the function to call when a date is selected 7860 * @param settings object - update the dialog date picker instance's settings (anonymous object) 7861 * @param pos int[2] - coordinates for the dialog's position within the screen or 7862 * event - with x/y coordinates or 7863 * leave empty for default (screen centre) 7864 * @return the manager object 7865 */ 7866 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 7867 var id, browserWidth, browserHeight, scrollX, scrollY, 7868 inst = this._dialogInst; // internal instance 7869 7870 if (!inst) { 7871 this.uuid += 1; 7872 id = "dp" + this.uuid; 7873 this._dialogInput = $("<input type='text' id='" + id + 7874 "' style='position: absolute; top: -100px; width: 0px;'/>"); 7875 this._dialogInput.keydown(this._doKeyDown); 7876 $("body").append(this._dialogInput); 7877 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7878 inst.settings = {}; 7879 $.data(this._dialogInput[0], PROP_NAME, inst); 7880 } 7881 extendRemove(inst.settings, settings || {}); 7882 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 7883 this._dialogInput.val(date); 7884 7885 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7886 if (!this._pos) { 7887 browserWidth = document.documentElement.clientWidth; 7888 browserHeight = document.documentElement.clientHeight; 7889 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7890 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7891 this._pos = // should use actual width/height below 7892 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7893 } 7894 7895 // move input on screen for focus, but hidden behind dialog 7896 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 7897 inst.settings.onSelect = onSelect; 7898 this._inDialog = true; 7899 this.dpDiv.addClass(this._dialogClass); 7900 this._showDatepicker(this._dialogInput[0]); 7901 if ($.blockUI) { 7902 $.blockUI(this.dpDiv); 7903 } 7904 $.data(this._dialogInput[0], PROP_NAME, inst); 7905 return this; 7906 }, 7907 7908 /* Detach a datepicker from its control. 7909 * @param target element - the target input field or division or span 7910 */ 7911 _destroyDatepicker: function(target) { 7912 var nodeName, 7913 $target = $(target), 7914 inst = $.data(target, PROP_NAME); 7915 7916 if (!$target.hasClass(this.markerClassName)) { 7917 return; 7918 } 7919 7920 nodeName = target.nodeName.toLowerCase(); 7921 $.removeData(target, PROP_NAME); 7922 if (nodeName === "input") {
vendor: 4,434 bytes, lines 7923-8055
7923 inst.append.remove(); 7924 inst.trigger.remove(); 7925 $target.removeClass(this.markerClassName). 7926 unbind("focus", this._showDatepicker). 7927 unbind("keydown", this._doKeyDown). 7928 unbind("keypress", this._doKeyPress). 7929 unbind("keyup", this._doKeyUp); 7930 } else if (nodeName === "div" || nodeName === "span") { 7931 $target.removeClass(this.markerClassName).empty(); 7932 } 7933 }, 7934 7935 /* Enable the date picker to a jQuery selection. 7936 * @param target element - the target input field or division or span 7937 */ 7938 _enableDatepicker: function(target) { 7939 var nodeName, inline, 7940 $target = $(target), 7941 inst = $.data(target, PROP_NAME); 7942 7943 if (!$target.hasClass(this.markerClassName)) { 7944 return; 7945 } 7946 7947 nodeName = target.nodeName.toLowerCase(); 7948 if (nodeName === "input") { 7949 target.disabled = false; 7950 inst.trigger.filter("button"). 7951 each(function() { this.disabled = false; }).end(). 7952 filter("img").css({opacity: "1.0", cursor: ""}); 7953 } else if (nodeName === "div" || nodeName === "span") { 7954 inline = $target.children("." + this._inlineClass); 7955 inline.children().removeClass("ui-state-disabled"); 7956 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7957 prop("disabled", false); 7958 } 7959 this._disabledInputs = $.map(this._disabledInputs, 7960 function(value) { return (value === target ? null : value); }); // delete entry 7961 }, 7962 7963 /* Disable the date picker to a jQuery selection. 7964 * @param target element - the target input field or division or span 7965 */ 7966 _disableDatepicker: function(target) { 7967 var nodeName, inline, 7968 $target = $(target), 7969 inst = $.data(target, PROP_NAME); 7970 7971 if (!$target.hasClass(this.markerClassName)) { 7972 return; 7973 } 7974 7975 nodeName = target.nodeName.toLowerCase(); 7976 if (nodeName === "input") { 7977 target.disabled = true; 7978 inst.trigger.filter("button"). 7979 each(function() { this.disabled = true; }).end(). 7980 filter("img").css({opacity: "0.5", cursor: "default"}); 7981 } else if (nodeName === "div" || nodeName === "span") { 7982 inline = $target.children("." + this._inlineClass); 7983 inline.children().addClass("ui-state-disabled"); 7984 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7985 prop("disabled", true); 7986 } 7987 this._disabledInputs = $.map(this._disabledInputs, 7988 function(value) { return (value === target ? null : value); }); // delete entry 7989 this._disabledInputs[this._disabledInputs.length] = target; 7990 }, 7991 7992 /* Is the first field in a jQuery collection disabled as a datepicker? 7993 * @param target element - the target input field or division or span 7994 * @return boolean - true if disabled, false if enabled 7995 */ 7996 _isDisabledDatepicker: function(target) { 7997 if (!target) { 7998 return false; 7999 } 8000 for (var i = 0; i < this._disabledInputs.length; i++) { 8001 if (this._disabledInputs[i] === target) { 8002 return true; 8003 } 8004 } 8005 return false; 8006 }, 8007 8008 /* Retrieve the instance data for the target control. 8009 * @param target element - the target input field or division or span 8010 * @return object - the associated instance data 8011 * @throws error if a jQuery problem getting data 8012 */ 8013 _getInst: function(target) { 8014 try { 8015 return $.data(target, PROP_NAME); 8016 } 8017 catch (err) { 8018 throw "Missing instance data for this datepicker"; 8019 } 8020 }, 8021 8022 /* Update or retrieve the settings for a date picker attached to an input field or division. 8023 * @param target element - the target input field or division or span 8024 * @param name object - the new settings to update or 8025 * string - the name of the setting to change or retrieve, 8026 * when retrieving also "all" for all instance settings or 8027 * "defaults" for all global defaults 8028 * @param value any - the new value for the setting 8029 * (omit if above is an object or to retrieve a value) 8030 */ 8031 _optionDatepicker: function(target, name, value) { 8032 var settings, date, minDate, maxDate, 8033 inst = this._getInst(target); 8034 8035 if (arguments.length === 2 && typeof name === "string") { 8036 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 8037 (inst ? (name === "all" ? $.extend({}, inst.settings) : 8038 this._get(inst, name)) : null)); 8039 } 8040 8041 settings = name || {}; 8042 if (typeof name === "string") { 8043 settings = {}; 8044 settings[name] = value; 8045 } 8046 8047 if (inst) { 8048 if (this._curInst === inst) { 8049 this._hideDatepicker(); 8050 } 8051 8052 date = this._getDateDatepicker(target, true); 8053 minDate = this._getMinMaxDate(inst, "min"); 8054 maxDate = this._getMinMaxDate(inst, "max"); 8055
vendor: 7,816 bytes, lines 8055-8283
8055extendRemove(inst.settings, settings); 8056 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 8057 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 8058 inst.settings.minDate = this._formatDate(inst, minDate); 8059 } 8060 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 8061 inst.settings.maxDate = this._formatDate(inst, maxDate); 8062 } 8063 if ( "disabled" in settings ) { 8064 if ( settings.disabled ) { 8065 this._disableDatepicker(target); 8066 } else { 8067 this._enableDatepicker(target); 8068 } 8069 } 8070 this._attachments($(target), inst); 8071 this._autoSize(inst); 8072 this._setDate(inst, date); 8073 this._updateAlternate(inst); 8074 this._updateDatepicker(inst); 8075 } 8076 }, 8077 8078 // change method deprecated 8079 _changeDatepicker: function(target, name, value) { 8080 this._optionDatepicker(target, name, value); 8081 }, 8082 8083 /* Redraw the date picker attached to an input field or division. 8084 * @param target element - the target input field or division or span 8085 */ 8086 _refreshDatepicker: function(target) { 8087 var inst = this._getInst(target); 8088 if (inst) { 8089 this._updateDatepicker(inst); 8090 } 8091 }, 8092 8093 /* Set the dates for a jQuery selection. 8094 * @param target element - the target input field or division or span 8095 * @param date Date - the new date 8096 */ 8097 _setDateDatepicker: function(target, date) { 8098 var inst = this._getInst(target); 8099 if (inst) { 8100 this._setDate(inst, date); 8101 this._updateDatepicker(inst); 8102 this._updateAlternate(inst); 8103 } 8104 }, 8105 8106 /* Get the date(s) for the first entry in a jQuery selection. 8107 * @param target element - the target input field or division or span 8108 * @param noDefault boolean - true if no default date is to be used 8109 * @return Date - the current date 8110 */ 8111 _getDateDatepicker: function(target, noDefault) { 8112 var inst = this._getInst(target); 8113 if (inst && !inst.inline) { 8114 this._setDateFromField(inst, noDefault); 8115 } 8116 return (inst ? this._getDate(inst) : null); 8117 }, 8118 8119 /* Handle keystrokes. */ 8120 _doKeyDown: function(event) { 8121 var onSelect, dateStr, sel, 8122 inst = $.datepicker._getInst(event.target), 8123 handled = true, 8124 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 8125 8126 inst._keyEvent = true; 8127 if ($.datepicker._datepickerShowing) { 8128 switch (event.keyCode) { 8129 case 9: $.datepicker._hideDatepicker(); 8130 handled = false; 8131 break; // hide on tab out 8132 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 8133 $.datepicker._currentClass + ")", inst.dpDiv); 8134 if (sel[0]) { 8135 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 8136 } 8137 8138 onSelect = $.datepicker._get(inst, "onSelect"); 8139 if (onSelect) { 8140 dateStr = $.datepicker._formatDate(inst); 8141 8142 // trigger custom callback 8143 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 8144 } else { 8145 $.datepicker._hideDatepicker(); 8146 } 8147 8148 return false; // don't submit the form 8149 case 27: $.datepicker._hideDatepicker(); 8150 break; // hide on escape 8151 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8152 -$.datepicker._get(inst, "stepBigMonths") : 8153 -$.datepicker._get(inst, "stepMonths")), "M"); 8154 break; // previous month/year on page up/+ ctrl 8155 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8156 +$.datepicker._get(inst, "stepBigMonths") : 8157 +$.datepicker._get(inst, "stepMonths")), "M"); 8158 break; // next month/year on page down/+ ctrl 8159 case 35: if (event.ctrlKey || event.metaKey) { 8160 $.datepicker._clearDate(event.target); 8161 } 8162 handled = event.ctrlKey || event.metaKey; 8163 break; // clear on ctrl or command +end 8164 case 36: if (event.ctrlKey || event.metaKey) { 8165 $.datepicker._gotoToday(event.target); 8166 } 8167 handled = event.ctrlKey || event.metaKey; 8168 break; // current on ctrl or command +home 8169 case 37: if (event.ctrlKey || event.metaKey) { 8170 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 8171 } 8172 handled = event.ctrlKey || event.metaKey; 8173 // -1 day on ctrl or command +left 8174 if (event.originalEvent.altKey) { 8175 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8176 -$.datepicker._get(inst, "stepBigMonths") : 8177 -$.datepicker._get(inst, "stepMonths")), "M"); 8178 } 8179 // next month/year on alt +left on Mac 8180 break; 8181 case 38: if (event.ctrlKey || event.metaKey) { 8182 $.datepicker._adjustDate(event.target, -7, "D"); 8183 } 8184 handled = event.ctrlKey || event.metaKey; 8185 break; // -1 week on ctrl or command +up 8186 case 39: if (event.ctrlKey || event.metaKey) { 8187 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 8188 } 8189 handled = event.ctrlKey || event.metaKey; 8190 // +1 day on ctrl or command +right 8191 if (event.originalEvent.altKey) { 8192 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8193 +$.datepicker._get(inst, "stepBigMonths") : 8194 +$.datepicker._get(inst, "stepMonths")), "M"); 8195 } 8196 // next month/year on alt +right 8197 break; 8198 case 40: if (event.ctrlKey || event.metaKey) { 8199 $.datepicker._adjustDate(event.target, +7, "D"); 8200 } 8201 handled = event.ctrlKey || event.metaKey; 8202 break; // +1 week on ctrl or command +down 8203 default: handled = false; 8204 } 8205 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 8206 $.datepicker._showDatepicker(this); 8207 } else { 8208 handled = false; 8209 } 8210 8211 if (handled) { 8212 event.preventDefault(); 8213 event.stopPropagation(); 8214 } 8215 }, 8216 8217 /* Filter entered characters - based on date format. */ 8218 _doKeyPress: function(event) { 8219 var chars, chr, 8220 inst = $.datepicker._getInst(event.target); 8221 8222 if ($.datepicker._get(inst, "constrainInput")) { 8223 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 8224 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 8225 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 8226 } 8227 }, 8228 8229 /* Synchronise manual entry and field/alternate field. */ 8230 _doKeyUp: function(event) { 8231 var date, 8232 inst = $.datepicker._getInst(event.target); 8233 8234 if (inst.input.val() !== inst.lastVal) { 8235 try { 8236 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8237 (inst.input ? inst.input.val() : null), 8238 $.datepicker._getFormatConfig(inst)); 8239 8240 if (date) { // only if valid 8241 $.datepicker._setDateFromField(inst); 8242 $.datepicker._updateAlternate(inst); 8243 $.datepicker._updateDatepicker(inst); 8244 } 8245 } 8246 catch (err) { 8247 } 8248 } 8249 return true; 8250 }, 8251 8252 /* Pop-up the date picker for a given input field. 8253 * If false returned from beforeShow event handler do not show. 8254 * @param input element - the input field attached to the date picker or 8255 * event - if triggered by focus 8256 */ 8257 _showDatepicker: function(input) { 8258 input = input.target || input; 8259 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 8260 input = $("input", input.parentNode)[0]; 8261 } 8262 8263 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 8264 return; 8265 } 8266 8267 var inst, beforeShow, beforeShowSettings, isFixed, 8268 offset, showAnim, duration; 8269 8270 inst = $.datepicker._getInst(input); 8271 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 8272 $.datepicker._curInst.dpDiv.stop(true, true); 8273 if ( inst && $.datepicker._datepickerShowing ) { 8274 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 8275 } 8276 } 8277 8278 beforeShow = $.datepicker._get(inst, "beforeShow"); 8279 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 8280 if(beforeShowSettings === false){ 8281 return; 8282 } 8283
vendor: 5,662 bytes, lines 8283-8433
8283extendRemove(inst.settings, beforeShowSettings); 8284 8285 inst.lastVal = null; 8286 $.datepicker._lastInput = input; 8287 $.datepicker._setDateFromField(inst); 8288 8289 if ($.datepicker._inDialog) { // hide cursor 8290 input.value = ""; 8291 } 8292 if (!$.datepicker._pos) { // position below input 8293 $.datepicker._pos = $.datepicker._findPos(input); 8294 $.datepicker._pos[1] += input.offsetHeight; // add the height 8295 } 8296 8297 isFixed = false; 8298 $(input).parents().each(function() { 8299 isFixed |= $(this).css("position") === "fixed"; 8300 return !isFixed; 8301 }); 8302 8303 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 8304 $.datepicker._pos = null; 8305 //to avoid flashes on Firefox 8306 inst.dpDiv.empty(); 8307 // determine sizing offscreen 8308 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 8309 $.datepicker._updateDatepicker(inst); 8310 // fix width for dynamic number of date pickers 8311 // and adjust position before showing 8312 offset = $.datepicker._checkOffset(inst, offset, isFixed); 8313 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 8314 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 8315 left: offset.left + "px", top: offset.top + "px"}); 8316 8317 if (!inst.inline) { 8318 showAnim = $.datepicker._get(inst, "showAnim"); 8319 duration = $.datepicker._get(inst, "duration"); 8320 inst.dpDiv.zIndex($(input).zIndex()+1); 8321 $.datepicker._datepickerShowing = true; 8322 8323 if ( $.effects && $.effects.effect[ showAnim ] ) { 8324 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 8325 } else { 8326 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 8327 } 8328 8329 if (inst.input.is(":visible") && !inst.input.is(":disabled")) { 8330 inst.input.focus(); 8331 } 8332 $.datepicker._curInst = inst; 8333 } 8334 }, 8335 8336 /* Generate the date picker content. */ 8337 _updateDatepicker: function(inst) { 8338 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8339 instActive = inst; // for delegate hover events 8340 inst.dpDiv.empty().append(this._generateHTML(inst)); 8341 this._attachHandlers(inst); 8342 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 8343 8344 var origyearshtml, 8345 numMonths = this._getNumberOfMonths(inst), 8346 cols = numMonths[1], 8347 width = 17; 8348 8349 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 8350 if (cols > 1) { 8351 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 8352 } 8353 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 8354 "Class"]("ui-datepicker-multi"); 8355 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 8356 "Class"]("ui-datepicker-rtl"); 8357 8358 // #6694 - don't focus the input if it's already focused 8359 // this breaks the change event in IE 8360 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 8361 inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) { 8362 inst.input.focus(); 8363 } 8364 8365 // deffered render of the years select (to avoid flashes on Firefox) 8366 if( inst.yearshtml ){ 8367 origyearshtml = inst.yearshtml; 8368 setTimeout(function(){ 8369 //assure that inst.yearshtml didn't change. 8370 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 8371 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 8372 } 8373 origyearshtml = inst.yearshtml = null; 8374 }, 0); 8375 } 8376 }, 8377 8378 /* Retrieve the size of left and top borders for an element. 8379 * @param elem (jQuery object) the element of interest 8380 * @return (number[2]) the left and top borders 8381 */ 8382 _getBorders: function(elem) { 8383 var convert = function(value) { 8384 return {thin: 1, medium: 2, thick: 3}[value] || value; 8385 }; 8386 return [parseFloat(convert(elem.css("border-left-width"))), 8387 parseFloat(convert(elem.css("border-top-width")))]; 8388 }, 8389 8390 /* Check positioning to remain on screen. */ 8391 _checkOffset: function(inst, offset, isFixed) { 8392 var dpWidth = inst.dpDiv.outerWidth(), 8393 dpHeight = inst.dpDiv.outerHeight(), 8394 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8395 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8396 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 8397 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 8398 8399 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 8400 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 8401 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 8402 8403 // now check if datepicker is showing outside window viewport - move to a better place if so. 8404 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 8405 Math.abs(offset.left + dpWidth - viewWidth) : 0); 8406 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 8407 Math.abs(dpHeight + inputHeight) : 0); 8408 8409 return offset; 8410 }, 8411 8412 /* Find an object's position on the screen. */ 8413 _findPos: function(obj) { 8414 var position, 8415 inst = this._getInst(obj), 8416 isRTL = this._get(inst, "isRTL"); 8417 8418 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 8419 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 8420 } 8421 8422 position = $(obj).offset(); 8423 return [position.left, position.top]; 8424 }, 8425 8426 /* Hide the date picker from view. 8427 * @param input element - the input field attached to the date picker 8428 */ 8429 _hideDatepicker: function(input) { 8430 var showAnim, duration, postProcess, onClose, 8431 inst = this._curInst; 8432 8433 if (!inst || (input && inst !== $.data(input, PROP_NAME
vendor: 8,428 bytes, lines 8433-8689
8433))) { 8434 return; 8435 } 8436 8437 if (this._datepickerShowing) { 8438 showAnim = this._get(inst, "showAnim"); 8439 duration = this._get(inst, "duration"); 8440 postProcess = function() { 8441 $.datepicker._tidyDialog(inst); 8442 }; 8443 8444 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8445 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 8446 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 8447 } else { 8448 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 8449 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 8450 } 8451 8452 if (!showAnim) { 8453 postProcess(); 8454 } 8455 this._datepickerShowing = false; 8456 8457 onClose = this._get(inst, "onClose"); 8458 if (onClose) { 8459 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 8460 } 8461 8462 this._lastInput = null; 8463 if (this._inDialog) { 8464 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 8465 if ($.blockUI) { 8466 $.unblockUI(); 8467 $("body").append(this.dpDiv); 8468 } 8469 } 8470 this._inDialog = false; 8471 } 8472 }, 8473 8474 /* Tidy up after a dialog display. */ 8475 _tidyDialog: function(inst) { 8476 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 8477 }, 8478 8479 /* Close date picker if clicked elsewhere. */ 8480 _checkExternalClick: function(event) { 8481 if (!$.datepicker._curInst) { 8482 return; 8483 } 8484 8485 var $target = $(event.target), 8486 inst = $.datepicker._getInst($target[0]); 8487 8488 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 8489 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 8490 !$target.hasClass($.datepicker.markerClassName) && 8491 !$target.closest("." + $.datepicker._triggerClass).length && 8492 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 8493 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 8494 $.datepicker._hideDatepicker(); 8495 } 8496 }, 8497 8498 /* Adjust one of the date sub-fields. */ 8499 _adjustDate: function(id, offset, period) { 8500 var target = $(id), 8501 inst = this._getInst(target[0]); 8502 8503 if (this._isDisabledDatepicker(target[0])) { 8504 return; 8505 } 8506 this._adjustInstDate(inst, offset + 8507 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 8508 period); 8509 this._updateDatepicker(inst); 8510 }, 8511 8512 /* Action for current link. */ 8513 _gotoToday: function(id) { 8514 var date, 8515 target = $(id), 8516 inst = this._getInst(target[0]); 8517 8518 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 8519 inst.selectedDay = inst.currentDay; 8520 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8521 inst.drawYear = inst.selectedYear = inst.currentYear; 8522 } else { 8523 date = new Date(); 8524 inst.selectedDay = date.getDate(); 8525 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8526 inst.drawYear = inst.selectedYear = date.getFullYear(); 8527 } 8528 this._notifyChange(inst); 8529 this._adjustDate(target); 8530 }, 8531 8532 /* Action for selecting a new month/year. */ 8533 _selectMonthYear: function(id, select, period) { 8534 var target = $(id), 8535 inst = this._getInst(target[0]); 8536 8537 inst["selected" + (period === "M" ? "Month" : "Year")] = 8538 inst["draw" + (period === "M" ? "Month" : "Year")] = 8539 parseInt(select.options[select.selectedIndex].value,10); 8540 8541 this._notifyChange(inst); 8542 this._adjustDate(target); 8543 }, 8544 8545 /* Action for selecting a day. */ 8546 _selectDay: function(id, month, year, td) { 8547 var inst, 8548 target = $(id); 8549 8550 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8551 return; 8552 } 8553 8554 inst = this._getInst(target[0]); 8555 inst.selectedDay = inst.currentDay = $("a", td).html(); 8556 inst.selectedMonth = inst.currentMonth = month; 8557 inst.selectedYear = inst.currentYear = year; 8558 this._selectDate(id, this._formatDate(inst, 8559 inst.currentDay, inst.currentMonth, inst.currentYear)); 8560 }, 8561 8562 /* Erase the input field and hide the date picker. */ 8563 _clearDate: function(id) { 8564 var target = $(id); 8565 this._selectDate(target, ""); 8566 }, 8567 8568 /* Update the input field with the selected date. */ 8569 _selectDate: function(id, dateStr) { 8570 var onSelect, 8571 target = $(id), 8572 inst = this._getInst(target[0]); 8573 8574 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 8575 if (inst.input) { 8576 inst.input.val(dateStr); 8577 } 8578 this._updateAlternate(inst); 8579 8580 onSelect = this._get(inst, "onSelect"); 8581 if (onSelect) { 8582 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 8583 } else if (inst.input) { 8584 inst.input.trigger("change"); // fire the change event 8585 } 8586 8587 if (inst.inline){ 8588 this._updateDatepicker(inst); 8589 } else { 8590 this._hideDatepicker(); 8591 this._lastInput = inst.input[0]; 8592 if (typeof(inst.input[0]) !== "object") { 8593 inst.input.focus(); // restore focus 8594 } 8595 this._lastInput = null; 8596 } 8597 }, 8598 8599 /* Update any alternate field to synchronise with the main field. */ 8600 _updateAlternate: function(inst) { 8601 var altFormat, date, dateStr, 8602 altField = this._get(inst, "altField"); 8603 8604 if (altField) { // update alternate field too 8605 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 8606 date = this._getDate(inst); 8607 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 8608 $(altField).each(function() { $(this).val(dateStr); }); 8609 } 8610 }, 8611 8612 /* Set as beforeShowDay function to prevent selection of weekends. 8613 * @param date Date - the date to customise 8614 * @return [boolean, string] - is this date selectable?, what is its CSS class? 8615 */ 8616 noWeekends: function(date) { 8617 var day = date.getDay(); 8618 return [(day > 0 && day < 6), ""]; 8619 }, 8620 8621 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8622 * @param date Date - the date to get the week for 8623 * @return number - the number of the week within the year that contains this date 8624 */ 8625 iso8601Week: function(date) { 8626 var time, 8627 checkDate = new Date(date.getTime()); 8628 8629 // Find Thursday of this week starting on Monday 8630 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 8631 8632 time = checkDate.getTime(); 8633 checkDate.setMonth(0); // Compare with Jan 1 8634 checkDate.setDate(1); 8635 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 8636 }, 8637 8638 /* Parse a string value into a date object. 8639 * See formatDate below for the possible formats. 8640 * 8641 * @param format string - the expected format of the date 8642 * @param value string - the date in the above format 8643 * @param settings Object - attributes include: 8644 * shortYearCutoff number - the cutoff year for determining the century (optional) 8645 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8646 * dayNames string[7] - names of the days from Sunday (optional) 8647 * monthNamesShort string[12] - abbreviated names of the months (optional) 8648 * monthNames string[12] - names of the months (optional) 8649 * @return Date - the extracted date value or null if value is blank 8650 */ 8651 parseDate: function (format, value, settings) { 8652 if (format == null || value == null) { 8653 throw "Invalid arguments"; 8654 } 8655 8656 value = (typeof value === "object" ? value.toString() : value + ""); 8657 if (value === "") { 8658 return null; 8659 } 8660 8661 var iFormat, dim, extra, 8662 iValue = 0, 8663 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 8664 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 8665 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 8666 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8667 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8668 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8669 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8670 year = -1, 8671 month = -1, 8672 day = -1, 8673 doy = -1, 8674 literal = false, 8675 date, 8676 // Check whether a format character is doubled 8677 lookAhead = function(match) { 8678 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8679 if (matches) { 8680 iFormat++; 8681 } 8682 return matches; 8683 }, 8684 // Extract a number from the string value 8685 getNumber = function(match) { 8686 var isDoubled = lookAhead(match), 8687 size = (match === "@" ? 14 : (match === "!" ? 20 : 8688 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 8689
8689digits = new RegExp("^\\d{1
vendor: 13,244 bytes, lines 8689-9134
8689," + size + "}"), 8690 num = value.substring(iValue).match(digits); 8691 if (!num) { 8692 throw "Missing number at position " + iValue; 8693 } 8694 iValue += num[0].length; 8695 return parseInt(num[0], 10); 8696 }, 8697 // Extract a name from the string value and convert to an index 8698 getName = function(match, shortNames, longNames) { 8699 var index = -1, 8700 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 8701 return [ [k, v] ]; 8702 }).sort(function (a, b) { 8703 return -(a[1].length - b[1].length); 8704 }); 8705 8706 $.each(names, function (i, pair) { 8707 var name = pair[1]; 8708 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 8709 index = pair[0]; 8710 iValue += name.length; 8711 return false; 8712 } 8713 }); 8714 if (index !== -1) { 8715 return index + 1; 8716 } else { 8717 throw "Unknown name at position " + iValue; 8718 } 8719 }, 8720 // Confirm that a literal character matches the string value 8721 checkLiteral = function() { 8722 if (value.charAt(iValue) !== format.charAt(iFormat)) { 8723 throw "Unexpected literal at position " + iValue; 8724 } 8725 iValue++; 8726 }; 8727 8728 for (iFormat = 0; iFormat < format.length; iFormat++) { 8729 if (literal) { 8730 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8731 literal = false; 8732 } else { 8733 checkLiteral(); 8734 } 8735 } else { 8736 switch (format.charAt(iFormat)) { 8737 case "d": 8738 day = getNumber("d"); 8739 break; 8740 case "D": 8741 getName("D", dayNamesShort, dayNames); 8742 break; 8743 case "o": 8744 doy = getNumber("o"); 8745 break; 8746 case "m": 8747 month = getNumber("m"); 8748 break; 8749 case "M": 8750 month = getName("M", monthNamesShort, monthNames); 8751 break; 8752 case "y": 8753 year = getNumber("y"); 8754 break; 8755 case "@": 8756 date = new Date(getNumber("@")); 8757 year = date.getFullYear(); 8758 month = date.getMonth() + 1; 8759 day = date.getDate(); 8760 break; 8761 case "!": 8762 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 8763 year = date.getFullYear(); 8764 month = date.getMonth() + 1; 8765 day = date.getDate(); 8766 break; 8767 case "'": 8768 if (lookAhead("'")){ 8769 checkLiteral(); 8770 } else { 8771 literal = true; 8772 } 8773 break; 8774 default: 8775 checkLiteral(); 8776 } 8777 } 8778 } 8779 8780 if (iValue < value.length){ 8781 extra = value.substr(iValue); 8782 if (!/^\s+/.test(extra)) { 8783 throw "Extra/unparsed characters found in date: " + extra; 8784 } 8785 } 8786 8787 if (year === -1) { 8788 year = new Date().getFullYear(); 8789 } else if (year < 100) { 8790 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8791 (year <= shortYearCutoff ? 0 : -100); 8792 } 8793 8794 if (doy > -1) { 8795 month = 1; 8796 day = doy; 8797 do { 8798 dim = this._getDaysInMonth(year, month - 1); 8799 if (day <= dim) { 8800 break; 8801 } 8802 month++; 8803 day -= dim; 8804 } while (true); 8805 } 8806 8807 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 8808 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 8809 throw "Invalid date"; // E.g. 31/02/00 8810 } 8811 return date; 8812 }, 8813 8814 /* Standard date formats. */ 8815 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 8816 COOKIE: "D, dd M yy", 8817 ISO_8601: "yy-mm-dd", 8818 RFC_822: "D, d M y", 8819 RFC_850: "DD, dd-M-y", 8820 RFC_1036: "D, d M y", 8821 RFC_1123: "D, d M yy", 8822 RFC_2822: "D, d M yy", 8823 RSS: "D, d M y", // RFC 822 8824 TICKS: "!", 8825 TIMESTAMP: "@", 8826 W3C: "yy-mm-dd", // ISO 8601 8827 8828 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8829 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8830 8831 /* Format a date object into a string value. 8832 * The format can be combinations of the following: 8833 * d - day of month (no leading zero) 8834 * dd - day of month (two digit) 8835 * o - day of year (no leading zeros) 8836 * oo - day of year (three digit) 8837 * D - day name short 8838 * DD - day name long 8839 * m - month of year (no leading zero) 8840 * mm - month of year (two digit) 8841 * M - month name short 8842 * MM - month name long 8843 * y - year (two digit) 8844 * yy - year (four digit) 8845 * @ - Unix timestamp (ms since 01/01/1970) 8846 * ! - Windows ticks (100ns since 01/01/0001) 8847 * "..." - literal text 8848 * '' - single quote 8849 * 8850 * @param format string - the desired format of the date 8851 * @param date Date - the date value to format 8852 * @param settings Object - attributes include: 8853 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8854 * dayNames string[7] - names of the days from Sunday (optional) 8855 * monthNamesShort string[12] - abbreviated names of the months (optional) 8856 * monthNames string[12] - names of the months (optional) 8857 * @return string - the date in the above format 8858 */ 8859 formatDate: function (format, date, settings) { 8860 if (!date) { 8861 return ""; 8862 } 8863 8864 var iFormat, 8865 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8866 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8867 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8868 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8869 // Check whether a format character is doubled 8870 lookAhead = function(match) { 8871 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8872 if (matches) { 8873 iFormat++; 8874 } 8875 return matches; 8876 }, 8877 // Format a number, with leading zero if necessary 8878 formatNumber = function(match, value, len) { 8879 var num = "" + value; 8880 if (lookAhead(match)) { 8881 while (num.length < len) { 8882 num = "0" + num; 8883 } 8884 } 8885 return num; 8886 }, 8887 // Format a name, short or long as requested 8888 formatName = function(match, value, shortNames, longNames) { 8889 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8890 }, 8891 output = "", 8892 literal = false; 8893 8894 if (date) { 8895 for (iFormat = 0; iFormat < format.length; iFormat++) { 8896 if (literal) { 8897 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8898 literal = false; 8899 } else { 8900 output += format.charAt(iFormat); 8901 } 8902 } else { 8903 switch (format.charAt(iFormat)) { 8904 case "d": 8905 output += formatNumber("d", date.getDate(), 2); 8906 break; 8907 case "D": 8908 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 8909 break; 8910 case "o": 8911 output += formatNumber("o", 8912 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8913 break; 8914 case "m": 8915 output += formatNumber("m", date.getMonth() + 1, 2); 8916 break; 8917 case "M": 8918 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 8919 break; 8920 case "y": 8921 output += (lookAhead("y") ? date.getFullYear() : 8922 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 8923 break; 8924 case "@": 8925 output += date.getTime(); 8926 break; 8927 case "!": 8928 output += date.getTime() * 10000 + this._ticksTo1970; 8929 break; 8930 case "'": 8931 if (lookAhead("'")) { 8932 output += "'"; 8933 } else { 8934 literal = true; 8935 } 8936 break; 8937 default: 8938 output += format.charAt(iFormat); 8939 } 8940 } 8941 } 8942 } 8943 return output; 8944 }, 8945 8946 /* Extract all possible characters from the date format. */ 8947 _possibleChars: function (format) { 8948 var iFormat, 8949 chars = "", 8950 literal = false, 8951 // Check whether a format character is doubled 8952 lookAhead = function(match) { 8953 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8954 if (matches) { 8955 iFormat++; 8956 } 8957 return matches; 8958 }; 8959 8960 for (iFormat = 0; iFormat < format.length; iFormat++) { 8961 if (literal) { 8962 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8963 literal = false; 8964 } else { 8965 chars += format.charAt(iFormat); 8966 } 8967 } else { 8968 switch (format.charAt(iFormat)) { 8969 case "d": case "m": case "y": case "@": 8970 chars += "0123456789"; 8971 break; 8972 case "D": case "M": 8973 return null; // Accept anything 8974 case "'": 8975 if (lookAhead("'")) { 8976 chars += "'"; 8977 } else { 8978 literal = true; 8979 } 8980 break; 8981 default: 8982 chars += format.charAt(iFormat); 8983 } 8984 } 8985 } 8986 return chars; 8987 }, 8988 8989 /* Get a setting value, defaulting if necessary. */ 8990 _get: function(inst, name) { 8991 return inst.settings[name] !== undefined ? 8992 inst.settings[name] : this._defaults[name]; 8993 }, 8994 8995 /* Parse existing date and initialise date picker. */ 8996 _setDateFromField: function(inst, noDefault) { 8997 if (inst.input.val() === inst.lastVal) { 8998 return; 8999 } 9000 9001 var dateFormat = this._get(inst, "dateFormat"), 9002 dates = inst.lastVal = inst.input ? inst.input.val() : null, 9003 defaultDate = this._getDefaultDate(inst), 9004 date = defaultDate, 9005 settings = this._getFormatConfig(inst); 9006 9007 try { 9008 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 9009 } catch (event) { 9010 dates = (noDefault ? "" : dates); 9011 } 9012 inst.selectedDay = date.getDate(); 9013 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9014 inst.drawYear = inst.selectedYear = date.getFullYear(); 9015 inst.currentDay = (dates ? date.getDate() : 0); 9016 inst.currentMonth = (dates ? date.getMonth() : 0); 9017 inst.currentYear = (dates ? date.getFullYear() : 0); 9018 this._adjustInstDate(inst); 9019 }, 9020 9021 /* Retrieve the default date shown on opening. */ 9022 _getDefaultDate: function(inst) { 9023 return this._restrictMinMax(inst, 9024 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 9025 }, 9026 9027 /* A date may be specified as an exact value or a relative one. */ 9028 _determineDate: function(inst, date, defaultDate) { 9029 var offsetNumeric = function(offset) { 9030 var date = new Date(); 9031 date.setDate(date.getDate() + offset); 9032 return date; 9033 }, 9034 offsetString = function(offset) { 9035 try { 9036 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 9037 offset, $.datepicker._getFormatConfig(inst)); 9038 } 9039 catch (e) { 9040 // Ignore 9041 } 9042 9043 var date = (offset.toLowerCase().match(/^c/) ? 9044 $.datepicker._getDate(inst) : null) || new Date(), 9045 year = date.getFullYear(), 9046 month = date.getMonth(), 9047 day = date.getDate(), 9048 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 9049 matches = pattern.exec(offset); 9050 9051 while (matches) { 9052 switch (matches[2] || "d") { 9053 case "d" : case "D" : 9054 day += parseInt(matches[1],10); break; 9055 case "w" : case "W" : 9056 day += parseInt(matches[1],10) * 7; break; 9057 case "m" : case "M" : 9058 month += parseInt(matches[1],10); 9059 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9060 break; 9061 case "y": case "Y" : 9062 year += parseInt(matches[1],10); 9063 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9064 break; 9065 } 9066 matches = pattern.exec(offset); 9067 } 9068 return new Date(year, month, day); 9069 }, 9070 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 9071 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 9072 9073 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 9074 if (newDate) { 9075 newDate.setHours(0); 9076 newDate.setMinutes(0); 9077 newDate.setSeconds(0); 9078 newDate.setMilliseconds(0); 9079 } 9080 return this._daylightSavingAdjust(newDate); 9081 }, 9082 9083 /* Handle switch to/from daylight saving. 9084 * Hours may be non-zero on daylight saving cut-over: 9085 * > 12 when midnight changeover, but then cannot generate 9086 * midnight datetime, so jump to 1AM, otherwise reset. 9087 * @param date (Date) the date to check 9088 * @return (Date) the corrected date 9089 */ 9090 _daylightSavingAdjust: function(date) { 9091 if (!date) { 9092 return null; 9093 } 9094 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 9095 return date; 9096 }, 9097 9098 /* Set the date(s) directly. */ 9099 _setDate: function(inst, date, noChange) { 9100 var clear = !date, 9101 origMonth = inst.selectedMonth, 9102 origYear = inst.selectedYear, 9103 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 9104 9105 inst.selectedDay = inst.currentDay = newDate.getDate(); 9106 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 9107 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 9108 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 9109 this._notifyChange(inst); 9110 } 9111 this._adjustInstDate(inst); 9112 if (inst.input) { 9113 inst.input.val(clear ? "" : this._formatDate(inst)); 9114 } 9115 }, 9116 9117 /* Retrieve the date(s) directly. */ 9118 _getDate: function(inst) { 9119 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 9120 this._daylightSavingAdjust(new Date( 9121 inst.currentYear, inst.currentMonth, inst.currentDay))); 9122 return startDate; 9123 }, 9124 9125 /* Attach the onxxx handlers. These are declared statically so 9126 * they work with static code transformers like Caja. 9127 */ 9128 _attachHandlers: function(inst) { 9129 var stepMonths = this._get(inst, "stepMonths"), 9130 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 9131 inst.dpDiv.find("[data-handler]").map(function () { 9132 var handler = { 9133 prev: function () { 9134
9134window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, -stepMonths, "M"); 9135 }, 9136 next: function () { 9137 window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, +stepMonths, "M"); 9138 }, 9139 hide: function () { 9140 window["DP_jQuery_" + dpuuid].datepicker._hideDatepicker(); 9141 }, 9142 today: function () { 9143 window["DP_jQuery_" + dpuuid].datepicker._gotoToday(id); 9144 }, 9145 selectDay: function () { 9146 window["DP_jQuery_" + dpuuid].datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 9147 return false; 9148 }, 9149 selectMonth: function () { 9150 window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "M"); 9151 return false; 9152 }, 9153 selectYear: function () { 9154 window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "Y"); 9155 return false; 9156 } 9157 }; 9158 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 9159 }); 9160 }, 9161 9162 /* Generate the HTML for the current state of the date picker. */ 9163 _generateHTML: function(inst) { 9164 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 9165 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 9166 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 9167 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 9168 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 9169 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 9170 tempDate = new Date(), 9171 today = this._daylightSavingAdjust( 9172 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 9173 isRTL = this._get(inst, "isRTL"), 9174 showButtonPanel = this._get(inst, "showButtonPanel"), 9175 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 9176 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 9177 numMonths = this._getNumberOfMonths(inst), 9178 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 9179 stepMonths = this._get(inst, "stepMonths"), 9180 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 9181 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 9182 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 9183 minDate = this._getMinMaxDate(inst, "min"),
vendor: 5,135 bytes, lines 9184-9283
9184 maxDate = this._getMinMaxDate(inst, "max"), 9185 drawMonth = inst.drawMonth - showCurrentAtPos, 9186 drawYear = inst.drawYear; 9187 9188 if (drawMonth < 0) { 9189 drawMonth += 12; 9190 drawYear--; 9191 } 9192 if (maxDate) { 9193 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 9194 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 9195 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 9196 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 9197 drawMonth--; 9198 if (drawMonth < 0) { 9199 drawMonth = 11; 9200 drawYear--; 9201 } 9202 } 9203 } 9204 inst.drawMonth = drawMonth; 9205 inst.drawYear = drawYear; 9206 9207 prevText = this._get(inst, "prevText"); 9208 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 9209 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 9210 this._getFormatConfig(inst))); 9211 9212 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 9213 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 9214 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 9215 (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>")); 9216 9217 nextText = this._get(inst, "nextText"); 9218 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 9219 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 9220 this._getFormatConfig(inst))); 9221 9222 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 9223 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 9224 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 9225 (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>")); 9226 9227 currentText = this._get(inst, "currentText"); 9228 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 9229 currentText = (!navigationAsDateFormat ? currentText : 9230 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 9231 9232 controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + 9233 this._get(inst, "closeText") + "</button>" : ""); 9234 9235 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 9236 (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + 9237 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 9238 9239 firstDay = parseInt(this._get(inst, "firstDay"),10); 9240 firstDay = (isNaN(firstDay) ? 0 : firstDay); 9241 9242 showWeek = this._get(inst, "showWeek"); 9243 dayNames = this._get(inst, "dayNames"); 9244 dayNamesMin = this._get(inst, "dayNamesMin"); 9245 monthNames = this._get(inst, "monthNames"); 9246 monthNamesShort = this._get(inst, "monthNamesShort"); 9247 beforeShowDay = this._get(inst, "beforeShowDay"); 9248 showOtherMonths = this._get(inst, "showOtherMonths"); 9249 selectOtherMonths = this._get(inst, "selectOtherMonths"); 9250 defaultDate = this._getDefaultDate(inst); 9251 html = ""; 9252 dow; 9253 for (row = 0; row < numMonths[0]; row++) { 9254 group = ""; 9255 this.maxRows = 4; 9256 for (col = 0; col < numMonths[1]; col++) { 9257 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 9258 cornerClass = " ui-corner-all"; 9259 calender = ""; 9260 if (isMultiMonth) { 9261 calender += "<div class='ui-datepicker-group"; 9262 if (numMonths[1] > 1) { 9263 switch (col) { 9264 case 0: calender += " ui-datepicker-group-first"; 9265 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 9266 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 9267 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 9268 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 9269 } 9270 } 9271 calender += "'>"; 9272 } 9273 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 9274 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 9275 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 9276 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 9277 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 9278 "</div><table class='ui-datepicker-calendar'><thead>" + 9279 "<tr>"; 9280 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 9281 for (dow = 0; dow < 7; dow++) { // days of the week 9282 day = (dow + firstDay) % 7; 9283 thead += "<th
vendor: 11,347 bytes, lines 9283-9537
9283" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 9284 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 9285 } 9286 calender += thead + "</tr></thead><tbody>"; 9287 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 9288 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 9289 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 9290 } 9291 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 9292 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 9293 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 9294 this.maxRows = numRows; 9295 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 9296 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 9297 calender += "<tr>"; 9298 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 9299 this._get(inst, "calculateWeek")(printDate) + "</td>"); 9300 for (dow = 0; dow < 7; dow++) { // create date picker days 9301 daySettings = (beforeShowDay ? 9302 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 9303 otherMonth = (printDate.getMonth() !== drawMonth); 9304 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 9305 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 9306 tbody += "<td class='" + 9307 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 9308 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 9309 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 9310 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 9311 // or defaultDate is current printedDate and defaultDate is selectedDate 9312 " " + this._dayOverClass : "") + // highlight selected day 9313 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 9314 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 9315 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 9316 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 9317 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 9318 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 9319 (otherMonth && !showOtherMonths ? " " : // display for other months 9320 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9321 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 9322 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 9323 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 9324 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 9325 printDate.setDate(printDate.getDate() + 1); 9326 printDate = this._daylightSavingAdjust(printDate); 9327 } 9328 calender += tbody + "</tr>"; 9329 } 9330 drawMonth++; 9331 if (drawMonth > 11) { 9332 drawMonth = 0; 9333 drawYear++; 9334 } 9335 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 9336 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 9337 group += calender; 9338 } 9339 html += group; 9340 } 9341 html += buttonPanel; 9342 inst._keyEvent = false; 9343 return html; 9344 }, 9345 9346 /* Generate the month and year header. */ 9347 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 9348 secondary, monthNames, monthNamesShort) { 9349 9350 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9351 changeMonth = this._get(inst, "changeMonth"), 9352 changeYear = this._get(inst, "changeYear"), 9353 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 9354 html = "<div class='ui-datepicker-title'>", 9355 monthHtml = ""; 9356 9357 // month selection 9358 if (secondary || !changeMonth) { 9359 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 9360 } else { 9361 inMinYear = (minDate && minDate.getFullYear() === drawYear); 9362 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 9363 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 9364 for ( month = 0; month < 12; month++) { 9365 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 9366 monthHtml += "<option value='" + month + "'" + 9367 (month === drawMonth ? " selected='selected'" : "") + 9368 ">" + monthNamesShort[month] + "</option>"; 9369 } 9370 } 9371 monthHtml += "</select>"; 9372 } 9373 9374 if (!showMonthAfterYear) { 9375 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 9376 } 9377 9378 // year selection 9379 if ( !inst.yearshtml ) { 9380 inst.yearshtml = ""; 9381 if (secondary || !changeYear) { 9382 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9383 } else { 9384 // determine range of years to display 9385 years = this._get(inst, "yearRange").split(":"); 9386 thisYear = new Date().getFullYear(); 9387 determineYear = function(value) { 9388 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 9389 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 9390 parseInt(value, 10))); 9391 return (isNaN(year) ? thisYear : year); 9392 }; 9393 year = determineYear(years[0]); 9394 endYear = Math.max(year, determineYear(years[1] || "")); 9395 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 9396 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 9397 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 9398 for (; year <= endYear; year++) { 9399 inst.yearshtml += "<option value='" + year + "'" + 9400 (year === drawYear ? " selected='selected'" : "") + 9401 ">" + year + "</option>"; 9402 } 9403 inst.yearshtml += "</select>"; 9404 9405 html += inst.yearshtml; 9406 inst.yearshtml = null; 9407 } 9408 } 9409 9410 html += this._get(inst, "yearSuffix"); 9411 if (showMonthAfterYear) { 9412 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 9413 } 9414 html += "</div>"; // Close datepicker_header 9415 return html; 9416 }, 9417 9418 /* Adjust one of the date sub-fields. */ 9419 _adjustInstDate: function(inst, offset, period) { 9420 var year = inst.drawYear + (period === "Y" ? offset : 0), 9421 month = inst.drawMonth + (period === "M" ? offset : 0), 9422 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 9423 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 9424 9425 inst.selectedDay = date.getDate(); 9426 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9427 inst.drawYear = inst.selectedYear = date.getFullYear(); 9428 if (period === "M" || period === "Y") { 9429 this._notifyChange(inst); 9430 } 9431 }, 9432 9433 /* Ensure a date is within any min/max bounds. */ 9434 _restrictMinMax: function(inst, date) { 9435 var minDate = this._getMinMaxDate(inst, "min"), 9436 maxDate = this._getMinMaxDate(inst, "max"), 9437 newDate = (minDate && date < minDate ? minDate : date); 9438 return (maxDate && newDate > maxDate ? maxDate : newDate); 9439 }, 9440 9441 /* Notify change of month/year. */ 9442 _notifyChange: function(inst) { 9443 var onChange = this._get(inst, "onChangeMonthYear"); 9444 if (onChange) { 9445 onChange.apply((inst.input ? inst.input[0] : null), 9446 [inst.selectedYear, inst.selectedMonth + 1, inst]); 9447 } 9448 }, 9449 9450 /* Determine the number of months to show. */ 9451 _getNumberOfMonths: function(inst) { 9452 var numMonths = this._get(inst, "numberOfMonths"); 9453 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 9454 }, 9455 9456 /* Determine the current maximum date - ensure no time components are set. */ 9457 _getMinMaxDate: function(inst, minMax) { 9458 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 9459 }, 9460 9461 /* Find the number of days in a given month. */ 9462 _getDaysInMonth: function(year, month) { 9463 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 9464 }, 9465 9466 /* Find the day of the week of the first of a month. */ 9467 _getFirstDayOfMonth: function(year, month) { 9468 return new Date(year, month, 1).getDay(); 9469 }, 9470 9471 /* Determines if we should allow a "next/prev" month display change. */ 9472 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 9473 var numMonths = this._getNumberOfMonths(inst), 9474 date = this._daylightSavingAdjust(new Date(curYear, 9475 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 9476 9477 if (offset < 0) { 9478 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 9479 } 9480 return this._isInRange(inst, date); 9481 }, 9482 9483 /* Is the given date in the accepted range? */ 9484 _isInRange: function(inst, date) { 9485 var yearSplit, currentYear, 9486 minDate = this._getMinMaxDate(inst, "min"), 9487 maxDate = this._getMinMaxDate(inst, "max"), 9488 minYear = null, 9489 maxYear = null, 9490 years = this._get(inst, "yearRange"); 9491 if (years){ 9492 yearSplit = years.split(":"); 9493 currentYear = new Date().getFullYear(); 9494 minYear = parseInt(yearSplit[0], 10); 9495 maxYear = parseInt(yearSplit[1], 10); 9496 if ( yearSplit[0].match(/[+\-].*/) ) { 9497 minYear += currentYear; 9498 } 9499 if ( yearSplit[1].match(/[+\-].*/) ) { 9500 maxYear += currentYear; 9501 } 9502 } 9503 9504 return ((!minDate || date.getTime() >= minDate.getTime()) && 9505 (!maxDate || date.getTime() <= maxDate.getTime()) && 9506 (!minYear || date.getFullYear() >= minYear) && 9507 (!maxYear || date.getFullYear() <= maxYear)); 9508 }, 9509 9510 /* Provide the configuration settings for formatting/parsing. */ 9511 _getFormatConfig: function(inst) { 9512 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 9513 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 9514 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 9515 return {shortYearCutoff: shortYearCutoff, 9516 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 9517 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 9518 }, 9519 9520 /* Format the given date for display. */ 9521 _formatDate: function(inst, day, month, year) { 9522 if (!day) { 9523 inst.currentDay = inst.selectedDay; 9524 inst.currentMonth = inst.selectedMonth; 9525 inst.currentYear = inst.selectedYear; 9526 } 9527 var date = (day ? (typeof day === "object" ? day : 9528 this._daylightSavingAdjust(new Date(year, month, day))) : 9529 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 9530 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 9531 } 9532}); 9533 9534/* 9535 * Bind hover events for datepicker elements. 9536 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9537 * Global
vendor: 20,694 bytes, lines 9537-10334
9537instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9538 */ 9539function bindHover(dpDiv) { 9540 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9541 return dpDiv.delegate(selector, "mouseout", function() { 9542 $(this).removeClass("ui-state-hover"); 9543 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9544 $(this).removeClass("ui-datepicker-prev-hover"); 9545 } 9546 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9547 $(this).removeClass("ui-datepicker-next-hover"); 9548 } 9549 }) 9550 .delegate(selector, "mouseover", function(){ 9551 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 9552 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 9553 $(this).addClass("ui-state-hover"); 9554 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9555 $(this).addClass("ui-datepicker-prev-hover"); 9556 } 9557 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9558 $(this).addClass("ui-datepicker-next-hover"); 9559 } 9560 } 9561 }); 9562} 9563 9564/* jQuery extend now ignores nulls! */ 9565function extendRemove(target, props) { 9566 $.extend(target, props); 9567 for (var name in props) { 9568 if (props[name] == null) { 9569 target[name] = props[name]; 9570 } 9571 } 9572 return target; 9573} 9574 9575/* Invoke the datepicker functionality. 9576 @param options string - a command, optionally followed by additional parameters or 9577 Object - settings for attaching new datepicker functionality 9578 @return jQuery object */ 9579$.fn.datepicker = function(options){ 9580 9581 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9582 if ( !this.length ) { 9583 return this; 9584 } 9585 9586 /* Initialise the date picker. */ 9587 if (!$.datepicker.initialized) { 9588 $(document).mousedown($.datepicker._checkExternalClick); 9589 $.datepicker.initialized = true; 9590 } 9591 9592 /* Append datepicker main container to body if not exist. */ 9593 if ($("#"+$.datepicker._mainDivId).length === 0) { 9594 $("body").append($.datepicker.dpDiv); 9595 } 9596 9597 var otherArgs = Array.prototype.slice.call(arguments, 1); 9598 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 9599 return $.datepicker["_" + options + "Datepicker"]. 9600 apply($.datepicker, [this[0]].concat(otherArgs)); 9601 } 9602 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 9603 return $.datepicker["_" + options + "Datepicker"]. 9604 apply($.datepicker, [this[0]].concat(otherArgs)); 9605 } 9606 return this.each(function() { 9607 typeof options === "string" ? 9608 $.datepicker["_" + options + "Datepicker"]. 9609 apply($.datepicker, [this].concat(otherArgs)) : 9610 $.datepicker._attachDatepicker(this, options); 9611 }); 9612}; 9613 9614$.datepicker = new Datepicker(); // singleton instance 9615$.datepicker.initialized = false; 9616$.datepicker.uuid = new Date().getTime(); 9617$.datepicker.version = "1.10.2"; 9618 9619// Workaround for #4055 9620// Add another global to avoid noConflict issues with inline event handlers 9621window["DP_jQuery_" + dpuuid] = $; 9622 9623})(jQuery); 9624 9625(function( $, undefined ) { 9626 9627var sizeRelatedOptions = { 9628 buttons: true, 9629 height: true, 9630 maxHeight: true, 9631 maxWidth: true, 9632 minHeight: true, 9633 minWidth: true, 9634 width: true 9635 }, 9636 resizableRelatedOptions = { 9637 maxHeight: true, 9638 maxWidth: true, 9639 minHeight: true, 9640 minWidth: true 9641 }; 9642 9643$.widget( "ui.dialog", { 9644 version: "1.10.2", 9645 options: { 9646 appendTo: "body", 9647 autoOpen: true, 9648 buttons: [], 9649 closeOnEscape: true, 9650 closeText: "close", 9651 dialogClass: "", 9652 draggable: true, 9653 hide: null, 9654 height: "auto", 9655 maxHeight: null, 9656 maxWidth: null, 9657 minHeight: 150, 9658 minWidth: 150, 9659 modal: false, 9660 position: { 9661 my: "center", 9662 at: "center", 9663 of: window, 9664 collision: "fit", 9665 // Ensure the titlebar is always visible 9666 using: function( pos ) { 9667 var topOffset = $( this ).css( pos ).offset().top; 9668 if ( topOffset < 0 ) { 9669 $( this ).css( "top", pos.top - topOffset ); 9670 } 9671 } 9672 }, 9673 resizable: true, 9674 show: null, 9675 title: null, 9676 width: 300, 9677 9678 // callbacks 9679 beforeClose: null, 9680 close: null, 9681 drag: null, 9682 dragStart: null, 9683 dragStop: null, 9684 focus: null, 9685 open: null, 9686 resize: null, 9687 resizeStart: null, 9688 resizeStop: null 9689 }, 9690 9691 _create: function() { 9692 this.originalCss = { 9693 display: this.element[0].style.display, 9694 width: this.element[0].style.width, 9695 minHeight: this.element[0].style.minHeight, 9696 maxHeight: this.element[0].style.maxHeight, 9697 height: this.element[0].style.height 9698 }; 9699 this.originalPosition = { 9700 parent: this.element.parent(), 9701 index: this.element.parent().children().index( this.element ) 9702 }; 9703 this.originalTitle = this.element.attr("title"); 9704 this.options.title = this.options.title || this.originalTitle; 9705 9706 this._createWrapper(); 9707 9708 this.element 9709 .show() 9710 .removeAttr("title") 9711 .addClass("ui-dialog-content ui-widget-content") 9712 .appendTo( this.uiDialog ); 9713 9714 this._createTitlebar(); 9715 this._createButtonPane(); 9716 9717 if ( this.options.draggable && $.fn.draggable ) { 9718 this._makeDraggable(); 9719 } 9720 if ( this.options.resizable && $.fn.resizable ) { 9721 this._makeResizable(); 9722 } 9723 9724 this._isOpen = false; 9725 }, 9726 9727 _init: function() { 9728 if ( this.options.autoOpen ) { 9729 this.open(); 9730 } 9731 }, 9732 9733 _appendTo: function() { 9734 var element = this.options.appendTo; 9735 if ( element && (element.jquery || element.nodeType) ) { 9736 return $( element ); 9737 } 9738 return this.document.find( element || "body" ).eq( 0 ); 9739 }, 9740 9741 _destroy: function() { 9742 var next, 9743 originalPosition = this.originalPosition; 9744 9745 this._destroyOverlay(); 9746 9747 this.element 9748 .removeUniqueId() 9749 .removeClass("ui-dialog-content ui-widget-content") 9750 .css( this.originalCss ) 9751 // Without detaching first, the following becomes really slow 9752 .detach(); 9753 9754 this.uiDialog.stop( true, true ).remove(); 9755 9756 if ( this.originalTitle ) { 9757 this.element.attr( "title", this.originalTitle ); 9758 } 9759 9760 next = originalPosition.parent.children().eq( originalPosition.index ); 9761 // Don't try to place the dialog next to itself (#8613) 9762 if ( next.length && next[0] !== this.element[0] ) { 9763 next.before( this.element ); 9764 } else { 9765 originalPosition.parent.append( this.element ); 9766 } 9767 }, 9768 9769 widget: function() { 9770 return this.uiDialog; 9771 }, 9772 9773 disable: $.noop, 9774 enable: $.noop, 9775 9776 close: function( event ) { 9777 var that = this; 9778 9779 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 9780 return; 9781 } 9782 9783 this._isOpen = false; 9784 this._destroyOverlay(); 9785 9786 if ( !this.opener.filter(":focusable").focus().length ) { 9787 // Hiding a focused element doesn't trigger blur in WebKit 9788 // so in case we have nothing to focus on, explicitly blur the active element 9789 // https://bugs.webkit.org/show_bug.cgi?id=47182 9790 $( this.document[0].activeElement ).blur(); 9791 } 9792 9793 this._hide( this.uiDialog, this.options.hide, function() { 9794 that._trigger( "close", event ); 9795 }); 9796 }, 9797 9798 isOpen: function() { 9799 return this._isOpen; 9800 }, 9801 9802 moveToTop: function() { 9803 this._moveToTop(); 9804 }, 9805 9806 _moveToTop: function( event, silent ) { 9807 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; 9808 if ( moved && !silent ) { 9809 this._trigger( "focus", event ); 9810 } 9811 return moved; 9812 }, 9813 9814 open: function() { 9815 var that = this; 9816 if ( this._isOpen ) { 9817 if ( this._moveToTop() ) { 9818 this._focusTabbable(); 9819 } 9820 return; 9821 } 9822 9823 this._isOpen = true; 9824 this.opener = $( this.document[0].activeElement ); 9825 9826 this._size(); 9827 this._position(); 9828 this._createOverlay(); 9829 this._moveToTop( null, true ); 9830 this._show( this.uiDialog, this.options.show, function() { 9831 that._focusTabbable(); 9832 that._trigger("focus"); 9833 }); 9834 9835 this._trigger("open"); 9836 }, 9837 9838 _focusTabbable: function() { 9839 // Set focus to the first match: 9840 // 1. First element inside the dialog matching [autofocus] 9841 // 2. Tabbable element inside the content element 9842 // 3. Tabbable element inside the buttonpane 9843 // 4. The close button 9844 // 5. The dialog itself 9845 var hasFocus = this.element.find("[autofocus]"); 9846 if ( !hasFocus.length ) { 9847 hasFocus = this.element.find(":tabbable"); 9848 } 9849 if ( !hasFocus.length ) { 9850 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 9851 } 9852 if ( !hasFocus.length ) { 9853 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); 9854 } 9855 if ( !hasFocus.length ) { 9856 hasFocus = this.uiDialog; 9857 } 9858 hasFocus.eq( 0 ).focus(); 9859 }, 9860 9861 _keepFocus: function( event ) { 9862 function checkFocus() { 9863 var activeElement = this.document[0].activeElement, 9864 isActive = this.uiDialog[0] === activeElement || 9865 $.contains( this.uiDialog[0], activeElement ); 9866 if ( !isActive ) { 9867 this._focusTabbable(); 9868 } 9869 } 9870 event.preventDefault(); 9871 checkFocus.call( this ); 9872 // support: IE 9873 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 9874 // so we check again later 9875 this._delay( checkFocus ); 9876 }, 9877 9878 _createWrapper: function() { 9879 this.uiDialog = $("<div>") 9880 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 9881 this.options.dialogClass ) 9882 .hide() 9883 .attr({ 9884 // Setting tabIndex makes the div focusable 9885 tabIndex: -1, 9886 role: "dialog" 9887 }) 9888 .appendTo( this._appendTo() ); 9889 9890 this._on( this.uiDialog, { 9891 keydown: function( event ) { 9892 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9893 event.keyCode === $.ui.keyCode.ESCAPE ) { 9894 event.preventDefault(); 9895 this.close( event ); 9896 return; 9897 } 9898 9899 // prevent tabbing out of dialogs 9900 if ( event.keyCode !== $.ui.keyCode.TAB ) { 9901 return; 9902 } 9903 var tabbables = this.uiDialog.find(":tabbable"), 9904 first = tabbables.filter(":first"), 9905 last = tabbables.filter(":last"); 9906 9907 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 9908 first.focus( 1 ); 9909 event.preventDefault(); 9910 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 9911 last.focus( 1 ); 9912 event.preventDefault(); 9913 } 9914 }, 9915 mousedown: function( event ) { 9916 if ( this._moveToTop( event ) ) { 9917 this._focusTabbable(); 9918 } 9919 } 9920 }); 9921 9922 // We assume that any existing aria-describedby attribute means 9923 // that the dialog content is marked up properly 9924 // otherwise we brute force the content as the description 9925 if ( !this.element.find("[aria-describedby]").length ) { 9926 this.uiDialog.attr({ 9927 "aria-describedby": this.element.uniqueId().attr("id") 9928 }); 9929 } 9930 }, 9931 9932 _createTitlebar: function() { 9933 var uiDialogTitle; 9934 9935 this.uiDialogTitlebar = $("<div>") 9936 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") 9937 .prependTo( this.uiDialog ); 9938 this._on( this.uiDialogTitlebar, { 9939 mousedown: function( event ) { 9940 // Don't prevent click on close button (#8838) 9941 // Focusing a dialog that is partially scrolled out of view 9942 // causes the browser to scroll it into view, preventing the click event 9943 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { 9944 // Dialog isn't getting focus when dragging (#8063) 9945 this.uiDialog.focus(); 9946 } 9947 } 9948 }); 9949 9950 this.uiDialogTitlebarClose = $("<button></button>") 9951 .button({ 9952 label: this.options.closeText, 9953 icons: { 9954 primary: "ui-icon-closethick" 9955 }, 9956 text: false 9957 }) 9958 .addClass("ui-dialog-titlebar-close") 9959 .appendTo( this.uiDialogTitlebar ); 9960 this._on( this.uiDialogTitlebarClose, { 9961 click: function( event ) { 9962 event.preventDefault(); 9963 this.close( event ); 9964 } 9965 }); 9966 9967 uiDialogTitle = $("<span>") 9968 .uniqueId() 9969 .addClass("ui-dialog-title") 9970 .prependTo( this.uiDialogTitlebar ); 9971 this._title( uiDialogTitle ); 9972 9973 this.uiDialog.attr({ 9974 "aria-labelledby": uiDialogTitle.attr("id") 9975 }); 9976 }, 9977 9978 _title: function( title ) { 9979 if ( !this.options.title ) { 9980 title.html(" "); 9981 } 9982 title.text( this.options.title ); 9983 }, 9984 9985 _createButtonPane: function() { 9986 this.uiDialogButtonPane = $("<div>") 9987 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 9988 9989 this.uiButtonSet = $("<div>") 9990 .addClass("ui-dialog-buttonset") 9991 .appendTo( this.uiDialogButtonPane ); 9992 9993 this._createButtons(); 9994 }, 9995 9996 _createButtons: function() { 9997 var that = this, 9998 buttons = this.options.buttons; 9999 10000 // if we already have a button pane, remove it 10001 this.uiDialogButtonPane.remove(); 10002 this.uiButtonSet.empty(); 10003 10004 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 10005 this.uiDialog.removeClass("ui-dialog-buttons"); 10006 return; 10007 } 10008 10009 $.each( buttons, function( name, props ) { 10010 var click, buttonOptions; 10011 props = $.isFunction( props ) ? 10012 { click: props, text: name } : 10013 props; 10014 // Default to a non-submitting button 10015 props = $.extend( { type: "button" }, props ); 10016 // Change the context for the click callback to be the main element 10017 click = props.click; 10018 props.click = function() { 10019 click.apply( that.element[0], arguments ); 10020 }; 10021 buttonOptions = { 10022 icons: props.icons, 10023 text: props.showText 10024 }; 10025 delete props.icons; 10026 delete props.showText; 10027 $( "<button></button>", props ) 10028 .button( buttonOptions ) 10029 .appendTo( that.uiButtonSet ); 10030 }); 10031 this.uiDialog.addClass("ui-dialog-buttons"); 10032 this.uiDialogButtonPane.appendTo( this.uiDialog ); 10033 }, 10034 10035 _makeDraggable: function() { 10036 var that = this, 10037 options = this.options; 10038 10039 function filteredUi( ui ) { 10040 return { 10041 position: ui.position, 10042 offset: ui.offset 10043 }; 10044 } 10045 10046 this.uiDialog.draggable({ 10047 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 10048 handle: ".ui-dialog-titlebar", 10049 containment: "document", 10050 start: function( event, ui ) { 10051 $( this ).addClass("ui-dialog-dragging"); 10052 that._blockFrames(); 10053 that._trigger( "dragStart", event, filteredUi( ui ) ); 10054 }, 10055 drag: function( event, ui ) { 10056 that._trigger( "drag", event, filteredUi( ui ) ); 10057 }, 10058 stop: function( event, ui ) { 10059 options.position = [ 10060 ui.position.left - that.document.scrollLeft(), 10061 ui.position.top - that.document.scrollTop() 10062 ]; 10063 $( this ).removeClass("ui-dialog-dragging"); 10064 that._unblockFrames(); 10065 that._trigger( "dragStop", event, filteredUi( ui ) ); 10066 } 10067 }); 10068 }, 10069 10070 _makeResizable: function() { 10071 var that = this, 10072 options = this.options, 10073 handles = options.resizable, 10074 // .ui-resizable has position: relative defined in the stylesheet 10075 // but dialogs have to use absolute or fixed positioning 10076 position = this.uiDialog.css("position"), 10077 resizeHandles = typeof handles === "string" ? 10078 handles : 10079 "n,e,s,w,se,sw,ne,nw"; 10080 10081 function filteredUi( ui ) { 10082 return { 10083 originalPosition: ui.originalPosition, 10084 originalSize: ui.originalSize, 10085 position: ui.position, 10086 size: ui.size 10087 }; 10088 } 10089 10090 this.uiDialog.resizable({ 10091 cancel: ".ui-dialog-content", 10092 containment: "document", 10093 alsoResize: this.element, 10094 maxWidth: options.maxWidth, 10095 maxHeight: options.maxHeight, 10096 minWidth: options.minWidth, 10097 minHeight: this._minHeight(), 10098 handles: resizeHandles, 10099 start: function( event, ui ) { 10100 $( this ).addClass("ui-dialog-resizing"); 10101 that._blockFrames(); 10102 that._trigger( "resizeStart", event, filteredUi( ui ) ); 10103 }, 10104 resize: function( event, ui ) { 10105 that._trigger( "resize", event, filteredUi( ui ) ); 10106 }, 10107 stop: function( event, ui ) { 10108 options.height = $( this ).height(); 10109 options.width = $( this ).width(); 10110 $( this ).removeClass("ui-dialog-resizing"); 10111 that._unblockFrames(); 10112 that._trigger( "resizeStop", event, filteredUi( ui ) ); 10113 } 10114 }) 10115 .css( "position", position ); 10116 }, 10117 10118 _minHeight: function() { 10119 var options = this.options; 10120 10121 return options.height === "auto" ? 10122 options.minHeight : 10123 Math.min( options.minHeight, options.height ); 10124 }, 10125 10126 _position: function() { 10127 // Need to show the dialog to get the actual offset in the position plugin 10128 var isVisible = this.uiDialog.is(":visible"); 10129 if ( !isVisible ) { 10130 this.uiDialog.show(); 10131 } 10132 this.uiDialog.position( this.options.position ); 10133 if ( !isVisible ) { 10134 this.uiDialog.hide(); 10135 } 10136 }, 10137 10138 _setOptions: function( options ) { 10139 var that = this, 10140 resize = false, 10141 resizableOptions = {}; 10142 10143 $.each( options, function( key, value ) { 10144 that._setOption( key, value ); 10145 10146 if ( key in sizeRelatedOptions ) { 10147 resize = true; 10148 } 10149 if ( key in resizableRelatedOptions ) { 10150 resizableOptions[ key ] = value; 10151 } 10152 }); 10153 10154 if ( resize ) { 10155 this._size(); 10156 this._position(); 10157 } 10158 if ( this.uiDialog.is(":data(ui-resizable)") ) { 10159 this.uiDialog.resizable( "option", resizableOptions ); 10160 } 10161 }, 10162 10163 _setOption: function( key, value ) { 10164 /*jshint maxcomplexity:15*/ 10165 var isDraggable, isResizable, 10166 uiDialog = this.uiDialog; 10167 10168 if ( key === "dialogClass" ) { 10169 uiDialog 10170 .removeClass( this.options.dialogClass ) 10171 .addClass( value ); 10172 } 10173 10174 if ( key === "disabled" ) { 10175 return; 10176 } 10177 10178 this._super( key, value ); 10179 10180 if ( key === "appendTo" ) { 10181 this.uiDialog.appendTo( this._appendTo() ); 10182 } 10183 10184 if ( key === "buttons" ) { 10185 this._createButtons(); 10186 } 10187 10188 if ( key === "closeText" ) { 10189 this.uiDialogTitlebarClose.button({ 10190 // Ensure that we always pass a string 10191 label: "" + value 10192 }); 10193 } 10194 10195 if ( key === "draggable" ) { 10196 isDraggable = uiDialog.is(":data(ui-draggable)"); 10197 if ( isDraggable && !value ) { 10198 uiDialog.draggable("destroy"); 10199 } 10200 10201 if ( !isDraggable && value ) { 10202 this._makeDraggable(); 10203 } 10204 } 10205 10206 if ( key === "position" ) { 10207 this._position(); 10208 } 10209 10210 if ( key === "resizable" ) { 10211 // currently resizable, becoming non-resizable 10212 isResizable = uiDialog.is(":data(ui-resizable)"); 10213 if ( isResizable && !value ) { 10214 uiDialog.resizable("destroy"); 10215 } 10216 10217 // currently resizable, changing handles 10218 if ( isResizable && typeof value === "string" ) { 10219 uiDialog.resizable( "option", "handles", value ); 10220 } 10221 10222 // currently non-resizable, becoming resizable 10223 if ( !isResizable && value !== false ) { 10224 this._makeResizable(); 10225 } 10226 } 10227 10228 if ( key === "title" ) { 10229 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); 10230 } 10231 }, 10232 10233 _size: function() { 10234 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 10235 // divs will both have width and height set, so we need to reset them 10236 var nonContentHeight, minContentHeight, maxContentHeight, 10237 options = this.options; 10238 10239 // Reset content sizing 10240 this.element.show().css({ 10241 width: "auto", 10242 minHeight: 0, 10243 maxHeight: "none", 10244 height: 0 10245 }); 10246 10247 if ( options.minWidth > options.width ) { 10248 options.width = options.minWidth; 10249 } 10250 10251 // reset wrapper sizing 10252 // determine the height of all the non-content elements 10253 nonContentHeight = this.uiDialog.css({ 10254 height: "auto", 10255 width: options.width 10256 }) 10257 .outerHeight(); 10258 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 10259 maxContentHeight = typeof options.maxHeight === "number" ? 10260 Math.max( 0, options.maxHeight - nonContentHeight ) : 10261 "none"; 10262 10263 if ( options.height === "auto" ) { 10264 this.element.css({ 10265 minHeight: minContentHeight, 10266 maxHeight: maxContentHeight, 10267 height: "auto" 10268 }); 10269 } else { 10270 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 10271 } 10272 10273 if (this.uiDialog.is(":data(ui-resizable)") ) { 10274 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 10275 } 10276 }, 10277 10278 _blockFrames: function() { 10279 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 10280 var iframe = $( this ); 10281 10282 return $( "<div>" ) 10283 .css({ 10284 position: "absolute", 10285 width: iframe.outerWidth(), 10286 height: iframe.outerHeight() 10287 }) 10288 .appendTo( iframe.parent() ) 10289 .offset( iframe.offset() )[0]; 10290 }); 10291 }, 10292 10293 _unblockFrames: function() { 10294 if ( this.iframeBlocks ) { 10295 this.iframeBlocks.remove(); 10296 delete this.iframeBlocks; 10297 } 10298 }, 10299 10300 _allowInteraction: function( event ) { 10301 if ( $( event.target ).closest(".ui-dialog").length ) { 10302 return true; 10303 } 10304 10305 // TODO: Remove hack when datepicker implements 10306 // the .ui-front logic (#8989) 10307 return !!$( event.target ).closest(".ui-datepicker").length; 10308 }, 10309 10310 _createOverlay: function() { 10311 if ( !this.options.modal ) { 10312 return; 10313 } 10314 10315 var that = this, 10316 widgetFullName = this.widgetFullName; 10317 if ( !$.ui.dialog.overlayInstances ) { 10318 // Prevent use of anchors and inputs. 10319 // We use a delay in case the overlay is created from an 10320 // event that we're going to be cancelling. (#2804) 10321 this._delay(function() { 10322 // Handle .dialog().dialog("close") (#4065) 10323 if ( $.ui.dialog.overlayInstances ) { 10324 this.document.bind( "focusin.dialog", function( event ) { 10325 if ( !that._allowInteraction( event ) ) { 10326 event.preventDefault(); 10327 $(".ui-dialog:visible:last .ui-dialog-content") 10328 .data( widgetFullName )._focusTabbable(); 10329 } 10330 }); 10331 } 10332 }); 10333 } 10334
10335 this.overlay = $("<div>") 10336 .addClass("ui-widget-overlay ui-front") 10337 .appendTo( this._appendTo() ); 10338 this._on( this.overlay, { 10339 mousedown: "_keepFocus" 10340 }); 10341 $.ui.dialog.overlayInstances++; 10342 }, 10343 10344 _destroyOverlay: function() { 10345 if ( !this.options.modal ) { 10346 return; 10347 } 10348 10349 if ( this.overlay ) { 10350 $.ui.dialog.overlayInstances--; 10351 10352 if ( !$.ui.dialog.overlayInstances ) { 10353 this.document.unbind( "focusin.dialog" ); 10354 } 10355 this.overlay.remove(); 10356 this.overlay = null; 10357 } 10358 } 10359}); 10360 10361$.ui.dialog.overlayInstances = 0; 10362 10363// DEPRECATED 10364if ( $.uiBackCompat !== false ) { 10365 // position option with array notation 10366 // just override with old implementation 10367 $.widget( "ui.dialog", $.ui.dialog, { 10368 _position: function() { 10369 var position = this.options.position, 10370 myAt = [], 10371 offset = [ 0, 0 ], 10372 isVisible; 10373 10374 if ( position ) { 10375 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 10376 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; 10377 if ( myAt.length === 1 ) { 10378 myAt[1] = myAt[0]; 10379 } 10380 10381 $.each( [ "left", "top" ], function( i, offsetPosition ) { 10382 if ( +myAt[ i ] === myAt[ i ] ) { 10383 offset[ i ] = myAt[ i ]; 10384 myAt[ i ] = offsetPosition; 10385 } 10386 }); 10387 10388 position = { 10389 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 10390 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 10391 at: myAt.join(" ") 10392 }; 10393 } 10394 10395 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 10396 } else { 10397 position = $.ui.dialog.prototype.options.position; 10398 } 10399 10400 // need to show the dialog to get the actual offset in the position plugin 10401 isVisible = this.uiDialog.is(":visible"); 10402 if ( !isVisible ) { 10403 this.uiDialog.show(); 10404 } 10405 this.uiDialog.position( position ); 10406 if ( !isVisible ) { 10407 this.uiDialog.hide(); 10408 } 10409 } 10410 }); 10411} 10412 10413}( jQuery ) ); 10414 10415(function( $, undefined ) { 10416 10417var rvertical = /up|down|vertical/, 10418 rpositivemotion = /up|left|vertical|horizontal/; 10419 10420$.effects.effect.blind = function( o, done ) { 10421 // Create element 10422 var el = $( this ), 10423 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10424 mode = $.effects.setMode( el, o.mode || "hide" ), 10425 direction = o.direction || "up", 10426 vertical = rvertical.test( direction ), 10427 ref = vertical ? "height" : "width", 10428 ref2 = vertical ? "top" : "left", 10429 motion = rpositivemotion.test( direction ), 10430 animation = {}, 10431 show = mode === "show", 10432 wrapper, distance, margin; 10433 10434 // if already wrapped, the wrapper's properties are my property. #6245 10435 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 10436 $.effects.save( el.parent(), props ); 10437 } else { 10438 $.effects.save( el, props ); 10439 } 10440 el.show(); 10441 wrapper = $.effects.createWrapper( el ).css({ 10442 overflow: "hidden" 10443 }); 10444 10445 distance = wrapper[ ref ](); 10446 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 10447 10448 animation[ ref ] = show ? distance : 0; 10449 if ( !motion ) { 10450 el 10451 .css( vertical ? "bottom" : "right", 0 ) 10452 .css( vertical ? "top" : "left", "auto" ) 10453 .css({ position: "absolute" }); 10454 10455 animation[ ref2 ] = show ? margin : distance + margin; 10456 } 10457 10458 // start at 0 if we are showing 10459 if ( show ) { 10460 wrapper.css( ref, 0 ); 10461 if ( ! motion ) { 10462 wrapper.css( ref2, margin + distance ); 10463 } 10464 } 10465 10466 // Animate 10467 wrapper.animate( animation, { 10468 duration: o.duration, 10469 easing: o.easing, 10470 queue: false, 10471 complete: function() { 10472 if ( mode === "hide" ) { 10473 el.hide(); 10474 } 10475 $.effects.restore( el, props ); 10476 $.effects.removeWrapper( el ); 10477 done(); 10478 } 10479 }); 10480 10481}; 10482 10483})(jQuery); 10484 10485(function( $, undefined ) { 10486 10487$.effects.effect.bounce = function( o, done ) { 10488 var el = $( this ), 10489 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10490 10491 // defaults: 10492 mode = $.effects.setMode( el, o.mode || "effect" ), 10493 hide = mode === "hide", 10494 show = mode === "show", 10495 direction = o.direction || "up", 10496 distance = o.distance, 10497 times = o.times || 5, 10498 10499 // number of internal animations 10500 anims = times * 2 + ( show || hide ? 1 : 0 ), 10501 speed = o.duration / anims, 10502 easing = o.easing, 10503 10504 // utility: 10505 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10506 motion = ( direction === "up" || direction === "left" ), 10507 i, 10508 upAnim, 10509 downAnim, 10510 10511 // we will need to re-assemble the queue to stack our animations in place 10512 queue = el.queue(), 10513 queuelen = queue.length; 10514 10515 // Avoid touching opacity to prevent clearType and PNG issues in IE 10516 if ( show || hide ) { 10517 props.push( "opacity" ); 10518 } 10519 10520 $.effects.save( el, props ); 10521 el.show(); 10522 $.effects.createWrapper( el ); // Create Wrapper 10523 10524 // default distance for the BIGGEST bounce is the outer Distance / 3 10525 if ( !distance ) { 10526 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 10527 } 10528 10529 if ( show ) { 10530 downAnim = { opacity: 1 }; 10531 downAnim[ ref ] = 0; 10532 10533 // if we are showing, force opacity 0 and set the initial position 10534 // then do the "first" animation 10535 el.css( "opacity", 0 ) 10536 .css( ref, motion ? -distance * 2 : distance * 2 ) 10537 .animate( downAnim, speed, easing ); 10538 } 10539 10540 // start at the smallest distance if we are hiding 10541 if ( hide ) { 10542 distance = distance / Math.pow( 2, times - 1 ); 10543 } 10544 10545 downAnim = {}; 10546 downAnim[ ref ] = 0; 10547 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 10548 for ( i = 0; i < times; i++ ) { 10549 upAnim = {}; 10550 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10551 10552 el.animate( upAnim, speed, easing ) 10553 .animate( downAnim, speed, easing ); 10554 10555 distance = hide ? distance * 2 : distance / 2; 10556 } 10557 10558 // Last Bounce when Hiding 10559 if ( hide ) { 10560 upAnim = { opacity: 0 }; 10561 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10562 10563 el.animate( upAnim, speed, easing ); 10564 } 10565 10566 el.queue(function() { 10567 if ( hide ) { 10568 el.hide(); 10569 } 10570 $.effects.restore( el, props ); 10571 $.effects.removeWrapper( el ); 10572 done(); 10573 }); 10574 10575 // inject all the animations we just queued to be first in line (after "inprogress") 10576 if ( queuelen > 1) { 10577 queue.splice.apply( queue, 10578 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10579 } 10580 el.dequeue(); 10581 10582}; 10583 10584})(jQuery); 10585 10586(function( $, undefined ) { 10587 10588$.effects.effect.clip = function( o, done ) { 10589 // Create element 10590 var el = $( this ), 10591 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10592 mode = $.effects.setMode( el, o.mode || "hide" ), 10593 show = mode === "show", 10594 direction = o.direction || "vertical", 10595 vert = direction === "vertical", 10596 size = vert ? "height" : "width", 10597 position = vert ? "top" : "left", 10598 animation = {}, 10599 wrapper, animate, distance; 10600 10601 // Save & Show 10602 $.effects.save( el, props ); 10603 el.show(); 10604 10605 // Create Wrapper 10606 wrapper = $.effects.createWrapper( el ).css({ 10607 overflow: "hidden" 10608 }); 10609 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 10610 distance = animate[ size ](); 10611 10612 // Shift 10613 if ( show ) { 10614 animate.css( size, 0 ); 10615 animate.css( position, distance / 2 ); 10616 } 10617 10618 // Create Animation Object: 10619 animation[ size ] = show ? distance : 0; 10620 animation[ position ] = show ? 0 : distance / 2; 10621 10622 // Animate 10623 animate.animate( animation, { 10624 queue: false, 10625 duration: o.duration, 10626 easing: o.easing,
vendor: 24,502 bytes, lines 10627-11609
10627 complete: function() { 10628 if ( !show ) { 10629 el.hide(); 10630 } 10631 $.effects.restore( el, props ); 10632 $.effects.removeWrapper( el ); 10633 done(); 10634 } 10635 }); 10636 10637}; 10638 10639})(jQuery); 10640 10641(function( $, undefined ) { 10642 10643$.effects.effect.drop = function( o, done ) { 10644 10645 var el = $( this ), 10646 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 10647 mode = $.effects.setMode( el, o.mode || "hide" ), 10648 show = mode === "show", 10649 direction = o.direction || "left", 10650 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10651 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 10652 animation = { 10653 opacity: show ? 1 : 0 10654 }, 10655 distance; 10656 10657 // Adjust 10658 $.effects.save( el, props ); 10659 el.show(); 10660 $.effects.createWrapper( el ); 10661 10662 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 10663 10664 if ( show ) { 10665 el 10666 .css( "opacity", 0 ) 10667 .css( ref, motion === "pos" ? -distance : distance ); 10668 } 10669 10670 // Animation 10671 animation[ ref ] = ( show ? 10672 ( motion === "pos" ? "+=" : "-=" ) : 10673 ( motion === "pos" ? "-=" : "+=" ) ) + 10674 distance; 10675 10676 // Animate 10677 el.animate( animation, { 10678 queue: false, 10679 duration: o.duration, 10680 easing: o.easing, 10681 complete: function() { 10682 if ( mode === "hide" ) { 10683 el.hide(); 10684 } 10685 $.effects.restore( el, props ); 10686 $.effects.removeWrapper( el ); 10687 done(); 10688 } 10689 }); 10690}; 10691 10692})(jQuery); 10693 10694(function( $, undefined ) { 10695 10696$.effects.effect.explode = function( o, done ) { 10697 10698 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 10699 cells = rows, 10700 el = $( this ), 10701 mode = $.effects.setMode( el, o.mode || "hide" ), 10702 show = mode === "show", 10703 10704 // show and then visibility:hidden the element before calculating offset 10705 offset = el.show().css( "visibility", "hidden" ).offset(), 10706 10707 // width and height of a piece 10708 width = Math.ceil( el.outerWidth() / cells ), 10709 height = Math.ceil( el.outerHeight() / rows ), 10710 pieces = [], 10711 10712 // loop 10713 i, j, left, top, mx, my; 10714 10715 // children animate complete: 10716 function childComplete() { 10717 pieces.push( this ); 10718 if ( pieces.length === rows * cells ) { 10719 animComplete(); 10720 } 10721 } 10722 10723 // clone the element for each row and cell. 10724 for( i = 0; i < rows ; i++ ) { // ===> 10725 top = offset.top + i * height; 10726 my = i - ( rows - 1 ) / 2 ; 10727 10728 for( j = 0; j < cells ; j++ ) { // ||| 10729 left = offset.left + j * width; 10730 mx = j - ( cells - 1 ) / 2 ; 10731 10732 // Create a clone of the now hidden main element that will be absolute positioned 10733 // within a wrapper div off the -left and -top equal to size of our pieces 10734 el 10735 .clone() 10736 .appendTo( "body" ) 10737 .wrap( "<div></div>" ) 10738 .css({ 10739 position: "absolute", 10740 visibility: "visible", 10741 left: -j * width, 10742 top: -i * height 10743 }) 10744 10745 // select the wrapper - make it overflow: hidden and absolute positioned based on 10746 // where the original was located +left and +top equal to the size of pieces 10747 .parent() 10748 .addClass( "ui-effects-explode" ) 10749 .css({ 10750 position: "absolute", 10751 overflow: "hidden", 10752 width: width, 10753 height: height, 10754 left: left + ( show ? mx * width : 0 ), 10755 top: top + ( show ? my * height : 0 ), 10756 opacity: show ? 0 : 1 10757 }).animate({ 10758 left: left + ( show ? 0 : mx * width ), 10759 top: top + ( show ? 0 : my * height ), 10760 opacity: show ? 1 : 0 10761 }, o.duration || 500, o.easing, childComplete ); 10762 } 10763 } 10764 10765 function animComplete() { 10766 el.css({ 10767 visibility: "visible" 10768 }); 10769 $( pieces ).remove(); 10770 if ( !show ) { 10771 el.hide(); 10772 } 10773 done(); 10774 } 10775}; 10776 10777})(jQuery); 10778 10779(function( $, undefined ) { 10780 10781$.effects.effect.fade = function( o, done ) { 10782 var el = $( this ), 10783 mode = $.effects.setMode( el, o.mode || "toggle" ); 10784 10785 el.animate({ 10786 opacity: mode 10787 }, { 10788 queue: false, 10789 duration: o.duration, 10790 easing: o.easing, 10791 complete: done 10792 }); 10793}; 10794 10795})( jQuery ); 10796 10797(function( $, undefined ) { 10798 10799$.effects.effect.fold = function( o, done ) { 10800 10801 // Create element 10802 var el = $( this ), 10803 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10804 mode = $.effects.setMode( el, o.mode || "hide" ), 10805 show = mode === "show", 10806 hide = mode === "hide", 10807 size = o.size || 15, 10808 percent = /([0-9]+)%/.exec( size ), 10809 horizFirst = !!o.horizFirst, 10810 widthFirst = show !== horizFirst, 10811 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 10812 duration = o.duration / 2, 10813 wrapper, distance, 10814 animation1 = {}, 10815 animation2 = {}; 10816 10817 $.effects.save( el, props ); 10818 el.show(); 10819 10820 // Create Wrapper 10821 wrapper = $.effects.createWrapper( el ).css({ 10822 overflow: "hidden" 10823 }); 10824 distance = widthFirst ? 10825 [ wrapper.width(), wrapper.height() ] : 10826 [ wrapper.height(), wrapper.width() ]; 10827 10828 if ( percent ) { 10829 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 10830 } 10831 if ( show ) { 10832 wrapper.css( horizFirst ? { 10833 height: 0, 10834 width: size 10835 } : { 10836 height: size, 10837 width: 0 10838 }); 10839 } 10840 10841 // Animation 10842 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 10843 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 10844 10845 // Animate 10846 wrapper 10847 .animate( animation1, duration, o.easing ) 10848 .animate( animation2, duration, o.easing, function() { 10849 if ( hide ) { 10850 el.hide(); 10851 } 10852 $.effects.restore( el, props ); 10853 $.effects.removeWrapper( el ); 10854 done(); 10855 }); 10856 10857}; 10858 10859})(jQuery); 10860 10861(function( $, undefined ) { 10862 10863$.effects.effect.highlight = function( o, done ) { 10864 var elem = $( this ), 10865 props = [ "backgroundImage", "backgroundColor", "opacity" ], 10866 mode = $.effects.setMode( elem, o.mode || "show" ), 10867 animation = { 10868 backgroundColor: elem.css( "backgroundColor" ) 10869 }; 10870 10871 if (mode === "hide") { 10872 animation.opacity = 0; 10873 } 10874 10875 $.effects.save( elem, props ); 10876 10877 elem 10878 .show() 10879 .css({ 10880 backgroundImage: "none", 10881 backgroundColor: o.color || "#ffff99" 10882 }) 10883 .animate( animation, { 10884 queue: false, 10885 duration: o.duration, 10886 easing: o.easing, 10887 complete: function() { 10888 if ( mode === "hide" ) { 10889 elem.hide(); 10890 } 10891 $.effects.restore( elem, props ); 10892 done(); 10893 } 10894 }); 10895}; 10896 10897})(jQuery); 10898 10899(function( $, undefined ) { 10900 10901$.effects.effect.pulsate = function( o, done ) { 10902 var elem = $( this ), 10903 mode = $.effects.setMode( elem, o.mode || "show" ), 10904 show = mode === "show", 10905 hide = mode === "hide", 10906 showhide = ( show || mode === "hide" ), 10907 10908 // showing or hiding leaves of the "last" animation 10909 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 10910 duration = o.duration / anims, 10911 animateTo = 0, 10912 queue = elem.queue(), 10913 queuelen = queue.length, 10914 i; 10915 10916 if ( show || !elem.is(":visible")) { 10917 elem.css( "opacity", 0 ).show(); 10918 animateTo = 1; 10919 } 10920 10921 // anims - 1 opacity "toggles" 10922 for ( i = 1; i < anims; i++ ) { 10923 elem.animate({ 10924 opacity: animateTo 10925 }, duration, o.easing ); 10926 animateTo = 1 - animateTo; 10927 } 10928 10929 elem.animate({ 10930 opacity: animateTo 10931 }, duration, o.easing); 10932 10933 elem.queue(function() { 10934 if ( hide ) { 10935 elem.hide(); 10936 } 10937 done(); 10938 }); 10939 10940 // We just queued up "anims" animations, we need to put them next in the queue 10941 if ( queuelen > 1 ) { 10942 queue.splice.apply( queue, 10943 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10944 } 10945 elem.dequeue(); 10946}; 10947 10948})(jQuery); 10949 10950(function( $, undefined ) { 10951 10952$.effects.effect.puff = function( o, done ) { 10953 var elem = $( this ), 10954 mode = $.effects.setMode( elem, o.mode || "hide" ), 10955 hide = mode === "hide", 10956 percent = parseInt( o.percent, 10 ) || 150, 10957 factor = percent / 100, 10958 original = { 10959 height: elem.height(), 10960 width: elem.width(), 10961 outerHeight: elem.outerHeight(), 10962 outerWidth: elem.outerWidth() 10963 }; 10964 10965 $.extend( o, { 10966 effect: "scale", 10967 queue: false, 10968 fade: true, 10969 mode: mode, 10970 complete: done, 10971 percent: hide ? percent : 100, 10972 from: hide ? 10973 original : 10974 { 10975 height: original.height * factor, 10976 width: original.width * factor, 10977 outerHeight: original.outerHeight * factor, 10978 outerWidth: original.outerWidth * factor 10979 } 10980 }); 10981 10982 elem.effect( o ); 10983}; 10984 10985$.effects.effect.scale = function( o, done ) { 10986 10987 // Create element 10988 var el = $( this ), 10989 options = $.extend( true, {}, o ), 10990 mode = $.effects.setMode( el, o.mode || "effect" ), 10991 percent = parseInt( o.percent, 10 ) || 10992 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 10993 direction = o.direction || "both", 10994 origin = o.origin, 10995 original = { 10996 height: el.height(), 10997 width: el.width(), 10998 outerHeight: el.outerHeight(), 10999 outerWidth: el.outerWidth() 11000 }, 11001 factor = { 11002 y: direction !== "horizontal" ? (percent / 100) : 1, 11003 x: direction !== "vertical" ? (percent / 100) : 1 11004 }; 11005 11006 // We are going to pass this effect to the size effect: 11007 options.effect = "size"; 11008 options.queue = false; 11009 options.complete = done; 11010 11011 // Set default origin and restore for show/hide 11012 if ( mode !== "effect" ) { 11013 options.origin = origin || ["middle","center"]; 11014 options.restore = true; 11015 } 11016 11017 options.from = o.from || ( mode === "show" ? { 11018 height: 0, 11019 width: 0, 11020 outerHeight: 0, 11021 outerWidth: 0 11022 } : original ); 11023 options.to = { 11024 height: original.height * factor.y, 11025 width: original.width * factor.x, 11026 outerHeight: original.outerHeight * factor.y, 11027 outerWidth: original.outerWidth * factor.x 11028 }; 11029 11030 // Fade option to support puff 11031 if ( options.fade ) { 11032 if ( mode === "show" ) { 11033 options.from.opacity = 0; 11034 options.to.opacity = 1; 11035 } 11036 if ( mode === "hide" ) { 11037 options.from.opacity = 1; 11038 options.to.opacity = 0; 11039 } 11040 } 11041 11042 // Animate 11043 el.effect( options ); 11044 11045}; 11046 11047$.effects.effect.size = function( o, done ) { 11048 11049 // Create element 11050 var original, baseline, factor, 11051 el = $( this ), 11052 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 11053 11054 // Always restore 11055 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 11056 11057 // Copy for children 11058 props2 = [ "width", "height", "overflow" ], 11059 cProps = [ "fontSize" ], 11060 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 11061 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 11062 11063 // Set options 11064 mode = $.effects.setMode( el, o.mode || "effect" ), 11065 restore = o.restore || mode !== "effect", 11066 scale = o.scale || "both", 11067 origin = o.origin || [ "middle", "center" ], 11068 position = el.css( "position" ), 11069 props = restore ? props0 : props1, 11070 zero = { 11071 height: 0, 11072 width: 0, 11073 outerHeight: 0, 11074 outerWidth: 0 11075 }; 11076 11077 if ( mode === "show" ) { 11078 el.show(); 11079 } 11080 original = { 11081 height: el.height(), 11082 width: el.width(), 11083 outerHeight: el.outerHeight(), 11084 outerWidth: el.outerWidth() 11085 }; 11086 11087 if ( o.mode === "toggle" && mode === "show" ) { 11088 el.from = o.to || zero; 11089 el.to = o.from || original; 11090 } else { 11091 el.from = o.from || ( mode === "show" ? zero : original ); 11092 el.to = o.to || ( mode === "hide" ? zero : original ); 11093 } 11094 11095 // Set scaling factor 11096 factor = { 11097 from: { 11098 y: el.from.height / original.height, 11099 x: el.from.width / original.width 11100 }, 11101 to: { 11102 y: el.to.height / original.height, 11103 x: el.to.width / original.width 11104 } 11105 }; 11106 11107 // Scale the css box 11108 if ( scale === "box" || scale === "both" ) { 11109 11110 // Vertical props scaling 11111 if ( factor.from.y !== factor.to.y ) { 11112 props = props.concat( vProps ); 11113 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 11114 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 11115 } 11116 11117 // Horizontal props scaling 11118 if ( factor.from.x !== factor.to.x ) { 11119 props = props.concat( hProps ); 11120 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 11121 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 11122 } 11123 } 11124 11125 // Scale the content 11126 if ( scale === "content" || scale === "both" ) { 11127 11128 // Vertical props scaling 11129 if ( factor.from.y !== factor.to.y ) { 11130 props = props.concat( cProps ).concat( props2 ); 11131 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 11132 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 11133 } 11134 } 11135 11136 $.effects.save( el, props ); 11137 el.show(); 11138 $.effects.createWrapper( el ); 11139 el.css( "overflow", "hidden" ).css( el.from ); 11140 11141 // Adjust 11142 if (origin) { // Calculate baseline shifts 11143 baseline = $.effects.getBaseline( origin, original ); 11144 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 11145 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 11146 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 11147 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 11148 } 11149 el.css( el.from ); // set top & left 11150 11151 // Animate 11152 if ( scale === "content" || scale === "both" ) { // Scale the children 11153 11154 // Add margins/font-size 11155 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 11156 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 11157 props2 = props0.concat(vProps).concat(hProps); 11158 11159 el.find( "*[width]" ).each( function(){ 11160 var child = $( this ), 11161 c_original = { 11162 height: child.height(), 11163 width: child.width(), 11164 outerHeight: child.outerHeight(), 11165 outerWidth: child.outerWidth() 11166 }; 11167 if (restore) { 11168 $.effects.save(child, props2); 11169 } 11170 11171 child.from = { 11172 height: c_original.height * factor.from.y, 11173 width: c_original.width * factor.from.x, 11174 outerHeight: c_original.outerHeight * factor.from.y, 11175 outerWidth: c_original.outerWidth * factor.from.x 11176 }; 11177 child.to = { 11178 height: c_original.height * factor.to.y, 11179 width: c_original.width * factor.to.x, 11180 outerHeight: c_original.height * factor.to.y, 11181 outerWidth: c_original.width * factor.to.x 11182 }; 11183 11184 // Vertical props scaling 11185 if ( factor.from.y !== factor.to.y ) { 11186 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 11187 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 11188 } 11189 11190 // Horizontal props scaling 11191 if ( factor.from.x !== factor.to.x ) { 11192 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 11193 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 11194 } 11195 11196 // Animate children 11197 child.css( child.from ); 11198 child.animate( child.to, o.duration, o.easing, function() { 11199 11200 // Restore children 11201 if ( restore ) { 11202 $.effects.restore( child, props2 ); 11203 } 11204 }); 11205 }); 11206 } 11207 11208 // Animate 11209 el.animate( el.to, { 11210 queue: false, 11211 duration: o.duration, 11212 easing: o.easing, 11213 complete: function() { 11214 if ( el.to.opacity === 0 ) { 11215 el.css( "opacity", el.from.opacity ); 11216 } 11217 if( mode === "hide" ) { 11218 el.hide(); 11219 } 11220 $.effects.restore( el, props ); 11221 if ( !restore ) { 11222 11223 // we need to calculate our new positioning based on the scaling 11224 if ( position === "static" ) { 11225 el.css({ 11226 position: "relative", 11227 top: el.to.top, 11228 left: el.to.left 11229 }); 11230 } else { 11231 $.each([ "top", "left" ], function( idx, pos ) { 11232 el.css( pos, function( _, str ) { 11233 var val = parseInt( str, 10 ), 11234 toRef = idx ? el.to.left : el.to.top; 11235 11236 // if original was "auto", recalculate the new value from wrapper 11237 if ( str === "auto" ) { 11238 return toRef + "px"; 11239 } 11240 11241 return val + toRef + "px"; 11242 }); 11243 }); 11244 } 11245 } 11246 11247 $.effects.removeWrapper( el ); 11248 done(); 11249 } 11250 }); 11251 11252}; 11253 11254})(jQuery); 11255 11256(function( $, undefined ) { 11257 11258$.effects.effect.shake = function( o, done ) { 11259 11260 var el = $( this ), 11261 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11262 mode = $.effects.setMode( el, o.mode || "effect" ), 11263 direction = o.direction || "left", 11264 distance = o.distance || 20, 11265 times = o.times || 3, 11266 anims = times * 2 + 1, 11267 speed = Math.round(o.duration/anims), 11268 ref = (direction === "up" || direction === "down") ? "top" : "left", 11269 positiveMotion = (direction === "up" || direction === "left"), 11270 animation = {}, 11271 animation1 = {}, 11272 animation2 = {}, 11273 i, 11274 11275 // we will need to re-assemble the queue to stack our animations in place 11276 queue = el.queue(), 11277 queuelen = queue.length; 11278 11279 $.effects.save( el, props ); 11280 el.show(); 11281 $.effects.createWrapper( el ); 11282 11283 // Animation 11284 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 11285 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 11286 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 11287 11288 // Animate 11289 el.animate( animation, speed, o.easing ); 11290 11291 // Shakes 11292 for ( i = 1; i < times; i++ ) { 11293 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 11294 } 11295 el 11296 .animate( animation1, speed, o.easing ) 11297 .animate( animation, speed / 2, o.easing ) 11298 .queue(function() { 11299 if ( mode === "hide" ) { 11300 el.hide(); 11301 } 11302 $.effects.restore( el, props ); 11303 $.effects.removeWrapper( el ); 11304 done(); 11305 }); 11306 11307 // inject all the animations we just queued to be first in line (after "inprogress") 11308 if ( queuelen > 1) { 11309 queue.splice.apply( queue, 11310 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11311 } 11312 el.dequeue(); 11313 11314}; 11315 11316})(jQuery); 11317 11318(function( $, undefined ) { 11319 11320$.effects.effect.slide = function( o, done ) { 11321 11322 // Create element 11323 var el = $( this ), 11324 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 11325 mode = $.effects.setMode( el, o.mode || "show" ), 11326 show = mode === "show", 11327 direction = o.direction || "left", 11328 ref = (direction === "up" || direction === "down") ? "top" : "left", 11329 positiveMotion = (direction === "up" || direction === "left"), 11330 distance, 11331 animation = {}; 11332 11333 // Adjust 11334 $.effects.save( el, props ); 11335 el.show(); 11336 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 11337 11338 $.effects.createWrapper( el ).css({ 11339 overflow: "hidden" 11340 }); 11341 11342 if ( show ) { 11343 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 11344 } 11345 11346 // Animation 11347 animation[ ref ] = ( show ? 11348 ( positiveMotion ? "+=" : "-=") : 11349 ( positiveMotion ? "-=" : "+=")) + 11350 distance; 11351 11352 // Animate 11353 el.animate( animation, { 11354 queue: false, 11355 duration: o.duration, 11356 easing: o.easing, 11357 complete: function() { 11358 if ( mode === "hide" ) { 11359 el.hide(); 11360 } 11361 $.effects.restore( el, props ); 11362 $.effects.removeWrapper( el ); 11363 done(); 11364 } 11365 }); 11366}; 11367 11368})(jQuery); 11369 11370(function( $, undefined ) { 11371 11372$.effects.effect.transfer = function( o, done ) { 11373 var elem = $( this ), 11374 target = $( o.to ), 11375 targetFixed = target.css( "position" ) === "fixed", 11376 body = $("body"), 11377 fixTop = targetFixed ? body.scrollTop() : 0, 11378 fixLeft = targetFixed ? body.scrollLeft() : 0, 11379 endPosition = target.offset(), 11380 animation = { 11381 top: endPosition.top - fixTop , 11382 left: endPosition.left - fixLeft , 11383 height: target.innerHeight(), 11384 width: target.innerWidth() 11385 }, 11386 startPosition = elem.offset(), 11387 transfer = $( "<div class='ui-effects-transfer'></div>" ) 11388 .appendTo( document.body ) 11389 .addClass( o.className ) 11390 .css({ 11391 top: startPosition.top - fixTop , 11392 left: startPosition.left - fixLeft , 11393 height: elem.innerHeight(), 11394 width: elem.innerWidth(), 11395 position: targetFixed ? "fixed" : "absolute" 11396 }) 11397 .animate( animation, o.duration, o.easing, function() { 11398 transfer.remove(); 11399 done(); 11400 }); 11401}; 11402 11403})(jQuery); 11404 11405(function( $, undefined ) { 11406 11407$.widget( "ui.menu", { 11408 version: "1.10.2", 11409 defaultElement: "<ul>", 11410 delay: 300, 11411 options: { 11412 icons: { 11413 submenu: "ui-icon-carat-1-e" 11414 }, 11415 menus: "ul", 11416 position: { 11417 my: "left top", 11418 at: "right top" 11419 }, 11420 role: "menu", 11421 11422 // callbacks 11423 blur: null, 11424 focus: null, 11425 select: null 11426 }, 11427 11428 _create: function() { 11429 this.activeMenu = this.element; 11430 // flag used to prevent firing of the click handler 11431 // as the event bubbles up through nested menus 11432 this.mouseHandled = false; 11433 this.element 11434 .uniqueId() 11435 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11436 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 11437 .attr({ 11438 role: this.options.role, 11439 tabIndex: 0 11440 }) 11441 // need to catch all clicks on disabled menu 11442 // not possible through _on 11443 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 11444 if ( this.options.disabled ) { 11445 event.preventDefault(); 11446 } 11447 }, this )); 11448 11449 if ( this.options.disabled ) { 11450 this.element 11451 .addClass( "ui-state-disabled" ) 11452 .attr( "aria-disabled", "true" ); 11453 } 11454 11455 this._on({ 11456 // Prevent focus from sticking to links inside menu after clicking 11457 // them (focus should always stay on UL during navigation). 11458 "mousedown .ui-menu-item > a": function( event ) { 11459 event.preventDefault(); 11460 }, 11461 "click .ui-state-disabled > a": function( event ) { 11462 event.preventDefault(); 11463 }, 11464 "click .ui-menu-item:has(a)": function( event ) { 11465 var target = $( event.target ).closest( ".ui-menu-item" ); 11466 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 11467 this.mouseHandled = true; 11468 11469 this.select( event ); 11470 // Open submenu on click 11471 if ( target.has( ".ui-menu" ).length ) { 11472 this.expand( event ); 11473 } else if ( !this.element.is( ":focus" ) ) { 11474 // Redirect focus to the menu 11475 this.element.trigger( "focus", [ true ] ); 11476 11477 // If the active item is on the top level, let it stay active. 11478 // Otherwise, blur the active item since it is no longer visible. 11479 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 11480 clearTimeout( this.timer ); 11481 } 11482 } 11483 } 11484 }, 11485 "mouseenter .ui-menu-item": function( event ) { 11486 var target = $( event.currentTarget ); 11487 // Remove ui-state-active class from siblings of the newly focused menu item 11488 // to avoid a jump caused by adjacent elements both having a class with a border 11489 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 11490 this.focus( event, target ); 11491 }, 11492 mouseleave: "collapseAll", 11493 "mouseleave .ui-menu": "collapseAll", 11494 focus: function( event, keepActiveItem ) { 11495 // If there's already an active item, keep it active 11496 // If not, activate the first item 11497 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 11498 11499 if ( !keepActiveItem ) { 11500 this.focus( event, item ); 11501 } 11502 }, 11503 blur: function( event ) { 11504 this._delay(function() { 11505 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 11506 this.collapseAll( event ); 11507 } 11508 }); 11509 }, 11510 keydown: "_keydown" 11511 }); 11512 11513 this.refresh(); 11514 11515 // Clicks outside of a menu collapse any open menus 11516 this._on( this.document, { 11517 click: function( event ) { 11518 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 11519 this.collapseAll( event ); 11520 } 11521 11522 // Reset the mouseHandled flag 11523 this.mouseHandled = false; 11524 } 11525 }); 11526 }, 11527 11528 _destroy: function() { 11529 // Destroy (sub)menus 11530 this.element 11531 .removeAttr( "aria-activedescendant" ) 11532 .find( ".ui-menu" ).addBack() 11533 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 11534 .removeAttr( "role" ) 11535 .removeAttr( "tabIndex" ) 11536 .removeAttr( "aria-labelledby" ) 11537 .removeAttr( "aria-expanded" ) 11538 .removeAttr( "aria-hidden" ) 11539 .removeAttr( "aria-disabled" ) 11540 .removeUniqueId() 11541 .show(); 11542 11543 // Destroy menu items 11544 this.element.find( ".ui-menu-item" ) 11545 .removeClass( "ui-menu-item" ) 11546 .removeAttr( "role" ) 11547 .removeAttr( "aria-disabled" ) 11548 .children( "a" ) 11549 .removeUniqueId() 11550 .removeClass( "ui-corner-all ui-state-hover" ) 11551 .removeAttr( "tabIndex" ) 11552 .removeAttr( "role" ) 11553 .removeAttr( "aria-haspopup" ) 11554 .children().each( function() { 11555 var elem = $( this ); 11556 if ( elem.data( "ui-menu-submenu-carat" ) ) { 11557 elem.remove(); 11558 } 11559 }); 11560 11561 // Destroy menu dividers 11562 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 11563 }, 11564 11565 _keydown: function( event ) { 11566 /*jshint maxcomplexity:20*/ 11567 var match, prev, character, skip, regex, 11568 preventDefault = true; 11569 11570 function escape( value ) { 11571 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 11572 } 11573 11574 switch ( event.keyCode ) { 11575 case $.ui.keyCode.PAGE_UP: 11576 this.previousPage( event ); 11577 break; 11578 case $.ui.keyCode.PAGE_DOWN: 11579 this.nextPage( event ); 11580 break; 11581 case $.ui.keyCode.HOME: 11582 this._move( "first", "first", event ); 11583 break; 11584 case $.ui.keyCode.END: 11585 this._move( "last", "last", event ); 11586 break; 11587 case $.ui.keyCode.UP: 11588 this.previous( event ); 11589 break; 11590 case $.ui.keyCode.DOWN: 11591 this.next( event ); 11592 break; 11593 case $.ui.keyCode.LEFT: 11594 this.collapse( event ); 11595 break; 11596 case $.ui.keyCode.RIGHT: 11597 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 11598 this.expand( event ); 11599 } 11600 break; 11601 case $.ui.keyCode.ENTER: 11602 case $.ui.keyCode.SPACE: 11603 this._activate( event ); 11604 break; 11605 case $.ui.keyCode.ESCAPE: 11606 this.collapse( event ); 11607 break; 11608 default: 11609 preventDefault = false;
11610 prev = this.previousFilter || ""; 11611 character = String.fromCharCode( event.keyCode ); 11612 skip = false; 11613 11614 clearTimeout( this.filterTimer ); 11615 11616 if ( character === prev ) { 11617 skip = true; 11618 } else { 11619 character = prev + character; 11620 } 11621 11622 regex = new RegExp( "^" + escape( character ), "i" ); 11623 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11624 return regex.test( $( this ).children( "a" ).text() ); 11625 }); 11626 match = skip && match.index( this.active.next() ) !== -1 ? 11627 this.active.nextAll( ".ui-menu-item" ) : 11628 match; 11629 11630 // If no matches on the current filter, reset to the last character pressed 11631 // to move down the menu to the first item that starts with that character 11632 if ( !match.length ) { 11633 character = String.fromCharCode( event.keyCode ); 11634 regex = new RegExp( "^" + escape( character ), "i" ); 11635 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11636 return regex.test( $( this ).children( "a" ).text() ); 11637 }); 11638 } 11639 11640 if ( match.length ) { 11641 this.focus( event, match ); 11642 if ( match.length > 1 ) { 11643 this.previousFilter = character; 11644 this.filterTimer = this._delay(function() { 11645 delete this.previousFilter; 11646 }, 1000 ); 11647 } else { 11648 delete this.previousFilter; 11649 } 11650 } else { 11651 delete this.previousFilter; 11652 } 11653 } 11654 11655 if ( preventDefault ) { 11656 event.preventDefault(); 11657 } 11658 }, 11659 11660 _activate: function( event ) { 11661 if ( !this.active.is( ".ui-state-disabled" ) ) { 11662 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 11663 this.expand( event ); 11664 } else { 11665 this.select( event ); 11666 } 11667 } 11668 }, 11669 11670 refresh: function() { 11671 var menus, 11672 icon = this.options.icons.submenu, 11673 submenus = this.element.find( this.options.menus ); 11674 11675 // Initialize nested menus 11676 submenus.filter( ":not(.ui-menu)" ) 11677 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11678 .hide() 11679 .attr({ 11680 role: this.options.role, 11681 "aria-hidden": "true", 11682 "aria-expanded": "false" 11683 }) 11684 .each(function() { 11685 var menu = $( this ), 11686 item = menu.prev( "a" ), 11687 submenuCarat = $( "<span>" ) 11688 .addClass( "ui-menu-icon ui-icon " + icon ) 11689 .data( "ui-menu-submenu-carat", true ); 11690 11691 item 11692 .attr( "aria-haspopup", "true" ) 11693 .prepend( submenuCarat ); 11694 menu.attr( "aria-labelledby", item.attr( "id" ) ); 11695 }); 11696 11697 menus = submenus.add( this.element ); 11698 11699 // Don't refresh list items that are already adapted 11700 menus.children( ":not(.ui-menu-item):has(a)" ) 11701 .addClass( "ui-menu-item" ) 11702 .attr( "role", "presentation" ) 11703 .children( "a" ) 11704 .uniqueId() 11705 .addClass( "ui-corner-all" ) 11706 .attr({ 11707 tabIndex: -1, 11708 role: this._itemRole() 11709 }); 11710
vendor: 84,232 bytes, lines 11711-14826
11711 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 11712 menus.children( ":not(.ui-menu-item)" ).each(function() { 11713 var item = $( this ); 11714 // hyphen, em dash, en dash 11715 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 11716 item.addClass( "ui-widget-content ui-menu-divider" ); 11717 } 11718 }); 11719 11720 // Add aria-disabled attribute to any disabled menu item 11721 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 11722 11723 // If the active item has been removed, blur the menu 11724 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 11725 this.blur(); 11726 } 11727 }, 11728 11729 _itemRole: function() { 11730 return { 11731 menu: "menuitem", 11732 listbox: "option" 11733 }[ this.options.role ]; 11734 }, 11735 11736 _setOption: function( key, value ) { 11737 if ( key === "icons" ) { 11738 this.element.find( ".ui-menu-icon" ) 11739 .removeClass( this.options.icons.submenu ) 11740 .addClass( value.submenu ); 11741 } 11742 this._super( key, value ); 11743 }, 11744 11745 focus: function( event, item ) { 11746 var nested, focused; 11747 this.blur( event, event && event.type === "focus" ); 11748 11749 this._scrollIntoView( item ); 11750 11751 this.active = item.first(); 11752 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 11753 // Only update aria-activedescendant if there's a role 11754 // otherwise we assume focus is managed elsewhere 11755 if ( this.options.role ) { 11756 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 11757 } 11758 11759 // Highlight active parent menu item, if any 11760 this.active 11761 .parent() 11762 .closest( ".ui-menu-item" ) 11763 .children( "a:first" ) 11764 .addClass( "ui-state-active" ); 11765 11766 if ( event && event.type === "keydown" ) { 11767 this._close(); 11768 } else { 11769 this.timer = this._delay(function() { 11770 this._close(); 11771 }, this.delay ); 11772 } 11773 11774 nested = item.children( ".ui-menu" ); 11775 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 11776 this._startOpening(nested); 11777 } 11778 this.activeMenu = item.parent(); 11779 11780 this._trigger( "focus", event, { item: item } ); 11781 }, 11782 11783 _scrollIntoView: function( item ) { 11784 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 11785 if ( this._hasScroll() ) { 11786 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 11787 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 11788 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 11789 scroll = this.activeMenu.scrollTop(); 11790 elementHeight = this.activeMenu.height(); 11791 itemHeight = item.height(); 11792 11793 if ( offset < 0 ) { 11794 this.activeMenu.scrollTop( scroll + offset ); 11795 } else if ( offset + itemHeight > elementHeight ) { 11796 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 11797 } 11798 } 11799 }, 11800 11801 blur: function( event, fromFocus ) { 11802 if ( !fromFocus ) { 11803 clearTimeout( this.timer ); 11804 } 11805 11806 if ( !this.active ) { 11807 return; 11808 } 11809 11810 this.active.children( "a" ).removeClass( "ui-state-focus" ); 11811 this.active = null; 11812 11813 this._trigger( "blur", event, { item: this.active } ); 11814 }, 11815 11816 _startOpening: function( submenu ) { 11817 clearTimeout( this.timer ); 11818 11819 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 11820 // shift in the submenu position when mousing over the carat icon 11821 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 11822 return; 11823 } 11824 11825 this.timer = this._delay(function() { 11826 this._close(); 11827 this._open( submenu ); 11828 }, this.delay ); 11829 }, 11830 11831 _open: function( submenu ) { 11832 var position = $.extend({ 11833 of: this.active 11834 }, this.options.position ); 11835 11836 clearTimeout( this.timer ); 11837 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 11838 .hide() 11839 .attr( "aria-hidden", "true" ); 11840 11841 submenu 11842 .show() 11843 .removeAttr( "aria-hidden" ) 11844 .attr( "aria-expanded", "true" ) 11845 .position( position ); 11846 }, 11847 11848 collapseAll: function( event, all ) { 11849 clearTimeout( this.timer ); 11850 this.timer = this._delay(function() { 11851 // If we were passed an event, look for the submenu that contains the event 11852 var currentMenu = all ? this.element : 11853 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 11854 11855 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 11856 if ( !currentMenu.length ) { 11857 currentMenu = this.element; 11858 } 11859 11860 this._close( currentMenu ); 11861 11862 this.blur( event ); 11863 this.activeMenu = currentMenu; 11864 }, this.delay ); 11865 }, 11866 11867 // With no arguments, closes the currently active menu - if nothing is active 11868 // it closes all menus. If passed an argument, it will search for menus BELOW 11869 _close: function( startMenu ) { 11870 if ( !startMenu ) { 11871 startMenu = this.active ? this.active.parent() : this.element; 11872 } 11873 11874 startMenu 11875 .find( ".ui-menu" ) 11876 .hide() 11877 .attr( "aria-hidden", "true" ) 11878 .attr( "aria-expanded", "false" ) 11879 .end() 11880 .find( "a.ui-state-active" ) 11881 .removeClass( "ui-state-active" ); 11882 }, 11883 11884 collapse: function( event ) { 11885 var newItem = this.active && 11886 this.active.parent().closest( ".ui-menu-item", this.element ); 11887 if ( newItem && newItem.length ) { 11888 this._close(); 11889 this.focus( event, newItem ); 11890 } 11891 }, 11892 11893 expand: function( event ) { 11894 var newItem = this.active && 11895 this.active 11896 .children( ".ui-menu " ) 11897 .children( ".ui-menu-item" ) 11898 .first(); 11899 11900 if ( newItem && newItem.length ) { 11901 this._open( newItem.parent() ); 11902 11903 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 11904 this._delay(function() { 11905 this.focus( event, newItem ); 11906 }); 11907 } 11908 }, 11909 11910 next: function( event ) { 11911 this._move( "next", "first", event ); 11912 }, 11913 11914 previous: function( event ) { 11915 this._move( "prev", "last", event ); 11916 }, 11917 11918 isFirstItem: function() { 11919 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 11920 }, 11921 11922 isLastItem: function() { 11923 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 11924 }, 11925 11926 _move: function( direction, filter, event ) { 11927 var next; 11928 if ( this.active ) { 11929 if ( direction === "first" || direction === "last" ) { 11930 next = this.active 11931 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 11932 .eq( -1 ); 11933 } else { 11934 next = this.active 11935 [ direction + "All" ]( ".ui-menu-item" ) 11936 .eq( 0 ); 11937 } 11938 } 11939 if ( !next || !next.length || !this.active ) { 11940 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 11941 } 11942 11943 this.focus( event, next ); 11944 }, 11945 11946 nextPage: function( event ) { 11947 var item, base, height; 11948 11949 if ( !this.active ) { 11950 this.next( event ); 11951 return; 11952 } 11953 if ( this.isLastItem() ) { 11954 return; 11955 } 11956 if ( this._hasScroll() ) { 11957 base = this.active.offset().top; 11958 height = this.element.height(); 11959 this.active.nextAll( ".ui-menu-item" ).each(function() { 11960 item = $( this ); 11961 return item.offset().top - base - height < 0; 11962 }); 11963 11964 this.focus( event, item ); 11965 } else { 11966 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 11967 [ !this.active ? "first" : "last" ]() ); 11968 } 11969 }, 11970 11971 previousPage: function( event ) { 11972 var item, base, height; 11973 if ( !this.active ) { 11974 this.next( event ); 11975 return; 11976 } 11977 if ( this.isFirstItem() ) { 11978 return; 11979 } 11980 if ( this._hasScroll() ) { 11981 base = this.active.offset().top; 11982 height = this.element.height(); 11983 this.active.prevAll( ".ui-menu-item" ).each(function() { 11984 item = $( this ); 11985 return item.offset().top - base + height > 0; 11986 }); 11987 11988 this.focus( event, item ); 11989 } else { 11990 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 11991 } 11992 }, 11993 11994 _hasScroll: function() { 11995 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 11996 }, 11997 11998 select: function( event ) { 11999 // TODO: It should never be possible to not have an active item at this 12000 // point, but the tests don't trigger mouseenter before click. 12001 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 12002 var ui = { item: this.active }; 12003 if ( !this.active.has( ".ui-menu" ).length ) { 12004 this.collapseAll( event, true ); 12005 } 12006 this._trigger( "select", event, ui ); 12007 } 12008}); 12009 12010}( jQuery )); 12011 12012(function( $, undefined ) { 12013 12014$.ui = $.ui || {}; 12015 12016var cachedScrollbarWidth, 12017 max = Math.max, 12018 abs = Math.abs, 12019 round = Math.round, 12020 rhorizontal = /left|center|right/, 12021 rvertical = /top|center|bottom/, 12022 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 12023 rposition = /^\w+/, 12024 rpercent = /%$/, 12025 _position = $.fn.position; 12026 12027function getOffsets( offsets, width, height ) { 12028 return [ 12029 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 12030 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 12031 ]; 12032} 12033 12034function parseCss( element, property ) { 12035 return parseInt( $.css( element, property ), 10 ) || 0; 12036} 12037 12038function getDimensions( elem ) { 12039 var raw = elem[0]; 12040 if ( raw.nodeType === 9 ) { 12041 return { 12042 width: elem.width(), 12043 height: elem.height(), 12044 offset: { top: 0, left: 0 } 12045 }; 12046 } 12047 if ( $.isWindow( raw ) ) { 12048 return { 12049 width: elem.width(), 12050 height: elem.height(), 12051 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 12052 }; 12053 } 12054 if ( raw.preventDefault ) { 12055 return { 12056 width: 0, 12057 height: 0, 12058 offset: { top: raw.pageY, left: raw.pageX } 12059 }; 12060 } 12061 return { 12062 width: elem.outerWidth(), 12063 height: elem.outerHeight(), 12064 offset: elem.offset() 12065 }; 12066} 12067 12068$.position = { 12069 scrollbarWidth: function() { 12070 if ( cachedScrollbarWidth !== undefined ) { 12071 return cachedScrollbarWidth; 12072 } 12073 var w1, w2, 12074 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 12075 innerDiv = div.children()[0]; 12076 12077 $( "body" ).append( div ); 12078 w1 = innerDiv.offsetWidth; 12079 div.css( "overflow", "scroll" ); 12080 12081 w2 = innerDiv.offsetWidth; 12082 12083 if ( w1 === w2 ) { 12084 w2 = div[0].clientWidth; 12085 } 12086 12087 div.remove(); 12088 12089 return (cachedScrollbarWidth = w1 - w2); 12090 }, 12091 getScrollInfo: function( within ) { 12092 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 12093 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 12094 hasOverflowX = overflowX === "scroll" || 12095 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 12096 hasOverflowY = overflowY === "scroll" || 12097 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 12098 return { 12099 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 12100 height: hasOverflowX ? $.position.scrollbarWidth() : 0 12101 }; 12102 }, 12103 getWithinInfo: function( element ) { 12104 var withinElement = $( element || window ), 12105 isWindow = $.isWindow( withinElement[0] ); 12106 return { 12107 element: withinElement, 12108 isWindow: isWindow, 12109 offset: withinElement.offset() || { left: 0, top: 0 }, 12110 scrollLeft: withinElement.scrollLeft(), 12111 scrollTop: withinElement.scrollTop(), 12112 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 12113 height: isWindow ? withinElement.height() : withinElement.outerHeight() 12114 }; 12115 } 12116}; 12117 12118$.fn.position = function( options ) { 12119 if ( !options || !options.of ) { 12120 return _position.apply( this, arguments ); 12121 } 12122 12123 // make a copy, we don't want to modify arguments 12124 options = $.extend( {}, options ); 12125 12126 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 12127 target = $( options.of ), 12128 within = $.position.getWithinInfo( options.within ), 12129 scrollInfo = $.position.getScrollInfo( within ), 12130 collision = ( options.collision || "flip" ).split( " " ), 12131 offsets = {}; 12132 12133 dimensions = getDimensions( target ); 12134 if ( target[0].preventDefault ) { 12135 // force left top to allow flipping 12136 options.at = "left top"; 12137 } 12138 targetWidth = dimensions.width; 12139 targetHeight = dimensions.height; 12140 targetOffset = dimensions.offset; 12141 // clone to reuse original targetOffset later 12142 basePosition = $.extend( {}, targetOffset ); 12143 12144 // force my and at to have valid horizontal and vertical positions 12145 // if a value is missing or invalid, it will be converted to center 12146 $.each( [ "my", "at" ], function() { 12147 var pos = ( options[ this ] || "" ).split( " " ), 12148 horizontalOffset, 12149 verticalOffset; 12150 12151 if ( pos.length === 1) { 12152 pos = rhorizontal.test( pos[ 0 ] ) ? 12153 pos.concat( [ "center" ] ) : 12154 rvertical.test( pos[ 0 ] ) ? 12155 [ "center" ].concat( pos ) : 12156 [ "center", "center" ]; 12157 } 12158 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 12159 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 12160 12161 // calculate offsets 12162 horizontalOffset = roffset.exec( pos[ 0 ] ); 12163 verticalOffset = roffset.exec( pos[ 1 ] ); 12164 offsets[ this ] = [ 12165 horizontalOffset ? horizontalOffset[ 0 ] : 0, 12166 verticalOffset ? verticalOffset[ 0 ] : 0 12167 ]; 12168 12169 // reduce to just the positions without the offsets 12170 options[ this ] = [ 12171 rposition.exec( pos[ 0 ] )[ 0 ], 12172 rposition.exec( pos[ 1 ] )[ 0 ] 12173 ]; 12174 }); 12175 12176 // normalize collision option 12177 if ( collision.length === 1 ) { 12178 collision[ 1 ] = collision[ 0 ]; 12179 } 12180 12181 if ( options.at[ 0 ] === "right" ) { 12182 basePosition.left += targetWidth; 12183 } else if ( options.at[ 0 ] === "center" ) { 12184 basePosition.left += targetWidth / 2; 12185 } 12186 12187 if ( options.at[ 1 ] === "bottom" ) { 12188 basePosition.top += targetHeight; 12189 } else if ( options.at[ 1 ] === "center" ) { 12190 basePosition.top += targetHeight / 2; 12191 } 12192 12193 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 12194 basePosition.left += atOffset[ 0 ]; 12195 basePosition.top += atOffset[ 1 ]; 12196 12197 return this.each(function() { 12198 var collisionPosition, using, 12199 elem = $( this ), 12200 elemWidth = elem.outerWidth(), 12201 elemHeight = elem.outerHeight(), 12202 marginLeft = parseCss( this, "marginLeft" ), 12203 marginTop = parseCss( this, "marginTop" ), 12204 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 12205 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 12206 position = $.extend( {}, basePosition ), 12207 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 12208 12209 if ( options.my[ 0 ] === "right" ) { 12210 position.left -= elemWidth; 12211 } else if ( options.my[ 0 ] === "center" ) { 12212 position.left -= elemWidth / 2; 12213 } 12214 12215 if ( options.my[ 1 ] === "bottom" ) { 12216 position.top -= elemHeight; 12217 } else if ( options.my[ 1 ] === "center" ) { 12218 position.top -= elemHeight / 2; 12219 } 12220 12221 position.left += myOffset[ 0 ]; 12222 position.top += myOffset[ 1 ]; 12223 12224 // if the browser doesn't support fractions, then round for consistent results 12225 if ( !$.support.offsetFractions ) { 12226 position.left = round( position.left ); 12227 position.top = round( position.top ); 12228 } 12229 12230 collisionPosition = { 12231 marginLeft: marginLeft, 12232 marginTop: marginTop 12233 }; 12234 12235 $.each( [ "left", "top" ], function( i, dir ) { 12236 if ( $.ui.position[ collision[ i ] ] ) { 12237 $.ui.position[ collision[ i ] ][ dir ]( position, { 12238 targetWidth: targetWidth, 12239 targetHeight: targetHeight, 12240 elemWidth: elemWidth, 12241 elemHeight: elemHeight, 12242 collisionPosition: collisionPosition, 12243 collisionWidth: collisionWidth, 12244 collisionHeight: collisionHeight, 12245 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 12246 my: options.my, 12247 at: options.at, 12248 within: within, 12249 elem : elem 12250 }); 12251 } 12252 }); 12253 12254 if ( options.using ) { 12255 // adds feedback as second argument to using callback, if present 12256 using = function( props ) { 12257 var left = targetOffset.left - position.left, 12258 right = left + targetWidth - elemWidth, 12259 top = targetOffset.top - position.top, 12260 bottom = top + targetHeight - elemHeight, 12261 feedback = { 12262 target: { 12263 element: target, 12264 left: targetOffset.left, 12265 top: targetOffset.top, 12266 width: targetWidth, 12267 height: targetHeight 12268 }, 12269 element: { 12270 element: elem, 12271 left: position.left, 12272 top: position.top, 12273 width: elemWidth, 12274 height: elemHeight 12275 }, 12276 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 12277 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 12278 }; 12279 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 12280 feedback.horizontal = "center"; 12281 } 12282 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 12283 feedback.vertical = "middle"; 12284 } 12285 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 12286 feedback.important = "horizontal"; 12287 } else { 12288 feedback.important = "vertical"; 12289 } 12290 options.using.call( this, props, feedback ); 12291 }; 12292 } 12293 12294 elem.offset( $.extend( position, { using: using } ) ); 12295 }); 12296}; 12297 12298$.ui.position = { 12299 fit: { 12300 left: function( position, data ) { 12301 var within = data.within, 12302 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 12303 outerWidth = within.width, 12304 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12305 overLeft = withinOffset - collisionPosLeft, 12306 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 12307 newOverRight; 12308 12309 // element is wider than within 12310 if ( data.collisionWidth > outerWidth ) { 12311 // element is initially over the left side of within 12312 if ( overLeft > 0 && overRight <= 0 ) { 12313 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 12314 position.left += overLeft - newOverRight; 12315 // element is initially over right side of within 12316 } else if ( overRight > 0 && overLeft <= 0 ) { 12317 position.left = withinOffset; 12318 // element is initially over both left and right sides of within 12319 } else { 12320 if ( overLeft > overRight ) { 12321 position.left = withinOffset + outerWidth - data.collisionWidth; 12322 } else { 12323 position.left = withinOffset; 12324 } 12325 } 12326 // too far left -> align with left edge 12327 } else if ( overLeft > 0 ) { 12328 position.left += overLeft; 12329 // too far right -> align with right edge 12330 } else if ( overRight > 0 ) { 12331 position.left -= overRight; 12332 // adjust based on position and margin 12333 } else { 12334 position.left = max( position.left - collisionPosLeft, position.left ); 12335 } 12336 }, 12337 top: function( position, data ) { 12338 var within = data.within, 12339 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 12340 outerHeight = data.within.height, 12341 collisionPosTop = position.top - data.collisionPosition.marginTop, 12342 overTop = withinOffset - collisionPosTop, 12343 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 12344 newOverBottom; 12345 12346 // element is taller than within 12347 if ( data.collisionHeight > outerHeight ) { 12348 // element is initially over the top of within 12349 if ( overTop > 0 && overBottom <= 0 ) { 12350 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 12351 position.top += overTop - newOverBottom; 12352 // element is initially over bottom of within 12353 } else if ( overBottom > 0 && overTop <= 0 ) { 12354 position.top = withinOffset; 12355 // element is initially over both top and bottom of within 12356 } else { 12357 if ( overTop > overBottom ) { 12358 position.top = withinOffset + outerHeight - data.collisionHeight; 12359 } else { 12360 position.top = withinOffset; 12361 } 12362 } 12363 // too far up -> align with top 12364 } else if ( overTop > 0 ) { 12365 position.top += overTop; 12366 // too far down -> align with bottom edge 12367 } else if ( overBottom > 0 ) { 12368 position.top -= overBottom; 12369 // adjust based on position and margin 12370 } else { 12371 position.top = max( position.top - collisionPosTop, position.top ); 12372 } 12373 } 12374 }, 12375 flip: { 12376 left: function( position, data ) { 12377 var within = data.within, 12378 withinOffset = within.offset.left + within.scrollLeft, 12379 outerWidth = within.width, 12380 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 12381 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12382 overLeft = collisionPosLeft - offsetLeft, 12383 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 12384 myOffset = data.my[ 0 ] === "left" ? 12385 -data.elemWidth : 12386 data.my[ 0 ] === "right" ? 12387 data.elemWidth : 12388 0, 12389 atOffset = data.at[ 0 ] === "left" ? 12390 data.targetWidth : 12391 data.at[ 0 ] === "right" ? 12392 -data.targetWidth : 12393 0, 12394 offset = -2 * data.offset[ 0 ], 12395 newOverRight, 12396 newOverLeft; 12397 12398 if ( overLeft < 0 ) { 12399 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 12400 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 12401 position.left += myOffset + atOffset + offset; 12402 } 12403 } 12404 else if ( overRight > 0 ) { 12405 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 12406 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 12407 position.left += myOffset + atOffset + offset; 12408 } 12409 } 12410 }, 12411 top: function( position, data ) { 12412 var within = data.within, 12413 withinOffset = within.offset.top + within.scrollTop, 12414 outerHeight = within.height, 12415 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 12416 collisionPosTop = position.top - data.collisionPosition.marginTop, 12417 overTop = collisionPosTop - offsetTop, 12418 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 12419 top = data.my[ 1 ] === "top", 12420 myOffset = top ? 12421 -data.elemHeight : 12422 data.my[ 1 ] === "bottom" ? 12423 data.elemHeight : 12424 0, 12425 atOffset = data.at[ 1 ] === "top" ? 12426 data.targetHeight : 12427 data.at[ 1 ] === "bottom" ? 12428 -data.targetHeight : 12429 0, 12430 offset = -2 * data.offset[ 1 ], 12431 newOverTop, 12432 newOverBottom; 12433 if ( overTop < 0 ) { 12434 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 12435 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 12436 position.top += myOffset + atOffset + offset; 12437 } 12438 } 12439 else if ( overBottom > 0 ) { 12440 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 12441 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 12442 position.top += myOffset + atOffset + offset; 12443 } 12444 } 12445 } 12446 }, 12447 flipfit: { 12448 left: function() { 12449 $.ui.position.flip.left.apply( this, arguments ); 12450 $.ui.position.fit.left.apply( this, arguments ); 12451 }, 12452 top: function() { 12453 $.ui.position.flip.top.apply( this, arguments ); 12454 $.ui.position.fit.top.apply( this, arguments ); 12455 } 12456 } 12457}; 12458 12459// fraction support test 12460(function () { 12461 var testElement, testElementParent, testElementStyle, offsetLeft, i, 12462 body = document.getElementsByTagName( "body" )[ 0 ], 12463 div = document.createElement( "div" ); 12464 12465 //Create a "fake body" for testing based on method used in jQuery.support 12466 testElement = document.createElement( body ? "div" : "body" ); 12467 testElementStyle = { 12468 visibility: "hidden", 12469 width: 0, 12470 height: 0, 12471 border: 0, 12472 margin: 0, 12473 background: "none" 12474 }; 12475 if ( body ) { 12476 $.extend( testElementStyle, { 12477 position: "absolute", 12478 left: "-1000px", 12479 top: "-1000px" 12480 }); 12481 } 12482 for ( i in testElementStyle ) { 12483 testElement.style[ i ] = testElementStyle[ i ]; 12484 } 12485 testElement.appendChild( div ); 12486 testElementParent = body || document.documentElement; 12487 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 12488 12489 div.style.cssText = "position: absolute; left: 10.7432222px;"; 12490 12491 offsetLeft = $( div ).offset().left; 12492 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 12493 12494 testElement.innerHTML = ""; 12495 testElementParent.removeChild( testElement ); 12496})(); 12497 12498}( jQuery ) ); 12499 12500(function( $, undefined ) { 12501 12502$.widget( "ui.progressbar", { 12503 version: "1.10.2", 12504 options: { 12505 max: 100, 12506 value: 0, 12507 12508 change: null, 12509 complete: null 12510 }, 12511 12512 min: 0, 12513 12514 _create: function() { 12515 // Constrain initial value 12516 this.oldValue = this.options.value = this._constrainedValue(); 12517 12518 this.element 12519 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12520 .attr({ 12521 // Only set static values, aria-valuenow and aria-valuemax are 12522 // set inside _refreshValue() 12523 role: "progressbar", 12524 "aria-valuemin": this.min 12525 }); 12526 12527 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 12528 .appendTo( this.element ); 12529 12530 this._refreshValue(); 12531 }, 12532 12533 _destroy: function() { 12534 this.element 12535 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12536 .removeAttr( "role" ) 12537 .removeAttr( "aria-valuemin" ) 12538 .removeAttr( "aria-valuemax" ) 12539 .removeAttr( "aria-valuenow" ); 12540 12541 this.valueDiv.remove(); 12542 }, 12543 12544 value: function( newValue ) { 12545 if ( newValue === undefined ) { 12546 return this.options.value; 12547 } 12548 12549 this.options.value = this._constrainedValue( newValue ); 12550 this._refreshValue(); 12551 }, 12552 12553 _constrainedValue: function( newValue ) { 12554 if ( newValue === undefined ) { 12555 newValue = this.options.value; 12556 } 12557 12558 this.indeterminate = newValue === false; 12559 12560 // sanitize value 12561 if ( typeof newValue !== "number" ) { 12562 newValue = 0; 12563 } 12564 12565 return this.indeterminate ? false : 12566 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12567 }, 12568 12569 _setOptions: function( options ) { 12570 // Ensure "value" option is set after other values (like max) 12571 var value = options.value; 12572 delete options.value; 12573 12574 this._super( options ); 12575 12576 this.options.value = this._constrainedValue( value ); 12577 this._refreshValue(); 12578 }, 12579 12580 _setOption: function( key, value ) { 12581 if ( key === "max" ) { 12582 // Don't allow a max less than min 12583 value = Math.max( this.min, value ); 12584 } 12585 12586 this._super( key, value ); 12587 }, 12588 12589 _percentage: function() { 12590 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 12591 }, 12592 12593 _refreshValue: function() { 12594 var value = this.options.value, 12595 percentage = this._percentage(); 12596 12597 this.valueDiv 12598 .toggle( this.indeterminate || value > this.min ) 12599 .toggleClass( "ui-corner-right", value === this.options.max ) 12600 .width( percentage.toFixed(0) + "%" ); 12601 12602 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 12603 12604 if ( this.indeterminate ) { 12605 this.element.removeAttr( "aria-valuenow" ); 12606 if ( !this.overlayDiv ) { 12607 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 12608 } 12609 } else { 12610 this.element.attr({ 12611 "aria-valuemax": this.options.max, 12612 "aria-valuenow": value 12613 }); 12614 if ( this.overlayDiv ) { 12615 this.overlayDiv.remove(); 12616 this.overlayDiv = null; 12617 } 12618 } 12619 12620 if ( this.oldValue !== value ) { 12621 this.oldValue = value; 12622 this._trigger( "change" ); 12623 } 12624 if ( value === this.options.max ) { 12625 this._trigger( "complete" ); 12626 } 12627 } 12628}); 12629 12630})( jQuery ); 12631 12632(function( $, undefined ) { 12633 12634// number of pages in a slider 12635// (how many times can you page up/down to go through the whole range) 12636var numPages = 5; 12637 12638$.widget( "ui.slider", $.ui.mouse, { 12639 version: "1.10.2", 12640 widgetEventPrefix: "slide", 12641 12642 options: { 12643 animate: false, 12644 distance: 0, 12645 max: 100, 12646 min: 0, 12647 orientation: "horizontal", 12648 range: false, 12649 step: 1, 12650 value: 0, 12651 values: null, 12652 12653 // callbacks 12654 change: null, 12655 slide: null, 12656 start: null, 12657 stop: null 12658 }, 12659 12660 _create: function() { 12661 this._keySliding = false; 12662 this._mouseSliding = false; 12663 this._animateOff = true; 12664 this._handleIndex = null; 12665 this._detectOrientation(); 12666 this._mouseInit(); 12667 12668 this.element 12669 .addClass( "ui-slider" + 12670 " ui-slider-" + this.orientation + 12671 " ui-widget" + 12672 " ui-widget-content" + 12673 " ui-corner-all"); 12674 12675 this._refresh(); 12676 this._setOption( "disabled", this.options.disabled ); 12677 12678 this._animateOff = false; 12679 }, 12680 12681 _refresh: function() { 12682 this._createRange(); 12683 this._createHandles(); 12684 this._setupEvents(); 12685 this._refreshValue(); 12686 }, 12687 12688 _createHandles: function() { 12689 var i, handleCount, 12690 options = this.options, 12691 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 12692 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 12693 handles = []; 12694 12695 handleCount = ( options.values && options.values.length ) || 1; 12696 12697 if ( existingHandles.length > handleCount ) { 12698 existingHandles.slice( handleCount ).remove(); 12699 existingHandles = existingHandles.slice( 0, handleCount ); 12700 } 12701 12702 for ( i = existingHandles.length; i < handleCount; i++ ) { 12703 handles.push( handle ); 12704 } 12705 12706 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 12707 12708 this.handle = this.handles.eq( 0 ); 12709 12710 this.handles.each(function( i ) { 12711 $( this ).data( "ui-slider-handle-index", i ); 12712 }); 12713 }, 12714 12715 _createRange: function() { 12716 var options = this.options, 12717 classes = ""; 12718 12719 if ( options.range ) { 12720 if ( options.range === true ) { 12721 if ( !options.values ) { 12722 options.values = [ this._valueMin(), this._valueMin() ]; 12723 } else if ( options.values.length && options.values.length !== 2 ) { 12724 options.values = [ options.values[0], options.values[0] ]; 12725 } else if ( $.isArray( options.values ) ) { 12726 options.values = options.values.slice(0); 12727 } 12728 } 12729 12730 if ( !this.range || !this.range.length ) { 12731 this.range = $( "<div></div>" ) 12732 .appendTo( this.element ); 12733 12734 classes = "ui-slider-range" + 12735 // note: this isn't the most fittingly semantic framework class for this element, 12736 // but worked best visually with a variety of themes 12737 " ui-widget-header ui-corner-all"; 12738 } else { 12739 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 12740 // Handle range switching from true to min/max 12741 .css({ 12742 "left": "", 12743 "bottom": "" 12744 }); 12745 } 12746 12747 this.range.addClass( classes + 12748 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 12749 } else { 12750 this.range = $([]); 12751 } 12752 }, 12753 12754 _setupEvents: function() { 12755 var elements = this.handles.add( this.range ).filter( "a" ); 12756 this._off( elements ); 12757 this._on( elements, this._handleEvents ); 12758 this._hoverable( elements ); 12759 this._focusable( elements ); 12760 }, 12761 12762 _destroy: function() { 12763 this.handles.remove(); 12764 this.range.remove(); 12765 12766 this.element 12767 .removeClass( "ui-slider" + 12768 " ui-slider-horizontal" + 12769 " ui-slider-vertical" + 12770 " ui-widget" + 12771 " ui-widget-content" + 12772 " ui-corner-all" ); 12773 12774 this._mouseDestroy(); 12775 }, 12776 12777 _mouseCapture: function( event ) { 12778 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 12779 that = this, 12780 o = this.options; 12781 12782 if ( o.disabled ) { 12783 return false; 12784 } 12785 12786 this.elementSize = { 12787 width: this.element.outerWidth(), 12788 height: this.element.outerHeight() 12789 }; 12790 this.elementOffset = this.element.offset(); 12791 12792 position = { x: event.pageX, y: event.pageY }; 12793 normValue = this._normValueFromMouse( position ); 12794 distance = this._valueMax() - this._valueMin() + 1; 12795 this.handles.each(function( i ) { 12796 var thisDistance = Math.abs( normValue - that.values(i) ); 12797 if (( distance > thisDistance ) || 12798 ( distance === thisDistance && 12799 (i === that._lastChangedValue || that.values(i) === o.min ))) { 12800 distance = thisDistance; 12801 closestHandle = $( this ); 12802 index = i; 12803 } 12804 }); 12805 12806 allowed = this._start( event, index ); 12807 if ( allowed === false ) { 12808 return false; 12809 } 12810 this._mouseSliding = true; 12811 12812 this._handleIndex = index; 12813 12814 closestHandle 12815 .addClass( "ui-state-active" ) 12816 .focus(); 12817 12818 offset = closestHandle.offset(); 12819 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 12820 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 12821 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 12822 top: event.pageY - offset.top - 12823 ( closestHandle.height() / 2 ) - 12824 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 12825 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 12826 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 12827 }; 12828 12829 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 12830 this._slide( event, index, normValue ); 12831 } 12832 this._animateOff = true; 12833 return true; 12834 }, 12835 12836 _mouseStart: function() { 12837 return true; 12838 }, 12839 12840 _mouseDrag: function( event ) { 12841 var position = { x: event.pageX, y: event.pageY }, 12842 normValue = this._normValueFromMouse( position ); 12843 12844 this._slide( event, this._handleIndex, normValue ); 12845 12846 return false; 12847 }, 12848 12849 _mouseStop: function( event ) { 12850 this.handles.removeClass( "ui-state-active" ); 12851 this._mouseSliding = false; 12852 12853 this._stop( event, this._handleIndex ); 12854 this._change( event, this._handleIndex ); 12855 12856 this._handleIndex = null; 12857 this._clickOffset = null; 12858 this._animateOff = false; 12859 12860 return false; 12861 }, 12862 12863 _detectOrientation: function() { 12864 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 12865 }, 12866 12867 _normValueFromMouse: function( position ) { 12868 var pixelTotal, 12869 pixelMouse, 12870 percentMouse, 12871 valueTotal, 12872 valueMouse; 12873 12874 if ( this.orientation === "horizontal" ) { 12875 pixelTotal = this.elementSize.width; 12876 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 12877 } else { 12878 pixelTotal = this.elementSize.height; 12879 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 12880 } 12881 12882 percentMouse = ( pixelMouse / pixelTotal ); 12883 if ( percentMouse > 1 ) { 12884 percentMouse = 1; 12885 } 12886 if ( percentMouse < 0 ) { 12887 percentMouse = 0; 12888 } 12889 if ( this.orientation === "vertical" ) { 12890 percentMouse = 1 - percentMouse; 12891 } 12892 12893 valueTotal = this._valueMax() - this._valueMin(); 12894 valueMouse = this._valueMin() + percentMouse * valueTotal; 12895 12896 return this._trimAlignValue( valueMouse ); 12897 }, 12898 12899 _start: function( event, index ) { 12900 var uiHash = { 12901 handle: this.handles[ index ], 12902 value: this.value() 12903 }; 12904 if ( this.options.values && this.options.values.length ) { 12905 uiHash.value = this.values( index ); 12906 uiHash.values = this.values(); 12907 } 12908 return this._trigger( "start", event, uiHash ); 12909 }, 12910 12911 _slide: function( event, index, newVal ) { 12912 var otherVal, 12913 newValues, 12914 allowed; 12915 12916 if ( this.options.values && this.options.values.length ) { 12917 otherVal = this.values( index ? 0 : 1 ); 12918 12919 if ( ( this.options.values.length === 2 && this.options.range === true ) && 12920 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 12921 ) { 12922 newVal = otherVal; 12923 } 12924 12925 if ( newVal !== this.values( index ) ) { 12926 newValues = this.values(); 12927 newValues[ index ] = newVal; 12928 // A slide can be canceled by returning false from the slide callback 12929 allowed = this._trigger( "slide", event, { 12930 handle: this.handles[ index ], 12931 value: newVal, 12932 values: newValues 12933 } ); 12934 otherVal = this.values( index ? 0 : 1 ); 12935 if ( allowed !== false ) { 12936 this.values( index, newVal, true ); 12937 } 12938 } 12939 } else { 12940 if ( newVal !== this.value() ) { 12941 // A slide can be canceled by returning false from the slide callback 12942 allowed = this._trigger( "slide", event, { 12943 handle: this.handles[ index ], 12944 value: newVal 12945 } ); 12946 if ( allowed !== false ) { 12947 this.value( newVal ); 12948 } 12949 } 12950 } 12951 }, 12952 12953 _stop: function( event, index ) { 12954 var uiHash = { 12955 handle: this.handles[ index ], 12956 value: this.value() 12957 }; 12958 if ( this.options.values && this.options.values.length ) { 12959 uiHash.value = this.values( index ); 12960 uiHash.values = this.values(); 12961 } 12962 12963 this._trigger( "stop", event, uiHash ); 12964 }, 12965 12966 _change: function( event, index ) { 12967 if ( !this._keySliding && !this._mouseSliding ) { 12968 var uiHash = { 12969 handle: this.handles[ index ], 12970 value: this.value() 12971 }; 12972 if ( this.options.values && this.options.values.length ) { 12973 uiHash.value = this.values( index ); 12974 uiHash.values = this.values(); 12975 } 12976 12977 //store the last changed value index for reference when handles overlap 12978 this._lastChangedValue = index; 12979 12980 this._trigger( "change", event, uiHash ); 12981 } 12982 }, 12983 12984 value: function( newValue ) { 12985 if ( arguments.length ) { 12986 this.options.value = this._trimAlignValue( newValue ); 12987 this._refreshValue(); 12988 this._change( null, 0 ); 12989 return; 12990 } 12991 12992 return this._value(); 12993 }, 12994 12995 values: function( index, newValue ) { 12996 var vals, 12997 newValues, 12998 i; 12999 13000 if ( arguments.length > 1 ) { 13001 this.options.values[ index ] = this._trimAlignValue( newValue ); 13002 this._refreshValue(); 13003 this._change( null, index ); 13004 return; 13005 } 13006 13007 if ( arguments.length ) { 13008 if ( $.isArray( arguments[ 0 ] ) ) { 13009 vals = this.options.values; 13010 newValues = arguments[ 0 ]; 13011 for ( i = 0; i < vals.length; i += 1 ) { 13012 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13013 this._change( null, i ); 13014 } 13015 this._refreshValue(); 13016 } else { 13017 if ( this.options.values && this.options.values.length ) { 13018 return this._values( index ); 13019 } else { 13020 return this.value(); 13021 } 13022 } 13023 } else { 13024 return this._values(); 13025 } 13026 }, 13027 13028 _setOption: function( key, value ) { 13029 var i, 13030 valsLength = 0; 13031 13032 if ( key === "range" && this.options.range === true ) { 13033 if ( value === "min" ) { 13034 this.options.value = this._values( 0 ); 13035 this.options.values = null; 13036 } else if ( value === "max" ) { 13037 this.options.value = this._values( this.options.values.length-1 ); 13038 this.options.values = null; 13039 } 13040 } 13041 13042 if ( $.isArray( this.options.values ) ) { 13043 valsLength = this.options.values.length; 13044 } 13045 13046 $.Widget.prototype._setOption.apply( this, arguments ); 13047 13048 switch ( key ) { 13049 case "orientation": 13050 this._detectOrientation(); 13051 this.element 13052 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13053 .addClass( "ui-slider-" + this.orientation ); 13054 this._refreshValue(); 13055 break; 13056 case "value": 13057 this._animateOff = true; 13058 this._refreshValue(); 13059 this._change( null, 0 ); 13060 this._animateOff = false; 13061 break; 13062 case "values": 13063 this._animateOff = true; 13064 this._refreshValue(); 13065 for ( i = 0; i < valsLength; i += 1 ) { 13066 this._change( null, i ); 13067 } 13068 this._animateOff = false; 13069 break; 13070 case "min": 13071 case "max": 13072 this._animateOff = true; 13073 this._refreshValue(); 13074 this._animateOff = false; 13075 break; 13076 case "range": 13077 this._animateOff = true; 13078 this._refresh(); 13079 this._animateOff = false; 13080 break; 13081 } 13082 }, 13083 13084 //internal value getter 13085 // _value() returns value trimmed by min and max, aligned by step 13086 _value: function() { 13087 var val = this.options.value; 13088 val = this._trimAlignValue( val ); 13089 13090 return val; 13091 }, 13092 13093 //internal values getter 13094 // _values() returns array of values trimmed by min and max, aligned by step 13095 // _values( index ) returns single value trimmed by min and max, aligned by step 13096 _values: function( index ) { 13097 var val, 13098 vals, 13099 i; 13100 13101 if ( arguments.length ) { 13102 val = this.options.values[ index ]; 13103 val = this._trimAlignValue( val ); 13104 13105 return val; 13106 } else if ( this.options.values && this.options.values.length ) { 13107 // .slice() creates a copy of the array 13108 // this copy gets trimmed by min and max and then returned 13109 vals = this.options.values.slice(); 13110 for ( i = 0; i < vals.length; i+= 1) { 13111 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13112 } 13113 13114 return vals; 13115 } else { 13116 return []; 13117 } 13118 }, 13119 13120 // returns the step-aligned value that val is closest to, between (inclusive) min and max 13121 _trimAlignValue: function( val ) { 13122 if ( val <= this._valueMin() ) { 13123 return this._valueMin(); 13124 } 13125 if ( val >= this._valueMax() ) { 13126 return this._valueMax(); 13127 } 13128 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13129 valModStep = (val - this._valueMin()) % step, 13130 alignValue = val - valModStep; 13131 13132 if ( Math.abs(valModStep) * 2 >= step ) { 13133 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13134 } 13135 13136 // Since JavaScript has problems with large floats, round 13137 // the final value to 5 digits after the decimal point (see #4124) 13138 return parseFloat( alignValue.toFixed(5) ); 13139 }, 13140 13141 _valueMin: function() { 13142 return this.options.min; 13143 }, 13144 13145 _valueMax: function() { 13146 return this.options.max; 13147 }, 13148 13149 _refreshValue: function() { 13150 var lastValPercent, valPercent, value, valueMin, valueMax, 13151 oRange = this.options.range, 13152 o = this.options, 13153 that = this, 13154 animate = ( !this._animateOff ) ? o.animate : false, 13155 _set = {}; 13156 13157 if ( this.options.values && this.options.values.length ) { 13158 this.handles.each(function( i ) { 13159 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 13160 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13161 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13162 if ( that.options.range === true ) { 13163 if ( that.orientation === "horizontal" ) { 13164 if ( i === 0 ) { 13165 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 13166 } 13167 if ( i === 1 ) { 13168 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13169 } 13170 } else { 13171 if ( i === 0 ) { 13172 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 13173 } 13174 if ( i === 1 ) { 13175 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13176 } 13177 } 13178 } 13179 lastValPercent = valPercent; 13180 }); 13181 } else { 13182 value = this.value(); 13183 valueMin = this._valueMin(); 13184 valueMax = this._valueMax(); 13185 valPercent = ( valueMax !== valueMin ) ? 13186 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 13187 0; 13188 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13189 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13190 13191 if ( oRange === "min" && this.orientation === "horizontal" ) { 13192 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 13193 } 13194 if ( oRange === "max" && this.orientation === "horizontal" ) { 13195 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13196 } 13197 if ( oRange === "min" && this.orientation === "vertical" ) { 13198 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 13199 } 13200 if ( oRange === "max" && this.orientation === "vertical" ) { 13201 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13202 } 13203 } 13204 }, 13205 13206 _handleEvents: { 13207 keydown: function( event ) { 13208 /*jshint maxcomplexity:25*/ 13209 var allowed, curVal, newVal, step, 13210 index = $( event.target ).data( "ui-slider-handle-index" ); 13211 13212 switch ( event.keyCode ) { 13213 case $.ui.keyCode.HOME: 13214 case $.ui.keyCode.END: 13215 case $.ui.keyCode.PAGE_UP: 13216 case $.ui.keyCode.PAGE_DOWN: 13217 case $.ui.keyCode.UP: 13218 case $.ui.keyCode.RIGHT: 13219 case $.ui.keyCode.DOWN: 13220 case $.ui.keyCode.LEFT: 13221 event.preventDefault(); 13222 if ( !this._keySliding ) { 13223 this._keySliding = true; 13224 $( event.target ).addClass( "ui-state-active" ); 13225 allowed = this._start( event, index ); 13226 if ( allowed === false ) { 13227 return; 13228 } 13229 } 13230 break; 13231 } 13232 13233 step = this.options.step; 13234 if ( this.options.values && this.options.values.length ) { 13235 curVal = newVal = this.values( index ); 13236 } else { 13237 curVal = newVal = this.value(); 13238 } 13239 13240 switch ( event.keyCode ) { 13241 case $.ui.keyCode.HOME: 13242 newVal = this._valueMin(); 13243 break; 13244 case $.ui.keyCode.END: 13245 newVal = this._valueMax(); 13246 break; 13247 case $.ui.keyCode.PAGE_UP: 13248 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 13249 break; 13250 case $.ui.keyCode.PAGE_DOWN: 13251 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 13252 break; 13253 case $.ui.keyCode.UP: 13254 case $.ui.keyCode.RIGHT: 13255 if ( curVal === this._valueMax() ) { 13256 return; 13257 } 13258 newVal = this._trimAlignValue( curVal + step ); 13259 break; 13260 case $.ui.keyCode.DOWN: 13261 case $.ui.keyCode.LEFT: 13262 if ( curVal === this._valueMin() ) { 13263 return; 13264 } 13265 newVal = this._trimAlignValue( curVal - step ); 13266 break; 13267 } 13268 13269 this._slide( event, index, newVal ); 13270 }, 13271 click: function( event ) { 13272 event.preventDefault(); 13273 }, 13274 keyup: function( event ) { 13275 var index = $( event.target ).data( "ui-slider-handle-index" ); 13276 13277 if ( this._keySliding ) { 13278 this._keySliding = false; 13279 this._stop( event, index ); 13280 this._change( event, index ); 13281 $( event.target ).removeClass( "ui-state-active" ); 13282 } 13283 } 13284 } 13285 13286}); 13287 13288}(jQuery)); 13289 13290(function( $ ) { 13291 13292function modifier( fn ) { 13293 return function() { 13294 var previous = this.element.val(); 13295 fn.apply( this, arguments ); 13296 this._refresh(); 13297 if ( previous !== this.element.val() ) { 13298 this._trigger( "change" ); 13299 } 13300 }; 13301} 13302 13303$.widget( "ui.spinner", { 13304 version: "1.10.2", 13305 defaultElement: "<input>", 13306 widgetEventPrefix: "spin", 13307 options: { 13308 culture: null, 13309 icons: { 13310 down: "ui-icon-triangle-1-s", 13311 up: "ui-icon-triangle-1-n" 13312 }, 13313 incremental: true, 13314 max: null, 13315 min: null, 13316 numberFormat: null, 13317 page: 10, 13318 step: 1, 13319 13320 change: null, 13321 spin: null, 13322 start: null, 13323 stop: null 13324 }, 13325 13326 _create: function() { 13327 // handle string values that need to be parsed 13328 this._setOption( "max", this.options.max ); 13329 this._setOption( "min", this.options.min ); 13330 this._setOption( "step", this.options.step ); 13331 13332 // format the value, but don't constrain 13333 this._value( this.element.val(), true ); 13334 13335 this._draw(); 13336 this._on( this._events ); 13337 this._refresh(); 13338 13339 // turning off autocomplete prevents the browser from remembering the 13340 // value when navigating through history, so we re-enable autocomplete 13341 // if the page is unloaded before the widget is destroyed. #7790 13342 this._on( this.window, { 13343 beforeunload: function() { 13344 this.element.removeAttr( "autocomplete" ); 13345 } 13346 }); 13347 }, 13348 13349 _getCreateOptions: function() { 13350 var options = {}, 13351 element = this.element; 13352 13353 $.each( [ "min", "max", "step" ], function( i, option ) { 13354 var value = element.attr( option ); 13355 if ( value !== undefined && value.length ) { 13356 options[ option ] = value; 13357 } 13358 }); 13359 13360 return options; 13361 }, 13362 13363 _events: { 13364 keydown: function( event ) { 13365 if ( this._start( event ) && this._keydown( event ) ) { 13366 event.preventDefault(); 13367 } 13368 }, 13369 keyup: "_stop", 13370 focus: function() { 13371 this.previous = this.element.val(); 13372 }, 13373 blur: function( event ) { 13374 if ( this.cancelBlur ) { 13375 delete this.cancelBlur; 13376 return; 13377 } 13378 13379 this._stop(); 13380 this._refresh(); 13381 if ( this.previous !== this.element.val() ) { 13382 this._trigger( "change", event ); 13383 } 13384 }, 13385 mousewheel: function( event, delta ) { 13386 if ( !delta ) { 13387 return; 13388 } 13389 if ( !this.spinning && !this._start( event ) ) { 13390 return false; 13391 } 13392 13393 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 13394 clearTimeout( this.mousewheelTimer ); 13395 this.mousewheelTimer = this._delay(function() { 13396 if ( this.spinning ) { 13397 this._stop( event ); 13398 } 13399 }, 100 ); 13400 event.preventDefault(); 13401 }, 13402 "mousedown .ui-spinner-button": function( event ) { 13403 var previous; 13404 13405 // We never want the buttons to have focus; whenever the user is 13406 // interacting with the spinner, the focus should be on the input. 13407 // If the input is focused then this.previous is properly set from 13408 // when the input first received focus. If the input is not focused 13409 // then we need to set this.previous based on the value before spinning. 13410 previous = this.element[0] === this.document[0].activeElement ? 13411 this.previous : this.element.val(); 13412 function checkFocus() { 13413 var isActive = this.element[0] === this.document[0].activeElement; 13414 if ( !isActive ) { 13415 this.element.focus(); 13416 this.previous = previous; 13417 // support: IE 13418 // IE sets focus asynchronously, so we need to check if focus 13419 // moved off of the input because the user clicked on the button. 13420 this._delay(function() { 13421 this.previous = previous; 13422 }); 13423 } 13424 } 13425 13426 // ensure focus is on (or stays on) the text field 13427 event.preventDefault(); 13428 checkFocus.call( this ); 13429 13430 // support: IE 13431 // IE doesn't prevent moving focus even with event.preventDefault() 13432 // so we set a flag to know when we should ignore the blur event 13433 // and check (again) if focus moved off of the input. 13434 this.cancelBlur = true; 13435 this._delay(function() { 13436 delete this.cancelBlur; 13437 checkFocus.call( this ); 13438 }); 13439 13440 if ( this._start( event ) === false ) { 13441 return; 13442 } 13443 13444 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13445 }, 13446 "mouseup .ui-spinner-button": "_stop", 13447 "mouseenter .ui-spinner-button": function( event ) { 13448 // button will add ui-state-active if mouse was down while mouseleave and kept down 13449 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 13450 return; 13451 } 13452 13453 if ( this._start( event ) === false ) { 13454 return false; 13455 } 13456 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13457 }, 13458 // TODO: do we really want to consider this a stop? 13459 // shouldn't we just stop the repeater and wait until mouseup before 13460 // we trigger the stop event? 13461 "mouseleave .ui-spinner-button": "_stop" 13462 }, 13463 13464 _draw: function() { 13465 var uiSpinner = this.uiSpinner = this.element 13466 .addClass( "ui-spinner-input" ) 13467 .attr( "autocomplete", "off" ) 13468 .wrap( this._uiSpinnerHtml() ) 13469 .parent() 13470 // add buttons 13471 .append( this._buttonHtml() ); 13472 13473 this.element.attr( "role", "spinbutton" ); 13474 13475 // button bindings 13476 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 13477 .attr( "tabIndex", -1 ) 13478 .button() 13479 .removeClass( "ui-corner-all" ); 13480 13481 // IE 6 doesn't understand height: 50% for the buttons 13482 // unless the wrapper has an explicit height 13483 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 13484 uiSpinner.height() > 0 ) { 13485 uiSpinner.height( uiSpinner.height() ); 13486 } 13487 13488 // disable spinner if element was already disabled 13489 if ( this.options.disabled ) { 13490 this.disable(); 13491 } 13492 }, 13493 13494 _keydown: function( event ) { 13495 var options = this.options, 13496 keyCode = $.ui.keyCode; 13497 13498 switch ( event.keyCode ) { 13499 case keyCode.UP: 13500 this._repeat( null, 1, event ); 13501 return true; 13502 case keyCode.DOWN: 13503 this._repeat( null, -1, event ); 13504 return true; 13505 case keyCode.PAGE_UP: 13506 this._repeat( null, options.page, event ); 13507 return true; 13508 case keyCode.PAGE_DOWN: 13509 this._repeat( null, -options.page, event ); 13510 return true; 13511 } 13512 13513 return false; 13514 }, 13515 13516 _uiSpinnerHtml: function() { 13517 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 13518 }, 13519 13520 _buttonHtml: function() { 13521 return "" + 13522 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 13523 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 13524 "</a>" + 13525 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 13526 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 13527 "</a>"; 13528 }, 13529 13530 _start: function( event ) { 13531 if ( !this.spinning && this._trigger( "start", event ) === false ) { 13532 return false; 13533 } 13534 13535 if ( !this.counter ) { 13536 this.counter = 1; 13537 } 13538 this.spinning = true; 13539 return true; 13540 }, 13541 13542 _repeat: function( i, steps, event ) { 13543 i = i || 500; 13544 13545 clearTimeout( this.timer ); 13546 this.timer = this._delay(function() { 13547 this._repeat( 40, steps, event ); 13548 }, i ); 13549 13550 this._spin( steps * this.options.step, event ); 13551 }, 13552 13553 _spin: function( step, event ) { 13554 var value = this.value() || 0; 13555 13556 if ( !this.counter ) { 13557 this.counter = 1; 13558 } 13559 13560 value = this._adjustValue( value + step * this._increment( this.counter ) ); 13561 13562 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 13563 this._value( value ); 13564 this.counter++; 13565 } 13566 }, 13567 13568 _increment: function( i ) { 13569 var incremental = this.options.incremental; 13570 13571 if ( incremental ) { 13572 return $.isFunction( incremental ) ? 13573 incremental( i ) : 13574 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 13575 } 13576 13577 return 1; 13578 }, 13579 13580 _precision: function() { 13581 var precision = this._precisionOf( this.options.step ); 13582 if ( this.options.min !== null ) { 13583 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13584 } 13585 return precision; 13586 }, 13587 13588 _precisionOf: function( num ) { 13589 var str = num.toString(), 13590 decimal = str.indexOf( "." ); 13591 return decimal === -1 ? 0 : str.length - decimal - 1; 13592 }, 13593 13594 _adjustValue: function( value ) { 13595 var base, aboveMin, 13596 options = this.options; 13597 13598 // make sure we're at a valid step 13599 // - find out where we are relative to the base (min or 0) 13600 base = options.min !== null ? options.min : 0; 13601 aboveMin = value - base; 13602 // - round to the nearest step 13603 aboveMin = Math.round(aboveMin / options.step) * options.step; 13604 // - rounding is based on 0, so adjust back to our base 13605 value = base + aboveMin; 13606 13607 // fix precision from bad JS floating point math 13608 value = parseFloat( value.toFixed( this._precision() ) ); 13609 13610 // clamp the value 13611 if ( options.max !== null && value > options.max) { 13612 return options.max; 13613 } 13614 if ( options.min !== null && value < options.min ) { 13615 return options.min; 13616 } 13617 13618 return value; 13619 }, 13620 13621 _stop: function( event ) { 13622 if ( !this.spinning ) { 13623 return; 13624 } 13625 13626 clearTimeout( this.timer ); 13627 clearTimeout( this.mousewheelTimer ); 13628 this.counter = 0; 13629 this.spinning = false; 13630 this._trigger( "stop", event ); 13631 }, 13632 13633 _setOption: function( key, value ) { 13634 if ( key === "culture" || key === "numberFormat" ) { 13635 var prevValue = this._parse( this.element.val() ); 13636 this.options[ key ] = value; 13637 this.element.val( this._format( prevValue ) ); 13638 return; 13639 } 13640 13641 if ( key === "max" || key === "min" || key === "step" ) { 13642 if ( typeof value === "string" ) { 13643 value = this._parse( value ); 13644 } 13645 } 13646 if ( key === "icons" ) { 13647 this.buttons.first().find( ".ui-icon" ) 13648 .removeClass( this.options.icons.up ) 13649 .addClass( value.up ); 13650 this.buttons.last().find( ".ui-icon" ) 13651 .removeClass( this.options.icons.down ) 13652 .addClass( value.down ); 13653 } 13654 13655 this._super( key, value ); 13656 13657 if ( key === "disabled" ) { 13658 if ( value ) { 13659 this.element.prop( "disabled", true ); 13660 this.buttons.button( "disable" ); 13661 } else { 13662 this.element.prop( "disabled", false ); 13663 this.buttons.button( "enable" ); 13664 } 13665 } 13666 }, 13667 13668 _setOptions: modifier(function( options ) { 13669 this._super( options ); 13670 this._value( this.element.val() ); 13671 }), 13672 13673 _parse: function( val ) { 13674 if ( typeof val === "string" && val !== "" ) { 13675 val = window.Globalize && this.options.numberFormat ? 13676 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 13677 } 13678 return val === "" || isNaN( val ) ? null : val; 13679 }, 13680 13681 _format: function( value ) { 13682 if ( value === "" ) { 13683 return ""; 13684 } 13685 return window.Globalize && this.options.numberFormat ? 13686 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 13687 value; 13688 }, 13689 13690 _refresh: function() { 13691 this.element.attr({ 13692 "aria-valuemin": this.options.min, 13693 "aria-valuemax": this.options.max, 13694 // TODO: what should we do with values that can't be parsed? 13695 "aria-valuenow": this._parse( this.element.val() ) 13696 }); 13697 }, 13698 13699 // update the value without triggering change 13700 _value: function( value, allowAny ) { 13701 var parsed; 13702 if ( value !== "" ) { 13703 parsed = this._parse( value ); 13704 if ( parsed !== null ) { 13705 if ( !allowAny ) { 13706 parsed = this._adjustValue( parsed ); 13707 } 13708 value = this._format( parsed ); 13709 } 13710 } 13711 this.element.val( value ); 13712 this._refresh(); 13713 }, 13714 13715 _destroy: function() { 13716 this.element 13717 .removeClass( "ui-spinner-input" ) 13718 .prop( "disabled", false ) 13719 .removeAttr( "autocomplete" ) 13720 .removeAttr( "role" ) 13721 .removeAttr( "aria-valuemin" ) 13722 .removeAttr( "aria-valuemax" ) 13723 .removeAttr( "aria-valuenow" ); 13724 this.uiSpinner.replaceWith( this.element ); 13725 }, 13726 13727 stepUp: modifier(function( steps ) { 13728 this._stepUp( steps ); 13729 }), 13730 _stepUp: function( steps ) { 13731 if ( this._start() ) { 13732 this._spin( (steps || 1) * this.options.step ); 13733 this._stop(); 13734 } 13735 }, 13736 13737 stepDown: modifier(function( steps ) { 13738 this._stepDown( steps ); 13739 }), 13740 _stepDown: function( steps ) { 13741 if ( this._start() ) { 13742 this._spin( (steps || 1) * -this.options.step ); 13743 this._stop(); 13744 } 13745 }, 13746 13747 pageUp: modifier(function( pages ) { 13748 this._stepUp( (pages || 1) * this.options.page ); 13749 }), 13750 13751 pageDown: modifier(function( pages ) { 13752 this._stepDown( (pages || 1) * this.options.page ); 13753 }), 13754 13755 value: function( newVal ) { 13756 if ( !arguments.length ) { 13757 return this._parse( this.element.val() ); 13758 } 13759 modifier( this._value ).call( this, newVal ); 13760 }, 13761 13762 widget: function() { 13763 return this.uiSpinner; 13764 } 13765}); 13766 13767}( jQuery ) ); 13768 13769(function( $, undefined ) { 13770 13771var tabId = 0, 13772 rhash = /#.*$/; 13773 13774function getNextTabId() { 13775 return ++tabId; 13776} 13777 13778function isLocal( anchor ) { 13779 return anchor.hash.length > 1 && 13780 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 13781 decodeURIComponent( location.href.replace( rhash, "" ) ); 13782} 13783 13784$.widget( "ui.tabs", { 13785 version: "1.10.2", 13786 delay: 300, 13787 options: { 13788 active: null, 13789 collapsible: false, 13790 event: "click", 13791 heightStyle: "content", 13792 hide: null, 13793 show: null, 13794 13795 // callbacks 13796 activate: null, 13797 beforeActivate: null, 13798 beforeLoad: null, 13799 load: null 13800 }, 13801 13802 _create: function() { 13803 var that = this, 13804 options = this.options; 13805 13806 this.running = false; 13807 13808 this.element 13809 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 13810 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 13811 // Prevent users from focusing disabled tabs via click 13812 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 13813 if ( $( this ).is( ".ui-state-disabled" ) ) { 13814 event.preventDefault(); 13815 } 13816 }) 13817 // support: IE <9 13818 // Preventing the default action in mousedown doesn't prevent IE 13819 // from focusing the element, so if the anchor gets focused, blur. 13820 // We don't have to worry about focusing the previously focused 13821 // element since clicking on a non-focusable element should focus 13822 // the body anyway. 13823 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 13824 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 13825 this.blur(); 13826 } 13827 }); 13828 13829 this._processTabs(); 13830 options.active = this._initialActive(); 13831 13832 // Take disabling tabs via class attribute from HTML 13833 // into account and update option properly. 13834 if ( $.isArray( options.disabled ) ) { 13835 options.disabled = $.unique( options.disabled.concat( 13836 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 13837 return that.tabs.index( li ); 13838 }) 13839 ) ).sort(); 13840 } 13841 13842 // check for length avoids error when initializing empty list 13843 if ( this.options.active !== false && this.anchors.length ) { 13844 this.active = this._findActive( options.active ); 13845 } else { 13846 this.active = $(); 13847 } 13848 13849 this._refresh(); 13850 13851 if ( this.active.length ) { 13852 this.load( options.active ); 13853 } 13854 }, 13855 13856 _initialActive: function() { 13857 var active = this.options.active, 13858 collapsible = this.options.collapsible, 13859 locationHash = location.hash.substring( 1 ); 13860 13861 if ( active === null ) { 13862 // check the fragment identifier in the URL 13863 if ( locationHash ) { 13864 this.tabs.each(function( i, tab ) { 13865 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 13866 active = i; 13867 return false; 13868 } 13869 }); 13870 } 13871 13872 // check for a tab marked active via a class 13873 if ( active === null ) { 13874 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 13875 } 13876 13877 // no active tab, set to false 13878 if ( active === null || active === -1 ) { 13879 active = this.tabs.length ? 0 : false; 13880 } 13881 } 13882 13883 // handle numbers: negative, out of range 13884 if ( active !== false ) { 13885 active = this.tabs.index( this.tabs.eq( active ) ); 13886 if ( active === -1 ) { 13887 active = collapsible ? false : 0; 13888 } 13889 } 13890 13891 // don't allow collapsible: false and active: false 13892 if ( !collapsible && active === false && this.anchors.length ) { 13893 active = 0; 13894 } 13895 13896 return active; 13897 }, 13898 13899 _getCreateEventData: function() { 13900 return { 13901 tab: this.active, 13902 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 13903 }; 13904 }, 13905 13906 _tabKeydown: function( event ) { 13907 /*jshint maxcomplexity:15*/ 13908 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 13909 selectedIndex = this.tabs.index( focusedTab ), 13910 goingForward = true; 13911 13912 if ( this._handlePageNav( event ) ) { 13913 return; 13914 } 13915 13916 switch ( event.keyCode ) { 13917 case $.ui.keyCode.RIGHT: 13918 case $.ui.keyCode.DOWN: 13919 selectedIndex++; 13920 break; 13921 case $.ui.keyCode.UP: 13922 case $.ui.keyCode.LEFT: 13923 goingForward = false; 13924 selectedIndex--; 13925 break; 13926 case $.ui.keyCode.END: 13927 selectedIndex = this.anchors.length - 1; 13928 break; 13929 case $.ui.keyCode.HOME: 13930 selectedIndex = 0; 13931 break; 13932 case $.ui.keyCode.SPACE: 13933 // Activate only, no collapsing 13934 event.preventDefault(); 13935 clearTimeout( this.activating ); 13936 this._activate( selectedIndex ); 13937 return; 13938 case $.ui.keyCode.ENTER: 13939 // Toggle (cancel delayed activation, allow collapsing) 13940 event.preventDefault(); 13941 clearTimeout( this.activating ); 13942 // Determine if we should collapse or activate 13943 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 13944 return; 13945 default: 13946 return; 13947 } 13948 13949 // Focus the appropriate tab, based on which key was pressed 13950 event.preventDefault(); 13951 clearTimeout( this.activating ); 13952 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 13953 13954 // Navigating with control key will prevent automatic activation 13955 if ( !event.ctrlKey ) { 13956 // Update aria-selected immediately so that AT think the tab is already selected. 13957 // Otherwise AT may confuse the user by stating that they need to activate the tab, 13958 // but the tab will already be activated by the time the announcement finishes. 13959 focusedTab.attr( "aria-selected", "false" ); 13960 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 13961 13962 this.activating = this._delay(function() { 13963 this.option( "active", selectedIndex ); 13964 }, this.delay ); 13965 } 13966 }, 13967 13968 _panelKeydown: function( event ) { 13969 if ( this._handlePageNav( event ) ) { 13970 return; 13971 } 13972 13973 // Ctrl+up moves focus to the current tab 13974 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 13975 event.preventDefault(); 13976 this.active.focus(); 13977 } 13978 }, 13979 13980 // Alt+page up/down moves focus to the previous/next tab (and activates) 13981 _handlePageNav: function( event ) { 13982 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 13983 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 13984 return true; 13985 } 13986 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 13987 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 13988 return true; 13989 } 13990 }, 13991 13992 _findNextTab: function( index, goingForward ) { 13993 var lastTabIndex = this.tabs.length - 1; 13994 13995 function constrain() { 13996 if ( index > lastTabIndex ) { 13997 index = 0; 13998 } 13999 if ( index < 0 ) { 14000 index = lastTabIndex; 14001 } 14002 return index; 14003 } 14004 14005 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 14006 index = goingForward ? index + 1 : index - 1; 14007 } 14008 14009 return index; 14010 }, 14011 14012 _focusNextTab: function( index, goingForward ) { 14013 index = this._findNextTab( index, goingForward ); 14014 this.tabs.eq( index ).focus(); 14015 return index; 14016 }, 14017 14018 _setOption: function( key, value ) { 14019 if ( key === "active" ) { 14020 // _activate() will handle invalid values and update this.options 14021 this._activate( value ); 14022 return; 14023 } 14024 14025 if ( key === "disabled" ) { 14026 // don't use the widget factory's disabled handling 14027 this._setupDisabled( value ); 14028 return; 14029 } 14030 14031 this._super( key, value); 14032 14033 if ( key === "collapsible" ) { 14034 this.element.toggleClass( "ui-tabs-collapsible", value ); 14035 // Setting collapsible: false while collapsed; open first panel 14036 if ( !value && this.options.active === false ) { 14037 this._activate( 0 ); 14038 } 14039 } 14040 14041 if ( key === "event" ) { 14042 this._setupEvents( value ); 14043 } 14044 14045 if ( key === "heightStyle" ) { 14046 this._setupHeightStyle( value ); 14047 } 14048 }, 14049 14050 _tabId: function( tab ) { 14051 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 14052 }, 14053 14054 _sanitizeSelector: function( hash ) { 14055 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 14056 }, 14057 14058 refresh: function() { 14059 var options = this.options, 14060 lis = this.tablist.children( ":has(a[href])" ); 14061 14062 // get disabled tabs from class attribute from HTML 14063 // this will get converted to a boolean if needed in _refresh() 14064 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 14065 return lis.index( tab ); 14066 }); 14067 14068 this._processTabs(); 14069 14070 // was collapsed or no tabs 14071 if ( options.active === false || !this.anchors.length ) { 14072 options.active = false; 14073 this.active = $(); 14074 // was active, but active tab is gone 14075 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 14076 // all remaining tabs are disabled 14077 if ( this.tabs.length === options.disabled.length ) { 14078 options.active = false; 14079 this.active = $(); 14080 // activate previous tab 14081 } else { 14082 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 14083 } 14084 // was active, active tab still exists 14085 } else { 14086 // make sure active index is correct 14087 options.active = this.tabs.index( this.active ); 14088 } 14089 14090 this._refresh(); 14091 }, 14092 14093 _refresh: function() { 14094 this._setupDisabled( this.options.disabled ); 14095 this._setupEvents( this.options.event ); 14096 this._setupHeightStyle( this.options.heightStyle ); 14097 14098 this.tabs.not( this.active ).attr({ 14099 "aria-selected": "false", 14100 tabIndex: -1 14101 }); 14102 this.panels.not( this._getPanelForTab( this.active ) ) 14103 .hide() 14104 .attr({ 14105 "aria-expanded": "false", 14106 "aria-hidden": "true" 14107 }); 14108 14109 // Make sure one tab is in the tab order 14110 if ( !this.active.length ) { 14111 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 14112 } else { 14113 this.active 14114 .addClass( "ui-tabs-active ui-state-active" ) 14115 .attr({ 14116 "aria-selected": "true", 14117 tabIndex: 0 14118 }); 14119 this._getPanelForTab( this.active ) 14120 .show() 14121 .attr({ 14122 "aria-expanded": "true", 14123 "aria-hidden": "false" 14124 }); 14125 } 14126 }, 14127 14128 _processTabs: function() { 14129 var that = this; 14130 14131 this.tablist = this._getList() 14132 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14133 .attr( "role", "tablist" ); 14134 14135 this.tabs = this.tablist.find( "> li:has(a[href])" ) 14136 .addClass( "ui-state-default ui-corner-top" ) 14137 .attr({ 14138 role: "tab", 14139 tabIndex: -1 14140 }); 14141 14142 this.anchors = this.tabs.map(function() { 14143 return $( "a", this )[ 0 ]; 14144 }) 14145 .addClass( "ui-tabs-anchor" ) 14146 .attr({ 14147 role: "presentation", 14148 tabIndex: -1 14149 }); 14150 14151 this.panels = $(); 14152 14153 this.anchors.each(function( i, anchor ) { 14154 var selector, panel, panelId, 14155 anchorId = $( anchor ).uniqueId().attr( "id" ), 14156 tab = $( anchor ).closest( "li" ), 14157 originalAriaControls = tab.attr( "aria-controls" ); 14158 14159 // inline tab 14160 if ( isLocal( anchor ) ) { 14161 selector = anchor.hash; 14162 panel = that.element.find( that._sanitizeSelector( selector ) ); 14163 // remote tab 14164 } else { 14165 panelId = that._tabId( tab ); 14166 selector = "#" + panelId; 14167 panel = that.element.find( selector ); 14168 if ( !panel.length ) { 14169 panel = that._createPanel( panelId ); 14170 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 14171 } 14172 panel.attr( "aria-live", "polite" ); 14173 } 14174 14175 if ( panel.length) { 14176 that.panels = that.panels.add( panel ); 14177 } 14178 if ( originalAriaControls ) { 14179 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 14180 } 14181 tab.attr({ 14182 "aria-controls": selector.substring( 1 ), 14183 "aria-labelledby": anchorId 14184 }); 14185 panel.attr( "aria-labelledby", anchorId ); 14186 }); 14187 14188 this.panels 14189 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14190 .attr( "role", "tabpanel" ); 14191 }, 14192 14193 // allow overriding how to find the list for rare usage scenarios (#7715) 14194 _getList: function() { 14195 return this.element.find( "ol,ul" ).eq( 0 ); 14196 }, 14197 14198 _createPanel: function( id ) { 14199 return $( "<div>" ) 14200 .attr( "id", id ) 14201 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14202 .data( "ui-tabs-destroy", true ); 14203 }, 14204 14205 _setupDisabled: function( disabled ) { 14206 if ( $.isArray( disabled ) ) { 14207 if ( !disabled.length ) { 14208 disabled = false; 14209 } else if ( disabled.length === this.anchors.length ) { 14210 disabled = true; 14211 } 14212 } 14213 14214 // disable tabs 14215 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 14216 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 14217 $( li ) 14218 .addClass( "ui-state-disabled" ) 14219 .attr( "aria-disabled", "true" ); 14220 } else { 14221 $( li ) 14222 .removeClass( "ui-state-disabled" ) 14223 .removeAttr( "aria-disabled" ); 14224 } 14225 } 14226 14227 this.options.disabled = disabled; 14228 }, 14229 14230 _setupEvents: function( event ) { 14231 var events = { 14232 click: function( event ) { 14233 event.preventDefault(); 14234 } 14235 }; 14236 if ( event ) { 14237 $.each( event.split(" "), function( index, eventName ) { 14238 events[ eventName ] = "_eventHandler"; 14239 }); 14240 } 14241 14242 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 14243 this._on( this.anchors, events ); 14244 this._on( this.tabs, { keydown: "_tabKeydown" } ); 14245 this._on( this.panels, { keydown: "_panelKeydown" } ); 14246 14247 this._focusable( this.tabs ); 14248 this._hoverable( this.tabs ); 14249 }, 14250 14251 _setupHeightStyle: function( heightStyle ) { 14252 var maxHeight, 14253 parent = this.element.parent(); 14254 14255 if ( heightStyle === "fill" ) { 14256 maxHeight = parent.height(); 14257 maxHeight -= this.element.outerHeight() - this.element.height(); 14258 14259 this.element.siblings( ":visible" ).each(function() { 14260 var elem = $( this ), 14261 position = elem.css( "position" ); 14262 14263 if ( position === "absolute" || position === "fixed" ) { 14264 return; 14265 } 14266 maxHeight -= elem.outerHeight( true ); 14267 }); 14268 14269 this.element.children().not( this.panels ).each(function() { 14270 maxHeight -= $( this ).outerHeight( true ); 14271 }); 14272 14273 this.panels.each(function() { 14274 $( this ).height( Math.max( 0, maxHeight - 14275 $( this ).innerHeight() + $( this ).height() ) ); 14276 }) 14277 .css( "overflow", "auto" ); 14278 } else if ( heightStyle === "auto" ) { 14279 maxHeight = 0; 14280 this.panels.each(function() { 14281 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 14282 }).height( maxHeight ); 14283 } 14284 }, 14285 14286 _eventHandler: function( event ) { 14287 var options = this.options, 14288 active = this.active, 14289 anchor = $( event.currentTarget ), 14290 tab = anchor.closest( "li" ), 14291 clickedIsActive = tab[ 0 ] === active[ 0 ], 14292 collapsing = clickedIsActive && options.collapsible, 14293 toShow = collapsing ? $() : this._getPanelForTab( tab ), 14294 toHide = !active.length ? $() : this._getPanelForTab( active ), 14295 eventData = { 14296 oldTab: active, 14297 oldPanel: toHide, 14298 newTab: collapsing ? $() : tab, 14299 newPanel: toShow 14300 }; 14301 14302 event.preventDefault(); 14303 14304 if ( tab.hasClass( "ui-state-disabled" ) || 14305 // tab is already loading 14306 tab.hasClass( "ui-tabs-loading" ) || 14307 // can't switch durning an animation 14308 this.running || 14309 // click on active header, but not collapsible 14310 ( clickedIsActive && !options.collapsible ) || 14311 // allow canceling activation 14312 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 14313 return; 14314 } 14315 14316 options.active = collapsing ? false : this.tabs.index( tab ); 14317 14318 this.active = clickedIsActive ? $() : tab; 14319 if ( this.xhr ) { 14320 this.xhr.abort(); 14321 } 14322 14323 if ( !toHide.length && !toShow.length ) { 14324 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 14325 } 14326 14327 if ( toShow.length ) { 14328 this.load( this.tabs.index( tab ), event ); 14329 } 14330 this._toggle( event, eventData ); 14331 }, 14332 14333 // handles show/hide for selecting tabs 14334 _toggle: function( event, eventData ) { 14335 var that = this, 14336 toShow = eventData.newPanel, 14337 toHide = eventData.oldPanel; 14338 14339 this.running = true; 14340 14341 function complete() { 14342 that.running = false; 14343 that._trigger( "activate", event, eventData ); 14344 } 14345 14346 function show() { 14347 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 14348 14349 if ( toShow.length && that.options.show ) { 14350 that._show( toShow, that.options.show, complete ); 14351 } else { 14352 toShow.show(); 14353 complete(); 14354 } 14355 } 14356 14357 // start out by hiding, then showing, then completing 14358 if ( toHide.length && this.options.hide ) { 14359 this._hide( toHide, this.options.hide, function() { 14360 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14361 show(); 14362 }); 14363 } else { 14364 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14365 toHide.hide(); 14366 show(); 14367 } 14368 14369 toHide.attr({ 14370 "aria-expanded": "false", 14371 "aria-hidden": "true" 14372 }); 14373 eventData.oldTab.attr( "aria-selected", "false" ); 14374 // If we're switching tabs, remove the old tab from the tab order. 14375 // If we're opening from collapsed state, remove the previous tab from the tab order. 14376 // If we're collapsing, then keep the collapsing tab in the tab order. 14377 if ( toShow.length && toHide.length ) { 14378 eventData.oldTab.attr( "tabIndex", -1 ); 14379 } else if ( toShow.length ) { 14380 this.tabs.filter(function() { 14381 return $( this ).attr( "tabIndex" ) === 0; 14382 }) 14383 .attr( "tabIndex", -1 ); 14384 } 14385 14386 toShow.attr({ 14387 "aria-expanded": "true", 14388 "aria-hidden": "false" 14389 }); 14390 eventData.newTab.attr({ 14391 "aria-selected": "true", 14392 tabIndex: 0 14393 }); 14394 }, 14395 14396 _activate: function( index ) { 14397 var anchor, 14398 active = this._findActive( index ); 14399 14400 // trying to activate the already active panel 14401 if ( active[ 0 ] === this.active[ 0 ] ) { 14402 return; 14403 } 14404 14405 // trying to collapse, simulate a click on the current active header 14406 if ( !active.length ) { 14407 active = this.active; 14408 } 14409 14410 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 14411 this._eventHandler({ 14412 target: anchor, 14413 currentTarget: anchor, 14414 preventDefault: $.noop 14415 }); 14416 }, 14417 14418 _findActive: function( index ) { 14419 return index === false ? $() : this.tabs.eq( index ); 14420 }, 14421 14422 _getIndex: function( index ) { 14423 // meta-function to give users option to provide a href string instead of a numerical index. 14424 if ( typeof index === "string" ) { 14425 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 14426 } 14427 14428 return index; 14429 }, 14430 14431 _destroy: function() { 14432 if ( this.xhr ) { 14433 this.xhr.abort(); 14434 } 14435 14436 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 14437 14438 this.tablist 14439 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14440 .removeAttr( "role" ); 14441 14442 this.anchors 14443 .removeClass( "ui-tabs-anchor" ) 14444 .removeAttr( "role" ) 14445 .removeAttr( "tabIndex" ) 14446 .removeUniqueId(); 14447 14448 this.tabs.add( this.panels ).each(function() { 14449 if ( $.data( this, "ui-tabs-destroy" ) ) { 14450 $( this ).remove(); 14451 } else { 14452 $( this ) 14453 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 14454 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 14455 .removeAttr( "tabIndex" ) 14456 .removeAttr( "aria-live" ) 14457 .removeAttr( "aria-busy" ) 14458 .removeAttr( "aria-selected" ) 14459 .removeAttr( "aria-labelledby" ) 14460 .removeAttr( "aria-hidden" ) 14461 .removeAttr( "aria-expanded" ) 14462 .removeAttr( "role" ); 14463 } 14464 }); 14465 14466 this.tabs.each(function() { 14467 var li = $( this ), 14468 prev = li.data( "ui-tabs-aria-controls" ); 14469 if ( prev ) { 14470 li 14471 .attr( "aria-controls", prev ) 14472 .removeData( "ui-tabs-aria-controls" ); 14473 } else { 14474 li.removeAttr( "aria-controls" ); 14475 } 14476 }); 14477 14478 this.panels.show(); 14479 14480 if ( this.options.heightStyle !== "content" ) { 14481 this.panels.css( "height", "" ); 14482 } 14483 }, 14484 14485 enable: function( index ) { 14486 var disabled = this.options.disabled; 14487 if ( disabled === false ) { 14488 return; 14489 } 14490 14491 if ( index === undefined ) { 14492 disabled = false; 14493 } else { 14494 index = this._getIndex( index ); 14495 if ( $.isArray( disabled ) ) { 14496 disabled = $.map( disabled, function( num ) { 14497 return num !== index ? num : null; 14498 }); 14499 } else { 14500 disabled = $.map( this.tabs, function( li, num ) { 14501 return num !== index ? num : null; 14502 }); 14503 } 14504 } 14505 this._setupDisabled( disabled ); 14506 }, 14507 14508 disable: function( index ) { 14509 var disabled = this.options.disabled; 14510 if ( disabled === true ) { 14511 return; 14512 } 14513 14514 if ( index === undefined ) { 14515 disabled = true; 14516 } else { 14517 index = this._getIndex( index ); 14518 if ( $.inArray( index, disabled ) !== -1 ) { 14519 return; 14520 } 14521 if ( $.isArray( disabled ) ) { 14522 disabled = $.merge( [ index ], disabled ).sort(); 14523 } else { 14524 disabled = [ index ]; 14525 } 14526 } 14527 this._setupDisabled( disabled ); 14528 }, 14529 14530 load: function( index, event ) { 14531 index = this._getIndex( index ); 14532 var that = this, 14533 tab = this.tabs.eq( index ), 14534 anchor = tab.find( ".ui-tabs-anchor" ), 14535 panel = this._getPanelForTab( tab ), 14536 eventData = { 14537 tab: tab, 14538 panel: panel 14539 }; 14540 14541 // not remote 14542 if ( isLocal( anchor[ 0 ] ) ) { 14543 return; 14544 } 14545 14546 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 14547 14548 // support: jQuery <1.8 14549 // jQuery <1.8 returns false if the request is canceled in beforeSend, 14550 // but as of 1.8, $.ajax() always returns a jqXHR object. 14551 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 14552 tab.addClass( "ui-tabs-loading" ); 14553 panel.attr( "aria-busy", "true" ); 14554 14555 this.xhr 14556 .success(function( response ) { 14557 // support: jQuery <1.8 14558 // http://bugs.jquery.com/ticket/11778 14559 setTimeout(function() { 14560 panel.html( response ); 14561 that._trigger( "load", event, eventData ); 14562 }, 1 ); 14563 }) 14564 .complete(function( jqXHR, status ) { 14565 // support: jQuery <1.8 14566 // http://bugs.jquery.com/ticket/11778 14567 setTimeout(function() { 14568 if ( status === "abort" ) { 14569 that.panels.stop( false, true ); 14570 } 14571 14572 tab.removeClass( "ui-tabs-loading" ); 14573 panel.removeAttr( "aria-busy" ); 14574 14575 if ( jqXHR === that.xhr ) { 14576 delete that.xhr; 14577 } 14578 }, 1 ); 14579 }); 14580 } 14581 }, 14582 14583 _ajaxSettings: function( anchor, event, eventData ) { 14584 var that = this; 14585 return { 14586 url: anchor.attr( "href" ), 14587 beforeSend: function( jqXHR, settings ) { 14588 return that._trigger( "beforeLoad", event, 14589 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 14590 } 14591 }; 14592 }, 14593 14594 _getPanelForTab: function( tab ) { 14595 var id = $( tab ).attr( "aria-controls" ); 14596 return this.element.find( this._sanitizeSelector( "#" + id ) ); 14597 } 14598}); 14599 14600})( jQuery ); 14601 14602(function( $ ) { 14603 14604var increments = 0; 14605 14606function addDescribedBy( elem, id ) { 14607 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 14608 describedby.push( id ); 14609 elem 14610 .data( "ui-tooltip-id", id ) 14611 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 14612} 14613 14614function removeDescribedBy( elem ) { 14615 var id = elem.data( "ui-tooltip-id" ), 14616 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 14617 index = $.inArray( id, describedby ); 14618 if ( index !== -1 ) { 14619 describedby.splice( index, 1 ); 14620 } 14621 14622 elem.removeData( "ui-tooltip-id" ); 14623 describedby = $.trim( describedby.join( " " ) ); 14624 if ( describedby ) { 14625 elem.attr( "aria-describedby", describedby ); 14626 } else { 14627 elem.removeAttr( "aria-describedby" ); 14628 } 14629} 14630 14631$.widget( "ui.tooltip", { 14632 version: "1.10.2", 14633 options: { 14634 content: function() { 14635 // support: IE<9, Opera in jQuery <1.7 14636 // .text() can't accept undefined, so coerce to a string 14637 var title = $( this ).attr( "title" ) || ""; 14638 // Escape title, since we're going from an attribute to raw HTML 14639 return $( "<a>" ).text( title ).html(); 14640 }, 14641 hide: true, 14642 // Disabled elements have inconsistent behavior across browsers (#8661) 14643 items: "[title]:not([disabled])", 14644 position: { 14645 my: "left top+15", 14646 at: "left bottom", 14647 collision: "flipfit flip" 14648 }, 14649 show: true, 14650 tooltipClass: null, 14651 track: false, 14652 14653 // callbacks 14654 close: null, 14655 open: null 14656 }, 14657 14658 _create: function() { 14659 this._on({ 14660 mouseover: "open", 14661 focusin: "open" 14662 }); 14663 14664 // IDs of generated tooltips, needed for destroy 14665 this.tooltips = {}; 14666 // IDs of parent tooltips where we removed the title attribute 14667 this.parents = {}; 14668 14669 if ( this.options.disabled ) { 14670 this._disable(); 14671 } 14672 }, 14673 14674 _setOption: function( key, value ) { 14675 var that = this; 14676 14677 if ( key === "disabled" ) { 14678 this[ value ? "_disable" : "_enable" ](); 14679 this.options[ key ] = value; 14680 // disable element style changes 14681 return; 14682 } 14683 14684 this._super( key, value ); 14685 14686 if ( key === "content" ) { 14687 $.each( this.tooltips, function( id, element ) { 14688 that._updateContent( element ); 14689 }); 14690 } 14691 }, 14692 14693 _disable: function() { 14694 var that = this; 14695 14696 // close open tooltips 14697 $.each( this.tooltips, function( id, element ) { 14698 var event = $.Event( "blur" ); 14699 event.target = event.currentTarget = element[0]; 14700 that.close( event, true ); 14701 }); 14702 14703 // remove title attributes to prevent native tooltips 14704 this.element.find( this.options.items ).addBack().each(function() { 14705 var element = $( this ); 14706 if ( element.is( "[title]" ) ) { 14707 element 14708 .data( "ui-tooltip-title", element.attr( "title" ) ) 14709 .attr( "title", "" ); 14710 } 14711 }); 14712 }, 14713 14714 _enable: function() { 14715 // restore title attributes 14716 this.element.find( this.options.items ).addBack().each(function() { 14717 var element = $( this ); 14718 if ( element.data( "ui-tooltip-title" ) ) { 14719 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14720 } 14721 }); 14722 }, 14723 14724 open: function( event ) { 14725 var that = this, 14726 target = $( event ? event.target : this.element ) 14727 // we need closest here due to mouseover bubbling, 14728 // but always pointing at the same event target 14729 .closest( this.options.items ); 14730 14731 // No element to show a tooltip for or the tooltip is already open 14732 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 14733 return; 14734 } 14735 14736 if ( target.attr( "title" ) ) { 14737 target.data( "ui-tooltip-title", target.attr( "title" ) ); 14738 } 14739 14740 target.data( "ui-tooltip-open", true ); 14741 14742 // kill parent tooltips, custom or native, for hover 14743 if ( event && event.type === "mouseover" ) { 14744 target.parents().each(function() { 14745 var parent = $( this ), 14746 blurEvent; 14747 if ( parent.data( "ui-tooltip-open" ) ) { 14748 blurEvent = $.Event( "blur" ); 14749 blurEvent.target = blurEvent.currentTarget = this; 14750 that.close( blurEvent, true ); 14751 } 14752 if ( parent.attr( "title" ) ) { 14753 parent.uniqueId(); 14754 that.parents[ this.id ] = { 14755 element: this, 14756 title: parent.attr( "title" ) 14757 }; 14758 parent.attr( "title", "" ); 14759 } 14760 }); 14761 } 14762 14763 this._updateContent( target, event ); 14764 }, 14765 14766 _updateContent: function( target, event ) { 14767 var content, 14768 contentOption = this.options.content, 14769 that = this, 14770 eventType = event ? event.type : null; 14771 14772 if ( typeof contentOption === "string" ) { 14773 return this._open( event, target, contentOption ); 14774 } 14775 14776 content = contentOption.call( target[0], function( response ) { 14777 // ignore async response if tooltip was closed already 14778 if ( !target.data( "ui-tooltip-open" ) ) { 14779 return; 14780 } 14781 // IE may instantly serve a cached response for ajax requests 14782 // delay this call to _open so the other call to _open runs first 14783 that._delay(function() { 14784 // jQuery creates a special event for focusin when it doesn't 14785 // exist natively. To improve performance, the native event 14786 // object is reused and the type is changed. Therefore, we can't 14787 // rely on the type being correct after the event finished 14788 // bubbling, so we set it back to the previous value. (#8740) 14789 if ( event ) { 14790 event.type = eventType; 14791 } 14792 this._open( event, target, response ); 14793 }); 14794 }); 14795 if ( content ) { 14796 this._open( event, target, content ); 14797 } 14798 }, 14799 14800 _open: function( event, target, content ) { 14801 var tooltip, events, delayedShow, 14802 positionOption = $.extend( {}, this.options.position ); 14803 14804 if ( !content ) { 14805 return; 14806 } 14807 14808 // Content can be updated multiple times. If the tooltip already 14809 // exists, then just update the content and bail. 14810 tooltip = this._find( target ); 14811 if ( tooltip.length ) { 14812 tooltip.find( ".ui-tooltip-content" ).html( content ); 14813 return; 14814 } 14815 14816 // if we have a title, clear it to prevent the native tooltip 14817 // we have to check first to avoid defining a title if none exists 14818 // (we don't want to cause an element to start matching [title]) 14819 // 14820 // We use removeAttr only for key events, to allow IE to export the correct 14821 // accessible attributes. For mouse events, set to empty string to avoid 14822 // native tooltip showing up (happens only when removing inside mouseover). 14823 if ( target.is( "[title]" ) ) { 14824 if ( event && event.type === "mouseover" ) { 14825 target.attr( "title", "" ); 14826 } else {
14827 target.removeAttr( "title" ); 14828 } 14829 } 14830 14831 tooltip = this._tooltip( target ); 14832 addDescribedBy( target, tooltip.attr( "id" ) ); 14833 tooltip.find( ".ui-tooltip-content" ).html( content ); 14834 14835 function position( event ) { 14836 positionOption.of = event; 14837 if ( tooltip.is( ":hidden" ) ) { 14838 return; 14839 } 14840 tooltip.position( positionOption ); 14841 } 14842 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 14843 this._on( this.document, { 14844 mousemove: position 14845 }); 14846 // trigger once to override element-relative positioning 14847 position( event ); 14848 } else { 14849 tooltip.position( $.extend({ 14850 of: target 14851 }, this.options.position ) ); 14852 } 14853 14854 tooltip.hide(); 14855 14856 this._show( tooltip, this.options.show ); 14857 // Handle tracking tooltips that are shown with a delay (#8644). As soon 14858 // as the tooltip is visible, position the tooltip using the most recent 14859 // event. 14860 if ( this.options.show && this.options.show.delay ) { 14861 delayedShow = this.delayedShow = setInterval(function() { 14862 if ( tooltip.is( ":visible" ) ) { 14863 position( positionOption.of ); 14864 clearInterval( delayedShow ); 14865 } 14866 }, $.fx.interval ); 14867 } 14868 14869 this._trigger( "open", event, { tooltip: tooltip } ); 14870 14871 events = { 14872 keyup: function( event ) { 14873 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 14874 var fakeEvent = $.Event(event); 14875 fakeEvent.currentTarget = target[0]; 14876 this.close( fakeEvent, true ); 14877 } 14878 }, 14879 remove: function() { 14880 this._removeTooltip( tooltip ); 14881 } 14882 }; 14883 if ( !event || event.type === "mouseover" ) { 14884 events.mouseleave = "close"; 14885 } 14886 if ( !event || event.type === "focusin" ) { 14887 events.focusout = "close"; 14888 } 14889 this._on( true, target, events ); 14890 }, 14891 14892 close: function( event ) { 14893 var that = this, 14894 target = $( event ? event.currentTarget : this.element ), 14895 tooltip = this._find( target ); 14896 14897 // disabling closes the tooltip, so we need to track when we're closing 14898 // to avoid an infinite loop in case the tooltip becomes disabled on close 14899 if ( this.closing ) { 14900 return; 14901 } 14902 14903 // Clear the interval for delayed tracking tooltips 14904 clearInterval( this.delayedShow ); 14905 14906 // only set title if we had one before (see comment in _open()) 14907 if ( target.data( "ui-tooltip-title" ) ) { 14908 target.attr( "title", target.data( "ui-tooltip-title" ) ); 14909 } 14910 14911 removeDescribedBy( target ); 14912 14913 tooltip.stop( true ); 14914 this._hide( tooltip, this.options.hide, function() { 14915 that._removeTooltip( $( this ) ); 14916 }); 14917 14918 target.removeData( "ui-tooltip-open" ); 14919 this._off( target, "mouseleave focusout keyup" ); 14920 // Remove 'remove' binding only on delegated targets 14921 if ( target[0] !== this.element[0] ) { 14922 this._off( target, "remove" ); 14923 } 14924 this._off( this.document, "mousemove" ); 14925 14926 if ( event && event.type === "mouseleave" ) { 14927 $.each( this.parents, function( id, parent ) { 14928 $( parent.element ).attr( "title", parent.title ); 14929 delete that.parents[ id ]; 14930 }); 14931 } 14932 14933 this.closing = true; 14934 this._trigger( "close", event, { tooltip: tooltip } ); 14935 this.closing = false; 14936 }, 14937 14938 _tooltip: function( element ) { 14939 var id = "ui-tooltip-" + increments++, 14940 tooltip = $( "<div>" ) 14941 .attr({ 14942 id: id, 14943 role: "tooltip" 14944 }) 14945 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 14946 ( this.options.tooltipClass || "" ) ); 14947 $( "<div>" ) 14948 .addClass( "ui-tooltip-content" ) 14949 .appendTo( tooltip ); 14950 tooltip.appendTo( this.document[0].body ); 14951 this.tooltips[ id ] = element; 14952 return tooltip; 14953 }, 14954 14955 _find: function( target ) { 14956 var id = target.data( "ui-tooltip-id" ); 14957 return id ? $( "#" + id ) : $(); 14958 }, 14959 14960 _removeTooltip: function( tooltip ) { 14961 tooltip.remove(); 14962 delete this.tooltips[ tooltip.attr( "id" ) ]; 14963 }, 14964 14965 _destroy: function() { 14966 var that = this; 14967 14968 // close open tooltips 14969 $.each( this.tooltips, function( id, element ) { 14970 // Delegate to close method to handle common cleanup 14971 var event = $.Event( "blur" ); 14972 event.target = event.currentTarget = element[0]; 14973 that.close( event, true ); 14974 14975 // Remove immediately; destroying an open tooltip doesn't use the 14976 // hide animation 14977 $( "#" + id ).remove(); 14978 14979 // Restore the title 14980 if ( element.data( "ui-tooltip-title" ) ) { 14981 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14982 element.removeData( "ui-tooltip-title" ); 14983 } 14984 }); 14985 } 14986}); 14987 14988}( jQuery ) );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.