vendor: 9,605 bytes, lines 1-330
1/*! jQuery UI - v1.10.3 - 2013-05-03 2* http://jqueryui.com 3* 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 4* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ 5(function( $, undefined ) { 6 7var uuid = 0, 8 runiqueId = /^ui-id-\d+$/; 9 10// $.ui might exist from components with no dependencies, e.g., $.ui.position 11$.ui = $.ui || {}; 12 13$.extend( $.ui, { 14 version: "1.10.3", 15 16 keyCode: { 17 BACKSPACE: 8, 18 COMMA: 188, 19 DELETE: 46, 20 DOWN: 40, 21 END: 35, 22 ENTER: 13, 23 ESCAPE: 27, 24 HOME: 36, 25 LEFT: 37, 26 NUMPAD_ADD: 107, 27 NUMPAD_DECIMAL: 110, 28 NUMPAD_DIVIDE: 111, 29 NUMPAD_ENTER: 108, 30 NUMPAD_MULTIPLY: 106, 31 NUMPAD_SUBTRACT: 109, 32 PAGE_DOWN: 34, 33 PAGE_UP: 33, 34 PERIOD: 190, 35 RIGHT: 39, 36 SPACE: 32, 37 TAB: 9, 38 UP: 38 39 } 40}); 41 42// plugins 43$.fn.extend({ 44 focus: (function( orig ) { 45 return function( delay, fn ) { 46 return typeof delay === "number" ? 47 this.each(function() { 48 var elem = this; 49 setTimeout(function() { 50 $( elem ).focus(); 51 if ( fn ) { 52 fn.call( elem ); 53 } 54 }, delay ); 55 }) : 56 orig.apply( this, arguments ); 57 }; 58 })( $.fn.focus ), 59 60 scrollParent: function() { 61 var scrollParent; 62 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 63 scrollParent = this.parents().filter(function() { 64 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 65 }).eq(0); 66 } else { 67 scrollParent = this.parents().filter(function() { 68 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 69 }).eq(0); 70 } 71 72 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 73 }, 74 75 zIndex: function( zIndex ) { 76 if ( zIndex !== undefined ) { 77 return this.css( "zIndex", zIndex ); 78 } 79 80 if ( this.length ) { 81 var elem = $( this[ 0 ] ), position, value; 82 while ( elem.length && elem[ 0 ] !== document ) { 83 // Ignore z-index if position is set to a value where z-index is ignored by the browser 84 // This makes behavior of this function consistent across browsers 85 // WebKit always returns auto if the element is positioned 86 position = elem.css( "position" ); 87 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 88 // IE returns 0 when zIndex is not specified 89 // other browsers return a string 90 // we ignore the case of nested elements with an explicit value of 0 91 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 92 value = parseInt( elem.css( "zIndex" ), 10 ); 93 if ( !isNaN( value ) && value !== 0 ) { 94 return value; 95 } 96 } 97 elem = elem.parent(); 98 } 99 } 100 101 return 0; 102 }, 103 104 uniqueId: function() { 105 return this.each(function() { 106 if ( !this.id ) { 107 this.id = "ui-id-" + (++uuid); 108 } 109 }); 110 }, 111 112 removeUniqueId: function() { 113 return this.each(function() { 114 if ( runiqueId.test( this.id ) ) { 115 $( this ).removeAttr( "id" ); 116 } 117 }); 118 } 119}); 120 121// selectors 122function focusable( element, isTabIndexNotNaN ) { 123 var map, mapName, img, 124 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; 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 $.widget() extensions 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};
vendor: 14,737 bytes, lines 331-813
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 ] ) {
vendor: 36,969 bytes, lines 814-1940
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.3", 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.3", 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 this.offsetParent = this.helper.offsetParent(); 1101 this.offsetParentCssPosition = this.offsetParent.css( "position" ); 1102 1103 //The element's absolute position on the page minus margins 1104 this.offset = this.positionAbs = this.element.offset(); 1105 this.offset = { 1106 top: this.offset.top - this.margins.top, 1107 left: this.offset.left - this.margins.left 1108 }; 1109 1110 //Reset scroll cache 1111 this.offset.scroll = false; 1112 1113 $.extend(this.offset, { 1114 click: { //Where the click happened, relative to the element 1115 left: event.pageX - this.offset.left, 1116 top: event.pageY - this.offset.top 1117 }, 1118 parent: this._getParentOffset(), 1119 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1120 }); 1121 1122 //Generate the original position 1123 this.originalPosition = this.position = this._generatePosition(event); 1124 this.originalPageX = event.pageX; 1125 this.originalPageY = event.pageY; 1126 1127 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 1128 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1129 1130 //Set a containment if given in the options 1131 this._setContainment(); 1132 1133 //Trigger event + callbacks 1134 if(this._trigger("start", event) === false) { 1135 this._clear(); 1136 return false; 1137 } 1138 1139 //Recache the helper size 1140 this._cacheHelperProportions(); 1141 1142 //Prepare the droppable offsets 1143 if ($.ui.ddmanager && !o.dropBehaviour) { 1144 $.ui.ddmanager.prepareOffsets(this, event); 1145 } 1146 1147 1148 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1149 1150 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1151 if ( $.ui.ddmanager ) { 1152 $.ui.ddmanager.dragStart(this, event); 1153 } 1154 1155 return true; 1156 }, 1157 1158 _mouseDrag: function(event, noPropagation) { 1159 // reset any necessary cached properties (see #5009) 1160 if ( this.offsetParentCssPosition === "fixed" ) { 1161 this.offset.parent = this._getParentOffset(); 1162 } 1163 1164 //Compute the helpers position 1165 this.position = this._generatePosition(event); 1166 this.positionAbs = this._convertPositionTo("absolute"); 1167 1168 //Call plugins and callbacks and use the resulting position if something is returned 1169 if (!noPropagation) { 1170 var ui = this._uiHash(); 1171 if(this._trigger("drag", event, ui) === false) { 1172 this._mouseUp({}); 1173 return false; 1174 } 1175 this.position = ui.position; 1176 } 1177 1178 if(!this.options.axis || this.options.axis !== "y") { 1179 this.helper[0].style.left = this.position.left+"px"; 1180 } 1181 if(!this.options.axis || this.options.axis !== "x") { 1182 this.helper[0].style.top = this.position.top+"px"; 1183 } 1184 if($.ui.ddmanager) { 1185 $.ui.ddmanager.drag(this, event); 1186 } 1187 1188 return false; 1189 }, 1190 1191 _mouseStop: function(event) { 1192 1193 //If we are using droppables, inform the manager about the drop 1194 var that = this, 1195 dropped = false; 1196 if ($.ui.ddmanager && !this.options.dropBehaviour) { 1197 dropped = $.ui.ddmanager.drop(this, event); 1198 } 1199 1200 //if a drop comes from outside (a sortable) 1201 if(this.dropped) { 1202 dropped = this.dropped; 1203 this.dropped = false; 1204 } 1205 1206 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1207 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { 1208 return false; 1209 } 1210 1211 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))) { 1212 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1213 if(that._trigger("stop", event) !== false) { 1214 that._clear(); 1215 } 1216 }); 1217 } else { 1218 if(this._trigger("stop", event) !== false) { 1219 this._clear(); 1220 } 1221 } 1222 1223 return false; 1224 }, 1225 1226 _mouseUp: function(event) { 1227 //Remove frame helpers 1228 $("div.ui-draggable-iframeFix").each(function() { 1229 this.parentNode.removeChild(this); 1230 }); 1231 1232 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1233 if( $.ui.ddmanager ) { 1234 $.ui.ddmanager.dragStop(this, event); 1235 } 1236 1237 return $.ui.mouse.prototype._mouseUp.call(this, event); 1238 }, 1239 1240 cancel: function() { 1241 1242 if(this.helper.is(".ui-draggable-dragging")) { 1243 this._mouseUp({}); 1244 } else { 1245 this._clear(); 1246 } 1247 1248 return this; 1249 1250 }, 1251 1252 _getHandle: function(event) { 1253 return this.options.handle ? 1254 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 1255 true; 1256 }, 1257 1258 _createHelper: function(event) { 1259 1260 var o = this.options, 1261 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 1262 1263 if(!helper.parents("body").length) { 1264 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1265 } 1266 1267 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1268 helper.css("position", "absolute"); 1269 } 1270 1271 return helper; 1272 1273 }, 1274 1275 _adjustOffsetFromHelper: function(obj) { 1276 if (typeof obj === "string") { 1277 obj = obj.split(" "); 1278 } 1279 if ($.isArray(obj)) { 1280 obj = {left: +obj[0], top: +obj[1] || 0}; 1281 } 1282 if ("left" in obj) { 1283 this.offset.click.left = obj.left + this.margins.left; 1284 } 1285 if ("right" in obj) { 1286 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1287 } 1288 if ("top" in obj) { 1289 this.offset.click.top = obj.top + this.margins.top; 1290 } 1291 if ("bottom" in obj) { 1292 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1293 } 1294 }, 1295 1296 _getParentOffset: function() { 1297 1298 //Get the offsetParent and cache its position 1299 var po = this.offsetParent.offset(); 1300 1301 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1302 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1303 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1304 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1305 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1306 po.left += this.scrollParent.scrollLeft(); 1307 po.top += this.scrollParent.scrollTop(); 1308 } 1309 1310 //This needs to be actually done for all browsers, since pageX/pageY includes this information 1311 //Ugly IE fix 1312 if((this.offsetParent[0] === document.body) || 1313 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 1314 po = { top: 0, left: 0 }; 1315 } 1316 1317 return { 1318 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 1319 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1320 }; 1321 1322 }, 1323 1324 _getRelativeOffset: function() { 1325 1326 if(this.cssPosition === "relative") { 1327 var p = this.element.position(); 1328 return { 1329 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1330 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1331 }; 1332 } else { 1333 return { top: 0, left: 0 }; 1334 } 1335 1336 }, 1337 1338 _cacheMargins: function() { 1339 this.margins = { 1340 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1341 top: (parseInt(this.element.css("marginTop"),10) || 0), 1342 right: (parseInt(this.element.css("marginRight"),10) || 0), 1343 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1344 }; 1345 }, 1346 1347 _cacheHelperProportions: function() { 1348 this.helperProportions = { 1349 width: this.helper.outerWidth(), 1350 height: this.helper.outerHeight() 1351 }; 1352 }, 1353 1354 _setContainment: function() { 1355 1356 var over, c, ce, 1357 o = this.options; 1358 1359 if ( !o.containment ) { 1360 this.containment = null; 1361 return; 1362 } 1363 1364 if ( o.containment === "window" ) { 1365 this.containment = [ 1366 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1367 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1368 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 1369 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 1370 ]; 1371 return; 1372 } 1373 1374 if ( o.containment === "document") { 1375 this.containment = [ 1376 0, 1377 0, 1378 $( document ).width() - this.helperProportions.width - this.margins.left, 1379 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 1380 ]; 1381 return; 1382 } 1383 1384 if ( o.containment.constructor === Array ) { 1385 this.containment = o.containment; 1386 return; 1387 } 1388 1389 if ( o.containment === "parent" ) { 1390 o.containment = this.helper[ 0 ].parentNode; 1391 } 1392 1393 c = $( o.containment ); 1394 ce = c[ 0 ]; 1395 1396 if( !ce ) { 1397 return; 1398 } 1399 1400 over = c.css( "overflow" ) !== "hidden"; 1401 1402 this.containment = [ 1403 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 1404 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) , 1405 ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right, 1406 ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom 1407 ]; 1408 this.relative_container = c; 1409 }, 1410 1411 _convertPositionTo: function(d, pos) { 1412 1413 if(!pos) { 1414 pos = this.position; 1415 } 1416 1417 var mod = d === "absolute" ? 1 : -1, 1418 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; 1419 1420 //Cache the scroll 1421 if (!this.offset.scroll) { 1422 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 1423 } 1424 1425 return { 1426 top: ( 1427 pos.top + // The absolute mouse position 1428 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1429 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 1430 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) 1431 ), 1432 left: ( 1433 pos.left + // The absolute mouse position 1434 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1435 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 1436 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) 1437 ) 1438 }; 1439 1440 }, 1441 1442 _generatePosition: function(event) { 1443 1444 var containment, co, top, left, 1445 o = this.options, 1446 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, 1447 pageX = event.pageX, 1448 pageY = event.pageY; 1449 1450 //Cache the scroll 1451 if (!this.offset.scroll) { 1452 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 1453 } 1454 1455 /* 1456 * - Position constraining - 1457 * Constrain the position to a mix of grid, containment. 1458 */ 1459 1460 // If we are not dragging yet, we won't check for options 1461 if ( this.originalPosition ) { 1462 if ( this.containment ) { 1463 if ( this.relative_container ){ 1464 co = this.relative_container.offset(); 1465 containment = [ 1466 this.containment[ 0 ] + co.left, 1467 this.containment[ 1 ] + co.top, 1468 this.containment[ 2 ] + co.left, 1469 this.containment[ 3 ] + co.top 1470 ]; 1471 } 1472 else { 1473 containment = this.containment; 1474 } 1475 1476 if(event.pageX - this.offset.click.left < containment[0]) { 1477 pageX = containment[0] + this.offset.click.left; 1478 } 1479 if(event.pageY - this.offset.click.top < containment[1]) { 1480 pageY = containment[1] + this.offset.click.top; 1481 } 1482 if(event.pageX - this.offset.click.left > containment[2]) { 1483 pageX = containment[2] + this.offset.click.left; 1484 } 1485 if(event.pageY - this.offset.click.top > containment[3]) { 1486 pageY = containment[3] + this.offset.click.top; 1487 } 1488 } 1489 1490 if(o.grid) { 1491 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1492 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1493 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; 1494 1495 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1496 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; 1497 } 1498 1499 } 1500 1501 return { 1502 top: ( 1503 pageY - // The absolute mouse position 1504 this.offset.click.top - // Click offset (relative to the element) 1505 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 1506 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 1507 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) 1508 ), 1509 left: ( 1510 pageX - // The absolute mouse position 1511 this.offset.click.left - // Click offset (relative to the element) 1512 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 1513 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 1514 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) 1515 ) 1516 }; 1517 1518 }, 1519 1520 _clear: function() { 1521 this.helper.removeClass("ui-draggable-dragging"); 1522 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 1523 this.helper.remove(); 1524 } 1525 this.helper = null; 1526 this.cancelHelperRemoval = false; 1527 }, 1528 1529 // From now on bulk stuff - mainly helpers 1530 1531 _trigger: function(type, event, ui) { 1532 ui = ui || this._uiHash(); 1533 $.ui.plugin.call(this, type, [event, ui]); 1534 //The absolute position has to be recalculated after plugins 1535 if(type === "drag") { 1536 this.positionAbs = this._convertPositionTo("absolute"); 1537 } 1538 return $.Widget.prototype._trigger.call(this, type, event, ui); 1539 }, 1540 1541 plugins: {}, 1542 1543 _uiHash: function() { 1544 return { 1545 helper: this.helper, 1546 position: this.position, 1547 originalPosition: this.originalPosition, 1548 offset: this.positionAbs 1549 }; 1550 } 1551 1552}); 1553 1554$.ui.plugin.add("draggable", "connectToSortable", { 1555 start: function(event, ui) { 1556 1557 var inst = $(this).data("ui-draggable"), o = inst.options, 1558 uiSortable = $.extend({}, ui, { item: inst.element }); 1559 inst.sortables = []; 1560 $(o.connectToSortable).each(function() { 1561 var sortable = $.data(this, "ui-sortable"); 1562 if (sortable && !sortable.options.disabled) { 1563 inst.sortables.push({ 1564 instance: sortable, 1565 shouldRevert: sortable.options.revert 1566 }); 1567 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). 1568 sortable._trigger("activate", event, uiSortable); 1569 } 1570 }); 1571 1572 }, 1573 stop: function(event, ui) { 1574 1575 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 1576 var inst = $(this).data("ui-draggable"), 1577 uiSortable = $.extend({}, ui, { item: inst.element }); 1578 1579 $.each(inst.sortables, function() { 1580 if(this.instance.isOver) { 1581 1582 this.instance.isOver = 0; 1583 1584 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 1585 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 1586 1587 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 1588 if(this.shouldRevert) { 1589 this.instance.options.revert = this.shouldRevert; 1590 } 1591 1592 //Trigger the stop of the sortable 1593 this.instance._mouseStop(event); 1594 1595 this.instance.options.helper = this.instance.options._helper; 1596 1597 //If the helper has been the original item, restore properties in the sortable 1598 if(inst.options.helper === "original") { 1599 this.instance.currentItem.css({ top: "auto", left: "auto" }); 1600 } 1601 1602 } else { 1603 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 1604 this.instance._trigger("deactivate", event, uiSortable); 1605 } 1606 1607 }); 1608 1609 }, 1610 drag: function(event, ui) { 1611 1612 var inst = $(this).data("ui-draggable"), that = this; 1613 1614 $.each(inst.sortables, function() { 1615 1616 var innermostIntersecting = false, 1617 thisSortable = this; 1618 1619 //Copy over some variables to allow calling the sortable's native _intersectsWith 1620 this.instance.positionAbs = inst.positionAbs; 1621 this.instance.helperProportions = inst.helperProportions; 1622 this.instance.offset.click = inst.offset.click; 1623 1624 if(this.instance._intersectsWith(this.instance.containerCache)) { 1625 innermostIntersecting = true; 1626 $.each(inst.sortables, function () { 1627 this.instance.positionAbs = inst.positionAbs; 1628 this.instance.helperProportions = inst.helperProportions; 1629 this.instance.offset.click = inst.offset.click; 1630 if (this !== thisSortable && 1631 this.instance._intersectsWith(this.instance.containerCache) && 1632 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 1633 ) { 1634 innermostIntersecting = false; 1635 } 1636 return innermostIntersecting; 1637 }); 1638 } 1639 1640 1641 if(innermostIntersecting) { 1642 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 1643 if(!this.instance.isOver) { 1644 1645 this.instance.isOver = 1; 1646 //Now we fake the start of dragging for the sortable instance, 1647 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 1648 //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) 1649 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 1650 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 1651 this.instance.options.helper = function() { return ui.helper[0]; }; 1652 1653 event.target = this.instance.currentItem[0]; 1654 this.instance._mouseCapture(event, true); 1655 this.instance._mouseStart(event, true, true); 1656 1657 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 1658 this.instance.offset.click.top = inst.offset.click.top; 1659 this.instance.offset.click.left = inst.offset.click.left; 1660 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 1661 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 1662 1663 inst._trigger("toSortable", event); 1664 inst.dropped = this.instance.element; //draggable revert needs that 1665 //hack so receive/update callbacks work (mostly) 1666 inst.currentItem = inst.element; 1667 this.instance.fromOutside = inst; 1668 1669 } 1670 1671 //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 1672 if(this.instance.currentItem) { 1673 this.instance._mouseDrag(event); 1674 } 1675 1676 } else { 1677 1678 //If it doesn't intersect with the sortable, and it intersected before, 1679 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 1680 if(this.instance.isOver) { 1681 1682 this.instance.isOver = 0; 1683 this.instance.cancelHelperRemoval = true; 1684 1685 //Prevent reverting on this forced stop 1686 this.instance.options.revert = false; 1687 1688 // The out event needs to be triggered independently 1689 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 1690 1691 this.instance._mouseStop(event, true); 1692 this.instance.options.helper = this.instance.options._helper; 1693 1694 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 1695 this.instance.currentItem.remove(); 1696 if(this.instance.placeholder) { 1697 this.instance.placeholder.remove(); 1698 } 1699 1700 inst._trigger("fromSortable", event); 1701 inst.dropped = false; //draggable revert needs that 1702 } 1703 1704 } 1705 1706 }); 1707 1708 } 1709}); 1710 1711$.ui.plugin.add("draggable", "cursor", { 1712 start: function() { 1713 var t = $("body"), o = $(this).data("ui-draggable").options; 1714 if (t.css("cursor")) { 1715 o._cursor = t.css("cursor"); 1716 } 1717 t.css("cursor", o.cursor); 1718 }, 1719 stop: function() { 1720 var o = $(this).data("ui-draggable").options; 1721 if (o._cursor) { 1722 $("body").css("cursor", o._cursor); 1723 } 1724 } 1725}); 1726 1727$.ui.plugin.add("draggable", "opacity", { 1728 start: function(event, ui) { 1729 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1730 if(t.css("opacity")) { 1731 o._opacity = t.css("opacity"); 1732 } 1733 t.css("opacity", o.opacity); 1734 }, 1735 stop: function(event, ui) { 1736 var o = $(this).data("ui-draggable").options; 1737 if(o._opacity) { 1738 $(ui.helper).css("opacity", o._opacity); 1739 } 1740 } 1741}); 1742 1743$.ui.plugin.add("draggable", "scroll", { 1744 start: function() { 1745 var i = $(this).data("ui-draggable"); 1746 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1747 i.overflowOffset = i.scrollParent.offset(); 1748 } 1749 }, 1750 drag: function( event ) { 1751 1752 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 1753 1754 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1755 1756 if(!o.axis || o.axis !== "x") { 1757 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 1758 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 1759 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 1760 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 1761 } 1762 } 1763 1764 if(!o.axis || o.axis !== "y") { 1765 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 1766 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 1767 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 1768 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 1769 } 1770 } 1771 1772 } else { 1773 1774 if(!o.axis || o.axis !== "x") { 1775 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 1776 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 1777 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 1778 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 1779 } 1780 } 1781 1782 if(!o.axis || o.axis !== "y") { 1783 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 1784 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 1785 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 1786 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 1787 } 1788 } 1789 1790 } 1791 1792 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 1793 $.ui.ddmanager.prepareOffsets(i, event); 1794 } 1795 1796 } 1797}); 1798 1799$.ui.plugin.add("draggable", "snap", { 1800 start: function() { 1801 1802 var i = $(this).data("ui-draggable"), 1803 o = i.options; 1804 1805 i.snapElements = []; 1806 1807 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 1808 var $t = $(this), 1809 $o = $t.offset(); 1810 if(this !== i.element[0]) { 1811 i.snapElements.push({ 1812 item: this, 1813 width: $t.outerWidth(), height: $t.outerHeight(), 1814 top: $o.top, left: $o.left 1815 }); 1816 } 1817 }); 1818 1819 }, 1820 drag: function(event, ui) { 1821 1822 var ts, bs, ls, rs, l, r, t, b, i, first, 1823 inst = $(this).data("ui-draggable"), 1824 o = inst.options, 1825 d = o.snapTolerance, 1826 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 1827 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 1828 1829 for (i = inst.snapElements.length - 1; i >= 0; i--){ 1830 1831 l = inst.snapElements[i].left; 1832 r = l + inst.snapElements[i].width; 1833 t = inst.snapElements[i].top; 1834 b = t + inst.snapElements[i].height; 1835 1836 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 1837 if(inst.snapElements[i].snapping) { 1838 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1839 } 1840 inst.snapElements[i].snapping = false; 1841 continue; 1842 } 1843 1844 if(o.snapMode !== "inner") { 1845 ts = Math.abs(t - y2) <= d; 1846 bs = Math.abs(b - y1) <= d; 1847 ls = Math.abs(l - x2) <= d; 1848 rs = Math.abs(r - x1) <= d; 1849 if(ts) { 1850 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1851 } 1852 if(bs) { 1853 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 1854 } 1855 if(ls) { 1856 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 1857 } 1858 if(rs) { 1859 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 1860 } 1861 } 1862 1863 first = (ts || bs || ls || rs); 1864 1865 if(o.snapMode !== "outer") { 1866 ts = Math.abs(t - y1) <= d; 1867 bs = Math.abs(b - y2) <= d; 1868 ls = Math.abs(l - x1) <= d; 1869 rs = Math.abs(r - x2) <= d; 1870 if(ts) { 1871 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 1872 } 1873 if(bs) { 1874 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1875 } 1876 if(ls) { 1877 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 1878 } 1879 if(rs) { 1880 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 1881 } 1882 } 1883 1884 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 1885 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1886 } 1887 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 1888 1889 } 1890 1891 } 1892}); 1893 1894$.ui.plugin.add("draggable", "stack", { 1895 start: function() { 1896 var min, 1897 o = this.data("ui-draggable").options, 1898 group = $.makeArray($(o.stack)).sort(function(a,b) { 1899 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 1900 }); 1901 1902 if (!group.length) { return; } 1903 1904 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 1905 $(group).each(function(i) { 1906 $(this).css("zIndex", min + i); 1907 }); 1908 this.css("zIndex", (min + group.length)); 1909 } 1910}); 1911 1912$.ui.plugin.add("draggable", "zIndex", { 1913 start: function(event, ui) { 1914 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1915 if(t.css("zIndex")) { 1916 o._zIndex = t.css("zIndex"); 1917 } 1918 t.css("zIndex", o.zIndex); 1919 }, 1920 stop: function(event, ui) { 1921 var o = $(this).data("ui-draggable").options; 1922 if(o._zIndex) { 1923 $(ui.helper).css("zIndex", o._zIndex); 1924 } 1925 } 1926}); 1927 1928})(jQuery); 1929 1930(function( $, undefined ) { 1931 1932function isOverAxis( x, reference, size ) { 1933 return ( x > reference ) && ( x < ( reference + size ) ); 1934} 1935 1936$.widget("ui.droppable", { 1937 version: "1.10.3", 1938 widgetEventPrefix: "drop", 1939 options: { 1940 accept: "*",
1941 activeClass: false, 1942 addClasses: true, 1943 greedy: false, 1944 hoverClass: false, 1945 scope: "default", 1946 tolerance: "intersect", 1947 1948 1949 // callbacks 1950 activate: null, 1951 deactivate: null, 1952 drop: null, 1953 out: null, 1954 over: null 1955 }, 1956 _create: function() { 1957 1958 var o = this.options, 1959 accept = o.accept; 1960 1961 this.isover = false; 1962 this.isout = true; 1963 1964 this.accept = $.isFunction(accept) ? accept : function(d) { 1965 return d.is(accept); 1966 }; 1967 1968 //Store the droppable's proportions 1969 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 1970 1971 // Add the reference and positions to the manager 1972 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 1973 $.ui.ddmanager.droppables[o.scope].push(this); 1974 1975 (o.addClasses && this.element.addClass("ui-droppable")); 1976 1977 }, 1978 1979 _destroy: function() { 1980 var i = 0, 1981 drop = $.ui.ddmanager.droppables[this.options.scope]; 1982 1983 for ( ; i < drop.length; i++ ) { 1984 if ( drop[i] === this ) { 1985 drop.splice(i, 1); 1986 } 1987 } 1988 1989 this.element.removeClass("ui-droppable ui-droppable-disabled"); 1990 }, 1991 1992 _setOption: function(key, value) { 1993 1994 if(key === "accept") { 1995 this.accept = $.isFunction(value) ? value : function(d) { 1996 return d.is(value); 1997 }; 1998 } 1999 $.Widget.prototype._setOption.apply(this, arguments); 2000 }, 2001 2002 _activate: function(event) { 2003 var draggable = $.ui.ddmanager.current; 2004 if(this.options.activeClass) { 2005 this.element.addClass(this.options.activeClass); 2006 } 2007 if(draggable){ 2008 this._trigger("activate", event, this.ui(draggable)); 2009 } 2010 }, 2011 2012 _deactivate: function(event) { 2013 var draggable = $.ui.ddmanager.current; 2014 if(this.options.activeClass) { 2015 this.element.removeClass(this.options.activeClass); 2016 } 2017 if(draggable){ 2018 this._trigger("deactivate", event, this.ui(draggable)); 2019 } 2020 }, 2021 2022 _over: function(event) { 2023 2024 var draggable = $.ui.ddmanager.current; 2025 2026 // Bail if draggable and droppable are same element 2027 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2028 return; 2029 } 2030 2031 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2032 if(this.options.hoverClass) { 2033 this.element.addClass(this.options.hoverClass); 2034 } 2035 this._trigger("over", event, this.ui(draggable)); 2036 } 2037 2038 }, 2039 2040 _out: function(event) { 2041 2042 var draggable = $.ui.ddmanager.current; 2043 2044 // Bail if draggable and droppable are same element 2045 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2046 return; 2047 } 2048 2049 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2050 if(this.options.hoverClass) { 2051 this.element.removeClass(this.options.hoverClass); 2052 } 2053 this._trigger("out", event, this.ui(draggable)); 2054 } 2055 2056 }, 2057 2058 _drop: function(event,custom) { 2059 2060 var draggable = custom || $.ui.ddmanager.current, 2061 childrenIntersection = false; 2062 2063 // Bail if draggable and droppable are same element 2064 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2065 return false; 2066 } 2067 2068 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 2069 var inst = $.data(this, "ui-droppable"); 2070 if( 2071 inst.options.greedy && 2072 !inst.options.disabled && 2073 inst.options.scope === draggable.options.scope && 2074 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 2075 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2076 ) { childrenIntersection = true; return false; } 2077 }); 2078 if(childrenIntersection) { 2079 return false; 2080 } 2081 2082 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2083 if(this.options.activeClass) { 2084 this.element.removeClass(this.options.activeClass); 2085 } 2086 if(this.options.hoverClass) { 2087 this.element.removeClass(this.options.hoverClass); 2088 } 2089 this._trigger("drop", event, this.ui(draggable)); 2090 return this.element; 2091 } 2092 2093 return false; 2094 2095 }, 2096 2097 ui: function(c) { 2098 return { 2099 draggable: (c.currentItem || c.element), 2100 helper: c.helper, 2101 position: c.position, 2102 offset: c.positionAbs 2103 }; 2104 } 2105 2106}); 2107 2108$.ui.intersect = function(draggable, droppable, toleranceMode) { 2109 2110 if (!droppable.offset) { 2111 return false; 2112 } 2113 2114 var draggableLeft, draggableTop, 2115 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 2116 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, 2117 l = droppable.offset.left, r = l + droppable.proportions.width, 2118 t = droppable.offset.top, b = t + droppable.proportions.height; 2119 2120 switch (toleranceMode) { 2121 case "fit":
vendor: 21,983 bytes, lines 2122-2853
2122 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 2123 case "intersect": 2124 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half 2125 x2 - (draggable.helperProportions.width / 2) < r && // Left Half 2126 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half 2127 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 2128 case "pointer": 2129 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 2130 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 2131 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); 2132 case "touch": 2133 return ( 2134 (y1 >= t && y1 <= b) || // Top edge touching 2135 (y2 >= t && y2 <= b) || // Bottom edge touching 2136 (y1 < t && y2 > b) // Surrounded vertically 2137 ) && ( 2138 (x1 >= l && x1 <= r) || // Left edge touching 2139 (x2 >= l && x2 <= r) || // Right edge touching 2140 (x1 < l && x2 > r) // Surrounded horizontally 2141 ); 2142 default: 2143 return false; 2144 } 2145 2146}; 2147 2148/* 2149 This manager tracks offsets of draggables and droppables 2150*/ 2151$.ui.ddmanager = { 2152 current: null, 2153 droppables: { "default": [] }, 2154 prepareOffsets: function(t, event) { 2155 2156 var i, j, 2157 m = $.ui.ddmanager.droppables[t.options.scope] || [], 2158 type = event ? event.type : null, // workaround for #2317 2159 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 2160 2161 droppablesLoop: for (i = 0; i < m.length; i++) { 2162 2163 //No disabled and non-accepted 2164 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 2165 continue; 2166 } 2167 2168 // Filter out elements in the current dragged item 2169 for (j=0; j < list.length; j++) { 2170 if(list[j] === m[i].element[0]) { 2171 m[i].proportions.height = 0; 2172 continue droppablesLoop; 2173 } 2174 } 2175 2176 m[i].visible = m[i].element.css("display") !== "none"; 2177 if(!m[i].visible) { 2178 continue; 2179 } 2180 2181 //Activate the droppable if used directly from draggables 2182 if(type === "mousedown") { 2183 m[i]._activate.call(m[i], event); 2184 } 2185 2186 m[i].offset = m[i].element.offset(); 2187 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2188 2189 } 2190 2191 }, 2192 drop: function(draggable, event) { 2193 2194 var dropped = false; 2195 // Create a copy of the droppables in case the list changes during the drop (#9116) 2196 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { 2197 2198 if(!this.options) { 2199 return; 2200 } 2201 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 2202 dropped = this._drop.call(this, event) || dropped; 2203 } 2204 2205 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2206 this.isout = true; 2207 this.isover = false; 2208 this._deactivate.call(this, event); 2209 } 2210 2211 }); 2212 return dropped; 2213 2214 }, 2215 dragStart: function( draggable, event ) { 2216 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2217 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2218 if( !draggable.options.refreshPositions ) { 2219 $.ui.ddmanager.prepareOffsets( draggable, event ); 2220 } 2221 }); 2222 }, 2223 drag: function(draggable, event) { 2224 2225 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2226 if(draggable.options.refreshPositions) { 2227 $.ui.ddmanager.prepareOffsets(draggable, event); 2228 } 2229 2230 //Run through all droppables and check their positions based on specific tolerance options 2231 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2232 2233 if(this.options.disabled || this.greedyChild || !this.visible) { 2234 return; 2235 } 2236 2237 var parentInstance, scope, parent, 2238 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 2239 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 2240 if(!c) { 2241 return; 2242 } 2243 2244 if (this.options.greedy) { 2245 // find droppable parents with same scope 2246 scope = this.options.scope; 2247 parent = this.element.parents(":data(ui-droppable)").filter(function () { 2248 return $.data(this, "ui-droppable").options.scope === scope; 2249 }); 2250 2251 if (parent.length) { 2252 parentInstance = $.data(parent[0], "ui-droppable"); 2253 parentInstance.greedyChild = (c === "isover"); 2254 } 2255 } 2256 2257 // we just moved into a greedy child 2258 if (parentInstance && c === "isover") { 2259 parentInstance.isover = false; 2260 parentInstance.isout = true; 2261 parentInstance._out.call(parentInstance, event); 2262 } 2263 2264 this[c] = true; 2265 this[c === "isout" ? "isover" : "isout"] = false; 2266 this[c === "isover" ? "_over" : "_out"].call(this, event); 2267 2268 // we just moved out of a greedy child 2269 if (parentInstance && c === "isout") { 2270 parentInstance.isout = false; 2271 parentInstance.isover = true; 2272 parentInstance._over.call(parentInstance, event); 2273 } 2274 }); 2275 2276 }, 2277 dragStop: function( draggable, event ) { 2278 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2279 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2280 if( !draggable.options.refreshPositions ) { 2281 $.ui.ddmanager.prepareOffsets( draggable, event ); 2282 } 2283 } 2284}; 2285 2286})(jQuery); 2287 2288(function( $, undefined ) { 2289 2290function num(v) { 2291 return parseInt(v, 10) || 0; 2292} 2293 2294function isNumber(value) { 2295 return !isNaN(parseInt(value, 10)); 2296} 2297 2298$.widget("ui.resizable", $.ui.mouse, { 2299 version: "1.10.3", 2300 widgetEventPrefix: "resize", 2301 options: { 2302 alsoResize: false, 2303 animate: false, 2304 animateDuration: "slow", 2305 animateEasing: "swing", 2306 aspectRatio: false, 2307 autoHide: false, 2308 containment: false, 2309 ghost: false, 2310 grid: false, 2311 handles: "e,s,se", 2312 helper: false, 2313 maxHeight: null, 2314 maxWidth: null, 2315 minHeight: 10, 2316 minWidth: 10, 2317 // See #7960 2318 zIndex: 90, 2319 2320 // callbacks 2321 resize: null, 2322 start: null, 2323 stop: null 2324 }, 2325 _create: function() { 2326 2327 var n, i, handle, axis, hname, 2328 that = this, 2329 o = this.options; 2330 this.element.addClass("ui-resizable"); 2331 2332 $.extend(this, { 2333 _aspectRatio: !!(o.aspectRatio), 2334 aspectRatio: o.aspectRatio, 2335 originalElement: this.element, 2336 _proportionallyResizeElements: [], 2337 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 2338 }); 2339 2340 //Wrap the element if it cannot hold child nodes 2341 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2342 2343 //Create a wrapper element and set the wrapper to the new current internal element 2344 this.element.wrap( 2345 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 2346 position: this.element.css("position"), 2347 width: this.element.outerWidth(), 2348 height: this.element.outerHeight(), 2349 top: this.element.css("top"), 2350 left: this.element.css("left") 2351 }) 2352 ); 2353 2354 //Overwrite the original this.element 2355 this.element = this.element.parent().data( 2356 "ui-resizable", this.element.data("ui-resizable") 2357 ); 2358 2359 this.elementIsWrapper = true; 2360 2361 //Move margins to the wrapper 2362 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2363 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2364 2365 //Prevent Safari textarea resize 2366 this.originalResizeStyle = this.originalElement.css("resize"); 2367 this.originalElement.css("resize", "none"); 2368 2369 //Push the actual element to our proportionallyResize internal array 2370 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 2371 2372 // avoid IE jump (hard set the margin) 2373 this.originalElement.css({ margin: this.originalElement.css("margin") }); 2374 2375 // fix handlers offset 2376 this._proportionallyResize(); 2377 2378 } 2379 2380 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" }); 2381 if(this.handles.constructor === String) { 2382 2383 if ( this.handles === "all") { 2384 this.handles = "n,e,s,w,se,sw,ne,nw"; 2385 } 2386 2387 n = this.handles.split(","); 2388 this.handles = {}; 2389 2390 for(i = 0; i < n.length; i++) { 2391 2392 handle = $.trim(n[i]); 2393 hname = "ui-resizable-"+handle; 2394 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 2395 2396 // Apply zIndex to all handles - see #7960 2397 axis.css({ zIndex: o.zIndex }); 2398 2399 //TODO : What's going on here? 2400 if ("se" === handle) { 2401 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 2402 } 2403 2404 //Insert into internal handles object and append to element 2405 this.handles[handle] = ".ui-resizable-"+handle; 2406 this.element.append(axis); 2407 } 2408 2409 } 2410 2411 this._renderAxis = function(target) { 2412 2413 var i, axis, padPos, padWrapper; 2414 2415 target = target || this.element; 2416 2417 for(i in this.handles) { 2418 2419 if(this.handles[i].constructor === String) { 2420 this.handles[i] = $(this.handles[i], this.element).show(); 2421 } 2422 2423 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2424 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2425 2426 axis = $(this.handles[i], this.element); 2427 2428 //Checking the correct pad and border 2429 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2430 2431 //The padding type i have to apply... 2432 padPos = [ "padding", 2433 /ne|nw|n/.test(i) ? "Top" : 2434 /se|sw|s/.test(i) ? "Bottom" : 2435 /^e$/.test(i) ? "Right" : "Left" ].join(""); 2436 2437 target.css(padPos, padWrapper); 2438 2439 this._proportionallyResize(); 2440 2441 } 2442 2443 //TODO: What's that good for? There's not anything to be executed left 2444 if(!$(this.handles[i]).length) { 2445 continue; 2446 } 2447 } 2448 }; 2449 2450 //TODO: make renderAxis a prototype function 2451 this._renderAxis(this.element); 2452 2453 this._handles = $(".ui-resizable-handle", this.element) 2454 .disableSelection(); 2455 2456 //Matching axis name 2457 this._handles.mouseover(function() { 2458 if (!that.resizing) { 2459 if (this.className) { 2460 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2461 } 2462 //Axis, default = se 2463 that.axis = axis && axis[1] ? axis[1] : "se"; 2464 } 2465 }); 2466 2467 //If we want to auto hide the elements 2468 if (o.autoHide) { 2469 this._handles.hide(); 2470 $(this.element) 2471 .addClass("ui-resizable-autohide") 2472 .mouseenter(function() { 2473 if (o.disabled) { 2474 return; 2475 } 2476 $(this).removeClass("ui-resizable-autohide"); 2477 that._handles.show(); 2478 }) 2479 .mouseleave(function(){ 2480 if (o.disabled) { 2481 return; 2482 } 2483 if (!that.resizing) { 2484 $(this).addClass("ui-resizable-autohide"); 2485 that._handles.hide(); 2486 } 2487 }); 2488 } 2489 2490 //Initialize the mouse interaction 2491 this._mouseInit(); 2492 2493 }, 2494 2495 _destroy: function() { 2496 2497 this._mouseDestroy(); 2498 2499 var wrapper, 2500 _destroy = function(exp) { 2501 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2502 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 2503 }; 2504 2505 //TODO: Unwrap at same DOM position 2506 if (this.elementIsWrapper) { 2507 _destroy(this.element); 2508 wrapper = this.element; 2509 this.originalElement.css({ 2510 position: wrapper.css("position"), 2511 width: wrapper.outerWidth(), 2512 height: wrapper.outerHeight(), 2513 top: wrapper.css("top"), 2514 left: wrapper.css("left") 2515 }).insertAfter( wrapper ); 2516 wrapper.remove(); 2517 } 2518 2519 this.originalElement.css("resize", this.originalResizeStyle); 2520 _destroy(this.originalElement); 2521 2522 return this; 2523 }, 2524 2525 _mouseCapture: function(event) { 2526 var i, handle, 2527 capture = false; 2528 2529 for (i in this.handles) { 2530 handle = $(this.handles[i])[0]; 2531 if (handle === event.target || $.contains(handle, event.target)) { 2532 capture = true; 2533 } 2534 } 2535 2536 return !this.options.disabled && capture; 2537 }, 2538 2539 _mouseStart: function(event) { 2540 2541 var curleft, curtop, cursor, 2542 o = this.options, 2543 iniPos = this.element.position(), 2544 el = this.element; 2545 2546 this.resizing = true; 2547 2548 // bugfix for http://dev.jquery.com/ticket/1749 2549 if ( (/absolute/).test( el.css("position") ) ) { 2550 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 2551 } else if (el.is(".ui-draggable")) { 2552 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 2553 } 2554 2555 this._renderProxy(); 2556 2557 curleft = num(this.helper.css("left")); 2558 curtop = num(this.helper.css("top")); 2559 2560 if (o.containment) { 2561 curleft += $(o.containment).scrollLeft() || 0; 2562 curtop += $(o.containment).scrollTop() || 0; 2563 } 2564 2565 //Store needed variables 2566 this.offset = this.helper.offset(); 2567 this.position = { left: curleft, top: curtop }; 2568 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2569 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2570 this.originalPosition = { left: curleft, top: curtop }; 2571 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 2572 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2573 2574 //Aspect Ratio 2575 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 2576 2577 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 2578 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 2579 2580 el.addClass("ui-resizable-resizing"); 2581 this._propagate("start", event); 2582 return true; 2583 }, 2584 2585 _mouseDrag: function(event) { 2586 2587 //Increase performance, avoid regex 2588 var data, 2589 el = this.helper, props = {}, 2590 smp = this.originalMousePosition, 2591 a = this.axis, 2592 prevTop = this.position.top, 2593 prevLeft = this.position.left, 2594 prevWidth = this.size.width, 2595 prevHeight = this.size.height, 2596 dx = (event.pageX-smp.left)||0, 2597 dy = (event.pageY-smp.top)||0, 2598 trigger = this._change[a]; 2599 2600 if (!trigger) { 2601 return false; 2602 } 2603 2604 // Calculate the attrs that will be change 2605 data = trigger.apply(this, [event, dx, dy]); 2606 2607 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 2608 this._updateVirtualBoundaries(event.shiftKey); 2609 if (this._aspectRatio || event.shiftKey) { 2610 data = this._updateRatio(data, event); 2611 } 2612 2613 data = this._respectSize(data, event); 2614 2615 this._updateCache(data); 2616 2617 // plugins callbacks need to be called first 2618 this._propagate("resize", event); 2619 2620 if (this.position.top !== prevTop) { 2621 props.top = this.position.top + "px"; 2622 } 2623 if (this.position.left !== prevLeft) { 2624 props.left = this.position.left + "px"; 2625 } 2626 if (this.size.width !== prevWidth) { 2627 props.width = this.size.width + "px"; 2628 } 2629 if (this.size.height !== prevHeight) { 2630 props.height = this.size.height + "px"; 2631 } 2632 el.css(props); 2633 2634 if (!this._helper && this._proportionallyResizeElements.length) { 2635 this._proportionallyResize(); 2636 } 2637 2638 // Call the user callback if the element was resized 2639 if ( ! $.isEmptyObject(props) ) { 2640 this._trigger("resize", event, this.ui()); 2641 } 2642 2643 return false; 2644 }, 2645 2646 _mouseStop: function(event) { 2647 2648 this.resizing = false; 2649 var pr, ista, soffseth, soffsetw, s, left, top, 2650 o = this.options, that = this; 2651 2652 if(this._helper) { 2653 2654 pr = this._proportionallyResizeElements; 2655 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 2656 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 2657 soffsetw = ista ? 0 : that.sizeDiff.width; 2658 2659 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 2660 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 2661 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2662 2663 if (!o.animate) { 2664 this.element.css($.extend(s, { top: top, left: left })); 2665 } 2666 2667 that.helper.height(that.size.height); 2668 that.helper.width(that.size.width); 2669 2670 if (this._helper && !o.animate) { 2671 this._proportionallyResize(); 2672 } 2673 } 2674 2675 $("body").css("cursor", "auto"); 2676 2677 this.element.removeClass("ui-resizable-resizing"); 2678 2679 this._propagate("stop", event); 2680 2681 if (this._helper) { 2682 this.helper.remove(); 2683 } 2684 2685 return false; 2686 2687 }, 2688 2689 _updateVirtualBoundaries: function(forceAspectRatio) { 2690 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 2691 o = this.options; 2692 2693 b = { 2694 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 2695 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 2696 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 2697 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 2698 }; 2699 2700 if(this._aspectRatio || forceAspectRatio) { 2701 // We want to create an enclosing box whose aspect ration is the requested one 2702 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 2703 pMinWidth = b.minHeight * this.aspectRatio; 2704 pMinHeight = b.minWidth / this.aspectRatio; 2705 pMaxWidth = b.maxHeight * this.aspectRatio; 2706 pMaxHeight = b.maxWidth / this.aspectRatio; 2707 2708 if(pMinWidth > b.minWidth) { 2709 b.minWidth = pMinWidth; 2710 } 2711 if(pMinHeight > b.minHeight) { 2712 b.minHeight = pMinHeight; 2713 } 2714 if(pMaxWidth < b.maxWidth) { 2715 b.maxWidth = pMaxWidth; 2716 } 2717 if(pMaxHeight < b.maxHeight) { 2718 b.maxHeight = pMaxHeight; 2719 } 2720 } 2721 this._vBoundaries = b; 2722 }, 2723 2724 _updateCache: function(data) { 2725 this.offset = this.helper.offset(); 2726 if (isNumber(data.left)) { 2727 this.position.left = data.left; 2728 } 2729 if (isNumber(data.top)) { 2730 this.position.top = data.top; 2731 } 2732 if (isNumber(data.height)) { 2733 this.size.height = data.height; 2734 } 2735 if (isNumber(data.width)) { 2736 this.size.width = data.width; 2737 } 2738 }, 2739 2740 _updateRatio: function( data ) { 2741 2742 var cpos = this.position, 2743 csize = this.size, 2744 a = this.axis; 2745 2746 if (isNumber(data.height)) { 2747 data.width = (data.height * this.aspectRatio); 2748 } else if (isNumber(data.width)) { 2749 data.height = (data.width / this.aspectRatio); 2750 } 2751 2752 if (a === "sw") { 2753 data.left = cpos.left + (csize.width - data.width); 2754 data.top = null; 2755 } 2756 if (a === "nw") { 2757 data.top = cpos.top + (csize.height - data.height); 2758 data.left = cpos.left + (csize.width - data.width); 2759 } 2760 2761 return data; 2762 }, 2763 2764 _respectSize: function( data ) { 2765 2766 var o = this._vBoundaries, 2767 a = this.axis, 2768 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 2769 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 2770 dw = this.originalPosition.left + this.originalSize.width, 2771 dh = this.position.top + this.size.height, 2772 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 2773 if (isminw) { 2774 data.width = o.minWidth; 2775 } 2776 if (isminh) { 2777 data.height = o.minHeight; 2778 } 2779 if (ismaxw) { 2780 data.width = o.maxWidth; 2781 } 2782 if (ismaxh) { 2783 data.height = o.maxHeight; 2784 } 2785 2786 if (isminw && cw) { 2787 data.left = dw - o.minWidth; 2788 } 2789 if (ismaxw && cw) { 2790 data.left = dw - o.maxWidth; 2791 } 2792 if (isminh && ch) { 2793 data.top = dh - o.minHeight; 2794 } 2795 if (ismaxh && ch) { 2796 data.top = dh - o.maxHeight; 2797 } 2798 2799 // fixing jump error on top/left - bug #2330 2800 if (!data.width && !data.height && !data.left && data.top) { 2801 data.top = null; 2802 } else if (!data.width && !data.height && !data.top && data.left) { 2803 data.left = null; 2804 } 2805 2806 return data; 2807 }, 2808 2809 _proportionallyResize: function() { 2810 2811 if (!this._proportionallyResizeElements.length) { 2812 return; 2813 } 2814 2815 var i, j, borders, paddings, prel, 2816 element = this.helper || this.element; 2817 2818 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 2819 2820 prel = this._proportionallyResizeElements[i]; 2821 2822 if (!this.borderDif) { 2823 this.borderDif = []; 2824 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 2825 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 2826 2827 for ( j = 0; j < borders.length; j++ ) { 2828 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 2829 } 2830 } 2831 2832 prel.css({ 2833 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 2834 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 2835 }); 2836 2837 } 2838 2839 }, 2840 2841 _renderProxy: function() { 2842 2843 var el = this.element, o = this.options; 2844 this.elementOffset = el.offset(); 2845 2846 if(this._helper) { 2847 2848 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 2849 2850 this.helper.addClass(this._helper).css({ 2851 width: this.element.outerWidth() - 1, 2852 height: this.element.outerHeight() - 1, 2853 position: "absolute",
vendor: 1,348 bytes, lines 2854-2897
2854 left: this.elementOffset.left +"px", 2855 top: this.elementOffset.top +"px", 2856 zIndex: ++o.zIndex //TODO: Don't modify option 2857 }); 2858 2859 this.helper 2860 .appendTo("body") 2861 .disableSelection(); 2862 2863 } else { 2864 this.helper = this.element; 2865 } 2866 2867 }, 2868 2869 _change: { 2870 e: function(event, dx) { 2871 return { width: this.originalSize.width + dx }; 2872 }, 2873 w: function(event, dx) { 2874 var cs = this.originalSize, sp = this.originalPosition; 2875 return { left: sp.left + dx, width: cs.width - dx }; 2876 }, 2877 n: function(event, dx, dy) { 2878 var cs = this.originalSize, sp = this.originalPosition; 2879 return { top: sp.top + dy, height: cs.height - dy }; 2880 }, 2881 s: function(event, dx, dy) { 2882 return { height: this.originalSize.height + dy }; 2883 }, 2884 se: function(event, dx, dy) { 2885 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2886 }, 2887 sw: function(event, dx, dy) { 2888 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2889 }, 2890 ne: function(event, dx, dy) { 2891 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2892 }, 2893 nw: function(event, dx, dy) { 2894 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2895 } 2896 }, 2897
vendor: 119,497 bytes, lines 2898-6967
2898 _propagate: function(n, event) { 2899 $.ui.plugin.call(this, n, [event, this.ui()]); 2900 (n !== "resize" && this._trigger(n, event, this.ui())); 2901 }, 2902 2903 plugins: {}, 2904 2905 ui: function() { 2906 return { 2907 originalElement: this.originalElement, 2908 element: this.element, 2909 helper: this.helper, 2910 position: this.position, 2911 size: this.size, 2912 originalSize: this.originalSize, 2913 originalPosition: this.originalPosition 2914 }; 2915 } 2916 2917}); 2918 2919/* 2920 * Resizable Extensions 2921 */ 2922 2923$.ui.plugin.add("resizable", "animate", { 2924 2925 stop: function( event ) { 2926 var that = $(this).data("ui-resizable"), 2927 o = that.options, 2928 pr = that._proportionallyResizeElements, 2929 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2930 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2931 soffsetw = ista ? 0 : that.sizeDiff.width, 2932 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 2933 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 2934 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2935 2936 that.element.animate( 2937 $.extend(style, top && left ? { top: top, left: left } : {}), { 2938 duration: o.animateDuration, 2939 easing: o.animateEasing, 2940 step: function() { 2941 2942 var data = { 2943 width: parseInt(that.element.css("width"), 10), 2944 height: parseInt(that.element.css("height"), 10), 2945 top: parseInt(that.element.css("top"), 10), 2946 left: parseInt(that.element.css("left"), 10) 2947 }; 2948 2949 if (pr && pr.length) { 2950 $(pr[0]).css({ width: data.width, height: data.height }); 2951 } 2952 2953 // propagating resize, and updating values for each animation step 2954 that._updateCache(data); 2955 that._propagate("resize", event); 2956 2957 } 2958 } 2959 ); 2960 } 2961 2962}); 2963 2964$.ui.plugin.add("resizable", "containment", { 2965 2966 start: function() { 2967 var element, p, co, ch, cw, width, height, 2968 that = $(this).data("ui-resizable"), 2969 o = that.options, 2970 el = that.element, 2971 oc = o.containment, 2972 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 2973 2974 if (!ce) { 2975 return; 2976 } 2977 2978 that.containerElement = $(ce); 2979 2980 if (/document/.test(oc) || oc === document) { 2981 that.containerOffset = { left: 0, top: 0 }; 2982 that.containerPosition = { left: 0, top: 0 }; 2983 2984 that.parentData = { 2985 element: $(document), left: 0, top: 0, 2986 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 2987 }; 2988 } 2989 2990 // i'm a node, so compute top, left, right, bottom 2991 else { 2992 element = $(ce); 2993 p = []; 2994 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 2995 2996 that.containerOffset = element.offset(); 2997 that.containerPosition = element.position(); 2998 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 2999 3000 co = that.containerOffset; 3001 ch = that.containerSize.height; 3002 cw = that.containerSize.width; 3003 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 3004 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 3005 3006 that.parentData = { 3007 element: ce, left: co.left, top: co.top, width: width, height: height 3008 }; 3009 } 3010 }, 3011 3012 resize: function( event ) { 3013 var woset, hoset, isParent, isOffsetRelative, 3014 that = $(this).data("ui-resizable"), 3015 o = that.options, 3016 co = that.containerOffset, cp = that.position, 3017 pRatio = that._aspectRatio || event.shiftKey, 3018 cop = { top:0, left:0 }, ce = that.containerElement; 3019 3020 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 3021 cop = co; 3022 } 3023 3024 if (cp.left < (that._helper ? co.left : 0)) { 3025 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 3026 if (pRatio) { 3027 that.size.height = that.size.width / that.aspectRatio; 3028 } 3029 that.position.left = o.helper ? co.left : 0; 3030 } 3031 3032 if (cp.top < (that._helper ? co.top : 0)) { 3033 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3034 if (pRatio) { 3035 that.size.width = that.size.height * that.aspectRatio; 3036 } 3037 that.position.top = that._helper ? co.top : 0; 3038 } 3039 3040 that.offset.left = that.parentData.left+that.position.left; 3041 that.offset.top = that.parentData.top+that.position.top; 3042 3043 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 3044 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3045 3046 isParent = that.containerElement.get(0) === that.element.parent().get(0); 3047 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 3048 3049 if(isParent && isOffsetRelative) { 3050 woset -= that.parentData.left; 3051 } 3052 3053 if (woset + that.size.width >= that.parentData.width) { 3054 that.size.width = that.parentData.width - woset; 3055 if (pRatio) { 3056 that.size.height = that.size.width / that.aspectRatio; 3057 } 3058 } 3059 3060 if (hoset + that.size.height >= that.parentData.height) { 3061 that.size.height = that.parentData.height - hoset; 3062 if (pRatio) { 3063 that.size.width = that.size.height * that.aspectRatio; 3064 } 3065 } 3066 }, 3067 3068 stop: function(){ 3069 var that = $(this).data("ui-resizable"), 3070 o = that.options, 3071 co = that.containerOffset, 3072 cop = that.containerPosition, 3073 ce = that.containerElement, 3074 helper = $(that.helper), 3075 ho = helper.offset(), 3076 w = helper.outerWidth() - that.sizeDiff.width, 3077 h = helper.outerHeight() - that.sizeDiff.height; 3078 3079 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 3080 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3081 } 3082 3083 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 3084 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3085 } 3086 3087 } 3088}); 3089 3090$.ui.plugin.add("resizable", "alsoResize", { 3091 3092 start: function () { 3093 var that = $(this).data("ui-resizable"), 3094 o = that.options, 3095 _store = function (exp) { 3096 $(exp).each(function() { 3097 var el = $(this); 3098 el.data("ui-resizable-alsoresize", { 3099 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3100 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 3101 }); 3102 }); 3103 }; 3104 3105 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 3106 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3107 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3108 }else{ 3109 _store(o.alsoResize); 3110 } 3111 }, 3112 3113 resize: function (event, ui) { 3114 var that = $(this).data("ui-resizable"), 3115 o = that.options, 3116 os = that.originalSize, 3117 op = that.originalPosition, 3118 delta = { 3119 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3120 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3121 }, 3122 3123 _alsoResize = function (exp, c) { 3124 $(exp).each(function() { 3125 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 3126 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 3127 3128 $.each(css, function (i, prop) { 3129 var sum = (start[prop]||0) + (delta[prop]||0); 3130 if (sum && sum >= 0) { 3131 style[prop] = sum || null; 3132 } 3133 }); 3134 3135 el.css(style); 3136 }); 3137 }; 3138 3139 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 3140 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3141 }else{ 3142 _alsoResize(o.alsoResize); 3143 } 3144 }, 3145 3146 stop: function () { 3147 $(this).removeData("resizable-alsoresize"); 3148 } 3149}); 3150 3151$.ui.plugin.add("resizable", "ghost", { 3152 3153 start: function() { 3154 3155 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 3156 3157 that.ghost = that.originalElement.clone(); 3158 that.ghost 3159 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3160 .addClass("ui-resizable-ghost") 3161 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 3162 3163 that.ghost.appendTo(that.helper); 3164 3165 }, 3166 3167 resize: function(){ 3168 var that = $(this).data("ui-resizable"); 3169 if (that.ghost) { 3170 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 3171 } 3172 }, 3173 3174 stop: function() { 3175 var that = $(this).data("ui-resizable"); 3176 if (that.ghost && that.helper) { 3177 that.helper.get(0).removeChild(that.ghost.get(0)); 3178 } 3179 } 3180 3181}); 3182 3183$.ui.plugin.add("resizable", "grid", { 3184 3185 resize: function() { 3186 var that = $(this).data("ui-resizable"), 3187 o = that.options, 3188 cs = that.size, 3189 os = that.originalSize, 3190 op = that.originalPosition, 3191 a = that.axis, 3192 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 3193 gridX = (grid[0]||1), 3194 gridY = (grid[1]||1), 3195 ox = Math.round((cs.width - os.width) / gridX) * gridX, 3196 oy = Math.round((cs.height - os.height) / gridY) * gridY, 3197 newWidth = os.width + ox, 3198 newHeight = os.height + oy, 3199 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 3200 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 3201 isMinWidth = o.minWidth && (o.minWidth > newWidth), 3202 isMinHeight = o.minHeight && (o.minHeight > newHeight); 3203 3204 o.grid = grid; 3205 3206 if (isMinWidth) { 3207 newWidth = newWidth + gridX; 3208 } 3209 if (isMinHeight) { 3210 newHeight = newHeight + gridY; 3211 } 3212 if (isMaxWidth) { 3213 newWidth = newWidth - gridX; 3214 } 3215 if (isMaxHeight) { 3216 newHeight = newHeight - gridY; 3217 } 3218 3219 if (/^(se|s|e)$/.test(a)) { 3220 that.size.width = newWidth; 3221 that.size.height = newHeight; 3222 } else if (/^(ne)$/.test(a)) { 3223 that.size.width = newWidth; 3224 that.size.height = newHeight; 3225 that.position.top = op.top - oy; 3226 } else if (/^(sw)$/.test(a)) { 3227 that.size.width = newWidth; 3228 that.size.height = newHeight; 3229 that.position.left = op.left - ox; 3230 } else { 3231 that.size.width = newWidth; 3232 that.size.height = newHeight; 3233 that.position.top = op.top - oy; 3234 that.position.left = op.left - ox; 3235 } 3236 } 3237 3238}); 3239 3240})(jQuery); 3241 3242(function( $, undefined ) { 3243 3244$.widget("ui.selectable", $.ui.mouse, { 3245 version: "1.10.3", 3246 options: { 3247 appendTo: "body", 3248 autoRefresh: true, 3249 distance: 0, 3250 filter: "*", 3251 tolerance: "touch", 3252 3253 // callbacks 3254 selected: null, 3255 selecting: null, 3256 start: null, 3257 stop: null, 3258 unselected: null, 3259 unselecting: null 3260 }, 3261 _create: function() { 3262 var selectees, 3263 that = this; 3264 3265 this.element.addClass("ui-selectable"); 3266 3267 this.dragged = false; 3268 3269 // cache selectee children based on filter 3270 this.refresh = function() { 3271 selectees = $(that.options.filter, that.element[0]); 3272 selectees.addClass("ui-selectee"); 3273 selectees.each(function() { 3274 var $this = $(this), 3275 pos = $this.offset(); 3276 $.data(this, "selectable-item", { 3277 element: this, 3278 $element: $this, 3279 left: pos.left, 3280 top: pos.top, 3281 right: pos.left + $this.outerWidth(), 3282 bottom: pos.top + $this.outerHeight(), 3283 startselected: false, 3284 selected: $this.hasClass("ui-selected"), 3285 selecting: $this.hasClass("ui-selecting"), 3286 unselecting: $this.hasClass("ui-unselecting") 3287 }); 3288 }); 3289 }; 3290 this.refresh(); 3291 3292 this.selectees = selectees.addClass("ui-selectee"); 3293 3294 this._mouseInit(); 3295 3296 this.helper = $("<div class='ui-selectable-helper'></div>"); 3297 }, 3298 3299 _destroy: function() { 3300 this.selectees 3301 .removeClass("ui-selectee") 3302 .removeData("selectable-item"); 3303 this.element 3304 .removeClass("ui-selectable ui-selectable-disabled"); 3305 this._mouseDestroy(); 3306 }, 3307 3308 _mouseStart: function(event) { 3309 var that = this, 3310 options = this.options; 3311 3312 this.opos = [event.pageX, event.pageY]; 3313 3314 if (this.options.disabled) { 3315 return; 3316 } 3317 3318 this.selectees = $(options.filter, this.element[0]); 3319 3320 this._trigger("start", event); 3321 3322 $(options.appendTo).append(this.helper); 3323 // position helper (lasso) 3324 this.helper.css({ 3325 "left": event.pageX, 3326 "top": event.pageY, 3327 "width": 0, 3328 "height": 0 3329 }); 3330 3331 if (options.autoRefresh) { 3332 this.refresh(); 3333 } 3334 3335 this.selectees.filter(".ui-selected").each(function() { 3336 var selectee = $.data(this, "selectable-item"); 3337 selectee.startselected = true; 3338 if (!event.metaKey && !event.ctrlKey) { 3339 selectee.$element.removeClass("ui-selected"); 3340 selectee.selected = false; 3341 selectee.$element.addClass("ui-unselecting"); 3342 selectee.unselecting = true; 3343 // selectable UNSELECTING callback 3344 that._trigger("unselecting", event, { 3345 unselecting: selectee.element 3346 }); 3347 } 3348 }); 3349 3350 $(event.target).parents().addBack().each(function() { 3351 var doSelect, 3352 selectee = $.data(this, "selectable-item"); 3353 if (selectee) { 3354 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 3355 selectee.$element 3356 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3357 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3358 selectee.unselecting = !doSelect; 3359 selectee.selecting = doSelect; 3360 selectee.selected = doSelect; 3361 // selectable (UN)SELECTING callback 3362 if (doSelect) { 3363 that._trigger("selecting", event, { 3364 selecting: selectee.element 3365 }); 3366 } else { 3367 that._trigger("unselecting", event, { 3368 unselecting: selectee.element 3369 }); 3370 } 3371 return false; 3372 } 3373 }); 3374 3375 }, 3376 3377 _mouseDrag: function(event) { 3378 3379 this.dragged = true; 3380 3381 if (this.options.disabled) { 3382 return; 3383 } 3384 3385 var tmp, 3386 that = this, 3387 options = this.options, 3388 x1 = this.opos[0], 3389 y1 = this.opos[1], 3390 x2 = event.pageX, 3391 y2 = event.pageY; 3392 3393 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 3394 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 3395 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3396 3397 this.selectees.each(function() { 3398 var selectee = $.data(this, "selectable-item"), 3399 hit = false; 3400 3401 //prevent helper from being selected if appendTo: selectable 3402 if (!selectee || selectee.element === that.element[0]) { 3403 return; 3404 } 3405 3406 if (options.tolerance === "touch") { 3407 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3408 } else if (options.tolerance === "fit") { 3409 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3410 } 3411 3412 if (hit) { 3413 // SELECT 3414 if (selectee.selected) { 3415 selectee.$element.removeClass("ui-selected"); 3416 selectee.selected = false; 3417 } 3418 if (selectee.unselecting) { 3419 selectee.$element.removeClass("ui-unselecting"); 3420 selectee.unselecting = false; 3421 } 3422 if (!selectee.selecting) { 3423 selectee.$element.addClass("ui-selecting"); 3424 selectee.selecting = true; 3425 // selectable SELECTING callback 3426 that._trigger("selecting", event, { 3427 selecting: selectee.element 3428 }); 3429 } 3430 } else { 3431 // UNSELECT 3432 if (selectee.selecting) { 3433 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3434 selectee.$element.removeClass("ui-selecting"); 3435 selectee.selecting = false; 3436 selectee.$element.addClass("ui-selected"); 3437 selectee.selected = true; 3438 } else { 3439 selectee.$element.removeClass("ui-selecting"); 3440 selectee.selecting = false; 3441 if (selectee.startselected) { 3442 selectee.$element.addClass("ui-unselecting"); 3443 selectee.unselecting = true; 3444 } 3445 // selectable UNSELECTING callback 3446 that._trigger("unselecting", event, { 3447 unselecting: selectee.element 3448 }); 3449 } 3450 } 3451 if (selectee.selected) { 3452 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3453 selectee.$element.removeClass("ui-selected"); 3454 selectee.selected = false; 3455 3456 selectee.$element.addClass("ui-unselecting"); 3457 selectee.unselecting = true; 3458 // selectable UNSELECTING callback 3459 that._trigger("unselecting", event, { 3460 unselecting: selectee.element 3461 }); 3462 } 3463 } 3464 } 3465 }); 3466 3467 return false; 3468 }, 3469 3470 _mouseStop: function(event) { 3471 var that = this; 3472 3473 this.dragged = false; 3474 3475 $(".ui-unselecting", this.element[0]).each(function() { 3476 var selectee = $.data(this, "selectable-item"); 3477 selectee.$element.removeClass("ui-unselecting"); 3478 selectee.unselecting = false; 3479 selectee.startselected = false; 3480 that._trigger("unselected", event, { 3481 unselected: selectee.element 3482 }); 3483 }); 3484 $(".ui-selecting", this.element[0]).each(function() { 3485 var selectee = $.data(this, "selectable-item"); 3486 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 3487 selectee.selecting = false; 3488 selectee.selected = true; 3489 selectee.startselected = true; 3490 that._trigger("selected", event, { 3491 selected: selectee.element 3492 }); 3493 }); 3494 this._trigger("stop", event); 3495 3496 this.helper.remove(); 3497 3498 return false; 3499 } 3500 3501}); 3502 3503})(jQuery); 3504 3505(function( $, undefined ) { 3506 3507/*jshint loopfunc: true */ 3508 3509function isOverAxis( x, reference, size ) { 3510 return ( x > reference ) && ( x < ( reference + size ) ); 3511} 3512 3513function isFloating(item) { 3514 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 3515} 3516 3517$.widget("ui.sortable", $.ui.mouse, { 3518 version: "1.10.3", 3519 widgetEventPrefix: "sort", 3520 ready: false, 3521 options: { 3522 appendTo: "parent", 3523 axis: false, 3524 connectWith: false, 3525 containment: false, 3526 cursor: "auto", 3527 cursorAt: false, 3528 dropOnEmpty: true, 3529 forcePlaceholderSize: false, 3530 forceHelperSize: false, 3531 grid: false, 3532 handle: false, 3533 helper: "original", 3534 items: "> *", 3535 opacity: false, 3536 placeholder: false, 3537 revert: false, 3538 scroll: true, 3539 scrollSensitivity: 20, 3540 scrollSpeed: 20, 3541 scope: "default", 3542 tolerance: "intersect", 3543 zIndex: 1000, 3544 3545 // callbacks 3546 activate: null, 3547 beforeStop: null, 3548 change: null, 3549 deactivate: null, 3550 out: null, 3551 over: null, 3552 receive: null, 3553 remove: null, 3554 sort: null, 3555 start: null, 3556 stop: null, 3557 update: null 3558 }, 3559 _create: function() { 3560 3561 var o = this.options; 3562 this.containerCache = {}; 3563 this.element.addClass("ui-sortable"); 3564 3565 //Get the items 3566 this.refresh(); 3567 3568 //Let's determine if the items are being displayed horizontally 3569 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; 3570 3571 //Let's determine the parent's offset 3572 this.offset = this.element.offset(); 3573 3574 //Initialize mouse events for interaction 3575 this._mouseInit(); 3576 3577 //We're ready to go 3578 this.ready = true; 3579 3580 }, 3581 3582 _destroy: function() { 3583 this.element 3584 .removeClass("ui-sortable ui-sortable-disabled"); 3585 this._mouseDestroy(); 3586 3587 for ( var i = this.items.length - 1; i >= 0; i-- ) { 3588 this.items[i].item.removeData(this.widgetName + "-item"); 3589 } 3590 3591 return this; 3592 }, 3593 3594 _setOption: function(key, value){ 3595 if ( key === "disabled" ) { 3596 this.options[ key ] = value; 3597 3598 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 3599 } else { 3600 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 3601 $.Widget.prototype._setOption.apply(this, arguments); 3602 } 3603 }, 3604 3605 _mouseCapture: function(event, overrideHandle) { 3606 var currentItem = null, 3607 validHandle = false, 3608 that = this; 3609 3610 if (this.reverting) { 3611 return false; 3612 } 3613 3614 if(this.options.disabled || this.options.type === "static") { 3615 return false; 3616 } 3617 3618 //We have to refresh the items data once first 3619 this._refreshItems(event); 3620 3621 //Find out if the clicked node (or one of its parents) is a actual item in this.items 3622 $(event.target).parents().each(function() { 3623 if($.data(this, that.widgetName + "-item") === that) { 3624 currentItem = $(this); 3625 return false; 3626 } 3627 }); 3628 if($.data(event.target, that.widgetName + "-item") === that) { 3629 currentItem = $(event.target); 3630 } 3631 3632 if(!currentItem) { 3633 return false; 3634 } 3635 if(this.options.handle && !overrideHandle) { 3636 $(this.options.handle, currentItem).find("*").addBack().each(function() { 3637 if(this === event.target) { 3638 validHandle = true; 3639 } 3640 }); 3641 if(!validHandle) { 3642 return false; 3643 } 3644 } 3645 3646 this.currentItem = currentItem; 3647 this._removeCurrentsFromItems(); 3648 return true; 3649 3650 }, 3651 3652 _mouseStart: function(event, overrideHandle, noActivation) { 3653 3654 var i, body, 3655 o = this.options; 3656 3657 this.currentContainer = this; 3658 3659 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 3660 this.refreshPositions(); 3661 3662 //Create and append the visible helper 3663 this.helper = this._createHelper(event); 3664 3665 //Cache the helper size 3666 this._cacheHelperProportions(); 3667 3668 /* 3669 * - Position generation - 3670 * This block generates everything position related - it's the core of draggables. 3671 */ 3672 3673 //Cache the margins of the original element 3674 this._cacheMargins(); 3675 3676 //Get the next scrolling parent 3677 this.scrollParent = this.helper.scrollParent(); 3678 3679 //The element's absolute position on the page minus margins 3680 this.offset = this.currentItem.offset(); 3681 this.offset = { 3682 top: this.offset.top - this.margins.top, 3683 left: this.offset.left - this.margins.left 3684 }; 3685 3686 $.extend(this.offset, { 3687 click: { //Where the click happened, relative to the element 3688 left: event.pageX - this.offset.left, 3689 top: event.pageY - this.offset.top 3690 }, 3691 parent: this._getParentOffset(), 3692 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3693 }); 3694 3695 // Only after we got the offset, we can change the helper's position to absolute 3696 // TODO: Still need to figure out a way to make relative sorting possible 3697 this.helper.css("position", "absolute"); 3698 this.cssPosition = this.helper.css("position"); 3699 3700 //Generate the original position 3701 this.originalPosition = this._generatePosition(event); 3702 this.originalPageX = event.pageX; 3703 this.originalPageY = event.pageY; 3704 3705 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 3706 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 3707 3708 //Cache the former DOM position 3709 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 3710 3711 //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 3712 if(this.helper[0] !== this.currentItem[0]) { 3713 this.currentItem.hide(); 3714 } 3715 3716 //Create the placeholder 3717 this._createPlaceholder(); 3718 3719 //Set a containment if given in the options 3720 if(o.containment) { 3721 this._setContainment(); 3722 } 3723 3724 if( o.cursor && o.cursor !== "auto" ) { // cursor option 3725 body = this.document.find( "body" ); 3726 3727 // support: IE 3728 this.storedCursor = body.css( "cursor" ); 3729 body.css( "cursor", o.cursor ); 3730 3731 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 3732 } 3733 3734 if(o.opacity) { // opacity option 3735 if (this.helper.css("opacity")) { 3736 this._storedOpacity = this.helper.css("opacity"); 3737 } 3738 this.helper.css("opacity", o.opacity); 3739 } 3740 3741 if(o.zIndex) { // zIndex option 3742 if (this.helper.css("zIndex")) { 3743 this._storedZIndex = this.helper.css("zIndex"); 3744 } 3745 this.helper.css("zIndex", o.zIndex); 3746 } 3747 3748 //Prepare scrolling 3749 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3750 this.overflowOffset = this.scrollParent.offset(); 3751 } 3752 3753 //Call callbacks 3754 this._trigger("start", event, this._uiHash()); 3755 3756 //Recache the helper size 3757 if(!this._preserveHelperProportions) { 3758 this._cacheHelperProportions(); 3759 } 3760 3761 3762 //Post "activate" events to possible containers 3763 if( !noActivation ) { 3764 for ( i = this.containers.length - 1; i >= 0; i-- ) { 3765 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 3766 } 3767 } 3768 3769 //Prepare possible droppables 3770 if($.ui.ddmanager) { 3771 $.ui.ddmanager.current = this; 3772 } 3773 3774 if ($.ui.ddmanager && !o.dropBehaviour) { 3775 $.ui.ddmanager.prepareOffsets(this, event); 3776 } 3777 3778 this.dragging = true; 3779 3780 this.helper.addClass("ui-sortable-helper"); 3781 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3782 return true; 3783 3784 }, 3785 3786 _mouseDrag: function(event) { 3787 var i, item, itemElement, intersection, 3788 o = this.options, 3789 scrolled = false; 3790 3791 //Compute the helpers position 3792 this.position = this._generatePosition(event); 3793 this.positionAbs = this._convertPositionTo("absolute"); 3794 3795 if (!this.lastPositionAbs) { 3796 this.lastPositionAbs = this.positionAbs; 3797 } 3798 3799 //Do scrolling 3800 if(this.options.scroll) { 3801 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3802 3803 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 3804 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 3805 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 3806 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 3807 } 3808 3809 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 3810 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 3811 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 3812 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 3813 } 3814 3815 } else { 3816 3817 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 3818 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3819 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 3820 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3821 } 3822 3823 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 3824 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3825 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 3826 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3827 } 3828 3829 } 3830 3831 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 3832 $.ui.ddmanager.prepareOffsets(this, event); 3833 } 3834 } 3835 3836 //Regenerate the absolute position used for position checks 3837 this.positionAbs = this._convertPositionTo("absolute"); 3838 3839 //Set the helper position 3840 if(!this.options.axis || this.options.axis !== "y") { 3841 this.helper[0].style.left = this.position.left+"px"; 3842 } 3843 if(!this.options.axis || this.options.axis !== "x") { 3844 this.helper[0].style.top = this.position.top+"px"; 3845 } 3846 3847 //Rearrange 3848 for (i = this.items.length - 1; i >= 0; i--) { 3849 3850 //Cache variables and intersection, continue if no intersection 3851 item = this.items[i]; 3852 itemElement = item.item[0]; 3853 intersection = this._intersectsWithPointer(item); 3854 if (!intersection) { 3855 continue; 3856 } 3857 3858 // Only put the placeholder inside the current Container, skip all 3859 // items form other containers. This works because when moving 3860 // an item from one container to another the 3861 // currentContainer is switched before the placeholder is moved. 3862 // 3863 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 3864 // beetween the outer and inner container. 3865 if (item.instance !== this.currentContainer) { 3866 continue; 3867 } 3868 3869 // cannot intersect with itself 3870 // no useless actions that have been done before 3871 // no action if the item moved is the parent of the item checked 3872 if (itemElement !== this.currentItem[0] && 3873 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 3874 !$.contains(this.placeholder[0], itemElement) && 3875 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 3876 ) { 3877 3878 this.direction = intersection === 1 ? "down" : "up"; 3879 3880 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 3881 this._rearrange(event, item); 3882 } else { 3883 break; 3884 } 3885 3886 this._trigger("change", event, this._uiHash()); 3887 break; 3888 } 3889 } 3890 3891 //Post events to containers 3892 this._contactContainers(event); 3893 3894 //Interconnect with droppables 3895 if($.ui.ddmanager) { 3896 $.ui.ddmanager.drag(this, event); 3897 } 3898 3899 //Call callbacks 3900 this._trigger("sort", event, this._uiHash()); 3901 3902 this.lastPositionAbs = this.positionAbs; 3903 return false; 3904 3905 }, 3906 3907 _mouseStop: function(event, noPropagation) { 3908 3909 if(!event) { 3910 return; 3911 } 3912 3913 //If we are using droppables, inform the manager about the drop 3914 if ($.ui.ddmanager && !this.options.dropBehaviour) { 3915 $.ui.ddmanager.drop(this, event); 3916 } 3917 3918 if(this.options.revert) { 3919 var that = this, 3920 cur = this.placeholder.offset(), 3921 axis = this.options.axis, 3922 animation = {}; 3923 3924 if ( !axis || axis === "x" ) { 3925 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 3926 } 3927 if ( !axis || axis === "y" ) { 3928 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 3929 } 3930 this.reverting = true; 3931 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 3932 that._clear(event); 3933 }); 3934 } else { 3935 this._clear(event, noPropagation); 3936 } 3937 3938 return false; 3939 3940 }, 3941 3942 cancel: function() { 3943 3944 if(this.dragging) { 3945 3946 this._mouseUp({ target: null }); 3947 3948 if(this.options.helper === "original") { 3949 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 3950 } else { 3951 this.currentItem.show(); 3952 } 3953 3954 //Post deactivating events to containers 3955 for (var i = this.containers.length - 1; i >= 0; i--){ 3956 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 3957 if(this.containers[i].containerCache.over) { 3958 this.containers[i]._trigger("out", null, this._uiHash(this)); 3959 this.containers[i].containerCache.over = 0; 3960 } 3961 } 3962 3963 } 3964 3965 if (this.placeholder) { 3966 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 3967 if(this.placeholder[0].parentNode) { 3968 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 3969 } 3970 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 3971 this.helper.remove(); 3972 } 3973 3974 $.extend(this, { 3975 helper: null, 3976 dragging: false, 3977 reverting: false, 3978 _noFinalSort: null 3979 }); 3980 3981 if(this.domPosition.prev) { 3982 $(this.domPosition.prev).after(this.currentItem); 3983 } else { 3984 $(this.domPosition.parent).prepend(this.currentItem); 3985 } 3986 } 3987 3988 return this; 3989 3990 }, 3991 3992 serialize: function(o) { 3993 3994 var items = this._getItemsAsjQuery(o && o.connected), 3995 str = []; 3996 o = o || {}; 3997 3998 $(items).each(function() { 3999 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 4000 if (res) { 4001 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 4002 } 4003 }); 4004 4005 if(!str.length && o.key) { 4006 str.push(o.key + "="); 4007 } 4008 4009 return str.join("&"); 4010 4011 }, 4012 4013 toArray: function(o) { 4014 4015 var items = this._getItemsAsjQuery(o && o.connected), 4016 ret = []; 4017 4018 o = o || {}; 4019 4020 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 4021 return ret; 4022 4023 }, 4024 4025 /* Be careful with the following core functions */ 4026 _intersectsWith: function(item) { 4027 4028 var x1 = this.positionAbs.left, 4029 x2 = x1 + this.helperProportions.width, 4030 y1 = this.positionAbs.top, 4031 y2 = y1 + this.helperProportions.height, 4032 l = item.left, 4033 r = l + item.width, 4034 t = item.top, 4035 b = t + item.height, 4036 dyClick = this.offset.click.top, 4037 dxClick = this.offset.click.left, 4038 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 4039 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 4040 isOverElement = isOverElementHeight && isOverElementWidth; 4041 4042 if ( this.options.tolerance === "pointer" || 4043 this.options.forcePointerForContainers || 4044 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 4045 ) { 4046 return isOverElement; 4047 } else { 4048 4049 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 4050 x2 - (this.helperProportions.width / 2) < r && // Left Half 4051 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 4052 y2 - (this.helperProportions.height / 2) < b ); // Top Half 4053 4054 } 4055 }, 4056 4057 _intersectsWithPointer: function(item) { 4058 4059 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4060 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4061 isOverElement = isOverElementHeight && isOverElementWidth, 4062 verticalDirection = this._getDragVerticalDirection(), 4063 horizontalDirection = this._getDragHorizontalDirection(); 4064 4065 if (!isOverElement) { 4066 return false; 4067 } 4068 4069 return this.floating ? 4070 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 4071 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 4072 4073 }, 4074 4075 _intersectsWithSides: function(item) { 4076 4077 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4078 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4079 verticalDirection = this._getDragVerticalDirection(), 4080 horizontalDirection = this._getDragHorizontalDirection(); 4081 4082 if (this.floating && horizontalDirection) { 4083 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 4084 } else { 4085 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 4086 } 4087 4088 }, 4089 4090 _getDragVerticalDirection: function() { 4091 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4092 return delta !== 0 && (delta > 0 ? "down" : "up"); 4093 }, 4094 4095 _getDragHorizontalDirection: function() { 4096 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4097 return delta !== 0 && (delta > 0 ? "right" : "left"); 4098 }, 4099 4100 refresh: function(event) { 4101 this._refreshItems(event); 4102 this.refreshPositions(); 4103 return this; 4104 }, 4105 4106 _connectWith: function() { 4107 var options = this.options; 4108 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 4109 }, 4110 4111 _getItemsAsjQuery: function(connected) { 4112 4113 var i, j, cur, inst, 4114 items = [], 4115 queries = [], 4116 connectWith = this._connectWith(); 4117 4118 if(connectWith && connected) { 4119 for (i = connectWith.length - 1; i >= 0; i--){ 4120 cur = $(connectWith[i]); 4121 for ( j = cur.length - 1; j >= 0; j--){ 4122 inst = $.data(cur[j], this.widgetFullName); 4123 if(inst && inst !== this && !inst.options.disabled) { 4124 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]); 4125 } 4126 } 4127 } 4128 } 4129 4130 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]); 4131 4132 for (i = queries.length - 1; i >= 0; i--){ 4133 queries[i][0].each(function() { 4134 items.push(this); 4135 }); 4136 } 4137 4138 return $(items); 4139 4140 }, 4141 4142 _removeCurrentsFromItems: function() { 4143 4144 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4145 4146 this.items = $.grep(this.items, function (item) { 4147 for (var j=0; j < list.length; j++) { 4148 if(list[j] === item.item[0]) { 4149 return false; 4150 } 4151 } 4152 return true; 4153 }); 4154 4155 }, 4156 4157 _refreshItems: function(event) { 4158 4159 this.items = []; 4160 this.containers = [this]; 4161 4162 var i, j, cur, inst, targetData, _queries, item, queriesLength, 4163 items = this.items, 4164 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 4165 connectWith = this._connectWith(); 4166 4167 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4168 for (i = connectWith.length - 1; i >= 0; i--){ 4169 cur = $(connectWith[i]); 4170 for (j = cur.length - 1; j >= 0; j--){ 4171 inst = $.data(cur[j], this.widgetFullName); 4172 if(inst && inst !== this && !inst.options.disabled) { 4173 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4174 this.containers.push(inst); 4175 } 4176 } 4177 } 4178 } 4179 4180 for (i = queries.length - 1; i >= 0; i--) { 4181 targetData = queries[i][1]; 4182 _queries = queries[i][0]; 4183 4184 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4185 item = $(_queries[j]); 4186 4187 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 4188 4189 items.push({ 4190 item: item, 4191 instance: targetData, 4192 width: 0, height: 0, 4193 left: 0, top: 0 4194 }); 4195 } 4196 } 4197 4198 }, 4199 4200 refreshPositions: function(fast) { 4201 4202 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4203 if(this.offsetParent && this.helper) { 4204 this.offset.parent = this._getParentOffset(); 4205 } 4206 4207 var i, item, t, p; 4208 4209 for (i = this.items.length - 1; i >= 0; i--){ 4210 item = this.items[i]; 4211 4212 //We ignore calculating positions of all connected containers when we're not over them 4213 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 4214 continue; 4215 } 4216 4217 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4218 4219 if (!fast) { 4220 item.width = t.outerWidth(); 4221 item.height = t.outerHeight(); 4222 } 4223 4224 p = t.offset(); 4225 item.left = p.left; 4226 item.top = p.top; 4227 } 4228 4229 if(this.options.custom && this.options.custom.refreshContainers) { 4230 this.options.custom.refreshContainers.call(this); 4231 } else { 4232 for (i = this.containers.length - 1; i >= 0; i--){ 4233 p = this.containers[i].element.offset(); 4234 this.containers[i].containerCache.left = p.left; 4235 this.containers[i].containerCache.top = p.top; 4236 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 4237 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4238 } 4239 } 4240 4241 return this; 4242 }, 4243 4244 _createPlaceholder: function(that) { 4245 that = that || this; 4246 var className, 4247 o = that.options; 4248 4249 if(!o.placeholder || o.placeholder.constructor === String) { 4250 className = o.placeholder; 4251 o.placeholder = { 4252 element: function() { 4253 4254 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 4255 element = $( "<" + nodeName + ">", that.document[0] ) 4256 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4257 .removeClass("ui-sortable-helper"); 4258 4259 if ( nodeName === "tr" ) { 4260 that.currentItem.children().each(function() { 4261 $( "<td> </td>", that.document[0] ) 4262 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 4263 .appendTo( element ); 4264 }); 4265 } else if ( nodeName === "img" ) { 4266 element.attr( "src", that.currentItem.attr( "src" ) ); 4267 } 4268 4269 if ( !className ) { 4270 element.css( "visibility", "hidden" ); 4271 } 4272 4273 return element; 4274 }, 4275 update: function(container, p) { 4276 4277 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4278 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4279 if(className && !o.forcePlaceholderSize) { 4280 return; 4281 } 4282 4283 //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 4284 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 4285 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 4286 } 4287 }; 4288 } 4289 4290 //Create the placeholder 4291 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4292 4293 //Append it after the actual current item 4294 that.currentItem.after(that.placeholder); 4295 4296 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4297 o.placeholder.update(that, that.placeholder); 4298 4299 }, 4300 4301 _contactContainers: function(event) { 4302 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, 4303 innermostContainer = null, 4304 innermostIndex = null; 4305 4306 // get innermost container that intersects with item 4307 for (i = this.containers.length - 1; i >= 0; i--) { 4308 4309 // never consider a container that's located within the item itself 4310 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 4311 continue; 4312 } 4313 4314 if(this._intersectsWith(this.containers[i].containerCache)) { 4315 4316 // if we've already found a container and it's more "inner" than this, then continue 4317 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 4318 continue; 4319 } 4320 4321 innermostContainer = this.containers[i]; 4322 innermostIndex = i; 4323 4324 } else { 4325 // container doesn't intersect. trigger "out" event if necessary 4326 if(this.containers[i].containerCache.over) { 4327 this.containers[i]._trigger("out", event, this._uiHash(this)); 4328 this.containers[i].containerCache.over = 0; 4329 } 4330 } 4331 4332 } 4333 4334 // if no intersecting containers found, return 4335 if(!innermostContainer) { 4336 return; 4337 } 4338 4339 // move the item into the container if it's not there already 4340 if(this.containers.length === 1) { 4341 if (!this.containers[innermostIndex].containerCache.over) { 4342 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4343 this.containers[innermostIndex].containerCache.over = 1; 4344 } 4345 } else { 4346 4347 //When entering a new container, we will find the item with the least distance and append our item near it 4348 dist = 10000; 4349 itemWithLeastDistance = null; 4350 floating = innermostContainer.floating || isFloating(this.currentItem); 4351 posProperty = floating ? "left" : "top"; 4352 sizeProperty = floating ? "width" : "height"; 4353 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 4354 for (j = this.items.length - 1; j >= 0; j--) { 4355 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 4356 continue; 4357 } 4358 if(this.items[j].item[0] === this.currentItem[0]) { 4359 continue; 4360 } 4361 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { 4362 continue; 4363 } 4364 cur = this.items[j].item.offset()[posProperty]; 4365 nearBottom = false; 4366 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 4367 nearBottom = true; 4368 cur += this.items[j][sizeProperty]; 4369 } 4370 4371 if(Math.abs(cur - base) < dist) { 4372 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 4373 this.direction = nearBottom ? "up": "down"; 4374 } 4375 } 4376 4377 //Check if dropOnEmpty is enabled 4378 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 4379 return; 4380 } 4381 4382 if(this.currentContainer === this.containers[innermostIndex]) { 4383 return; 4384 } 4385 4386 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 4387 this._trigger("change", event, this._uiHash()); 4388 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 4389 this.currentContainer = this.containers[innermostIndex]; 4390 4391 //Update the placeholder 4392 this.options.placeholder.update(this.currentContainer, this.placeholder); 4393 4394 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4395 this.containers[innermostIndex].containerCache.over = 1; 4396 } 4397 4398 4399 }, 4400 4401 _createHelper: function(event) { 4402 4403 var o = this.options, 4404 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 4405 4406 //Add the helper to the DOM if that didn't happen already 4407 if(!helper.parents("body").length) { 4408 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 4409 } 4410 4411 if(helper[0] === this.currentItem[0]) { 4412 this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; 4413 } 4414 4415 if(!helper[0].style.width || o.forceHelperSize) { 4416 helper.width(this.currentItem.width()); 4417 } 4418 if(!helper[0].style.height || o.forceHelperSize) { 4419 helper.height(this.currentItem.height()); 4420 } 4421 4422 return helper; 4423 4424 }, 4425 4426 _adjustOffsetFromHelper: function(obj) { 4427 if (typeof obj === "string") { 4428 obj = obj.split(" "); 4429 } 4430 if ($.isArray(obj)) { 4431 obj = {left: +obj[0], top: +obj[1] || 0}; 4432 } 4433 if ("left" in obj) { 4434 this.offset.click.left = obj.left + this.margins.left; 4435 } 4436 if ("right" in obj) { 4437 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4438 } 4439 if ("top" in obj) { 4440 this.offset.click.top = obj.top + this.margins.top; 4441 } 4442 if ("bottom" in obj) { 4443 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4444 } 4445 }, 4446 4447 _getParentOffset: function() { 4448 4449 4450 //Get the offsetParent and cache its position 4451 this.offsetParent = this.helper.offsetParent(); 4452 var po = this.offsetParent.offset(); 4453 4454 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4455 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4456 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4457 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4458 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4459 po.left += this.scrollParent.scrollLeft(); 4460 po.top += this.scrollParent.scrollTop(); 4461 } 4462 4463 // This needs to be actually done for all browsers, since pageX/pageY includes this information 4464 // with an ugly IE fix 4465 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 4466 po = { top: 0, left: 0 }; 4467 } 4468 4469 return { 4470 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4471 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4472 }; 4473 4474 }, 4475 4476 _getRelativeOffset: function() { 4477 4478 if(this.cssPosition === "relative") { 4479 var p = this.currentItem.position(); 4480 return { 4481 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4482 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4483 }; 4484 } else { 4485 return { top: 0, left: 0 }; 4486 } 4487 4488 }, 4489 4490 _cacheMargins: function() { 4491 this.margins = { 4492 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 4493 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 4494 }; 4495 }, 4496 4497 _cacheHelperProportions: function() { 4498 this.helperProportions = { 4499 width: this.helper.outerWidth(), 4500 height: this.helper.outerHeight() 4501 }; 4502 }, 4503 4504 _setContainment: function() { 4505 4506 var ce, co, over, 4507 o = this.options; 4508 if(o.containment === "parent") { 4509 o.containment = this.helper[0].parentNode; 4510 } 4511 if(o.containment === "document" || o.containment === "window") { 4512 this.containment = [ 4513 0 - this.offset.relative.left - this.offset.parent.left, 4514 0 - this.offset.relative.top - this.offset.parent.top, 4515 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 4516 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4517 ]; 4518 } 4519 4520 if(!(/^(document|window|parent)$/).test(o.containment)) { 4521 ce = $(o.containment)[0]; 4522 co = $(o.containment).offset(); 4523 over = ($(ce).css("overflow") !== "hidden"); 4524 4525 this.containment = [ 4526 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 4527 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 4528 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, 4529 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 4530 ]; 4531 } 4532 4533 }, 4534 4535 _convertPositionTo: function(d, pos) { 4536 4537 if(!pos) { 4538 pos = this.position; 4539 } 4540 var mod = d === "absolute" ? 1 : -1, 4541 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 4542 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 4543 4544 return { 4545 top: ( 4546 pos.top + // The absolute mouse position 4547 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4548 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 4549 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4550 ), 4551 left: ( 4552 pos.left + // The absolute mouse position 4553 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4554 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 4555 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4556 ) 4557 }; 4558 4559 }, 4560 4561 _generatePosition: function(event) { 4562 4563 var top, left, 4564 o = this.options, 4565 pageX = event.pageX, 4566 pageY = event.pageY, 4567 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); 4568 4569 // This is another very weird special case that only happens for relative elements: 4570 // 1. If the css position is relative 4571 // 2. and the scroll parent is the document or similar to the offset parent 4572 // we have to refresh the relative offset during the scroll so there are no jumps 4573 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 4574 this.offset.relative = this._getRelativeOffset(); 4575 } 4576 4577 /* 4578 * - Position constraining - 4579 * Constrain the position to a mix of grid, containment. 4580 */ 4581 4582 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 4583 4584 if(this.containment) { 4585 if(event.pageX - this.offset.click.left < this.containment[0]) { 4586 pageX = this.containment[0] + this.offset.click.left; 4587 } 4588 if(event.pageY - this.offset.click.top < this.containment[1]) { 4589 pageY = this.containment[1] + this.offset.click.top; 4590 } 4591 if(event.pageX - this.offset.click.left > this.containment[2]) { 4592 pageX = this.containment[2] + this.offset.click.left; 4593 } 4594 if(event.pageY - this.offset.click.top > this.containment[3]) { 4595 pageY = this.containment[3] + this.offset.click.top; 4596 } 4597 } 4598 4599 if(o.grid) { 4600 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 4601 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; 4602 4603 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 4604 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; 4605 } 4606 4607 } 4608 4609 return { 4610 top: ( 4611 pageY - // The absolute mouse position 4612 this.offset.click.top - // Click offset (relative to the element) 4613 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 4614 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 4615 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 4616 ), 4617 left: ( 4618 pageX - // The absolute mouse position 4619 this.offset.click.left - // Click offset (relative to the element) 4620 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 4621 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 4622 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 4623 ) 4624 }; 4625 4626 }, 4627 4628 _rearrange: function(event, i, a, hardRefresh) { 4629 4630 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)); 4631 4632 //Various things done here to improve the performance: 4633 // 1. we create a setTimeout, that calls refreshPositions 4634 // 2. on the instance, we have a counter variable, that get's higher after every append 4635 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 4636 // 4. this lets only the last addition to the timeout stack through 4637 this.counter = this.counter ? ++this.counter : 1; 4638 var counter = this.counter; 4639 4640 this._delay(function() { 4641 if(counter === this.counter) { 4642 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 4643 } 4644 }); 4645 4646 }, 4647 4648 _clear: function(event, noPropagation) { 4649 4650 this.reverting = false; 4651 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 4652 // everything else normalized again 4653 var i, 4654 delayedTriggers = []; 4655 4656 // We first have to update the dom position of the actual currentItem 4657 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 4658 if(!this._noFinalSort && this.currentItem.parent().length) { 4659 this.placeholder.before(this.currentItem); 4660 } 4661 this._noFinalSort = null; 4662 4663 if(this.helper[0] === this.currentItem[0]) { 4664 for(i in this._storedCSS) { 4665 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 4666 this._storedCSS[i] = ""; 4667 } 4668 } 4669 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4670 } else { 4671 this.currentItem.show(); 4672 } 4673 4674 if(this.fromOutside && !noPropagation) { 4675 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 4676 } 4677 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 4678 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 4679 } 4680 4681 // Check if the items Container has Changed and trigger appropriate 4682 // events. 4683 if (this !== this.currentContainer) { 4684 if(!noPropagation) { 4685 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 4686 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4687 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4688 } 4689 } 4690 4691 4692 //Post events to containers 4693 for (i = this.containers.length - 1; i >= 0; i--){ 4694 if(!noPropagation) { 4695 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4696 } 4697 if(this.containers[i].containerCache.over) { 4698 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4699 this.containers[i].containerCache.over = 0; 4700 } 4701 } 4702 4703 //Do what was originally in plugins 4704 if ( this.storedCursor ) { 4705 this.document.find( "body" ).css( "cursor", this.storedCursor ); 4706 this.storedStylesheet.remove(); 4707 } 4708 if(this._storedOpacity) { 4709 this.helper.css("opacity", this._storedOpacity); 4710 } 4711 if(this._storedZIndex) { 4712 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 4713 } 4714 4715 this.dragging = false; 4716 if(this.cancelHelperRemoval) { 4717 if(!noPropagation) { 4718 this._trigger("beforeStop", event, this._uiHash()); 4719 for (i=0; i < delayedTriggers.length; i++) { 4720 delayedTriggers[i].call(this, event); 4721 } //Trigger all delayed events 4722 this._trigger("stop", event, this._uiHash()); 4723 } 4724 4725 this.fromOutside = false; 4726 return false; 4727 } 4728 4729 if(!noPropagation) { 4730 this._trigger("beforeStop", event, this._uiHash()); 4731 } 4732 4733 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4734 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4735 4736 if(this.helper[0] !== this.currentItem[0]) { 4737 this.helper.remove(); 4738 } 4739 this.helper = null; 4740 4741 if(!noPropagation) { 4742 for (i=0; i < delayedTriggers.length; i++) { 4743 delayedTriggers[i].call(this, event); 4744 } //Trigger all delayed events 4745 this._trigger("stop", event, this._uiHash()); 4746 } 4747 4748 this.fromOutside = false; 4749 return true; 4750 4751 }, 4752 4753 _trigger: function() { 4754 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 4755 this.cancel(); 4756 } 4757 }, 4758 4759 _uiHash: function(_inst) { 4760 var inst = _inst || this; 4761 return { 4762 helper: inst.helper, 4763 placeholder: inst.placeholder || $([]), 4764 position: inst.position, 4765 originalPosition: inst.originalPosition, 4766 offset: inst.positionAbs, 4767 item: inst.currentItem, 4768 sender: _inst ? _inst.element : null 4769 }; 4770 } 4771 4772}); 4773 4774})(jQuery); 4775 4776(function($, undefined) { 4777 4778var dataSpace = "ui-effects-"; 4779 4780$.effects = { 4781 effect: {} 4782}; 4783 4784/*! 4785 * jQuery Color Animations v2.1.2 4786 * https://github.com/jquery/jquery-color 4787 * 4788 * Copyright 2013 jQuery Foundation and other contributors 4789 * Released under the MIT license. 4790 * http://jquery.org/license 4791 * 4792 * Date: Wed Jan 16 08:47:09 2013 -0600 4793 */ 4794(function( jQuery, undefined ) { 4795 4796 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 4797 4798 // plusequals test for += 100 -= 100 4799 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 4800 // a set of RE's that can match strings and generate color tuples. 4801 stringParsers = [{ 4802 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4803 parse: function( execResult ) { 4804 return [ 4805 execResult[ 1 ], 4806 execResult[ 2 ], 4807 execResult[ 3 ], 4808 execResult[ 4 ] 4809 ]; 4810 } 4811 }, { 4812 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4813 parse: function( execResult ) { 4814 return [ 4815 execResult[ 1 ] * 2.55, 4816 execResult[ 2 ] * 2.55, 4817 execResult[ 3 ] * 2.55, 4818 execResult[ 4 ] 4819 ]; 4820 } 4821 }, { 4822 // this regex ignores A-F because it's compared against an already lowercased string 4823 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 4824 parse: function( execResult ) { 4825 return [ 4826 parseInt( execResult[ 1 ], 16 ), 4827 parseInt( execResult[ 2 ], 16 ), 4828 parseInt( execResult[ 3 ], 16 ) 4829 ]; 4830 } 4831 }, { 4832 // this regex ignores A-F because it's compared against an already lowercased string 4833 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 4834 parse: function( execResult ) { 4835 return [ 4836 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 4837 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 4838 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 4839 ]; 4840 } 4841 }, { 4842 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4843 space: "hsla", 4844 parse: function( execResult ) { 4845 return [ 4846 execResult[ 1 ], 4847 execResult[ 2 ] / 100, 4848 execResult[ 3 ] / 100, 4849 execResult[ 4 ] 4850 ]; 4851 } 4852 }], 4853 4854 // jQuery.Color( ) 4855 color = jQuery.Color = function( color, green, blue, alpha ) { 4856 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 4857 }, 4858 spaces = { 4859 rgba: { 4860 props: { 4861 red: { 4862 idx: 0, 4863 type: "byte" 4864 }, 4865 green: { 4866 idx: 1, 4867 type: "byte" 4868 }, 4869 blue: { 4870 idx: 2, 4871 type: "byte" 4872 } 4873 } 4874 }, 4875 4876 hsla: { 4877 props: { 4878 hue: { 4879 idx: 0, 4880 type: "degrees" 4881 }, 4882 saturation: { 4883 idx: 1, 4884 type: "percent" 4885 }, 4886 lightness: { 4887 idx: 2, 4888 type: "percent" 4889 } 4890 } 4891 } 4892 }, 4893 propTypes = { 4894 "byte": { 4895 floor: true, 4896 max: 255 4897 }, 4898 "percent": { 4899 max: 1 4900 }, 4901 "degrees": { 4902 mod: 360, 4903 floor: true 4904 } 4905 }, 4906 support = color.support = {}, 4907 4908 // element for support tests 4909 supportElem = jQuery( "<p>" )[ 0 ], 4910 4911 // colors = jQuery.Color.names 4912 colors, 4913 4914 // local aliases of functions called often 4915 each = jQuery.each; 4916 4917// determine rgba support immediately 4918supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 4919support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 4920 4921// define cache name and alpha properties 4922// for rgba and hsla spaces 4923each( spaces, function( spaceName, space ) { 4924 space.cache = "_" + spaceName; 4925 space.props.alpha = { 4926 idx: 3, 4927 type: "percent", 4928 def: 1 4929 }; 4930}); 4931 4932function clamp( value, prop, allowEmpty ) { 4933 var type = propTypes[ prop.type ] || {}; 4934 4935 if ( value == null ) { 4936 return (allowEmpty || !prop.def) ? null : prop.def; 4937 } 4938 4939 // ~~ is an short way of doing floor for positive numbers 4940 value = type.floor ? ~~value : parseFloat( value ); 4941 4942 // IE will pass in empty strings as value for alpha, 4943 // which will hit this case 4944 if ( isNaN( value ) ) { 4945 return prop.def; 4946 } 4947 4948 if ( type.mod ) { 4949 // we add mod before modding to make sure that negatives values 4950 // get converted properly: -10 -> 350 4951 return (value + type.mod) % type.mod; 4952 } 4953 4954 // for now all property types without mod have min and max 4955 return 0 > value ? 0 : type.max < value ? type.max : value; 4956} 4957 4958function stringParse( string ) { 4959 var inst = color(), 4960 rgba = inst._rgba = []; 4961 4962 string = string.toLowerCase(); 4963 4964 each( stringParsers, function( i, parser ) { 4965 var parsed, 4966 match = parser.re.exec( string ), 4967 values = match && parser.parse( match ), 4968 spaceName = parser.space || "rgba"; 4969 4970 if ( values ) { 4971 parsed = inst[ spaceName ]( values ); 4972 4973 // if this was an rgba parse the assignment might happen twice 4974 // oh well.... 4975 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 4976 rgba = inst._rgba = parsed._rgba; 4977 4978 // exit each( stringParsers ) here because we matched 4979 return false; 4980 } 4981 }); 4982 4983 // Found a stringParser that handled it 4984 if ( rgba.length ) { 4985 4986 // if this came from a parsed string, force "transparent" when alpha is 0 4987 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 4988 if ( rgba.join() === "0,0,0,0" ) { 4989 jQuery.extend( rgba, colors.transparent ); 4990 } 4991 return inst; 4992 } 4993 4994 // named colors 4995 return colors[ string ]; 4996} 4997 4998color.fn = jQuery.extend( color.prototype, { 4999 parse: function( red, green, blue, alpha ) { 5000 if ( red === undefined ) { 5001 this._rgba = [ null, null, null, null ]; 5002 return this; 5003 } 5004 if ( red.jquery || red.nodeType ) { 5005 red = jQuery( red ).css( green ); 5006 green = undefined; 5007 } 5008 5009 var inst = this, 5010 type = jQuery.type( red ), 5011 rgba = this._rgba = []; 5012 5013 // more than 1 argument specified - assume ( red, green, blue, alpha ) 5014 if ( green !== undefined ) { 5015 red = [ red, green, blue, alpha ]; 5016 type = "array"; 5017 } 5018 5019 if ( type === "string" ) { 5020 return this.parse( stringParse( red ) || colors._default ); 5021 } 5022 5023 if ( type === "array" ) { 5024 each( spaces.rgba.props, function( key, prop ) { 5025 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 5026 }); 5027 return this; 5028 } 5029 5030 if ( type === "object" ) { 5031 if ( red instanceof color ) { 5032 each( spaces, function( spaceName, space ) { 5033 if ( red[ space.cache ] ) { 5034 inst[ space.cache ] = red[ space.cache ].slice(); 5035 } 5036 }); 5037 } else { 5038 each( spaces, function( spaceName, space ) { 5039 var cache = space.cache; 5040 each( space.props, function( key, prop ) { 5041 5042 // if the cache doesn't exist, and we know how to convert 5043 if ( !inst[ cache ] && space.to ) { 5044 5045 // if the value was null, we don't need to copy it 5046 // if the key was alpha, we don't need to copy it either 5047 if ( key === "alpha" || red[ key ] == null ) { 5048 return; 5049 } 5050 inst[ cache ] = space.to( inst._rgba ); 5051 } 5052 5053 // this is the only case where we allow nulls for ALL properties. 5054 // call clamp with alwaysAllowEmpty 5055 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 5056 }); 5057 5058 // everything defined but alpha? 5059 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 5060 // use the default of 1 5061 inst[ cache ][ 3 ] = 1; 5062 if ( space.from ) { 5063 inst._rgba = space.from( inst[ cache ] ); 5064 } 5065 } 5066 }); 5067 } 5068 return this; 5069 } 5070 }, 5071 is: function( compare ) { 5072 var is = color( compare ), 5073 same = true, 5074 inst = this; 5075 5076 each( spaces, function( _, space ) { 5077 var localCache, 5078 isCache = is[ space.cache ]; 5079 if (isCache) { 5080 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 5081 each( space.props, function( _, prop ) { 5082 if ( isCache[ prop.idx ] != null ) { 5083 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 5084 return same; 5085 } 5086 }); 5087 } 5088 return same; 5089 }); 5090 return same; 5091 }, 5092 _space: function() { 5093 var used = [], 5094 inst = this; 5095 each( spaces, function( spaceName, space ) { 5096 if ( inst[ space.cache ] ) { 5097 used.push( spaceName ); 5098 } 5099 }); 5100 return used.pop(); 5101 }, 5102 transition: function( other, distance ) { 5103 var end = color( other ), 5104 spaceName = end._space(), 5105 space = spaces[ spaceName ], 5106 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 5107 start = startColor[ space.cache ] || space.to( startColor._rgba ), 5108 result = start.slice(); 5109 5110 end = end[ space.cache ]; 5111 each( space.props, function( key, prop ) { 5112 var index = prop.idx, 5113 startValue = start[ index ], 5114 endValue = end[ index ], 5115 type = propTypes[ prop.type ] || {}; 5116 5117 // if null, don't override start value 5118 if ( endValue === null ) { 5119 return; 5120 } 5121 // if null - use end 5122 if ( startValue === null ) { 5123 result[ index ] = endValue; 5124 } else { 5125 if ( type.mod ) { 5126 if ( endValue - startValue > type.mod / 2 ) { 5127 startValue += type.mod; 5128 } else if ( startValue - endValue > type.mod / 2 ) { 5129 startValue -= type.mod; 5130 } 5131 } 5132 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 5133 } 5134 }); 5135 return this[ spaceName ]( result ); 5136 }, 5137 blend: function( opaque ) { 5138 // if we are already opaque - return ourself 5139 if ( this._rgba[ 3 ] === 1 ) { 5140 return this; 5141 } 5142 5143 var rgb = this._rgba.slice(), 5144 a = rgb.pop(), 5145 blend = color( opaque )._rgba; 5146 5147 return color( jQuery.map( rgb, function( v, i ) { 5148 return ( 1 - a ) * blend[ i ] + a * v; 5149 })); 5150 }, 5151 toRgbaString: function() { 5152 var prefix = "rgba(", 5153 rgba = jQuery.map( this._rgba, function( v, i ) { 5154 return v == null ? ( i > 2 ? 1 : 0 ) : v; 5155 }); 5156 5157 if ( rgba[ 3 ] === 1 ) { 5158 rgba.pop(); 5159 prefix = "rgb("; 5160 } 5161 5162 return prefix + rgba.join() + ")"; 5163 }, 5164 toHslaString: function() { 5165 var prefix = "hsla(", 5166 hsla = jQuery.map( this.hsla(), function( v, i ) { 5167 if ( v == null ) { 5168 v = i > 2 ? 1 : 0; 5169 } 5170 5171 // catch 1 and 2 5172 if ( i && i < 3 ) { 5173 v = Math.round( v * 100 ) + "%"; 5174 } 5175 return v; 5176 }); 5177 5178 if ( hsla[ 3 ] === 1 ) { 5179 hsla.pop(); 5180 prefix = "hsl("; 5181 } 5182 return prefix + hsla.join() + ")"; 5183 }, 5184 toHexString: function( includeAlpha ) { 5185 var rgba = this._rgba.slice(), 5186 alpha = rgba.pop(); 5187 5188 if ( includeAlpha ) { 5189 rgba.push( ~~( alpha * 255 ) ); 5190 } 5191 5192 return "#" + jQuery.map( rgba, function( v ) { 5193 5194 // default to 0 when nulls exist 5195 v = ( v || 0 ).toString( 16 ); 5196 return v.length === 1 ? "0" + v : v; 5197 }).join(""); 5198 }, 5199 toString: function() { 5200 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 5201 } 5202}); 5203color.fn.parse.prototype = color.fn; 5204 5205// hsla conversions adapted from: 5206// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 5207 5208function hue2rgb( p, q, h ) { 5209 h = ( h + 1 ) % 1; 5210 if ( h * 6 < 1 ) { 5211 return p + (q - p) * h * 6; 5212 } 5213 if ( h * 2 < 1) { 5214 return q; 5215 } 5216 if ( h * 3 < 2 ) { 5217 return p + (q - p) * ((2/3) - h) * 6; 5218 } 5219 return p; 5220} 5221 5222spaces.hsla.to = function ( rgba ) { 5223 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 5224 return [ null, null, null, rgba[ 3 ] ]; 5225 } 5226 var r = rgba[ 0 ] / 255, 5227 g = rgba[ 1 ] / 255, 5228 b = rgba[ 2 ] / 255, 5229 a = rgba[ 3 ], 5230 max = Math.max( r, g, b ), 5231 min = Math.min( r, g, b ), 5232 diff = max - min, 5233 add = max + min, 5234 l = add * 0.5, 5235 h, s; 5236 5237 if ( min === max ) { 5238 h = 0; 5239 } else if ( r === max ) { 5240 h = ( 60 * ( g - b ) / diff ) + 360; 5241 } else if ( g === max ) { 5242 h = ( 60 * ( b - r ) / diff ) + 120; 5243 } else { 5244 h = ( 60 * ( r - g ) / diff ) + 240; 5245 } 5246 5247 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 5248 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 5249 if ( diff === 0 ) { 5250 s = 0; 5251 } else if ( l <= 0.5 ) { 5252 s = diff / add; 5253 } else { 5254 s = diff / ( 2 - add ); 5255 } 5256 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 5257}; 5258 5259spaces.hsla.from = function ( hsla ) { 5260 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 5261 return [ null, null, null, hsla[ 3 ] ]; 5262 } 5263 var h = hsla[ 0 ] / 360, 5264 s = hsla[ 1 ], 5265 l = hsla[ 2 ], 5266 a = hsla[ 3 ], 5267 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 5268 p = 2 * l - q; 5269 5270 return [ 5271 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 5272 Math.round( hue2rgb( p, q, h ) * 255 ), 5273 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 5274 a 5275 ]; 5276}; 5277 5278 5279each( spaces, function( spaceName, space ) { 5280 var props = space.props, 5281 cache = space.cache, 5282 to = space.to, 5283 from = space.from; 5284 5285 // makes rgba() and hsla() 5286 color.fn[ spaceName ] = function( value ) { 5287 5288 // generate a cache for this space if it doesn't exist 5289 if ( to && !this[ cache ] ) { 5290 this[ cache ] = to( this._rgba ); 5291 } 5292 if ( value === undefined ) { 5293 return this[ cache ].slice(); 5294 } 5295 5296 var ret, 5297 type = jQuery.type( value ), 5298 arr = ( type === "array" || type === "object" ) ? value : arguments, 5299 local = this[ cache ].slice(); 5300 5301 each( props, function( key, prop ) { 5302 var val = arr[ type === "object" ? key : prop.idx ]; 5303 if ( val == null ) { 5304 val = local[ prop.idx ]; 5305 } 5306 local[ prop.idx ] = clamp( val, prop ); 5307 }); 5308 5309 if ( from ) { 5310 ret = color( from( local ) ); 5311 ret[ cache ] = local; 5312 return ret; 5313 } else { 5314 return color( local ); 5315 } 5316 }; 5317 5318 // makes red() green() blue() alpha() hue() saturation() lightness() 5319 each( props, function( key, prop ) { 5320 // alpha is included in more than one space 5321 if ( color.fn[ key ] ) { 5322 return; 5323 } 5324 color.fn[ key ] = function( value ) { 5325 var vtype = jQuery.type( value ), 5326 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 5327 local = this[ fn ](), 5328 cur = local[ prop.idx ], 5329 match; 5330 5331 if ( vtype === "undefined" ) { 5332 return cur; 5333 } 5334 5335 if ( vtype === "function" ) { 5336 value = value.call( this, cur ); 5337 vtype = jQuery.type( value ); 5338 } 5339 if ( value == null && prop.empty ) { 5340 return this; 5341 } 5342 if ( vtype === "string" ) { 5343 match = rplusequals.exec( value ); 5344 if ( match ) { 5345 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 5346 } 5347 } 5348 local[ prop.idx ] = value; 5349 return this[ fn ]( local ); 5350 }; 5351 }); 5352}); 5353 5354// add cssHook and .fx.step function for each named hook. 5355// accept a space separated string of properties 5356color.hook = function( hook ) { 5357 var hooks = hook.split( " " ); 5358 each( hooks, function( i, hook ) { 5359 jQuery.cssHooks[ hook ] = { 5360 set: function( elem, value ) { 5361 var parsed, curElem, 5362 backgroundColor = ""; 5363 5364 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 5365 value = color( parsed || value ); 5366 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 5367 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 5368 while ( 5369 (backgroundColor === "" || backgroundColor === "transparent") && 5370 curElem && curElem.style 5371 ) { 5372 try { 5373 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 5374 curElem = curElem.parentNode; 5375 } catch ( e ) { 5376 } 5377 } 5378 5379 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 5380 backgroundColor : 5381 "_default" ); 5382 } 5383 5384 value = value.toRgbaString(); 5385 } 5386 try { 5387 elem.style[ hook ] = value; 5388 } catch( e ) { 5389 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 5390 } 5391 } 5392 }; 5393 jQuery.fx.step[ hook ] = function( fx ) { 5394 if ( !fx.colorInit ) { 5395 fx.start = color( fx.elem, hook ); 5396 fx.end = color( fx.end ); 5397 fx.colorInit = true; 5398 } 5399 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 5400 }; 5401 }); 5402 5403}; 5404 5405color.hook( stepHooks ); 5406 5407jQuery.cssHooks.borderColor = { 5408 expand: function( value ) { 5409 var expanded = {}; 5410 5411 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 5412 expanded[ "border" + part + "Color" ] = value; 5413 }); 5414 return expanded; 5415 } 5416}; 5417 5418// Basic color names only. 5419// Usage of any of the other color names requires adding yourself or including 5420// jquery.color.svg-names.js. 5421colors = jQuery.Color.names = { 5422 // 4.1. Basic color keywords 5423 aqua: "#00ffff", 5424 black: "#000000", 5425 blue: "#0000ff", 5426 fuchsia: "#ff00ff", 5427 gray: "#808080", 5428 green: "#008000", 5429 lime: "#00ff00", 5430 maroon: "#800000", 5431 navy: "#000080", 5432 olive: "#808000", 5433 purple: "#800080", 5434 red: "#ff0000", 5435 silver: "#c0c0c0", 5436 teal: "#008080", 5437 white: "#ffffff", 5438 yellow: "#ffff00", 5439 5440 // 4.2.3. "transparent" color keyword 5441 transparent: [ null, null, null, 0 ], 5442 5443 _default: "#ffffff" 5444}; 5445 5446})( jQuery ); 5447 5448 5449/******************************************************************************/ 5450/****************************** CLASS ANIMATIONS ******************************/ 5451/******************************************************************************/ 5452(function() { 5453 5454var classAnimationActions = [ "add", "remove", "toggle" ], 5455 shorthandStyles = { 5456 border: 1, 5457 borderBottom: 1, 5458 borderColor: 1, 5459 borderLeft: 1, 5460 borderRight: 1, 5461 borderTop: 1, 5462 borderWidth: 1, 5463 margin: 1, 5464 padding: 1 5465 }; 5466 5467$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 5468 $.fx.step[ prop ] = function( fx ) { 5469 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 5470 jQuery.style( fx.elem, prop, fx.end ); 5471 fx.setAttr = true; 5472 } 5473 }; 5474}); 5475 5476function getElementStyles( elem ) { 5477 var key, len, 5478 style = elem.ownerDocument.defaultView ? 5479 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 5480 elem.currentStyle, 5481 styles = {}; 5482 5483 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 5484 len = style.length; 5485 while ( len-- ) { 5486 key = style[ len ]; 5487 if ( typeof style[ key ] === "string" ) { 5488 styles[ $.camelCase( key ) ] = style[ key ]; 5489 } 5490 } 5491 // support: Opera, IE <9 5492 } else { 5493 for ( key in style ) { 5494 if ( typeof style[ key ] === "string" ) { 5495 styles[ key ] = style[ key ]; 5496 } 5497 } 5498 } 5499 5500 return styles; 5501} 5502 5503 5504function styleDifference( oldStyle, newStyle ) { 5505 var diff = {}, 5506 name, value; 5507 5508 for ( name in newStyle ) { 5509 value = newStyle[ name ]; 5510 if ( oldStyle[ name ] !== value ) { 5511 if ( !shorthandStyles[ name ] ) { 5512 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 5513 diff[ name ] = value; 5514 } 5515 } 5516 } 5517 } 5518 5519 return diff; 5520} 5521 5522// support: jQuery <1.8 5523if ( !$.fn.addBack ) { 5524 $.fn.addBack = function( selector ) { 5525 return this.add( selector == null ? 5526 this.prevObject : this.prevObject.filter( selector ) 5527 ); 5528 }; 5529} 5530 5531$.effects.animateClass = function( value, duration, easing, callback ) { 5532 var o = $.speed( duration, easing, callback ); 5533 5534 return this.queue( function() { 5535 var animated = $( this ), 5536 baseClass = animated.attr( "class" ) || "", 5537 applyClassChange, 5538 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 5539 5540 // map the animated objects to store the original styles. 5541 allAnimations = allAnimations.map(function() { 5542 var el = $( this ); 5543 return { 5544 el: el, 5545 start: getElementStyles( this ) 5546 }; 5547 }); 5548 5549 // apply class change 5550 applyClassChange = function() { 5551 $.each( classAnimationActions, function(i, action) { 5552 if ( value[ action ] ) { 5553 animated[ action + "Class" ]( value[ action ] ); 5554 } 5555 }); 5556 }; 5557 applyClassChange(); 5558 5559 // map all animated objects again - calculate new styles and diff 5560 allAnimations = allAnimations.map(function() { 5561 this.end = getElementStyles( this.el[ 0 ] ); 5562 this.diff = styleDifference( this.start, this.end ); 5563 return this; 5564 }); 5565 5566 // apply original class 5567 animated.attr( "class", baseClass ); 5568 5569 // map all animated objects again - this time collecting a promise 5570 allAnimations = allAnimations.map(function() { 5571 var styleInfo = this, 5572 dfd = $.Deferred(), 5573 opts = $.extend({}, o, { 5574 queue: false, 5575 complete: function() { 5576 dfd.resolve( styleInfo ); 5577 } 5578 }); 5579 5580 this.el.animate( this.diff, opts ); 5581 return dfd.promise(); 5582 }); 5583 5584 // once all animations have completed: 5585 $.when.apply( $, allAnimations.get() ).done(function() { 5586 5587 // set the final class 5588 applyClassChange(); 5589 5590 // for each animated element, 5591 // clear all css properties that were animated 5592 $.each( arguments, function() { 5593 var el = this.el; 5594 $.each( this.diff, function(key) { 5595 el.css( key, "" ); 5596 }); 5597 }); 5598 5599 // this is guarnteed to be there if you use jQuery.speed() 5600 // it also handles dequeuing the next anim... 5601 o.complete.call( animated[ 0 ] ); 5602 }); 5603 }); 5604}; 5605 5606$.fn.extend({ 5607 addClass: (function( orig ) { 5608 return function( classNames, speed, easing, callback ) { 5609 return speed ? 5610 $.effects.animateClass.call( this, 5611 { add: classNames }, speed, easing, callback ) : 5612 orig.apply( this, arguments ); 5613 }; 5614 })( $.fn.addClass ), 5615 5616 removeClass: (function( orig ) { 5617 return function( classNames, speed, easing, callback ) { 5618 return arguments.length > 1 ? 5619 $.effects.animateClass.call( this, 5620 { remove: classNames }, speed, easing, callback ) : 5621 orig.apply( this, arguments ); 5622 }; 5623 })( $.fn.removeClass ), 5624 5625 toggleClass: (function( orig ) { 5626 return function( classNames, force, speed, easing, callback ) { 5627 if ( typeof force === "boolean" || force === undefined ) { 5628 if ( !speed ) { 5629 // without speed parameter 5630 return orig.apply( this, arguments ); 5631 } else { 5632 return $.effects.animateClass.call( this, 5633 (force ? { add: classNames } : { remove: classNames }), 5634 speed, easing, callback ); 5635 } 5636 } else { 5637 // without force parameter 5638 return $.effects.animateClass.call( this, 5639 { toggle: classNames }, force, speed, easing ); 5640 } 5641 }; 5642 })( $.fn.toggleClass ), 5643 5644 switchClass: function( remove, add, speed, easing, callback) { 5645 return $.effects.animateClass.call( this, { 5646 add: add, 5647 remove: remove 5648 }, speed, easing, callback ); 5649 } 5650}); 5651 5652})(); 5653 5654/******************************************************************************/ 5655/*********************************** EFFECTS **********************************/ 5656/******************************************************************************/ 5657 5658(function() { 5659 5660$.extend( $.effects, { 5661 version: "1.10.3", 5662 5663 // Saves a set of properties in a data storage 5664 save: function( element, set ) { 5665 for( var i=0; i < set.length; i++ ) { 5666 if ( set[ i ] !== null ) { 5667 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 5668 } 5669 } 5670 }, 5671 5672 // Restores a set of previously saved properties from a data storage 5673 restore: function( element, set ) { 5674 var val, i; 5675 for( i=0; i < set.length; i++ ) { 5676 if ( set[ i ] !== null ) { 5677 val = element.data( dataSpace + set[ i ] ); 5678 // support: jQuery 1.6.2 5679 // http://bugs.jquery.com/ticket/9917 5680 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 5681 // We can't differentiate between "" and 0 here, so we just assume 5682 // empty string since it's likely to be a more common value... 5683 if ( val === undefined ) { 5684 val = ""; 5685 } 5686 element.css( set[ i ], val ); 5687 } 5688 } 5689 }, 5690 5691 setMode: function( el, mode ) { 5692 if (mode === "toggle") { 5693 mode = el.is( ":hidden" ) ? "show" : "hide"; 5694 } 5695 return mode; 5696 }, 5697 5698 // Translates a [top,left] array into a baseline value 5699 // this should be a little more flexible in the future to handle a string & hash 5700 getBaseline: function( origin, original ) { 5701 var y, x; 5702 switch ( origin[ 0 ] ) { 5703 case "top": y = 0; break; 5704 case "middle": y = 0.5; break; 5705 case "bottom": y = 1; break; 5706 default: y = origin[ 0 ] / original.height; 5707 } 5708 switch ( origin[ 1 ] ) { 5709 case "left": x = 0; break; 5710 case "center": x = 0.5; break; 5711 case "right": x = 1; break; 5712 default: x = origin[ 1 ] / original.width; 5713 } 5714 return { 5715 x: x, 5716 y: y 5717 }; 5718 }, 5719 5720 // Wraps the element around a wrapper that copies position properties 5721 createWrapper: function( element ) { 5722 5723 // if the element is already wrapped, return it 5724 if ( element.parent().is( ".ui-effects-wrapper" )) { 5725 return element.parent(); 5726 } 5727 5728 // wrap the element 5729 var props = { 5730 width: element.outerWidth(true), 5731 height: element.outerHeight(true), 5732 "float": element.css( "float" ) 5733 }, 5734 wrapper = $( "<div></div>" ) 5735 .addClass( "ui-effects-wrapper" ) 5736 .css({ 5737 fontSize: "100%", 5738 background: "transparent", 5739 border: "none", 5740 margin: 0, 5741 padding: 0 5742 }), 5743 // Store the size in case width/height are defined in % - Fixes #5245 5744 size = { 5745 width: element.width(), 5746 height: element.height() 5747 }, 5748 active = document.activeElement; 5749 5750 // support: Firefox 5751 // Firefox incorrectly exposes anonymous content 5752 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 5753 try { 5754 active.id; 5755 } catch( e ) { 5756 active = document.body; 5757 } 5758 5759 element.wrap( wrapper ); 5760 5761 // Fixes #7595 - Elements lose focus when wrapped. 5762 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5763 $( active ).focus(); 5764 } 5765 5766 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 5767 5768 // transfer positioning properties to the wrapper 5769 if ( element.css( "position" ) === "static" ) { 5770 wrapper.css({ position: "relative" }); 5771 element.css({ position: "relative" }); 5772 } else { 5773 $.extend( props, { 5774 position: element.css( "position" ), 5775 zIndex: element.css( "z-index" ) 5776 }); 5777 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 5778 props[ pos ] = element.css( pos ); 5779 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 5780 props[ pos ] = "auto"; 5781 } 5782 }); 5783 element.css({ 5784 position: "relative", 5785 top: 0, 5786 left: 0, 5787 right: "auto", 5788 bottom: "auto" 5789 }); 5790 } 5791 element.css(size); 5792 5793 return wrapper.css( props ).show(); 5794 }, 5795 5796 removeWrapper: function( element ) { 5797 var active = document.activeElement; 5798 5799 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 5800 element.parent().replaceWith( element ); 5801 5802 // Fixes #7595 - Elements lose focus when wrapped. 5803 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5804 $( active ).focus(); 5805 } 5806 } 5807 5808 5809 return element; 5810 }, 5811 5812 setTransition: function( element, list, factor, value ) { 5813 value = value || {}; 5814 $.each( list, function( i, x ) { 5815 var unit = element.cssUnit( x ); 5816 if ( unit[ 0 ] > 0 ) { 5817 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 5818 } 5819 }); 5820 return value; 5821 } 5822}); 5823 5824// return an effect options object for the given parameters: 5825function _normalizeArguments( effect, options, speed, callback ) { 5826 5827 // allow passing all options as the first parameter 5828 if ( $.isPlainObject( effect ) ) { 5829 options = effect; 5830 effect = effect.effect; 5831 } 5832 5833 // convert to an object 5834 effect = { effect: effect }; 5835 5836 // catch (effect, null, ...) 5837 if ( options == null ) { 5838 options = {}; 5839 } 5840 5841 // catch (effect, callback) 5842 if ( $.isFunction( options ) ) { 5843 callback = options; 5844 speed = null; 5845 options = {}; 5846 } 5847 5848 // catch (effect, speed, ?) 5849 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 5850 callback = speed; 5851 speed = options; 5852 options = {}; 5853 } 5854 5855 // catch (effect, options, callback) 5856 if ( $.isFunction( speed ) ) { 5857 callback = speed; 5858 speed = null; 5859 } 5860 5861 // add options to effect 5862 if ( options ) { 5863 $.extend( effect, options ); 5864 } 5865 5866 speed = speed || options.duration; 5867 effect.duration = $.fx.off ? 0 : 5868 typeof speed === "number" ? speed : 5869 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 5870 $.fx.speeds._default; 5871 5872 effect.complete = callback || options.complete; 5873 5874 return effect; 5875} 5876 5877function standardAnimationOption( option ) { 5878 // Valid standard speeds (nothing, number, named speed) 5879 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 5880 return true; 5881 } 5882 5883 // Invalid strings - treat as "normal" speed 5884 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 5885 return true; 5886 } 5887 5888 // Complete callback 5889 if ( $.isFunction( option ) ) { 5890 return true; 5891 } 5892 5893 // Options hash (but not naming an effect) 5894 if ( typeof option === "object" && !option.effect ) { 5895 return true; 5896 } 5897 5898 // Didn't match any standard API 5899 return false; 5900} 5901 5902$.fn.extend({ 5903 effect: function( /* effect, options, speed, callback */ ) { 5904 var args = _normalizeArguments.apply( this, arguments ), 5905 mode = args.mode, 5906 queue = args.queue, 5907 effectMethod = $.effects.effect[ args.effect ]; 5908 5909 if ( $.fx.off || !effectMethod ) { 5910 // delegate to the original method (e.g., .show()) if possible 5911 if ( mode ) { 5912 return this[ mode ]( args.duration, args.complete ); 5913 } else { 5914 return this.each( function() { 5915 if ( args.complete ) { 5916 args.complete.call( this ); 5917 } 5918 }); 5919 } 5920 } 5921 5922 function run( next ) { 5923 var elem = $( this ), 5924 complete = args.complete, 5925 mode = args.mode; 5926 5927 function done() { 5928 if ( $.isFunction( complete ) ) { 5929 complete.call( elem[0] ); 5930 } 5931 if ( $.isFunction( next ) ) { 5932 next(); 5933 } 5934 } 5935 5936 // If the element already has the correct final state, delegate to 5937 // the core methods so the internal tracking of "olddisplay" works. 5938 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 5939 elem[ mode ](); 5940 done(); 5941 } else { 5942 effectMethod.call( elem[0], args, done ); 5943 } 5944 } 5945 5946 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 5947 }, 5948 5949 show: (function( orig ) { 5950 return function( option ) { 5951 if ( standardAnimationOption( option ) ) { 5952 return orig.apply( this, arguments ); 5953 } else { 5954 var args = _normalizeArguments.apply( this, arguments ); 5955 args.mode = "show"; 5956 return this.effect.call( this, args ); 5957 } 5958 }; 5959 })( $.fn.show ), 5960 5961 hide: (function( orig ) { 5962 return function( option ) { 5963 if ( standardAnimationOption( option ) ) { 5964 return orig.apply( this, arguments ); 5965 } else { 5966 var args = _normalizeArguments.apply( this, arguments ); 5967 args.mode = "hide"; 5968 return this.effect.call( this, args ); 5969 } 5970 }; 5971 })( $.fn.hide ), 5972 5973 toggle: (function( orig ) { 5974 return function( option ) { 5975 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 5976 return orig.apply( this, arguments ); 5977 } else { 5978 var args = _normalizeArguments.apply( this, arguments ); 5979 args.mode = "toggle"; 5980 return this.effect.call( this, args ); 5981 } 5982 }; 5983 })( $.fn.toggle ), 5984 5985 // helper functions 5986 cssUnit: function(key) { 5987 var style = this.css( key ), 5988 val = []; 5989 5990 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 5991 if ( style.indexOf( unit ) > 0 ) { 5992 val = [ parseFloat( style ), unit ]; 5993 } 5994 }); 5995 return val; 5996 } 5997}); 5998 5999})(); 6000 6001/******************************************************************************/ 6002/*********************************** EASING ***********************************/ 6003/******************************************************************************/ 6004 6005(function() { 6006 6007// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 6008 6009var baseEasings = {}; 6010 6011$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 6012 baseEasings[ name ] = function( p ) { 6013 return Math.pow( p, i + 2 ); 6014 }; 6015}); 6016 6017$.extend( baseEasings, { 6018 Sine: function ( p ) { 6019 return 1 - Math.cos( p * Math.PI / 2 ); 6020 }, 6021 Circ: function ( p ) { 6022 return 1 - Math.sqrt( 1 - p * p ); 6023 }, 6024 Elastic: function( p ) { 6025 return p === 0 || p === 1 ? p : 6026 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 6027 }, 6028 Back: function( p ) { 6029 return p * p * ( 3 * p - 2 ); 6030 }, 6031 Bounce: function ( p ) { 6032 var pow2, 6033 bounce = 4; 6034 6035 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 6036 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 6037 } 6038}); 6039 6040$.each( baseEasings, function( name, easeIn ) { 6041 $.easing[ "easeIn" + name ] = easeIn; 6042 $.easing[ "easeOut" + name ] = function( p ) { 6043 return 1 - easeIn( 1 - p ); 6044 }; 6045 $.easing[ "easeInOut" + name ] = function( p ) { 6046 return p < 0.5 ? 6047 easeIn( p * 2 ) / 2 : 6048 1 - easeIn( p * -2 + 2 ) / 2; 6049 }; 6050}); 6051 6052})(); 6053 6054})(jQuery); 6055 6056(function( $, undefined ) { 6057 6058var uid = 0, 6059 hideProps = {}, 6060 showProps = {}; 6061 6062hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 6063 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 6064showProps.height = showProps.paddingTop = showProps.paddingBottom = 6065 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 6066 6067$.widget( "ui.accordion", { 6068 version: "1.10.3", 6069 options: { 6070 active: 0, 6071 animate: {}, 6072 collapsible: false, 6073 event: "click", 6074 header: "> li > :first-child,> :not(li):even", 6075 heightStyle: "auto", 6076 icons: { 6077 activeHeader: "ui-icon-triangle-1-s", 6078 header: "ui-icon-triangle-1-e" 6079 }, 6080 6081 // callbacks 6082 activate: null, 6083 beforeActivate: null 6084 }, 6085 6086 _create: function() { 6087 var options = this.options; 6088 this.prevShow = this.prevHide = $(); 6089 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 6090 // ARIA 6091 .attr( "role", "tablist" ); 6092 6093 // don't allow collapsible: false and active: false / null 6094 if ( !options.collapsible && (options.active === false || options.active == null) ) { 6095 options.active = 0; 6096 } 6097 6098 this._processPanels(); 6099 // handle negative values 6100 if ( options.active < 0 ) { 6101 options.active += this.headers.length; 6102 } 6103 this._refresh(); 6104 }, 6105 6106 _getCreateEventData: function() { 6107 return { 6108 header: this.active, 6109 panel: !this.active.length ? $() : this.active.next(), 6110 content: !this.active.length ? $() : this.active.next() 6111 }; 6112 }, 6113 6114 _createIcons: function() { 6115 var icons = this.options.icons; 6116 if ( icons ) { 6117 $( "<span>" ) 6118 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 6119 .prependTo( this.headers ); 6120 this.active.children( ".ui-accordion-header-icon" ) 6121 .removeClass( icons.header ) 6122 .addClass( icons.activeHeader ); 6123 this.headers.addClass( "ui-accordion-icons" ); 6124 } 6125 }, 6126 6127 _destroyIcons: function() { 6128 this.headers 6129 .removeClass( "ui-accordion-icons" ) 6130 .children( ".ui-accordion-header-icon" ) 6131 .remove(); 6132 }, 6133 6134 _destroy: function() { 6135 var contents; 6136 6137 // clean up main element 6138 this.element 6139 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 6140 .removeAttr( "role" ); 6141 6142 // clean up headers 6143 this.headers 6144 .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" ) 6145 .removeAttr( "role" ) 6146 .removeAttr( "aria-selected" ) 6147 .removeAttr( "aria-controls" ) 6148 .removeAttr( "tabIndex" ) 6149 .each(function() { 6150 if ( /^ui-accordion/.test( this.id ) ) { 6151 this.removeAttribute( "id" ); 6152 } 6153 }); 6154 this._destroyIcons(); 6155 6156 // clean up content panels 6157 contents = this.headers.next() 6158 .css( "display", "" ) 6159 .removeAttr( "role" ) 6160 .removeAttr( "aria-expanded" ) 6161 .removeAttr( "aria-hidden" ) 6162 .removeAttr( "aria-labelledby" ) 6163 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 6164 .each(function() { 6165 if ( /^ui-accordion/.test( this.id ) ) { 6166 this.removeAttribute( "id" ); 6167 } 6168 }); 6169 if ( this.options.heightStyle !== "content" ) { 6170 contents.css( "height", "" ); 6171 } 6172 }, 6173 6174 _setOption: function( key, value ) { 6175 if ( key === "active" ) { 6176 // _activate() will handle invalid values and update this.options 6177 this._activate( value ); 6178 return; 6179 } 6180 6181 if ( key === "event" ) { 6182 if ( this.options.event ) { 6183 this._off( this.headers, this.options.event ); 6184 } 6185 this._setupEvents( value ); 6186 } 6187 6188 this._super( key, value ); 6189 6190 // setting collapsible: false while collapsed; open first panel 6191 if ( key === "collapsible" && !value && this.options.active === false ) { 6192 this._activate( 0 ); 6193 } 6194 6195 if ( key === "icons" ) { 6196 this._destroyIcons(); 6197 if ( value ) { 6198 this._createIcons(); 6199 } 6200 } 6201 6202 // #5332 - opacity doesn't cascade to positioned elements in IE 6203 // so we need to add the disabled class to the headers and panels 6204 if ( key === "disabled" ) { 6205 this.headers.add( this.headers.next() ) 6206 .toggleClass( "ui-state-disabled", !!value ); 6207 } 6208 }, 6209 6210 _keydown: function( event ) { 6211 /*jshint maxcomplexity:15*/ 6212 if ( event.altKey || event.ctrlKey ) { 6213 return; 6214 } 6215 6216 var keyCode = $.ui.keyCode, 6217 length = this.headers.length, 6218 currentIndex = this.headers.index( event.target ), 6219 toFocus = false; 6220 6221 switch ( event.keyCode ) { 6222 case keyCode.RIGHT: 6223 case keyCode.DOWN: 6224 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 6225 break; 6226 case keyCode.LEFT: 6227 case keyCode.UP: 6228 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 6229 break; 6230 case keyCode.SPACE: 6231 case keyCode.ENTER: 6232 this._eventHandler( event ); 6233 break; 6234 case keyCode.HOME: 6235 toFocus = this.headers[ 0 ]; 6236 break; 6237 case keyCode.END: 6238 toFocus = this.headers[ length - 1 ]; 6239 break; 6240 } 6241 6242 if ( toFocus ) { 6243 $( event.target ).attr( "tabIndex", -1 ); 6244 $( toFocus ).attr( "tabIndex", 0 ); 6245 toFocus.focus(); 6246 event.preventDefault(); 6247 } 6248 }, 6249 6250 _panelKeyDown : function( event ) { 6251 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 6252 $( event.currentTarget ).prev().focus(); 6253 } 6254 }, 6255 6256 refresh: function() { 6257 var options = this.options; 6258 this._processPanels(); 6259 6260 // was collapsed or no panel 6261 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 6262 options.active = false; 6263 this.active = $(); 6264 // active false only when collapsible is true 6265 } else if ( options.active === false ) { 6266 this._activate( 0 ); 6267 // was active, but active panel is gone 6268 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 6269 // all remaining panel are disabled 6270 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 6271 options.active = false; 6272 this.active = $(); 6273 // activate previous panel 6274 } else { 6275 this._activate( Math.max( 0, options.active - 1 ) ); 6276 } 6277 // was active, active panel still exists 6278 } else { 6279 // make sure active index is correct 6280 options.active = this.headers.index( this.active ); 6281 } 6282 6283 this._destroyIcons(); 6284 6285 this._refresh(); 6286 }, 6287 6288 _processPanels: function() { 6289 this.headers = this.element.find( this.options.header ) 6290 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 6291 6292 this.headers.next() 6293 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 6294 .filter(":not(.ui-accordion-content-active)") 6295 .hide(); 6296 }, 6297 6298 _refresh: function() { 6299 var maxHeight, 6300 options = this.options, 6301 heightStyle = options.heightStyle, 6302 parent = this.element.parent(), 6303 accordionId = this.accordionId = "ui-accordion-" + 6304 (this.element.attr( "id" ) || ++uid); 6305 6306 this.active = this._findActive( options.active ) 6307 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 6308 .removeClass( "ui-corner-all" ); 6309 this.active.next() 6310 .addClass( "ui-accordion-content-active" ) 6311 .show(); 6312 6313 this.headers 6314 .attr( "role", "tab" ) 6315 .each(function( i ) { 6316 var header = $( this ), 6317 headerId = header.attr( "id" ), 6318 panel = header.next(), 6319 panelId = panel.attr( "id" ); 6320 if ( !headerId ) { 6321 headerId = accordionId + "-header-" + i; 6322 header.attr( "id", headerId ); 6323 } 6324 if ( !panelId ) { 6325 panelId = accordionId + "-panel-" + i; 6326 panel.attr( "id", panelId ); 6327 } 6328 header.attr( "aria-controls", panelId ); 6329 panel.attr( "aria-labelledby", headerId ); 6330 }) 6331 .next() 6332 .attr( "role", "tabpanel" ); 6333 6334 this.headers 6335 .not( this.active ) 6336 .attr({ 6337 "aria-selected": "false", 6338 tabIndex: -1 6339 }) 6340 .next() 6341 .attr({ 6342 "aria-expanded": "false", 6343 "aria-hidden": "true" 6344 }) 6345 .hide(); 6346 6347 // make sure at least one header is in the tab order 6348 if ( !this.active.length ) { 6349 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 6350 } else { 6351 this.active.attr({ 6352 "aria-selected": "true", 6353 tabIndex: 0 6354 }) 6355 .next() 6356 .attr({ 6357 "aria-expanded": "true", 6358 "aria-hidden": "false" 6359 }); 6360 } 6361 6362 this._createIcons(); 6363 6364 this._setupEvents( options.event ); 6365 6366 if ( heightStyle === "fill" ) { 6367 maxHeight = parent.height(); 6368 this.element.siblings( ":visible" ).each(function() { 6369 var elem = $( this ), 6370 position = elem.css( "position" ); 6371 6372 if ( position === "absolute" || position === "fixed" ) { 6373 return; 6374 } 6375 maxHeight -= elem.outerHeight( true ); 6376 }); 6377 6378 this.headers.each(function() { 6379 maxHeight -= $( this ).outerHeight( true ); 6380 }); 6381 6382 this.headers.next() 6383 .each(function() { 6384 $( this ).height( Math.max( 0, maxHeight - 6385 $( this ).innerHeight() + $( this ).height() ) ); 6386 }) 6387 .css( "overflow", "auto" ); 6388 } else if ( heightStyle === "auto" ) { 6389 maxHeight = 0; 6390 this.headers.next() 6391 .each(function() { 6392 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 6393 }) 6394 .height( maxHeight ); 6395 } 6396 }, 6397 6398 _activate: function( index ) { 6399 var active = this._findActive( index )[ 0 ]; 6400 6401 // trying to activate the already active panel 6402 if ( active === this.active[ 0 ] ) { 6403 return; 6404 } 6405 6406 // trying to collapse, simulate a click on the currently active header 6407 active = active || this.active[ 0 ]; 6408 6409 this._eventHandler({ 6410 target: active, 6411 currentTarget: active, 6412 preventDefault: $.noop 6413 }); 6414 }, 6415 6416 _findActive: function( selector ) { 6417 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 6418 }, 6419 6420 _setupEvents: function( event ) { 6421 var events = { 6422 keydown: "_keydown" 6423 }; 6424 if ( event ) { 6425 $.each( event.split(" "), function( index, eventName ) { 6426 events[ eventName ] = "_eventHandler"; 6427 }); 6428 } 6429 6430 this._off( this.headers.add( this.headers.next() ) ); 6431 this._on( this.headers, events ); 6432 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 6433 this._hoverable( this.headers ); 6434 this._focusable( this.headers ); 6435 }, 6436 6437 _eventHandler: function( event ) { 6438 var options = this.options, 6439 active = this.active, 6440 clicked = $( event.currentTarget ), 6441 clickedIsActive = clicked[ 0 ] === active[ 0 ], 6442 collapsing = clickedIsActive && options.collapsible, 6443 toShow = collapsing ? $() : clicked.next(), 6444 toHide = active.next(), 6445 eventData = { 6446 oldHeader: active, 6447 oldPanel: toHide, 6448 newHeader: collapsing ? $() : clicked, 6449 newPanel: toShow 6450 }; 6451 6452 event.preventDefault(); 6453 6454 if ( 6455 // click on active header, but not collapsible 6456 ( clickedIsActive && !options.collapsible ) || 6457 // allow canceling activation 6458 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 6459 return; 6460 } 6461 6462 options.active = collapsing ? false : this.headers.index( clicked ); 6463 6464 // when the call to ._toggle() comes after the class changes 6465 // it causes a very odd bug in IE 8 (see #6720) 6466 this.active = clickedIsActive ? $() : clicked; 6467 this._toggle( eventData ); 6468 6469 // switch classes 6470 // corner classes on the previously active header stay after the animation 6471 active.removeClass( "ui-accordion-header-active ui-state-active" ); 6472 if ( options.icons ) { 6473 active.children( ".ui-accordion-header-icon" ) 6474 .removeClass( options.icons.activeHeader ) 6475 .addClass( options.icons.header ); 6476 } 6477 6478 if ( !clickedIsActive ) { 6479 clicked 6480 .removeClass( "ui-corner-all" ) 6481 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 6482 if ( options.icons ) { 6483 clicked.children( ".ui-accordion-header-icon" ) 6484 .removeClass( options.icons.header ) 6485 .addClass( options.icons.activeHeader ); 6486 } 6487 6488 clicked 6489 .next() 6490 .addClass( "ui-accordion-content-active" ); 6491 } 6492 }, 6493 6494 _toggle: function( data ) { 6495 var toShow = data.newPanel, 6496 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 6497 6498 // handle activating a panel during the animation for another activation 6499 this.prevShow.add( this.prevHide ).stop( true, true ); 6500 this.prevShow = toShow; 6501 this.prevHide = toHide; 6502 6503 if ( this.options.animate ) { 6504 this._animate( toShow, toHide, data ); 6505 } else { 6506 toHide.hide(); 6507 toShow.show(); 6508 this._toggleComplete( data ); 6509 } 6510 6511 toHide.attr({ 6512 "aria-expanded": "false", 6513 "aria-hidden": "true" 6514 }); 6515 toHide.prev().attr( "aria-selected", "false" ); 6516 // if we're switching panels, remove the old header from the tab order 6517 // if we're opening from collapsed state, remove the previous header from the tab order 6518 // if we're collapsing, then keep the collapsing header in the tab order 6519 if ( toShow.length && toHide.length ) { 6520 toHide.prev().attr( "tabIndex", -1 ); 6521 } else if ( toShow.length ) { 6522 this.headers.filter(function() { 6523 return $( this ).attr( "tabIndex" ) === 0; 6524 }) 6525 .attr( "tabIndex", -1 ); 6526 } 6527 6528 toShow 6529 .attr({ 6530 "aria-expanded": "true", 6531 "aria-hidden": "false" 6532 }) 6533 .prev() 6534 .attr({ 6535 "aria-selected": "true", 6536 tabIndex: 0 6537 }); 6538 }, 6539 6540 _animate: function( toShow, toHide, data ) { 6541 var total, easing, duration, 6542 that = this, 6543 adjust = 0, 6544 down = toShow.length && 6545 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 6546 animate = this.options.animate || {}, 6547 options = down && animate.down || animate, 6548 complete = function() { 6549 that._toggleComplete( data ); 6550 }; 6551 6552 if ( typeof options === "number" ) { 6553 duration = options; 6554 } 6555 if ( typeof options === "string" ) { 6556 easing = options; 6557 } 6558 // fall back from options to animation in case of partial down settings 6559 easing = easing || options.easing || animate.easing; 6560 duration = duration || options.duration || animate.duration; 6561 6562 if ( !toHide.length ) { 6563 return toShow.animate( showProps, duration, easing, complete ); 6564 } 6565 if ( !toShow.length ) { 6566 return toHide.animate( hideProps, duration, easing, complete ); 6567 } 6568 6569 total = toShow.show().outerHeight(); 6570 toHide.animate( hideProps, { 6571 duration: duration, 6572 easing: easing, 6573 step: function( now, fx ) { 6574 fx.now = Math.round( now ); 6575 } 6576 }); 6577 toShow 6578 .hide() 6579 .animate( showProps, { 6580 duration: duration, 6581 easing: easing, 6582 complete: complete, 6583 step: function( now, fx ) { 6584 fx.now = Math.round( now ); 6585 if ( fx.prop !== "height" ) { 6586 adjust += fx.now; 6587 } else if ( that.options.heightStyle !== "content" ) { 6588 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 6589 adjust = 0; 6590 } 6591 } 6592 }); 6593 }, 6594 6595 _toggleComplete: function( data ) { 6596 var toHide = data.oldPanel; 6597 6598 toHide 6599 .removeClass( "ui-accordion-content-active" ) 6600 .prev() 6601 .removeClass( "ui-corner-top" ) 6602 .addClass( "ui-corner-all" ); 6603 6604 // Work around for rendering bug in IE (#5421) 6605 if ( toHide.length ) { 6606 toHide.parent()[0].className = toHide.parent()[0].className; 6607 } 6608 6609 this._trigger( "activate", null, data ); 6610 } 6611}); 6612 6613})( jQuery ); 6614 6615(function( $, undefined ) { 6616 6617// used to prevent race conditions with remote data sources 6618var requestIndex = 0; 6619 6620$.widget( "ui.autocomplete", { 6621 version: "1.10.3", 6622 defaultElement: "<input>", 6623 options: { 6624 appendTo: null, 6625 autoFocus: false, 6626 delay: 300, 6627 minLength: 1, 6628 position: { 6629 my: "left top", 6630 at: "left bottom", 6631 collision: "none" 6632 }, 6633 source: null, 6634 6635 // callbacks 6636 change: null, 6637 close: null, 6638 focus: null, 6639 open: null, 6640 response: null, 6641 search: null, 6642 select: null 6643 }, 6644 6645 pending: 0, 6646 6647 _create: function() { 6648 // Some browsers only repeat keydown events, not keypress events, 6649 // so we use the suppressKeyPress flag to determine if we've already 6650 // handled the keydown event. #7269 6651 // Unfortunately the code for & in keypress is the same as the up arrow, 6652 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 6653 // events when we know the keydown event was used to modify the 6654 // search term. #7799 6655 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 6656 nodeName = this.element[0].nodeName.toLowerCase(), 6657 isTextarea = nodeName === "textarea", 6658 isInput = nodeName === "input"; 6659 6660 this.isMultiLine = 6661 // Textareas are always multi-line 6662 isTextarea ? true : 6663 // Inputs are always single-line, even if inside a contentEditable element 6664 // IE also treats inputs as contentEditable 6665 isInput ? false : 6666 // All other element types are determined by whether or not they're contentEditable 6667 this.element.prop( "isContentEditable" ); 6668 6669 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 6670 this.isNewMenu = true; 6671 6672 this.element 6673 .addClass( "ui-autocomplete-input" ) 6674 .attr( "autocomplete", "off" ); 6675 6676 this._on( this.element, { 6677 keydown: function( event ) { 6678 /*jshint maxcomplexity:15*/ 6679 if ( this.element.prop( "readOnly" ) ) { 6680 suppressKeyPress = true; 6681 suppressInput = true; 6682 suppressKeyPressRepeat = true; 6683 return; 6684 } 6685 6686 suppressKeyPress = false; 6687 suppressInput = false; 6688 suppressKeyPressRepeat = false; 6689 var keyCode = $.ui.keyCode; 6690 switch( event.keyCode ) { 6691 case keyCode.PAGE_UP: 6692 suppressKeyPress = true; 6693 this._move( "previousPage", event ); 6694 break; 6695 case keyCode.PAGE_DOWN: 6696 suppressKeyPress = true; 6697 this._move( "nextPage", event ); 6698 break; 6699 case keyCode.UP: 6700 suppressKeyPress = true; 6701 this._keyEvent( "previous", event ); 6702 break; 6703 case keyCode.DOWN: 6704 suppressKeyPress = true; 6705 this._keyEvent( "next", event ); 6706 break; 6707 case keyCode.ENTER: 6708 case keyCode.NUMPAD_ENTER: 6709 // when menu is open and has focus 6710 if ( this.menu.active ) { 6711 // #6055 - Opera still allows the keypress to occur 6712 // which causes forms to submit 6713 suppressKeyPress = true; 6714 event.preventDefault(); 6715 this.menu.select( event ); 6716 } 6717 break; 6718 case keyCode.TAB: 6719 if ( this.menu.active ) { 6720 this.menu.select( event ); 6721 } 6722 break; 6723 case keyCode.ESCAPE: 6724 if ( this.menu.element.is( ":visible" ) ) { 6725 this._value( this.term ); 6726 this.close( event ); 6727 // Different browsers have different default behavior for escape 6728 // Single press can mean undo or clear 6729 // Double press in IE means clear the whole form 6730 event.preventDefault(); 6731 } 6732 break; 6733 default: 6734 suppressKeyPressRepeat = true; 6735 // search timeout should be triggered before the input value is changed 6736 this._searchTimeout( event ); 6737 break; 6738 } 6739 }, 6740 keypress: function( event ) { 6741 if ( suppressKeyPress ) { 6742 suppressKeyPress = false; 6743 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6744 event.preventDefault(); 6745 } 6746 return; 6747 } 6748 if ( suppressKeyPressRepeat ) { 6749 return; 6750 } 6751 6752 // replicate some key handlers to allow them to repeat in Firefox and Opera 6753 var keyCode = $.ui.keyCode; 6754 switch( event.keyCode ) { 6755 case keyCode.PAGE_UP: 6756 this._move( "previousPage", event ); 6757 break; 6758 case keyCode.PAGE_DOWN: 6759 this._move( "nextPage", event ); 6760 break; 6761 case keyCode.UP: 6762 this._keyEvent( "previous", event ); 6763 break; 6764 case keyCode.DOWN: 6765 this._keyEvent( "next", event ); 6766 break; 6767 } 6768 }, 6769 input: function( event ) { 6770 if ( suppressInput ) { 6771 suppressInput = false; 6772 event.preventDefault(); 6773 return; 6774 } 6775 this._searchTimeout( event ); 6776 }, 6777 focus: function() { 6778 this.selectedItem = null; 6779 this.previous = this._value(); 6780 }, 6781 blur: function( event ) { 6782 if ( this.cancelBlur ) { 6783 delete this.cancelBlur; 6784 return; 6785 } 6786 6787 clearTimeout( this.searching ); 6788 this.close( event ); 6789 this._change( event ); 6790 } 6791 }); 6792 6793 this._initSource(); 6794 this.menu = $( "<ul>" ) 6795 .addClass( "ui-autocomplete ui-front" ) 6796 .appendTo( this._appendTo() ) 6797 .menu({ 6798 // disable ARIA support, the live region takes care of that 6799 role: null 6800 }) 6801 .hide() 6802 .data( "ui-menu" ); 6803 6804 this._on( this.menu.element, { 6805 mousedown: function( event ) { 6806 // prevent moving focus out of the text field 6807 event.preventDefault(); 6808 6809 // IE doesn't prevent moving focus even with event.preventDefault() 6810 // so we set a flag to know when we should ignore the blur event 6811 this.cancelBlur = true; 6812 this._delay(function() { 6813 delete this.cancelBlur; 6814 }); 6815 6816 // clicking on the scrollbar causes focus to shift to the body 6817 // but we can't detect a mouseup or a click immediately afterward 6818 // so we have to track the next mousedown and close the menu if 6819 // the user clicks somewhere outside of the autocomplete 6820 var menuElement = this.menu.element[ 0 ]; 6821 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 6822 this._delay(function() { 6823 var that = this; 6824 this.document.one( "mousedown", function( event ) { 6825 if ( event.target !== that.element[ 0 ] && 6826 event.target !== menuElement && 6827 !$.contains( menuElement, event.target ) ) { 6828 that.close(); 6829 } 6830 }); 6831 }); 6832 } 6833 }, 6834 menufocus: function( event, ui ) { 6835 // support: Firefox 6836 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 6837 if ( this.isNewMenu ) { 6838 this.isNewMenu = false; 6839 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 6840 this.menu.blur(); 6841 6842 this.document.one( "mousemove", function() { 6843 $( event.target ).trigger( event.originalEvent ); 6844 }); 6845 6846 return; 6847 } 6848 } 6849 6850 var item = ui.item.data( "ui-autocomplete-item" ); 6851 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6852 // use value to match what will end up in the input, if it was a key event 6853 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6854 this._value( item.value ); 6855 } 6856 } else { 6857 // Normally the input is populated with the item's value as the 6858 // menu is navigated, causing screen readers to notice a change and 6859 // announce the item. Since the focus event was canceled, this doesn't 6860 // happen, so we update the live region so that screen readers can 6861 // still notice the change and announce it. 6862 this.liveRegion.text( item.value ); 6863 } 6864 }, 6865 menuselect: function( event, ui ) { 6866 var item = ui.item.data( "ui-autocomplete-item" ), 6867 previous = this.previous; 6868 6869 // only trigger when focus was lost (click on menu) 6870 if ( this.element[0] !== this.document[0].activeElement ) { 6871 this.element.focus(); 6872 this.previous = previous; 6873 // #6109 - IE triggers two focus events and the second 6874 // is asynchronous, so we need to reset the previous 6875 // term synchronously and asynchronously :-( 6876 this._delay(function() { 6877 this.previous = previous; 6878 this.selectedItem = item; 6879 }); 6880 } 6881 6882 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6883 this._value( item.value ); 6884 } 6885 // reset the term after the select event 6886 // this allows custom select handling to work properly 6887 this.term = this._value(); 6888 6889 this.close( event ); 6890 this.selectedItem = item; 6891 } 6892 }); 6893 6894 this.liveRegion = $( "<span>", { 6895 role: "status", 6896 "aria-live": "polite" 6897 }) 6898 .addClass( "ui-helper-hidden-accessible" ) 6899 .insertBefore( this.element ); 6900 6901 // turning off autocomplete prevents the browser from remembering the 6902 // value when navigating through history, so we re-enable autocomplete 6903 // if the page is unloaded before the widget is destroyed. #7790 6904 this._on( this.window, { 6905 beforeunload: function() { 6906 this.element.removeAttr( "autocomplete" ); 6907 } 6908 }); 6909 }, 6910 6911 _destroy: function() { 6912 clearTimeout( this.searching ); 6913 this.element 6914 .removeClass( "ui-autocomplete-input" ) 6915 .removeAttr( "autocomplete" ); 6916 this.menu.element.remove(); 6917 this.liveRegion.remove(); 6918 }, 6919 6920 _setOption: function( key, value ) { 6921 this._super( key, value ); 6922 if ( key === "source" ) { 6923 this._initSource(); 6924 } 6925 if ( key === "appendTo" ) { 6926 this.menu.element.appendTo( this._appendTo() ); 6927 } 6928 if ( key === "disabled" && value && this.xhr ) { 6929 this.xhr.abort(); 6930 } 6931 }, 6932 6933 _appendTo: function() { 6934 var element = this.options.appendTo; 6935 6936 if ( element ) { 6937 element = element.jquery || element.nodeType ? 6938 $( element ) : 6939 this.document.find( element ).eq( 0 ); 6940 } 6941 6942 if ( !element ) { 6943 element = this.element.closest( ".ui-front" ); 6944 } 6945 6946 if ( !element.length ) { 6947 element = this.document[0].body; 6948 } 6949 6950 return element; 6951 }, 6952 6953 _initSource: function() { 6954 var array, url, 6955 that = this; 6956 if ( $.isArray(this.options.source) ) { 6957 array = this.options.source; 6958 this.source = function( request, response ) { 6959 response( $.ui.autocomplete.filter( array, request.term ) ); 6960 }; 6961 } else if ( typeof this.options.source === "string" ) { 6962 url = this.options.source; 6963 this.source = function( request, response ) { 6964 if ( that.xhr ) { 6965 that.xhr.abort(); 6966 } 6967 that.xhr = $.ajax({
vendor: 5,929 bytes, lines 6968-7208
6968 url: url, 6969 data: request, 6970 dataType: "json", 6971 success: function( data ) { 6972 response( data ); 6973 }, 6974 error: function() { 6975 response( [] ); 6976 } 6977 }); 6978 }; 6979 } else { 6980 this.source = this.options.source; 6981 } 6982 }, 6983 6984 _searchTimeout: function( event ) { 6985 clearTimeout( this.searching ); 6986 this.searching = this._delay(function() { 6987 // only search if the value has changed 6988 if ( this.term !== this._value() ) { 6989 this.selectedItem = null; 6990 this.search( null, event ); 6991 } 6992 }, this.options.delay ); 6993 }, 6994 6995 search: function( value, event ) { 6996 value = value != null ? value : this._value(); 6997 6998 // always save the actual value, not the one passed as an argument 6999 this.term = this._value(); 7000 7001 if ( value.length < this.options.minLength ) { 7002 return this.close( event ); 7003 } 7004 7005 if ( this._trigger( "search", event ) === false ) { 7006 return; 7007 } 7008 7009 return this._search( value ); 7010 }, 7011 7012 _search: function( value ) { 7013 this.pending++; 7014 this.element.addClass( "ui-autocomplete-loading" ); 7015 this.cancelSearch = false; 7016 7017 this.source( { term: value }, this._response() ); 7018 }, 7019 7020 _response: function() { 7021 var that = this, 7022 index = ++requestIndex; 7023 7024 return function( content ) { 7025 if ( index === requestIndex ) { 7026 that.__response( content ); 7027 } 7028 7029 that.pending--; 7030 if ( !that.pending ) { 7031 that.element.removeClass( "ui-autocomplete-loading" ); 7032 } 7033 }; 7034 }, 7035 7036 __response: function( content ) { 7037 if ( content ) { 7038 content = this._normalize( content ); 7039 } 7040 this._trigger( "response", null, { content: content } ); 7041 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 7042 this._suggest( content ); 7043 this._trigger( "open" ); 7044 } else { 7045 // use ._close() instead of .close() so we don't cancel future searches 7046 this._close(); 7047 } 7048 }, 7049 7050 close: function( event ) { 7051 this.cancelSearch = true; 7052 this._close( event ); 7053 }, 7054 7055 _close: function( event ) { 7056 if ( this.menu.element.is( ":visible" ) ) { 7057 this.menu.element.hide(); 7058 this.menu.blur(); 7059 this.isNewMenu = true; 7060 this._trigger( "close", event ); 7061 } 7062 }, 7063 7064 _change: function( event ) { 7065 if ( this.previous !== this._value() ) { 7066 this._trigger( "change", event, { item: this.selectedItem } ); 7067 } 7068 }, 7069 7070 _normalize: function( items ) { 7071 // assume all items have the right format when the first item is complete 7072 if ( items.length && items[0].label && items[0].value ) { 7073 return items; 7074 } 7075 return $.map( items, function( item ) { 7076 if ( typeof item === "string" ) { 7077 return { 7078 label: item, 7079 value: item 7080 }; 7081 } 7082 return $.extend({ 7083 label: item.label || item.value, 7084 value: item.value || item.label 7085 }, item ); 7086 }); 7087 }, 7088 7089 _suggest: function( items ) { 7090 var ul = this.menu.element.empty(); 7091 this._renderMenu( ul, items ); 7092 this.isNewMenu = true; 7093 this.menu.refresh(); 7094 7095 // size and position menu 7096 ul.show(); 7097 this._resizeMenu(); 7098 ul.position( $.extend({ 7099 of: this.element 7100 }, this.options.position )); 7101 7102 if ( this.options.autoFocus ) { 7103 this.menu.next(); 7104 } 7105 }, 7106 7107 _resizeMenu: function() { 7108 var ul = this.menu.element; 7109 ul.outerWidth( Math.max( 7110 // Firefox wraps long text (possibly a rounding bug) 7111 // so we add 1px to avoid the wrapping (#7513) 7112 ul.width( "" ).outerWidth() + 1, 7113 this.element.outerWidth() 7114 ) ); 7115 }, 7116 7117 _renderMenu: function( ul, items ) { 7118 var that = this; 7119 $.each( items, function( index, item ) { 7120 that._renderItemData( ul, item ); 7121 }); 7122 }, 7123 7124 _renderItemData: function( ul, item ) { 7125 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 7126 }, 7127 7128 _renderItem: function( ul, item ) { 7129 return $( "<li>" ) 7130 .append( $( "<a>" ).text( item.label ) ) 7131 .appendTo( ul ); 7132 }, 7133 7134 _move: function( direction, event ) { 7135 if ( !this.menu.element.is( ":visible" ) ) { 7136 this.search( null, event ); 7137 return; 7138 } 7139 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 7140 this.menu.isLastItem() && /^next/.test( direction ) ) { 7141 this._value( this.term ); 7142 this.menu.blur(); 7143 return; 7144 } 7145 this.menu[ direction ]( event ); 7146 }, 7147 7148 widget: function() { 7149 return this.menu.element; 7150 }, 7151 7152 _value: function() { 7153 return this.valueMethod.apply( this.element, arguments ); 7154 }, 7155 7156 _keyEvent: function( keyEvent, event ) { 7157 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 7158 this._move( keyEvent, event ); 7159 7160 // prevents moving cursor to beginning/end of the text field in some browsers 7161 event.preventDefault(); 7162 } 7163 } 7164}); 7165 7166$.extend( $.ui.autocomplete, { 7167 escapeRegex: function( value ) { 7168 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 7169 }, 7170 filter: function(array, term) { 7171 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 7172 return $.grep( array, function(value) { 7173 return matcher.test( value.label || value.value || value ); 7174 }); 7175 } 7176}); 7177 7178 7179// live region extension, adding a `messages` option 7180// NOTE: This is an experimental API. We are still investigating 7181// a full solution for string manipulation and internationalization. 7182$.widget( "ui.autocomplete", $.ui.autocomplete, { 7183 options: { 7184 messages: { 7185 noResults: "No search results.", 7186 results: function( amount ) { 7187 return amount + ( amount > 1 ? " results are" : " result is" ) + 7188 " available, use up and down arrow keys to navigate."; 7189 } 7190 } 7191 }, 7192 7193 __response: function( content ) { 7194 var message; 7195 this._superApply( arguments ); 7196 if ( this.options.disabled || this.cancelSearch ) { 7197 return; 7198 } 7199 if ( content && content.length ) { 7200 message = this.options.messages.results( content.length ); 7201 } else { 7202 message = this.options.messages.noResults; 7203 } 7204 this.liveRegion.text( message ); 7205 } 7206}); 7207 7208}( jQuery ));
vendor: 9,663 bytes, lines 7209-7527
7209 7210(function( $, undefined ) { 7211 7212var lastActive, startXPos, startYPos, clickDragged, 7213 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 7214 stateClasses = "ui-state-hover ui-state-active ", 7215 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", 7216 formResetHandler = function() { 7217 var form = $( this ); 7218 setTimeout(function() { 7219 form.find( ":ui-button" ).button( "refresh" ); 7220 }, 1 ); 7221 }, 7222 radioGroup = function( radio ) { 7223 var name = radio.name, 7224 form = radio.form, 7225 radios = $( [] ); 7226 if ( name ) { 7227 name = name.replace( /'/g, "\\'" ); 7228 if ( form ) { 7229 radios = $( form ).find( "[name='" + name + "']" ); 7230 } else { 7231 radios = $( "[name='" + name + "']", radio.ownerDocument ) 7232 .filter(function() { 7233 return !this.form; 7234 }); 7235 } 7236 } 7237 return radios; 7238 }; 7239 7240$.widget( "ui.button", { 7241 version: "1.10.3", 7242 defaultElement: "<button>", 7243 options: { 7244 disabled: null, 7245 text: true, 7246 label: null, 7247 icons: { 7248 primary: null, 7249 secondary: null 7250 } 7251 }, 7252 _create: function() { 7253 this.element.closest( "form" ) 7254 .unbind( "reset" + this.eventNamespace ) 7255 .bind( "reset" + this.eventNamespace, formResetHandler ); 7256 7257 if ( typeof this.options.disabled !== "boolean" ) { 7258 this.options.disabled = !!this.element.prop( "disabled" ); 7259 } else { 7260 this.element.prop( "disabled", this.options.disabled ); 7261 } 7262 7263 this._determineButtonType(); 7264 this.hasTitle = !!this.buttonElement.attr( "title" ); 7265 7266 var that = this, 7267 options = this.options, 7268 toggleButton = this.type === "checkbox" || this.type === "radio", 7269 activeClass = !toggleButton ? "ui-state-active" : "", 7270 focusClass = "ui-state-focus"; 7271 7272 if ( options.label === null ) { 7273 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 7274 } 7275 7276 this._hoverable( this.buttonElement ); 7277 7278 this.buttonElement 7279 .addClass( baseClasses ) 7280 .attr( "role", "button" ) 7281 .bind( "mouseenter" + this.eventNamespace, function() { 7282 if ( options.disabled ) { 7283 return; 7284 } 7285 if ( this === lastActive ) { 7286 $( this ).addClass( "ui-state-active" ); 7287 } 7288 }) 7289 .bind( "mouseleave" + this.eventNamespace, function() { 7290 if ( options.disabled ) { 7291 return; 7292 } 7293 $( this ).removeClass( activeClass ); 7294 }) 7295 .bind( "click" + this.eventNamespace, function( event ) { 7296 if ( options.disabled ) { 7297 event.preventDefault(); 7298 event.stopImmediatePropagation(); 7299 } 7300 }); 7301 7302 this.element 7303 .bind( "focus" + this.eventNamespace, function() { 7304 // no need to check disabled, focus won't be triggered anyway 7305 that.buttonElement.addClass( focusClass ); 7306 }) 7307 .bind( "blur" + this.eventNamespace, function() { 7308 that.buttonElement.removeClass( focusClass ); 7309 }); 7310 7311 if ( toggleButton ) { 7312 this.element.bind( "change" + this.eventNamespace, function() { 7313 if ( clickDragged ) { 7314 return; 7315 } 7316 that.refresh(); 7317 }); 7318 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 7319 // prevents issue where button state changes but checkbox/radio checked state 7320 // does not in Firefox (see ticket #6970) 7321 this.buttonElement 7322 .bind( "mousedown" + this.eventNamespace, function( event ) { 7323 if ( options.disabled ) { 7324 return; 7325 } 7326 clickDragged = false; 7327 startXPos = event.pageX; 7328 startYPos = event.pageY; 7329 }) 7330 .bind( "mouseup" + this.eventNamespace, function( event ) { 7331 if ( options.disabled ) { 7332 return; 7333 } 7334 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 7335 clickDragged = true; 7336 } 7337 }); 7338 } 7339 7340 if ( this.type === "checkbox" ) { 7341 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7342 if ( options.disabled || clickDragged ) { 7343 return false; 7344 } 7345 }); 7346 } else if ( this.type === "radio" ) { 7347 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7348 if ( options.disabled || clickDragged ) { 7349 return false; 7350 } 7351 $( this ).addClass( "ui-state-active" ); 7352 that.buttonElement.attr( "aria-pressed", "true" ); 7353 7354 var radio = that.element[ 0 ]; 7355 radioGroup( radio ) 7356 .not( radio ) 7357 .map(function() { 7358 return $( this ).button( "widget" )[ 0 ]; 7359 }) 7360 .removeClass( "ui-state-active" ) 7361 .attr( "aria-pressed", "false" ); 7362 }); 7363 } else { 7364 this.buttonElement 7365 .bind( "mousedown" + this.eventNamespace, function() { 7366 if ( options.disabled ) { 7367 return false; 7368 } 7369 $( this ).addClass( "ui-state-active" ); 7370 lastActive = this; 7371 that.document.one( "mouseup", function() { 7372 lastActive = null; 7373 }); 7374 }) 7375 .bind( "mouseup" + this.eventNamespace, function() { 7376 if ( options.disabled ) { 7377 return false; 7378 } 7379 $( this ).removeClass( "ui-state-active" ); 7380 }) 7381 .bind( "keydown" + this.eventNamespace, function(event) { 7382 if ( options.disabled ) { 7383 return false; 7384 } 7385 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 7386 $( this ).addClass( "ui-state-active" ); 7387 } 7388 }) 7389 // see #8559, we bind to blur here in case the button element loses 7390 // focus between keydown and keyup, it would be left in an "active" state 7391 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 7392 $( this ).removeClass( "ui-state-active" ); 7393 }); 7394 7395 if ( this.buttonElement.is("a") ) { 7396 this.buttonElement.keyup(function(event) { 7397 if ( event.keyCode === $.ui.keyCode.SPACE ) { 7398 // TODO pass through original event correctly (just as 2nd argument doesn't work) 7399 $( this ).click(); 7400 } 7401 }); 7402 } 7403 } 7404 7405 // TODO: pull out $.Widget's handling for the disabled option into 7406 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 7407 // be overridden by individual plugins 7408 this._setOption( "disabled", options.disabled ); 7409 this._resetButton(); 7410 }, 7411 7412 _determineButtonType: function() { 7413 var ancestor, labelSelector, checked; 7414 7415 if ( this.element.is("[type=checkbox]") ) { 7416 this.type = "checkbox"; 7417 } else if ( this.element.is("[type=radio]") ) { 7418 this.type = "radio"; 7419 } else if ( this.element.is("input") ) { 7420 this.type = "input"; 7421 } else { 7422 this.type = "button"; 7423 } 7424 7425 if ( this.type === "checkbox" || this.type === "radio" ) { 7426 // we don't search against the document in case the element 7427 // is disconnected from the DOM 7428 ancestor = this.element.parents().last(); 7429 labelSelector = "label[for='" + this.element.attr("id") + "']"; 7430 this.buttonElement = ancestor.find( labelSelector ); 7431 if ( !this.buttonElement.length ) { 7432 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 7433 this.buttonElement = ancestor.filter( labelSelector ); 7434 if ( !this.buttonElement.length ) { 7435 this.buttonElement = ancestor.find( labelSelector ); 7436 } 7437 } 7438 this.element.addClass( "ui-helper-hidden-accessible" ); 7439 7440 checked = this.element.is( ":checked" ); 7441 if ( checked ) { 7442 this.buttonElement.addClass( "ui-state-active" ); 7443 } 7444 this.buttonElement.prop( "aria-pressed", checked ); 7445 } else { 7446 this.buttonElement = this.element; 7447 } 7448 }, 7449 7450 widget: function() { 7451 return this.buttonElement; 7452 }, 7453 7454 _destroy: function() { 7455 this.element 7456 .removeClass( "ui-helper-hidden-accessible" ); 7457 this.buttonElement 7458 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 7459 .removeAttr( "role" ) 7460 .removeAttr( "aria-pressed" ) 7461 .html( this.buttonElement.find(".ui-button-text").html() ); 7462 7463 if ( !this.hasTitle ) { 7464 this.buttonElement.removeAttr( "title" ); 7465 } 7466 }, 7467 7468 _setOption: function( key, value ) { 7469 this._super( key, value ); 7470 if ( key === "disabled" ) { 7471 if ( value ) { 7472 this.element.prop( "disabled", true ); 7473 } else { 7474 this.element.prop( "disabled", false ); 7475 } 7476 return; 7477 } 7478 this._resetButton(); 7479 }, 7480 7481 refresh: function() { 7482 //See #8237 & #8828 7483 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 7484 7485 if ( isDisabled !== this.options.disabled ) { 7486 this._setOption( "disabled", isDisabled ); 7487 } 7488 if ( this.type === "radio" ) { 7489 radioGroup( this.element[0] ).each(function() { 7490 if ( $( this ).is( ":checked" ) ) { 7491 $( this ).button( "widget" ) 7492 .addClass( "ui-state-active" ) 7493 .attr( "aria-pressed", "true" ); 7494 } else { 7495 $( this ).button( "widget" ) 7496 .removeClass( "ui-state-active" ) 7497 .attr( "aria-pressed", "false" ); 7498 } 7499 }); 7500 } else if ( this.type === "checkbox" ) { 7501 if ( this.element.is( ":checked" ) ) { 7502 this.buttonElement 7503 .addClass( "ui-state-active" ) 7504 .attr( "aria-pressed", "true" ); 7505 } else { 7506 this.buttonElement 7507 .removeClass( "ui-state-active" ) 7508 .attr( "aria-pressed", "false" ); 7509 } 7510 } 7511 }, 7512 7513 _resetButton: function() { 7514 if ( this.type === "input" ) { 7515 if ( this.options.label ) { 7516 this.element.val( this.options.label ); 7517 } 7518 return; 7519 } 7520 var buttonElement = this.buttonElement.removeClass( typeClasses ), 7521 buttonText = $( "<span></span>", this.document[0] ) 7522 .addClass( "ui-button-text" ) 7523 .html( this.options.label ) 7524 .appendTo( buttonElement.empty() ) 7525 .text(), 7526 icons = this.options.icons, 7527 multipleIcons = icons.primary && icons.secondary,
vendor: 5,498 bytes, lines 7528-7664
7528 buttonClasses = []; 7529 7530 if ( icons.primary || icons.secondary ) { 7531 if ( this.options.text ) { 7532 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 7533 } 7534 7535 if ( icons.primary ) { 7536 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 7537 } 7538 7539 if ( icons.secondary ) { 7540 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 7541 } 7542 7543 if ( !this.options.text ) { 7544 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 7545 7546 if ( !this.hasTitle ) { 7547 buttonElement.attr( "title", $.trim( buttonText ) ); 7548 } 7549 } 7550 } else { 7551 buttonClasses.push( "ui-button-text-only" ); 7552 } 7553 buttonElement.addClass( buttonClasses.join( " " ) ); 7554 } 7555}); 7556 7557$.widget( "ui.buttonset", { 7558 version: "1.10.3", 7559 options: { 7560 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 7561 }, 7562 7563 _create: function() { 7564 this.element.addClass( "ui-buttonset" ); 7565 }, 7566 7567 _init: function() { 7568 this.refresh(); 7569 }, 7570 7571 _setOption: function( key, value ) { 7572 if ( key === "disabled" ) { 7573 this.buttons.button( "option", key, value ); 7574 } 7575 7576 this._super( key, value ); 7577 }, 7578 7579 refresh: function() { 7580 var rtl = this.element.css( "direction" ) === "rtl"; 7581 7582 this.buttons = this.element.find( this.options.items ) 7583 .filter( ":ui-button" ) 7584 .button( "refresh" ) 7585 .end() 7586 .not( ":ui-button" ) 7587 .button() 7588 .end() 7589 .map(function() { 7590 return $( this ).button( "widget" )[ 0 ]; 7591 }) 7592 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 7593 .filter( ":first" ) 7594 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 7595 .end() 7596 .filter( ":last" ) 7597 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 7598 .end() 7599 .end(); 7600 }, 7601 7602 _destroy: function() { 7603 this.element.removeClass( "ui-buttonset" ); 7604 this.buttons 7605 .map(function() { 7606 return $( this ).button( "widget" )[ 0 ]; 7607 }) 7608 .removeClass( "ui-corner-left ui-corner-right" ) 7609 .end() 7610 .button( "destroy" ); 7611 } 7612}); 7613 7614}( jQuery ) ); 7615 7616(function( $, undefined ) { 7617 7618$.extend($.ui, { datepicker: { version: "1.10.3" } }); 7619 7620var PROP_NAME = "datepicker", 7621 instActive; 7622 7623/* Date picker manager. 7624 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7625 Settings for (groups of) date pickers are maintained in an instance object, 7626 allowing multiple different settings on the same page. */ 7627 7628function Datepicker() { 7629 this._curInst = null; // The current instance in use 7630 this._keyEvent = false; // If the last event was a key event 7631 this._disabledInputs = []; // List of date picker inputs that have been disabled 7632 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7633 this._inDialog = false; // True if showing within a "dialog", false if not 7634 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 7635 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 7636 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 7637 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 7638 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 7639 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 7640 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 7641 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 7642 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 7643 this.regional = []; // Available regional settings, indexed by language code 7644 this.regional[""] = { // Default regional settings 7645 closeText: "Done", // Display text for close link 7646 prevText: "Prev", // Display text for previous month link 7647 nextText: "Next", // Display text for next month link 7648 currentText: "Today", // Display text for current month link 7649 monthNames: ["January","February","March","April","May","June", 7650 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 7651 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 7652 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 7653 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 7654 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 7655 weekHeader: "Wk", // Column header for week of the year 7656 dateFormat: "mm/dd/yy", // See format options on parseDate 7657 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7658 isRTL: false, // True if right-to-left language, false if left-to-right 7659 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7660 yearSuffix: "" // Additional text to append to the year in the month headers 7661 }; 7662 this._defaults = { // Global defaults for all the date picker instances 7663 showOn: "focus", // "focus" for popup on focus, 7664 // "button" for trigger button, or "both" for either
vendor: 6,490 bytes, lines 7665-7794
7665 showAnim: "fadeIn", // Name of jQuery animation for popup 7666 showOptions: {}, // Options for enhanced animations 7667 defaultDate: null, // Used when field is blank: actual date, 7668 // +/-number for offset from today, null for today 7669 appendText: "", // Display text following the input box, e.g. showing the format 7670 buttonText: "...", // Text for trigger button 7671 buttonImage: "", // URL for trigger button image 7672 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7673 hideIfNoPrevNext: false, // True to hide next/previous month links 7674 // if not applicable, false to just disable them 7675 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7676 gotoCurrent: false, // True if today link goes back to current selection instead 7677 changeMonth: false, // True if month can be selected directly, false if only prev/next 7678 changeYear: false, // True if year can be selected directly, false if only prev/next 7679 yearRange: "c-10:c+10", // Range of years to display in drop-down, 7680 // either relative to today's year (-nn:+nn), relative to currently displayed year 7681 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7682 showOtherMonths: false, // True to show dates in other months, false to leave blank 7683 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7684 showWeek: false, // True to show week of the year, false to not show it 7685 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7686 // takes a Date and returns the number of the week for it 7687 shortYearCutoff: "+10", // Short year values < this are in the current century, 7688 // > this are in the previous century, 7689 // string value starting with "+" for current year + value 7690 minDate: null, // The earliest selectable date, or null for no limit 7691 maxDate: null, // The latest selectable date, or null for no limit 7692 duration: "fast", // Duration of display/closure 7693 beforeShowDay: null, // Function that takes a date and returns an array with 7694 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 7695 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7696 beforeShow: null, // Function that takes an input field and 7697 // returns a set of custom settings for the date picker 7698 onSelect: null, // Define a callback function when a date is selected 7699 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7700 onClose: null, // Define a callback function when the datepicker is closed 7701 numberOfMonths: 1, // Number of months to show at a time 7702 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7703 stepMonths: 1, // Number of months to step back/forward 7704 stepBigMonths: 12, // Number of months to step back/forward for the big links 7705 altField: "", // Selector for an alternate field to store selected dates into 7706 altFormat: "", // The date format to use for the alternate field 7707 constrainInput: true, // The input is constrained by the current date format 7708 showButtonPanel: false, // True to show button panel, false to not show it 7709 autoSize: false, // True to size the input for the date format, false to leave as is 7710 disabled: false // The initial disabled state 7711 }; 7712 $.extend(this._defaults, this.regional[""]); 7713 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 7714} 7715 7716$.extend(Datepicker.prototype, { 7717 /* Class name added to elements to indicate already configured with a date picker. */ 7718 markerClassName: "hasDatepicker", 7719 7720 //Keep track of the maximum number of rows displayed (see #7043) 7721 maxRows: 4, 7722 7723 // TODO rename to "widget" when switching to widget factory 7724 _widgetDatepicker: function() { 7725 return this.dpDiv; 7726 }, 7727 7728 /* Override the default settings for all instances of the date picker. 7729 * @param settings object - the new settings to use as defaults (anonymous object) 7730 * @return the manager object 7731 */ 7732 setDefaults: function(settings) { 7733 extendRemove(this._defaults, settings || {}); 7734 return this; 7735 }, 7736 7737 /* Attach the date picker to a jQuery selection. 7738 * @param target element - the target input field or division or span 7739 * @param settings object - the new settings to use for this date picker instance (anonymous) 7740 */ 7741 _attachDatepicker: function(target, settings) { 7742 var nodeName, inline, inst; 7743 nodeName = target.nodeName.toLowerCase(); 7744 inline = (nodeName === "div" || nodeName === "span"); 7745 if (!target.id) { 7746 this.uuid += 1; 7747 target.id = "dp" + this.uuid; 7748 } 7749 inst = this._newInst($(target), inline); 7750 inst.settings = $.extend({}, settings || {}); 7751 if (nodeName === "input") { 7752 this._connectDatepicker(target, inst); 7753 } else if (inline) { 7754 this._inlineDatepicker(target, inst); 7755 } 7756 }, 7757 7758 /* Create a new instance object. */ 7759 _newInst: function(target, inline) { 7760 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 7761 return {id: id, input: target, // associated target 7762 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 7763 drawMonth: 0, drawYear: 0, // month being drawn 7764 inline: inline, // is datepicker inline or not 7765 dpDiv: (!inline ? this.dpDiv : // presentation div 7766 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 7767 }, 7768 7769 /* Attach the date picker to an input field. */ 7770 _connectDatepicker: function(target, inst) { 7771 var input = $(target); 7772 inst.append = $([]); 7773 inst.trigger = $([]); 7774 if (input.hasClass(this.markerClassName)) { 7775 return; 7776 } 7777 this._attachments(input, inst); 7778 input.addClass(this.markerClassName).keydown(this._doKeyDown). 7779 keypress(this._doKeyPress).keyup(this._doKeyUp); 7780 this._autoSize(inst); 7781 $.data(target, PROP_NAME, inst); 7782 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 7783 if( inst.settings.disabled ) { 7784 this._disableDatepicker( target ); 7785 } 7786 }, 7787 7788 /* Make attachments based on settings. */ 7789 _attachments: function(input, inst) { 7790 var showOn, buttonText, buttonImage, 7791 appendText = this._get(inst, "appendText"), 7792 isRTL = this._get(inst, "isRTL"); 7793 7794 if (inst.append) {
vendor: 5,933 bytes, lines 7795-7950
7795 inst.append.remove(); 7796 } 7797 if (appendText) { 7798 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 7799 input[isRTL ? "before" : "after"](inst.append); 7800 } 7801 7802 input.unbind("focus", this._showDatepicker); 7803 7804 if (inst.trigger) { 7805 inst.trigger.remove(); 7806 } 7807 7808 showOn = this._get(inst, "showOn"); 7809 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 7810 input.focus(this._showDatepicker); 7811 } 7812 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 7813 buttonText = this._get(inst, "buttonText"); 7814 buttonImage = this._get(inst, "buttonImage"); 7815 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 7816 $("<img/>").addClass(this._triggerClass). 7817 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 7818 $("<button type='button'></button>").addClass(this._triggerClass). 7819 html(!buttonImage ? buttonText : $("<img/>").attr( 7820 { src:buttonImage, alt:buttonText, title:buttonText }))); 7821 input[isRTL ? "before" : "after"](inst.trigger); 7822 inst.trigger.click(function() { 7823 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 7824 $.datepicker._hideDatepicker(); 7825 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 7826 $.datepicker._hideDatepicker(); 7827 $.datepicker._showDatepicker(input[0]); 7828 } else { 7829 $.datepicker._showDatepicker(input[0]); 7830 } 7831 return false; 7832 }); 7833 } 7834 }, 7835 7836 /* Apply the maximum length for the date format. */ 7837 _autoSize: function(inst) { 7838 if (this._get(inst, "autoSize") && !inst.inline) { 7839 var findMax, max, maxI, i, 7840 date = new Date(2009, 12 - 1, 20), // Ensure double digits 7841 dateFormat = this._get(inst, "dateFormat"); 7842 7843 if (dateFormat.match(/[DM]/)) { 7844 findMax = function(names) { 7845 max = 0; 7846 maxI = 0; 7847 for (i = 0; i < names.length; i++) { 7848 if (names[i].length > max) { 7849 max = names[i].length; 7850 maxI = i; 7851 } 7852 } 7853 return maxI; 7854 }; 7855 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7856 "monthNames" : "monthNamesShort")))); 7857 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7858 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 7859 } 7860 inst.input.attr("size", this._formatDate(inst, date).length); 7861 } 7862 }, 7863 7864 /* Attach an inline date picker to a div. */ 7865 _inlineDatepicker: function(target, inst) { 7866 var divSpan = $(target); 7867 if (divSpan.hasClass(this.markerClassName)) { 7868 return; 7869 } 7870 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 7871 $.data(target, PROP_NAME, inst); 7872 this._setDate(inst, this._getDefaultDate(inst), true); 7873 this._updateDatepicker(inst); 7874 this._updateAlternate(inst); 7875 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7876 if( inst.settings.disabled ) { 7877 this._disableDatepicker( target ); 7878 } 7879 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7880 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7881 inst.dpDiv.css( "display", "block" ); 7882 }, 7883 7884 /* Pop-up the date picker in a "dialog" box. 7885 * @param input element - ignored 7886 * @param date string or Date - the initial date to display 7887 * @param onSelect function - the function to call when a date is selected 7888 * @param settings object - update the dialog date picker instance's settings (anonymous object) 7889 * @param pos int[2] - coordinates for the dialog's position within the screen or 7890 * event - with x/y coordinates or 7891 * leave empty for default (screen centre) 7892 * @return the manager object 7893 */ 7894 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 7895 var id, browserWidth, browserHeight, scrollX, scrollY, 7896 inst = this._dialogInst; // internal instance 7897 7898 if (!inst) { 7899 this.uuid += 1; 7900 id = "dp" + this.uuid; 7901 this._dialogInput = $("<input type='text' id='" + id + 7902 "' style='position: absolute; top: -100px; width: 0px;'/>"); 7903 this._dialogInput.keydown(this._doKeyDown); 7904 $("body").append(this._dialogInput); 7905 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7906 inst.settings = {}; 7907 $.data(this._dialogInput[0], PROP_NAME, inst); 7908 } 7909 extendRemove(inst.settings, settings || {}); 7910 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 7911 this._dialogInput.val(date); 7912 7913 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7914 if (!this._pos) { 7915 browserWidth = document.documentElement.clientWidth; 7916 browserHeight = document.documentElement.clientHeight; 7917 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7918 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7919 this._pos = // should use actual width/height below 7920 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7921 } 7922 7923 // move input on screen for focus, but hidden behind dialog 7924 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 7925 inst.settings.onSelect = onSelect; 7926 this._inDialog = true; 7927 this.dpDiv.addClass(this._dialogClass); 7928 this._showDatepicker(this._dialogInput[0]); 7929 if ($.blockUI) { 7930 $.blockUI(this.dpDiv); 7931 } 7932 $.data(this._dialogInput[0], PROP_NAME, inst); 7933 return this; 7934 }, 7935 7936 /* Detach a datepicker from its control. 7937 * @param target element - the target input field or division or span 7938 */ 7939 _destroyDatepicker: function(target) { 7940 var nodeName, 7941 $target = $(target), 7942 inst = $.data(target, PROP_NAME); 7943 7944 if (!$target.hasClass(this.markerClassName)) { 7945 return; 7946 } 7947 7948 nodeName = target.nodeName.toLowerCase(); 7949 $.removeData(target, PROP_NAME); 7950 if (nodeName === "input") {
vendor: 11,661 bytes, lines 7951-8282
7951 inst.append.remove(); 7952 inst.trigger.remove(); 7953 $target.removeClass(this.markerClassName). 7954 unbind("focus", this._showDatepicker). 7955 unbind("keydown", this._doKeyDown). 7956 unbind("keypress", this._doKeyPress). 7957 unbind("keyup", this._doKeyUp); 7958 } else if (nodeName === "div" || nodeName === "span") { 7959 $target.removeClass(this.markerClassName).empty(); 7960 } 7961 }, 7962 7963 /* Enable the date picker to a jQuery selection. 7964 * @param target element - the target input field or division or span 7965 */ 7966 _enableDatepicker: 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 = false; 7978 inst.trigger.filter("button"). 7979 each(function() { this.disabled = false; }).end(). 7980 filter("img").css({opacity: "1.0", cursor: ""}); 7981 } else if (nodeName === "div" || nodeName === "span") { 7982 inline = $target.children("." + this._inlineClass); 7983 inline.children().removeClass("ui-state-disabled"); 7984 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7985 prop("disabled", false); 7986 } 7987 this._disabledInputs = $.map(this._disabledInputs, 7988 function(value) { return (value === target ? null : value); }); // delete entry 7989 }, 7990 7991 /* Disable the date picker to a jQuery selection. 7992 * @param target element - the target input field or division or span 7993 */ 7994 _disableDatepicker: function(target) { 7995 var nodeName, inline, 7996 $target = $(target), 7997 inst = $.data(target, PROP_NAME); 7998 7999 if (!$target.hasClass(this.markerClassName)) { 8000 return; 8001 } 8002 8003 nodeName = target.nodeName.toLowerCase(); 8004 if (nodeName === "input") { 8005 target.disabled = true; 8006 inst.trigger.filter("button"). 8007 each(function() { this.disabled = true; }).end(). 8008 filter("img").css({opacity: "0.5", cursor: "default"}); 8009 } else if (nodeName === "div" || nodeName === "span") { 8010 inline = $target.children("." + this._inlineClass); 8011 inline.children().addClass("ui-state-disabled"); 8012 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 8013 prop("disabled", true); 8014 } 8015 this._disabledInputs = $.map(this._disabledInputs, 8016 function(value) { return (value === target ? null : value); }); // delete entry 8017 this._disabledInputs[this._disabledInputs.length] = target; 8018 }, 8019 8020 /* Is the first field in a jQuery collection disabled as a datepicker? 8021 * @param target element - the target input field or division or span 8022 * @return boolean - true if disabled, false if enabled 8023 */ 8024 _isDisabledDatepicker: function(target) { 8025 if (!target) { 8026 return false; 8027 } 8028 for (var i = 0; i < this._disabledInputs.length; i++) { 8029 if (this._disabledInputs[i] === target) { 8030 return true; 8031 } 8032 } 8033 return false; 8034 }, 8035 8036 /* Retrieve the instance data for the target control. 8037 * @param target element - the target input field or division or span 8038 * @return object - the associated instance data 8039 * @throws error if a jQuery problem getting data 8040 */ 8041 _getInst: function(target) { 8042 try { 8043 return $.data(target, PROP_NAME); 8044 } 8045 catch (err) { 8046 throw "Missing instance data for this datepicker"; 8047 } 8048 }, 8049 8050 /* Update or retrieve the settings for a date picker attached to an input field or division. 8051 * @param target element - the target input field or division or span 8052 * @param name object - the new settings to update or 8053 * string - the name of the setting to change or retrieve, 8054 * when retrieving also "all" for all instance settings or 8055 * "defaults" for all global defaults 8056 * @param value any - the new value for the setting 8057 * (omit if above is an object or to retrieve a value) 8058 */ 8059 _optionDatepicker: function(target, name, value) { 8060 var settings, date, minDate, maxDate, 8061 inst = this._getInst(target); 8062 8063 if (arguments.length === 2 && typeof name === "string") { 8064 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 8065 (inst ? (name === "all" ? $.extend({}, inst.settings) : 8066 this._get(inst, name)) : null)); 8067 } 8068 8069 settings = name || {}; 8070 if (typeof name === "string") { 8071 settings = {}; 8072 settings[name] = value; 8073 } 8074 8075 if (inst) { 8076 if (this._curInst === inst) { 8077 this._hideDatepicker(); 8078 } 8079 8080 date = this._getDateDatepicker(target, true); 8081 minDate = this._getMinMaxDate(inst, "min"); 8082 maxDate = this._getMinMaxDate(inst, "max"); 8083 extendRemove(inst.settings, settings); 8084 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 8085 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 8086 inst.settings.minDate = this._formatDate(inst, minDate); 8087 } 8088 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 8089 inst.settings.maxDate = this._formatDate(inst, maxDate); 8090 } 8091 if ( "disabled" in settings ) { 8092 if ( settings.disabled ) { 8093 this._disableDatepicker(target); 8094 } else { 8095 this._enableDatepicker(target); 8096 } 8097 } 8098 this._attachments($(target), inst); 8099 this._autoSize(inst); 8100 this._setDate(inst, date); 8101 this._updateAlternate(inst); 8102 this._updateDatepicker(inst); 8103 } 8104 }, 8105 8106 // change method deprecated 8107 _changeDatepicker: function(target, name, value) { 8108 this._optionDatepicker(target, name, value); 8109 }, 8110 8111 /* Redraw the date picker attached to an input field or division. 8112 * @param target element - the target input field or division or span 8113 */ 8114 _refreshDatepicker: function(target) { 8115 var inst = this._getInst(target); 8116 if (inst) { 8117 this._updateDatepicker(inst); 8118 } 8119 }, 8120 8121 /* Set the dates for a jQuery selection. 8122 * @param target element - the target input field or division or span 8123 * @param date Date - the new date 8124 */ 8125 _setDateDatepicker: function(target, date) { 8126 var inst = this._getInst(target); 8127 if (inst) { 8128 this._setDate(inst, date); 8129 this._updateDatepicker(inst); 8130 this._updateAlternate(inst); 8131 } 8132 }, 8133 8134 /* Get the date(s) for the first entry in a jQuery selection. 8135 * @param target element - the target input field or division or span 8136 * @param noDefault boolean - true if no default date is to be used 8137 * @return Date - the current date 8138 */ 8139 _getDateDatepicker: function(target, noDefault) { 8140 var inst = this._getInst(target); 8141 if (inst && !inst.inline) { 8142 this._setDateFromField(inst, noDefault); 8143 } 8144 return (inst ? this._getDate(inst) : null); 8145 }, 8146 8147 /* Handle keystrokes. */ 8148 _doKeyDown: function(event) { 8149 var onSelect, dateStr, sel, 8150 inst = $.datepicker._getInst(event.target), 8151 handled = true, 8152 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 8153 8154 inst._keyEvent = true; 8155 if ($.datepicker._datepickerShowing) { 8156 switch (event.keyCode) { 8157 case 9: $.datepicker._hideDatepicker(); 8158 handled = false; 8159 break; // hide on tab out 8160 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 8161 $.datepicker._currentClass + ")", inst.dpDiv); 8162 if (sel[0]) { 8163 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 8164 } 8165 8166 onSelect = $.datepicker._get(inst, "onSelect"); 8167 if (onSelect) { 8168 dateStr = $.datepicker._formatDate(inst); 8169 8170 // trigger custom callback 8171 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 8172 } else { 8173 $.datepicker._hideDatepicker(); 8174 } 8175 8176 return false; // don't submit the form 8177 case 27: $.datepicker._hideDatepicker(); 8178 break; // hide on escape 8179 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8180 -$.datepicker._get(inst, "stepBigMonths") : 8181 -$.datepicker._get(inst, "stepMonths")), "M"); 8182 break; // previous month/year on page up/+ ctrl 8183 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8184 +$.datepicker._get(inst, "stepBigMonths") : 8185 +$.datepicker._get(inst, "stepMonths")), "M"); 8186 break; // next month/year on page down/+ ctrl 8187 case 35: if (event.ctrlKey || event.metaKey) { 8188 $.datepicker._clearDate(event.target); 8189 } 8190 handled = event.ctrlKey || event.metaKey; 8191 break; // clear on ctrl or command +end 8192 case 36: if (event.ctrlKey || event.metaKey) { 8193 $.datepicker._gotoToday(event.target); 8194 } 8195 handled = event.ctrlKey || event.metaKey; 8196 break; // current on ctrl or command +home 8197 case 37: if (event.ctrlKey || event.metaKey) { 8198 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 8199 } 8200 handled = event.ctrlKey || event.metaKey; 8201 // -1 day on ctrl or command +left 8202 if (event.originalEvent.altKey) { 8203 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8204 -$.datepicker._get(inst, "stepBigMonths") : 8205 -$.datepicker._get(inst, "stepMonths")), "M"); 8206 } 8207 // next month/year on alt +left on Mac 8208 break; 8209 case 38: if (event.ctrlKey || event.metaKey) { 8210 $.datepicker._adjustDate(event.target, -7, "D"); 8211 } 8212 handled = event.ctrlKey || event.metaKey; 8213 break; // -1 week on ctrl or command +up 8214 case 39: if (event.ctrlKey || event.metaKey) { 8215 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 8216 } 8217 handled = event.ctrlKey || event.metaKey; 8218 // +1 day on ctrl or command +right 8219 if (event.originalEvent.altKey) { 8220 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8221 +$.datepicker._get(inst, "stepBigMonths") : 8222 +$.datepicker._get(inst, "stepMonths")), "M"); 8223 } 8224 // next month/year on alt +right 8225 break; 8226 case 40: if (event.ctrlKey || event.metaKey) { 8227 $.datepicker._adjustDate(event.target, +7, "D"); 8228 } 8229 handled = event.ctrlKey || event.metaKey; 8230 break; // +1 week on ctrl or command +down 8231 default: handled = false; 8232 } 8233 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 8234 $.datepicker._showDatepicker(this); 8235 } else { 8236 handled = false; 8237 } 8238 8239 if (handled) { 8240 event.preventDefault(); 8241 event.stopPropagation(); 8242 } 8243 }, 8244 8245 /* Filter entered characters - based on date format. */ 8246 _doKeyPress: function(event) { 8247 var chars, chr, 8248 inst = $.datepicker._getInst(event.target); 8249 8250 if ($.datepicker._get(inst, "constrainInput")) { 8251 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 8252 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 8253 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 8254 } 8255 }, 8256 8257 /* Synchronise manual entry and field/alternate field. */ 8258 _doKeyUp: function(event) { 8259 var date, 8260 inst = $.datepicker._getInst(event.target); 8261 8262 if (inst.input.val() !== inst.lastVal) { 8263 try { 8264 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8265 (inst.input ? inst.input.val() : null), 8266 $.datepicker._getFormatConfig(inst)); 8267 8268 if (date) { // only if valid 8269 $.datepicker._setDateFromField(inst); 8270 $.datepicker._updateAlternate(inst); 8271 $.datepicker._updateDatepicker(inst); 8272 } 8273 } 8274 catch (err) { 8275 } 8276 } 8277 return true; 8278 }, 8279 8280 /* Pop-up the date picker for a given input field. 8281 * If false returned from beforeShow event handler do not show. 8282 * @param input element - the input field attached to the date picker or
vendor: 9,513 bytes, lines 8283-8553
8283 * event - if triggered by focus 8284 */ 8285 _showDatepicker: function(input) { 8286 input = input.target || input; 8287 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 8288 input = $("input", input.parentNode)[0]; 8289 } 8290 8291 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 8292 return; 8293 } 8294 8295 var inst, beforeShow, beforeShowSettings, isFixed, 8296 offset, showAnim, duration; 8297 8298 inst = $.datepicker._getInst(input); 8299 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 8300 $.datepicker._curInst.dpDiv.stop(true, true); 8301 if ( inst && $.datepicker._datepickerShowing ) { 8302 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 8303 } 8304 } 8305 8306 beforeShow = $.datepicker._get(inst, "beforeShow"); 8307 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 8308 if(beforeShowSettings === false){ 8309 return; 8310 } 8311 extendRemove(inst.settings, beforeShowSettings); 8312 8313 inst.lastVal = null; 8314 $.datepicker._lastInput = input; 8315 $.datepicker._setDateFromField(inst); 8316 8317 if ($.datepicker._inDialog) { // hide cursor 8318 input.value = ""; 8319 } 8320 if (!$.datepicker._pos) { // position below input 8321 $.datepicker._pos = $.datepicker._findPos(input); 8322 $.datepicker._pos[1] += input.offsetHeight; // add the height 8323 } 8324 8325 isFixed = false; 8326 $(input).parents().each(function() { 8327 isFixed |= $(this).css("position") === "fixed"; 8328 return !isFixed; 8329 }); 8330 8331 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 8332 $.datepicker._pos = null; 8333 //to avoid flashes on Firefox 8334 inst.dpDiv.empty(); 8335 // determine sizing offscreen 8336 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 8337 $.datepicker._updateDatepicker(inst); 8338 // fix width for dynamic number of date pickers 8339 // and adjust position before showing 8340 offset = $.datepicker._checkOffset(inst, offset, isFixed); 8341 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 8342 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 8343 left: offset.left + "px", top: offset.top + "px"}); 8344 8345 if (!inst.inline) { 8346 showAnim = $.datepicker._get(inst, "showAnim"); 8347 duration = $.datepicker._get(inst, "duration"); 8348 inst.dpDiv.zIndex($(input).zIndex()+1); 8349 $.datepicker._datepickerShowing = true; 8350 8351 if ( $.effects && $.effects.effect[ showAnim ] ) { 8352 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 8353 } else { 8354 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 8355 } 8356 8357 if ( $.datepicker._shouldFocusInput( inst ) ) { 8358 inst.input.focus(); 8359 } 8360 8361 $.datepicker._curInst = inst; 8362 } 8363 }, 8364 8365 /* Generate the date picker content. */ 8366 _updateDatepicker: function(inst) { 8367 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8368 instActive = inst; // for delegate hover events 8369 inst.dpDiv.empty().append(this._generateHTML(inst)); 8370 this._attachHandlers(inst); 8371 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 8372 8373 var origyearshtml, 8374 numMonths = this._getNumberOfMonths(inst), 8375 cols = numMonths[1], 8376 width = 17; 8377 8378 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 8379 if (cols > 1) { 8380 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 8381 } 8382 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 8383 "Class"]("ui-datepicker-multi"); 8384 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 8385 "Class"]("ui-datepicker-rtl"); 8386 8387 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 8388 inst.input.focus(); 8389 } 8390 8391 // deffered render of the years select (to avoid flashes on Firefox) 8392 if( inst.yearshtml ){ 8393 origyearshtml = inst.yearshtml; 8394 setTimeout(function(){ 8395 //assure that inst.yearshtml didn't change. 8396 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 8397 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 8398 } 8399 origyearshtml = inst.yearshtml = null; 8400 }, 0); 8401 } 8402 }, 8403 8404 // #6694 - don't focus the input if it's already focused 8405 // this breaks the change event in IE 8406 // Support: IE and jQuery <1.9 8407 _shouldFocusInput: function( inst ) { 8408 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 8409 }, 8410 8411 /* Check positioning to remain on screen. */ 8412 _checkOffset: function(inst, offset, isFixed) { 8413 var dpWidth = inst.dpDiv.outerWidth(), 8414 dpHeight = inst.dpDiv.outerHeight(), 8415 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8416 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8417 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 8418 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 8419 8420 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 8421 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 8422 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 8423 8424 // now check if datepicker is showing outside window viewport - move to a better place if so. 8425 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 8426 Math.abs(offset.left + dpWidth - viewWidth) : 0); 8427 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 8428 Math.abs(dpHeight + inputHeight) : 0); 8429 8430 return offset; 8431 }, 8432 8433 /* Find an object's position on the screen. */ 8434 _findPos: function(obj) { 8435 var position, 8436 inst = this._getInst(obj), 8437 isRTL = this._get(inst, "isRTL"); 8438 8439 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 8440 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 8441 } 8442 8443 position = $(obj).offset(); 8444 return [position.left, position.top]; 8445 }, 8446 8447 /* Hide the date picker from view. 8448 * @param input element - the input field attached to the date picker 8449 */ 8450 _hideDatepicker: function(input) { 8451 var showAnim, duration, postProcess, onClose, 8452 inst = this._curInst; 8453 8454 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { 8455 return; 8456 } 8457 8458 if (this._datepickerShowing) { 8459 showAnim = this._get(inst, "showAnim"); 8460 duration = this._get(inst, "duration"); 8461 postProcess = function() { 8462 $.datepicker._tidyDialog(inst); 8463 }; 8464 8465 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8466 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 8467 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 8468 } else { 8469 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 8470 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 8471 } 8472 8473 if (!showAnim) { 8474 postProcess(); 8475 } 8476 this._datepickerShowing = false; 8477 8478 onClose = this._get(inst, "onClose"); 8479 if (onClose) { 8480 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 8481 } 8482 8483 this._lastInput = null; 8484 if (this._inDialog) { 8485 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 8486 if ($.blockUI) { 8487 $.unblockUI(); 8488 $("body").append(this.dpDiv); 8489 } 8490 } 8491 this._inDialog = false; 8492 } 8493 }, 8494 8495 /* Tidy up after a dialog display. */ 8496 _tidyDialog: function(inst) { 8497 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 8498 }, 8499 8500 /* Close date picker if clicked elsewhere. */ 8501 _checkExternalClick: function(event) { 8502 if (!$.datepicker._curInst) { 8503 return; 8504 } 8505 8506 var $target = $(event.target), 8507 inst = $.datepicker._getInst($target[0]); 8508 8509 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 8510 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 8511 !$target.hasClass($.datepicker.markerClassName) && 8512 !$target.closest("." + $.datepicker._triggerClass).length && 8513 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 8514 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 8515 $.datepicker._hideDatepicker(); 8516 } 8517 }, 8518 8519 /* Adjust one of the date sub-fields. */ 8520 _adjustDate: function(id, offset, period) { 8521 var target = $(id), 8522 inst = this._getInst(target[0]); 8523 8524 if (this._isDisabledDatepicker(target[0])) { 8525 return; 8526 } 8527 this._adjustInstDate(inst, offset + 8528 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 8529 period); 8530 this._updateDatepicker(inst); 8531 }, 8532 8533 /* Action for current link. */ 8534 _gotoToday: function(id) { 8535 var date, 8536 target = $(id), 8537 inst = this._getInst(target[0]); 8538 8539 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 8540 inst.selectedDay = inst.currentDay; 8541 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8542 inst.drawYear = inst.selectedYear = inst.currentYear; 8543 } else { 8544 date = new Date(); 8545 inst.selectedDay = date.getDate(); 8546 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8547 inst.drawYear = inst.selectedYear = date.getFullYear(); 8548 } 8549 this._notifyChange(inst); 8550 this._adjustDate(target); 8551 }, 8552 8553 /* Action for selecting a new month/year. */
vendor: 4,567 bytes, lines 8554-8685
8554 _selectMonthYear: function(id, select, period) { 8555 var target = $(id), 8556 inst = this._getInst(target[0]); 8557 8558 inst["selected" + (period === "M" ? "Month" : "Year")] = 8559 inst["draw" + (period === "M" ? "Month" : "Year")] = 8560 parseInt(select.options[select.selectedIndex].value,10); 8561 8562 this._notifyChange(inst); 8563 this._adjustDate(target); 8564 }, 8565 8566 /* Action for selecting a day. */ 8567 _selectDay: function(id, month, year, td) { 8568 var inst, 8569 target = $(id); 8570 8571 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8572 return; 8573 } 8574 8575 inst = this._getInst(target[0]); 8576 inst.selectedDay = inst.currentDay = $("a", td).html(); 8577 inst.selectedMonth = inst.currentMonth = month; 8578 inst.selectedYear = inst.currentYear = year; 8579 this._selectDate(id, this._formatDate(inst, 8580 inst.currentDay, inst.currentMonth, inst.currentYear)); 8581 }, 8582 8583 /* Erase the input field and hide the date picker. */ 8584 _clearDate: function(id) { 8585 var target = $(id); 8586 this._selectDate(target, ""); 8587 }, 8588 8589 /* Update the input field with the selected date. */ 8590 _selectDate: function(id, dateStr) { 8591 var onSelect, 8592 target = $(id), 8593 inst = this._getInst(target[0]); 8594 8595 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 8596 if (inst.input) { 8597 inst.input.val(dateStr); 8598 } 8599 this._updateAlternate(inst); 8600 8601 onSelect = this._get(inst, "onSelect"); 8602 if (onSelect) { 8603 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 8604 } else if (inst.input) { 8605 inst.input.trigger("change"); // fire the change event 8606 } 8607 8608 if (inst.inline){ 8609 this._updateDatepicker(inst); 8610 } else { 8611 this._hideDatepicker(); 8612 this._lastInput = inst.input[0]; 8613 if (typeof(inst.input[0]) !== "object") { 8614 inst.input.focus(); // restore focus 8615 } 8616 this._lastInput = null; 8617 } 8618 }, 8619 8620 /* Update any alternate field to synchronise with the main field. */ 8621 _updateAlternate: function(inst) { 8622 var altFormat, date, dateStr, 8623 altField = this._get(inst, "altField"); 8624 8625 if (altField) { // update alternate field too 8626 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 8627 date = this._getDate(inst); 8628 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 8629 $(altField).each(function() { $(this).val(dateStr); }); 8630 } 8631 }, 8632 8633 /* Set as beforeShowDay function to prevent selection of weekends. 8634 * @param date Date - the date to customise 8635 * @return [boolean, string] - is this date selectable?, what is its CSS class? 8636 */ 8637 noWeekends: function(date) { 8638 var day = date.getDay(); 8639 return [(day > 0 && day < 6), ""]; 8640 }, 8641 8642 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8643 * @param date Date - the date to get the week for 8644 * @return number - the number of the week within the year that contains this date 8645 */ 8646 iso8601Week: function(date) { 8647 var time, 8648 checkDate = new Date(date.getTime()); 8649 8650 // Find Thursday of this week starting on Monday 8651 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 8652 8653 time = checkDate.getTime(); 8654 checkDate.setMonth(0); // Compare with Jan 1 8655 checkDate.setDate(1); 8656 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 8657 }, 8658 8659 /* Parse a string value into a date object. 8660 * See formatDate below for the possible formats. 8661 * 8662 * @param format string - the expected format of the date 8663 * @param value string - the date in the above format 8664 * @param settings Object - attributes include: 8665 * shortYearCutoff number - the cutoff year for determining the century (optional) 8666 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8667 * dayNames string[7] - names of the days from Sunday (optional) 8668 * monthNamesShort string[12] - abbreviated names of the months (optional) 8669 * monthNames string[12] - names of the months (optional) 8670 * @return Date - the extracted date value or null if value is blank 8671 */ 8672 parseDate: function (format, value, settings) { 8673 if (format == null || value == null) { 8674 throw "Invalid arguments"; 8675 } 8676 8677 value = (typeof value === "object" ? value.toString() : value + ""); 8678 if (value === "") { 8679 return null; 8680 } 8681 8682 var iFormat, dim, extra, 8683 iValue = 0, 8684 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 8685 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 5,390 bytes, lines 8685-8870
8685: 8686 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 8687 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8688 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8689 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8690 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8691 year = -1, 8692 month = -1, 8693 day = -1, 8694 doy = -1, 8695 literal = false, 8696 date, 8697 // Check whether a format character is doubled 8698 lookAhead = function(match) { 8699 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8700 if (matches) { 8701 iFormat++; 8702 } 8703 return matches; 8704 }, 8705 // Extract a number from the string value 8706 getNumber = function(match) { 8707 var isDoubled = lookAhead(match), 8708 size = (match === "@" ? 14 : (match === "!" ? 20 : 8709 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 8710 digits = new RegExp("^\\d{1," + size + "}"), 8711 num = value.substring(iValue).match(digits); 8712 if (!num) { 8713 throw "Missing number at position " + iValue; 8714 } 8715 iValue += num[0].length; 8716 return parseInt(num[0], 10); 8717 }, 8718 // Extract a name from the string value and convert to an index 8719 getName = function(match, shortNames, longNames) { 8720 var index = -1, 8721 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 8722 return [ [k, v] ]; 8723 }).sort(function (a, b) { 8724 return -(a[1].length - b[1].length); 8725 }); 8726 8727 $.each(names, function (i, pair) { 8728 var name = pair[1]; 8729 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 8730 index = pair[0]; 8731 iValue += name.length; 8732 return false; 8733 } 8734 }); 8735 if (index !== -1) { 8736 return index + 1; 8737 } else { 8738 throw "Unknown name at position " + iValue; 8739 } 8740 }, 8741 // Confirm that a literal character matches the string value 8742 checkLiteral = function() { 8743 if (value.charAt(iValue) !== format.charAt(iFormat)) { 8744 throw "Unexpected literal at position " + iValue; 8745 } 8746 iValue++; 8747 }; 8748 8749 for (iFormat = 0; iFormat < format.length; iFormat++) { 8750 if (literal) { 8751 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8752 literal = false; 8753 } else { 8754 checkLiteral(); 8755 } 8756 } else { 8757 switch (format.charAt(iFormat)) { 8758 case "d": 8759 day = getNumber("d"); 8760 break; 8761 case "D": 8762 getName("D", dayNamesShort, dayNames); 8763 break; 8764 case "o": 8765 doy = getNumber("o"); 8766 break; 8767 case "m": 8768 month = getNumber("m"); 8769 break; 8770 case "M": 8771 month = getName("M", monthNamesShort, monthNames); 8772 break; 8773 case "y": 8774 year = getNumber("y"); 8775 break; 8776 case "@": 8777 date = new Date(getNumber("@")); 8778 year = date.getFullYear(); 8779 month = date.getMonth() + 1; 8780 day = date.getDate(); 8781 break; 8782 case "!": 8783 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 8784 year = date.getFullYear(); 8785 month = date.getMonth() + 1; 8786 day = date.getDate(); 8787 break; 8788 case "'": 8789 if (lookAhead("'")){ 8790 checkLiteral(); 8791 } else { 8792 literal = true; 8793 } 8794 break; 8795 default: 8796 checkLiteral(); 8797 } 8798 } 8799 } 8800 8801 if (iValue < value.length){ 8802 extra = value.substr(iValue); 8803 if (!/^\s+/.test(extra)) { 8804 throw "Extra/unparsed characters found in date: " + extra; 8805 } 8806 } 8807 8808 if (year === -1) { 8809 year = new Date().getFullYear(); 8810 } else if (year < 100) { 8811 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8812 (year <= shortYearCutoff ? 0 : -100); 8813 } 8814 8815 if (doy > -1) { 8816 month = 1; 8817 day = doy; 8818 do { 8819 dim = this._getDaysInMonth(year, month - 1); 8820 if (day <= dim) { 8821 break; 8822 } 8823 month++; 8824 day -= dim; 8825 } while (true); 8826 } 8827 8828 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 8829 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 8830 throw "Invalid date"; // E.g. 31/02/00 8831 } 8832 return date; 8833 }, 8834 8835 /* Standard date formats. */ 8836 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 8837 COOKIE: "D, dd M yy", 8838 ISO_8601: "yy-mm-dd", 8839 RFC_822: "D, d M y", 8840 RFC_850: "DD, dd-M-y", 8841 RFC_1036: "D, d M y", 8842 RFC_1123: "D, d M yy", 8843 RFC_2822: "D, d M yy", 8844 RSS: "D, d M y", // RFC 822 8845 TICKS: "!", 8846 TIMESTAMP: "@", 8847 W3C: "yy-mm-dd", // ISO 8601 8848 8849 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8850 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8851 8852 /* Format a date object into a string value. 8853 * The format can be combinations of the following: 8854 * d - day of month (no leading zero) 8855 * dd - day of month (two digit) 8856 * o - day of year (no leading zeros) 8857 * oo - day of year (three digit) 8858 * D - day name short 8859 * DD - day name long 8860 * m - month of year (no leading zero) 8861 * mm - month of year (two digit) 8862 * M - month name short 8863 * MM - month name long 8864 * y - year (two digit) 8865 * yy - year (four digit) 8866 * @ - Unix timestamp (ms since 01/01/1970) 8867 * ! - Windows ticks (100ns since 01/01/0001) 8868 * "..." - literal text 8869 * '' - single quote 8870 *
vendor: 10,316 bytes, lines 8871-9185
8871 * @param format string - the desired format of the date 8872 * @param date Date - the date value to format 8873 * @param settings Object - attributes include: 8874 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8875 * dayNames string[7] - names of the days from Sunday (optional) 8876 * monthNamesShort string[12] - abbreviated names of the months (optional) 8877 * monthNames string[12] - names of the months (optional) 8878 * @return string - the date in the above format 8879 */ 8880 formatDate: function (format, date, settings) { 8881 if (!date) { 8882 return ""; 8883 } 8884 8885 var iFormat, 8886 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8887 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8888 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8889 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8890 // Check whether a format character is doubled 8891 lookAhead = function(match) { 8892 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8893 if (matches) { 8894 iFormat++; 8895 } 8896 return matches; 8897 }, 8898 // Format a number, with leading zero if necessary 8899 formatNumber = function(match, value, len) { 8900 var num = "" + value; 8901 if (lookAhead(match)) { 8902 while (num.length < len) { 8903 num = "0" + num; 8904 } 8905 } 8906 return num; 8907 }, 8908 // Format a name, short or long as requested 8909 formatName = function(match, value, shortNames, longNames) { 8910 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8911 }, 8912 output = "", 8913 literal = false; 8914 8915 if (date) { 8916 for (iFormat = 0; iFormat < format.length; iFormat++) { 8917 if (literal) { 8918 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8919 literal = false; 8920 } else { 8921 output += format.charAt(iFormat); 8922 } 8923 } else { 8924 switch (format.charAt(iFormat)) { 8925 case "d": 8926 output += formatNumber("d", date.getDate(), 2); 8927 break; 8928 case "D": 8929 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 8930 break; 8931 case "o": 8932 output += formatNumber("o", 8933 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8934 break; 8935 case "m": 8936 output += formatNumber("m", date.getMonth() + 1, 2); 8937 break; 8938 case "M": 8939 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 8940 break; 8941 case "y": 8942 output += (lookAhead("y") ? date.getFullYear() : 8943 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 8944 break; 8945 case "@": 8946 output += date.getTime(); 8947 break; 8948 case "!": 8949 output += date.getTime() * 10000 + this._ticksTo1970; 8950 break; 8951 case "'": 8952 if (lookAhead("'")) { 8953 output += "'"; 8954 } else { 8955 literal = true; 8956 } 8957 break; 8958 default: 8959 output += format.charAt(iFormat); 8960 } 8961 } 8962 } 8963 } 8964 return output; 8965 }, 8966 8967 /* Extract all possible characters from the date format. */ 8968 _possibleChars: function (format) { 8969 var iFormat, 8970 chars = "", 8971 literal = false, 8972 // Check whether a format character is doubled 8973 lookAhead = function(match) { 8974 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8975 if (matches) { 8976 iFormat++; 8977 } 8978 return matches; 8979 }; 8980 8981 for (iFormat = 0; iFormat < format.length; iFormat++) { 8982 if (literal) { 8983 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8984 literal = false; 8985 } else { 8986 chars += format.charAt(iFormat); 8987 } 8988 } else { 8989 switch (format.charAt(iFormat)) { 8990 case "d": case "m": case "y": case "@": 8991 chars += "0123456789"; 8992 break; 8993 case "D": case "M": 8994 return null; // Accept anything 8995 case "'": 8996 if (lookAhead("'")) { 8997 chars += "'"; 8998 } else { 8999 literal = true; 9000 } 9001 break; 9002 default: 9003 chars += format.charAt(iFormat); 9004 } 9005 } 9006 } 9007 return chars; 9008 }, 9009 9010 /* Get a setting value, defaulting if necessary. */ 9011 _get: function(inst, name) { 9012 return inst.settings[name] !== undefined ? 9013 inst.settings[name] : this._defaults[name]; 9014 }, 9015 9016 /* Parse existing date and initialise date picker. */ 9017 _setDateFromField: function(inst, noDefault) { 9018 if (inst.input.val() === inst.lastVal) { 9019 return; 9020 } 9021 9022 var dateFormat = this._get(inst, "dateFormat"), 9023 dates = inst.lastVal = inst.input ? inst.input.val() : null, 9024 defaultDate = this._getDefaultDate(inst), 9025 date = defaultDate, 9026 settings = this._getFormatConfig(inst); 9027 9028 try { 9029 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 9030 } catch (event) { 9031 dates = (noDefault ? "" : dates); 9032 } 9033 inst.selectedDay = date.getDate(); 9034 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9035 inst.drawYear = inst.selectedYear = date.getFullYear(); 9036 inst.currentDay = (dates ? date.getDate() : 0); 9037 inst.currentMonth = (dates ? date.getMonth() : 0); 9038 inst.currentYear = (dates ? date.getFullYear() : 0); 9039 this._adjustInstDate(inst); 9040 }, 9041 9042 /* Retrieve the default date shown on opening. */ 9043 _getDefaultDate: function(inst) { 9044 return this._restrictMinMax(inst, 9045 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 9046 }, 9047 9048 /* A date may be specified as an exact value or a relative one. */ 9049 _determineDate: function(inst, date, defaultDate) { 9050 var offsetNumeric = function(offset) { 9051 var date = new Date(); 9052 date.setDate(date.getDate() + offset); 9053 return date; 9054 }, 9055 offsetString = function(offset) { 9056 try { 9057 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 9058 offset, $.datepicker._getFormatConfig(inst)); 9059 } 9060 catch (e) { 9061 // Ignore 9062 } 9063 9064 var date = (offset.toLowerCase().match(/^c/) ? 9065 $.datepicker._getDate(inst) : null) || new Date(), 9066 year = date.getFullYear(), 9067 month = date.getMonth(), 9068 day = date.getDate(), 9069 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 9070 matches = pattern.exec(offset); 9071 9072 while (matches) { 9073 switch (matches[2] || "d") { 9074 case "d" : case "D" : 9075 day += parseInt(matches[1],10); break; 9076 case "w" : case "W" : 9077 day += parseInt(matches[1],10) * 7; break; 9078 case "m" : case "M" : 9079 month += parseInt(matches[1],10); 9080 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9081 break; 9082 case "y": case "Y" : 9083 year += parseInt(matches[1],10); 9084 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9085 break; 9086 } 9087 matches = pattern.exec(offset); 9088 } 9089 return new Date(year, month, day); 9090 }, 9091 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 9092 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 9093 9094 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 9095 if (newDate) { 9096 newDate.setHours(0); 9097 newDate.setMinutes(0); 9098 newDate.setSeconds(0); 9099 newDate.setMilliseconds(0); 9100 } 9101 return this._daylightSavingAdjust(newDate); 9102 }, 9103 9104 /* Handle switch to/from daylight saving. 9105 * Hours may be non-zero on daylight saving cut-over: 9106 * > 12 when midnight changeover, but then cannot generate 9107 * midnight datetime, so jump to 1AM, otherwise reset. 9108 * @param date (Date) the date to check 9109 * @return (Date) the corrected date 9110 */ 9111 _daylightSavingAdjust: function(date) { 9112 if (!date) { 9113 return null; 9114 } 9115 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 9116 return date; 9117 }, 9118 9119 /* Set the date(s) directly. */ 9120 _setDate: function(inst, date, noChange) { 9121 var clear = !date, 9122 origMonth = inst.selectedMonth, 9123 origYear = inst.selectedYear, 9124 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 9125 9126 inst.selectedDay = inst.currentDay = newDate.getDate(); 9127 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 9128 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 9129 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 9130 this._notifyChange(inst); 9131 } 9132 this._adjustInstDate(inst); 9133 if (inst.input) { 9134 inst.input.val(clear ? "" : this._formatDate(inst)); 9135 } 9136 }, 9137 9138 /* Retrieve the date(s) directly. */ 9139 _getDate: function(inst) { 9140 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 9141 this._daylightSavingAdjust(new Date( 9142 inst.currentYear, inst.currentMonth, inst.currentDay))); 9143 return startDate; 9144 }, 9145 9146 /* Attach the onxxx handlers. These are declared statically so 9147 * they work with static code transformers like Caja. 9148 */ 9149 _attachHandlers: function(inst) { 9150 var stepMonths = this._get(inst, "stepMonths"), 9151 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 9152 inst.dpDiv.find("[data-handler]").map(function () { 9153 var handler = { 9154 prev: function () { 9155 $.datepicker._adjustDate(id, -stepMonths, "M"); 9156 }, 9157 next: function () { 9158 $.datepicker._adjustDate(id, +stepMonths, "M"); 9159 }, 9160 hide: function () { 9161 $.datepicker._hideDatepicker(); 9162 }, 9163 today: function () { 9164 $.datepicker._gotoToday(id); 9165 }, 9166 selectDay: function () { 9167 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 9168 return false; 9169 }, 9170 selectMonth: function () { 9171 $.datepicker._selectMonthYear(id, this, "M"); 9172 return false; 9173 }, 9174 selectYear: function () { 9175 $.datepicker._selectMonthYear(id, this, "Y"); 9176 return false; 9177 } 9178 }; 9179 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 9180 }); 9181 }, 9182 9183 /* Generate the HTML for the current state of the date picker. */ 9184 _generateHTML: function(inst) { 9185 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
vendor: 38,029 bytes, lines 9186-10302
9186 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 9187 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 9188 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 9189 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 9190 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 9191 tempDate = new Date(), 9192 today = this._daylightSavingAdjust( 9193 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 9194 isRTL = this._get(inst, "isRTL"), 9195 showButtonPanel = this._get(inst, "showButtonPanel"), 9196 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 9197 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 9198 numMonths = this._getNumberOfMonths(inst), 9199 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 9200 stepMonths = this._get(inst, "stepMonths"), 9201 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 9202 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 9203 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 9204 minDate = this._getMinMaxDate(inst, "min"), 9205 maxDate = this._getMinMaxDate(inst, "max"), 9206 drawMonth = inst.drawMonth - showCurrentAtPos, 9207 drawYear = inst.drawYear; 9208 9209 if (drawMonth < 0) { 9210 drawMonth += 12; 9211 drawYear--; 9212 } 9213 if (maxDate) { 9214 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 9215 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 9216 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 9217 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 9218 drawMonth--; 9219 if (drawMonth < 0) { 9220 drawMonth = 11; 9221 drawYear--; 9222 } 9223 } 9224 } 9225 inst.drawMonth = drawMonth; 9226 inst.drawYear = drawYear; 9227 9228 prevText = this._get(inst, "prevText"); 9229 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 9230 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 9231 this._getFormatConfig(inst))); 9232 9233 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 9234 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 9235 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 9236 (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>")); 9237 9238 nextText = this._get(inst, "nextText"); 9239 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 9240 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 9241 this._getFormatConfig(inst))); 9242 9243 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 9244 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 9245 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 9246 (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>")); 9247 9248 currentText = this._get(inst, "currentText"); 9249 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 9250 currentText = (!navigationAsDateFormat ? currentText : 9251 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 9252 9253 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'>" + 9254 this._get(inst, "closeText") + "</button>" : ""); 9255 9256 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 9257 (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'" + 9258 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 9259 9260 firstDay = parseInt(this._get(inst, "firstDay"),10); 9261 firstDay = (isNaN(firstDay) ? 0 : firstDay); 9262 9263 showWeek = this._get(inst, "showWeek"); 9264 dayNames = this._get(inst, "dayNames"); 9265 dayNamesMin = this._get(inst, "dayNamesMin"); 9266 monthNames = this._get(inst, "monthNames"); 9267 monthNamesShort = this._get(inst, "monthNamesShort"); 9268 beforeShowDay = this._get(inst, "beforeShowDay"); 9269 showOtherMonths = this._get(inst, "showOtherMonths"); 9270 selectOtherMonths = this._get(inst, "selectOtherMonths"); 9271 defaultDate = this._getDefaultDate(inst); 9272 html = ""; 9273 dow; 9274 for (row = 0; row < numMonths[0]; row++) { 9275 group = ""; 9276 this.maxRows = 4; 9277 for (col = 0; col < numMonths[1]; col++) { 9278 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 9279 cornerClass = " ui-corner-all"; 9280 calender = ""; 9281 if (isMultiMonth) { 9282 calender += "<div class='ui-datepicker-group"; 9283 if (numMonths[1] > 1) { 9284 switch (col) { 9285 case 0: calender += " ui-datepicker-group-first"; 9286 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 9287 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 9288 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 9289 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 9290 } 9291 } 9292 calender += "'>"; 9293 } 9294 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 9295 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 9296 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 9297 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 9298 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 9299 "</div><table class='ui-datepicker-calendar'><thead>" + 9300 "<tr>"; 9301 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 9302 for (dow = 0; dow < 7; dow++) { // days of the week 9303 day = (dow + firstDay) % 7; 9304 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 9305 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 9306 } 9307 calender += thead + "</tr></thead><tbody>"; 9308 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 9309 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 9310 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 9311 } 9312 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 9313 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 9314 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 9315 this.maxRows = numRows; 9316 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 9317 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 9318 calender += "<tr>"; 9319 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 9320 this._get(inst, "calculateWeek")(printDate) + "</td>"); 9321 for (dow = 0; dow < 7; dow++) { // create date picker days 9322 daySettings = (beforeShowDay ? 9323 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 9324 otherMonth = (printDate.getMonth() !== drawMonth); 9325 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 9326 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 9327 tbody += "<td class='" + 9328 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 9329 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 9330 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 9331 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 9332 // or defaultDate is current printedDate and defaultDate is selectedDate 9333 " " + this._dayOverClass : "") + // highlight selected day 9334 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 9335 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 9336 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 9337 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 9338 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 9339 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 9340 (otherMonth && !showOtherMonths ? " " : // display for other months 9341 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9342 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 9343 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 9344 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 9345 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 9346 printDate.setDate(printDate.getDate() + 1); 9347 printDate = this._daylightSavingAdjust(printDate); 9348 } 9349 calender += tbody + "</tr>"; 9350 } 9351 drawMonth++; 9352 if (drawMonth > 11) { 9353 drawMonth = 0; 9354 drawYear++; 9355 } 9356 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 9357 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 9358 group += calender; 9359 } 9360 html += group; 9361 } 9362 html += buttonPanel; 9363 inst._keyEvent = false; 9364 return html; 9365 }, 9366 9367 /* Generate the month and year header. */ 9368 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 9369 secondary, monthNames, monthNamesShort) { 9370 9371 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9372 changeMonth = this._get(inst, "changeMonth"), 9373 changeYear = this._get(inst, "changeYear"), 9374 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 9375 html = "<div class='ui-datepicker-title'>", 9376 monthHtml = ""; 9377 9378 9379 // month selection 9380 if (secondary || !changeMonth) { 9381 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 9382 } else { 9383 inMinYear = (minDate && minDate.getFullYear() === drawYear); 9384 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 9385 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 9386 for ( month = 0; month < 12; month++) { 9387 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 9388 monthHtml += "<option value='" + month + "'" + 9389 (month === drawMonth ? " selected='selected'" : "") + 9390 ">" + monthNamesShort[month] + "</option>"; 9391 } 9392 } 9393 monthHtml += "</select>"; 9394 } 9395 9396 if (!showMonthAfterYear) { 9397 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 9398 } 9399 9400 // year selection 9401 if ( !inst.yearshtml ) { 9402 inst.yearshtml = ""; 9403 if (secondary || !changeYear) { 9404 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9405 } else { 9406 // determine range of years to display 9407 years = this._get(inst, "yearRange").split(":"); 9408 thisYear = new Date().getFullYear(); 9409 determineYear = function(value) { 9410 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 9411 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 9412 parseInt(value, 10))); 9413 return (isNaN(year) ? thisYear : year); 9414 }; 9415 year = determineYear(years[0]); 9416 endYear = Math.max(year, determineYear(years[1] || "")); 9417 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 9418 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 9419 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 9420 for (; year <= endYear; year++) { 9421 inst.yearshtml += "<option value='" + year + "'" + 9422 (year === drawYear ? " selected='selected'" : "") + 9423 ">" + year + "</option>"; 9424 } 9425 inst.yearshtml += "</select>"; 9426 9427 html += inst.yearshtml; 9428 inst.yearshtml = null; 9429 } 9430 } 9431 9432 html += this._get(inst, "yearSuffix"); 9433 if (showMonthAfterYear) { 9434 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 9435 } 9436 html += "</div>"; // Close datepicker_header 9437 return html; 9438 }, 9439 9440 /* Adjust one of the date sub-fields. */ 9441 _adjustInstDate: function(inst, offset, period) { 9442 var year = inst.drawYear + (period === "Y" ? offset : 0), 9443 month = inst.drawMonth + (period === "M" ? offset : 0), 9444 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 9445 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 9446 9447 inst.selectedDay = date.getDate(); 9448 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9449 inst.drawYear = inst.selectedYear = date.getFullYear(); 9450 if (period === "M" || period === "Y") { 9451 this._notifyChange(inst); 9452 } 9453 }, 9454 9455 /* Ensure a date is within any min/max bounds. */ 9456 _restrictMinMax: function(inst, date) { 9457 var minDate = this._getMinMaxDate(inst, "min"), 9458 maxDate = this._getMinMaxDate(inst, "max"), 9459 newDate = (minDate && date < minDate ? minDate : date); 9460 return (maxDate && newDate > maxDate ? maxDate : newDate); 9461 }, 9462 9463 /* Notify change of month/year. */ 9464 _notifyChange: function(inst) { 9465 var onChange = this._get(inst, "onChangeMonthYear"); 9466 if (onChange) { 9467 onChange.apply((inst.input ? inst.input[0] : null), 9468 [inst.selectedYear, inst.selectedMonth + 1, inst]); 9469 } 9470 }, 9471 9472 /* Determine the number of months to show. */ 9473 _getNumberOfMonths: function(inst) { 9474 var numMonths = this._get(inst, "numberOfMonths"); 9475 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 9476 }, 9477 9478 /* Determine the current maximum date - ensure no time components are set. */ 9479 _getMinMaxDate: function(inst, minMax) { 9480 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 9481 }, 9482 9483 /* Find the number of days in a given month. */ 9484 _getDaysInMonth: function(year, month) { 9485 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 9486 }, 9487 9488 /* Find the day of the week of the first of a month. */ 9489 _getFirstDayOfMonth: function(year, month) { 9490 return new Date(year, month, 1).getDay(); 9491 }, 9492 9493 /* Determines if we should allow a "next/prev" month display change. */ 9494 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 9495 var numMonths = this._getNumberOfMonths(inst), 9496 date = this._daylightSavingAdjust(new Date(curYear, 9497 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 9498 9499 if (offset < 0) { 9500 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 9501 } 9502 return this._isInRange(inst, date); 9503 }, 9504 9505 /* Is the given date in the accepted range? */ 9506 _isInRange: function(inst, date) { 9507 var yearSplit, currentYear, 9508 minDate = this._getMinMaxDate(inst, "min"), 9509 maxDate = this._getMinMaxDate(inst, "max"), 9510 minYear = null, 9511 maxYear = null, 9512 years = this._get(inst, "yearRange"); 9513 if (years){ 9514 yearSplit = years.split(":"); 9515 currentYear = new Date().getFullYear(); 9516 minYear = parseInt(yearSplit[0], 10); 9517 maxYear = parseInt(yearSplit[1], 10); 9518 if ( yearSplit[0].match(/[+\-].*/) ) { 9519 minYear += currentYear; 9520 } 9521 if ( yearSplit[1].match(/[+\-].*/) ) { 9522 maxYear += currentYear; 9523 } 9524 } 9525 9526 return ((!minDate || date.getTime() >= minDate.getTime()) && 9527 (!maxDate || date.getTime() <= maxDate.getTime()) && 9528 (!minYear || date.getFullYear() >= minYear) && 9529 (!maxYear || date.getFullYear() <= maxYear)); 9530 }, 9531 9532 /* Provide the configuration settings for formatting/parsing. */ 9533 _getFormatConfig: function(inst) { 9534 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 9535 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 9536 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 9537 return {shortYearCutoff: shortYearCutoff, 9538 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 9539 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 9540 }, 9541 9542 /* Format the given date for display. */ 9543 _formatDate: function(inst, day, month, year) { 9544 if (!day) { 9545 inst.currentDay = inst.selectedDay; 9546 inst.currentMonth = inst.selectedMonth; 9547 inst.currentYear = inst.selectedYear; 9548 } 9549 var date = (day ? (typeof day === "object" ? day : 9550 this._daylightSavingAdjust(new Date(year, month, day))) : 9551 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 9552 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 9553 } 9554}); 9555 9556/* 9557 * Bind hover events for datepicker elements. 9558 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9559 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9560 */ 9561function bindHover(dpDiv) { 9562 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9563 return dpDiv.delegate(selector, "mouseout", function() { 9564 $(this).removeClass("ui-state-hover"); 9565 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9566 $(this).removeClass("ui-datepicker-prev-hover"); 9567 } 9568 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9569 $(this).removeClass("ui-datepicker-next-hover"); 9570 } 9571 }) 9572 .delegate(selector, "mouseover", function(){ 9573 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 9574 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 9575 $(this).addClass("ui-state-hover"); 9576 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9577 $(this).addClass("ui-datepicker-prev-hover"); 9578 } 9579 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9580 $(this).addClass("ui-datepicker-next-hover"); 9581 } 9582 } 9583 }); 9584} 9585 9586/* jQuery extend now ignores nulls! */ 9587function extendRemove(target, props) { 9588 $.extend(target, props); 9589 for (var name in props) { 9590 if (props[name] == null) { 9591 target[name] = props[name]; 9592 } 9593 } 9594 return target; 9595} 9596 9597/* Invoke the datepicker functionality. 9598 @param options string - a command, optionally followed by additional parameters or 9599 Object - settings for attaching new datepicker functionality 9600 @return jQuery object */ 9601$.fn.datepicker = function(options){ 9602 9603 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9604 if ( !this.length ) { 9605 return this; 9606 } 9607 9608 /* Initialise the date picker. */ 9609 if (!$.datepicker.initialized) { 9610 $(document).mousedown($.datepicker._checkExternalClick); 9611 $.datepicker.initialized = true; 9612 } 9613 9614 /* Append datepicker main container to body if not exist. */ 9615 if ($("#"+$.datepicker._mainDivId).length === 0) { 9616 $("body").append($.datepicker.dpDiv); 9617 } 9618 9619 var otherArgs = Array.prototype.slice.call(arguments, 1); 9620 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 9621 return $.datepicker["_" + options + "Datepicker"]. 9622 apply($.datepicker, [this[0]].concat(otherArgs)); 9623 } 9624 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 9625 return $.datepicker["_" + options + "Datepicker"]. 9626 apply($.datepicker, [this[0]].concat(otherArgs)); 9627 } 9628 return this.each(function() { 9629 typeof options === "string" ? 9630 $.datepicker["_" + options + "Datepicker"]. 9631 apply($.datepicker, [this].concat(otherArgs)) : 9632 $.datepicker._attachDatepicker(this, options); 9633 }); 9634}; 9635 9636$.datepicker = new Datepicker(); // singleton instance 9637$.datepicker.initialized = false; 9638$.datepicker.uuid = new Date().getTime(); 9639$.datepicker.version = "1.10.3"; 9640 9641})(jQuery); 9642 9643(function( $, undefined ) { 9644 9645var sizeRelatedOptions = { 9646 buttons: true, 9647 height: true, 9648 maxHeight: true, 9649 maxWidth: true, 9650 minHeight: true, 9651 minWidth: true, 9652 width: true 9653 }, 9654 resizableRelatedOptions = { 9655 maxHeight: true, 9656 maxWidth: true, 9657 minHeight: true, 9658 minWidth: true 9659 }; 9660 9661$.widget( "ui.dialog", { 9662 version: "1.10.3", 9663 options: { 9664 appendTo: "body", 9665 autoOpen: true, 9666 buttons: [], 9667 closeOnEscape: true, 9668 closeText: "close", 9669 dialogClass: "", 9670 draggable: true, 9671 hide: null, 9672 height: "auto", 9673 maxHeight: null, 9674 maxWidth: null, 9675 minHeight: 150, 9676 minWidth: 150, 9677 modal: false, 9678 position: { 9679 my: "center", 9680 at: "center", 9681 of: window, 9682 collision: "fit", 9683 // Ensure the titlebar is always visible 9684 using: function( pos ) { 9685 var topOffset = $( this ).css( pos ).offset().top; 9686 if ( topOffset < 0 ) { 9687 $( this ).css( "top", pos.top - topOffset ); 9688 } 9689 } 9690 }, 9691 resizable: true, 9692 show: null, 9693 title: null, 9694 width: 300, 9695 9696 // callbacks 9697 beforeClose: null, 9698 close: null, 9699 drag: null, 9700 dragStart: null, 9701 dragStop: null, 9702 focus: null, 9703 open: null, 9704 resize: null, 9705 resizeStart: null, 9706 resizeStop: null 9707 }, 9708 9709 _create: function() { 9710 this.originalCss = { 9711 display: this.element[0].style.display, 9712 width: this.element[0].style.width, 9713 minHeight: this.element[0].style.minHeight, 9714 maxHeight: this.element[0].style.maxHeight, 9715 height: this.element[0].style.height 9716 }; 9717 this.originalPosition = { 9718 parent: this.element.parent(), 9719 index: this.element.parent().children().index( this.element ) 9720 }; 9721 this.originalTitle = this.element.attr("title"); 9722 this.options.title = this.options.title || this.originalTitle; 9723 9724 this._createWrapper(); 9725 9726 this.element 9727 .show() 9728 .removeAttr("title") 9729 .addClass("ui-dialog-content ui-widget-content") 9730 .appendTo( this.uiDialog ); 9731 9732 this._createTitlebar(); 9733 this._createButtonPane(); 9734 9735 if ( this.options.draggable && $.fn.draggable ) { 9736 this._makeDraggable(); 9737 } 9738 if ( this.options.resizable && $.fn.resizable ) { 9739 this._makeResizable(); 9740 } 9741 9742 this._isOpen = false; 9743 }, 9744 9745 _init: function() { 9746 if ( this.options.autoOpen ) { 9747 this.open(); 9748 } 9749 }, 9750 9751 _appendTo: function() { 9752 var element = this.options.appendTo; 9753 if ( element && (element.jquery || element.nodeType) ) { 9754 return $( element ); 9755 } 9756 return this.document.find( element || "body" ).eq( 0 ); 9757 }, 9758 9759 _destroy: function() { 9760 var next, 9761 originalPosition = this.originalPosition; 9762 9763 this._destroyOverlay(); 9764 9765 this.element 9766 .removeUniqueId() 9767 .removeClass("ui-dialog-content ui-widget-content") 9768 .css( this.originalCss ) 9769 // Without detaching first, the following becomes really slow 9770 .detach(); 9771 9772 this.uiDialog.stop( true, true ).remove(); 9773 9774 if ( this.originalTitle ) { 9775 this.element.attr( "title", this.originalTitle ); 9776 } 9777 9778 next = originalPosition.parent.children().eq( originalPosition.index ); 9779 // Don't try to place the dialog next to itself (#8613) 9780 if ( next.length && next[0] !== this.element[0] ) { 9781 next.before( this.element ); 9782 } else { 9783 originalPosition.parent.append( this.element ); 9784 } 9785 }, 9786 9787 widget: function() { 9788 return this.uiDialog; 9789 }, 9790 9791 disable: $.noop, 9792 enable: $.noop, 9793 9794 close: function( event ) { 9795 var that = this; 9796 9797 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 9798 return; 9799 } 9800 9801 this._isOpen = false; 9802 this._destroyOverlay(); 9803 9804 if ( !this.opener.filter(":focusable").focus().length ) { 9805 // Hiding a focused element doesn't trigger blur in WebKit 9806 // so in case we have nothing to focus on, explicitly blur the active element 9807 // https://bugs.webkit.org/show_bug.cgi?id=47182 9808 $( this.document[0].activeElement ).blur(); 9809 } 9810 9811 this._hide( this.uiDialog, this.options.hide, function() { 9812 that._trigger( "close", event ); 9813 }); 9814 }, 9815 9816 isOpen: function() { 9817 return this._isOpen; 9818 }, 9819 9820 moveToTop: function() { 9821 this._moveToTop(); 9822 }, 9823 9824 _moveToTop: function( event, silent ) { 9825 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; 9826 if ( moved && !silent ) { 9827 this._trigger( "focus", event ); 9828 } 9829 return moved; 9830 }, 9831 9832 open: function() { 9833 var that = this; 9834 if ( this._isOpen ) { 9835 if ( this._moveToTop() ) { 9836 this._focusTabbable(); 9837 } 9838 return; 9839 } 9840 9841 this._isOpen = true; 9842 this.opener = $( this.document[0].activeElement ); 9843 9844 this._size(); 9845 this._position(); 9846 this._createOverlay(); 9847 this._moveToTop( null, true ); 9848 this._show( this.uiDialog, this.options.show, function() { 9849 that._focusTabbable(); 9850 that._trigger("focus"); 9851 }); 9852 9853 this._trigger("open"); 9854 }, 9855 9856 _focusTabbable: function() { 9857 // Set focus to the first match: 9858 // 1. First element inside the dialog matching [autofocus] 9859 // 2. Tabbable element inside the content element 9860 // 3. Tabbable element inside the buttonpane 9861 // 4. The close button 9862 // 5. The dialog itself 9863 var hasFocus = this.element.find("[autofocus]"); 9864 if ( !hasFocus.length ) { 9865 hasFocus = this.element.find(":tabbable"); 9866 } 9867 if ( !hasFocus.length ) { 9868 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 9869 } 9870 if ( !hasFocus.length ) { 9871 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); 9872 } 9873 if ( !hasFocus.length ) { 9874 hasFocus = this.uiDialog; 9875 } 9876 hasFocus.eq( 0 ).focus(); 9877 }, 9878 9879 _keepFocus: function( event ) { 9880 function checkFocus() { 9881 var activeElement = this.document[0].activeElement, 9882 isActive = this.uiDialog[0] === activeElement || 9883 $.contains( this.uiDialog[0], activeElement ); 9884 if ( !isActive ) { 9885 this._focusTabbable(); 9886 } 9887 } 9888 event.preventDefault(); 9889 checkFocus.call( this ); 9890 // support: IE 9891 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 9892 // so we check again later 9893 this._delay( checkFocus ); 9894 }, 9895 9896 _createWrapper: function() { 9897 this.uiDialog = $("<div>") 9898 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 9899 this.options.dialogClass ) 9900 .hide() 9901 .attr({ 9902 // Setting tabIndex makes the div focusable 9903 tabIndex: -1, 9904 role: "dialog" 9905 }) 9906 .appendTo( this._appendTo() ); 9907 9908 this._on( this.uiDialog, { 9909 keydown: function( event ) { 9910 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9911 event.keyCode === $.ui.keyCode.ESCAPE ) { 9912 event.preventDefault(); 9913 this.close( event ); 9914 return; 9915 } 9916 9917 // prevent tabbing out of dialogs 9918 if ( event.keyCode !== $.ui.keyCode.TAB ) { 9919 return; 9920 } 9921 var tabbables = this.uiDialog.find(":tabbable"), 9922 first = tabbables.filter(":first"), 9923 last = tabbables.filter(":last"); 9924 9925 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 9926 first.focus( 1 ); 9927 event.preventDefault(); 9928 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 9929 last.focus( 1 ); 9930 event.preventDefault(); 9931 } 9932 }, 9933 mousedown: function( event ) { 9934 if ( this._moveToTop( event ) ) { 9935 this._focusTabbable(); 9936 } 9937 } 9938 }); 9939 9940 // We assume that any existing aria-describedby attribute means 9941 // that the dialog content is marked up properly 9942 // otherwise we brute force the content as the description 9943 if ( !this.element.find("[aria-describedby]").length ) { 9944 this.uiDialog.attr({ 9945 "aria-describedby": this.element.uniqueId().attr("id") 9946 }); 9947 } 9948 }, 9949 9950 _createTitlebar: function() { 9951 var uiDialogTitle; 9952 9953 this.uiDialogTitlebar = $("<div>") 9954 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") 9955 .prependTo( this.uiDialog ); 9956 this._on( this.uiDialogTitlebar, { 9957 mousedown: function( event ) { 9958 // Don't prevent click on close button (#8838) 9959 // Focusing a dialog that is partially scrolled out of view 9960 // causes the browser to scroll it into view, preventing the click event 9961 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { 9962 // Dialog isn't getting focus when dragging (#8063) 9963 this.uiDialog.focus(); 9964 } 9965 } 9966 }); 9967 9968 this.uiDialogTitlebarClose = $("<button></button>") 9969 .button({ 9970 label: this.options.closeText, 9971 icons: { 9972 primary: "ui-icon-closethick" 9973 }, 9974 text: false 9975 }) 9976 .addClass("ui-dialog-titlebar-close") 9977 .appendTo( this.uiDialogTitlebar ); 9978 this._on( this.uiDialogTitlebarClose, { 9979 click: function( event ) { 9980 event.preventDefault(); 9981 this.close( event ); 9982 } 9983 }); 9984 9985 uiDialogTitle = $("<span>") 9986 .uniqueId() 9987 .addClass("ui-dialog-title") 9988 .prependTo( this.uiDialogTitlebar ); 9989 this._title( uiDialogTitle ); 9990 9991 this.uiDialog.attr({ 9992 "aria-labelledby": uiDialogTitle.attr("id") 9993 }); 9994 }, 9995 9996 _title: function( title ) { 9997 if ( !this.options.title ) { 9998 title.html(" "); 9999 } 10000 title.text( this.options.title ); 10001 }, 10002 10003 _createButtonPane: function() { 10004 this.uiDialogButtonPane = $("<div>") 10005 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 10006 10007 this.uiButtonSet = $("<div>") 10008 .addClass("ui-dialog-buttonset") 10009 .appendTo( this.uiDialogButtonPane ); 10010 10011 this._createButtons(); 10012 }, 10013 10014 _createButtons: function() { 10015 var that = this, 10016 buttons = this.options.buttons; 10017 10018 // if we already have a button pane, remove it 10019 this.uiDialogButtonPane.remove(); 10020 this.uiButtonSet.empty(); 10021 10022 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 10023 this.uiDialog.removeClass("ui-dialog-buttons"); 10024 return; 10025 } 10026 10027 $.each( buttons, function( name, props ) { 10028 var click, buttonOptions; 10029 props = $.isFunction( props ) ? 10030 { click: props, text: name } : 10031 props; 10032 // Default to a non-submitting button 10033 props = $.extend( { type: "button" }, props ); 10034 // Change the context for the click callback to be the main element 10035 click = props.click; 10036 props.click = function() { 10037 click.apply( that.element[0], arguments ); 10038 }; 10039 buttonOptions = { 10040 icons: props.icons, 10041 text: props.showText 10042 }; 10043 delete props.icons; 10044 delete props.showText; 10045 $( "<button></button>", props ) 10046 .button( buttonOptions ) 10047 .appendTo( that.uiButtonSet ); 10048 }); 10049 this.uiDialog.addClass("ui-dialog-buttons"); 10050 this.uiDialogButtonPane.appendTo( this.uiDialog ); 10051 }, 10052 10053 _makeDraggable: function() { 10054 var that = this, 10055 options = this.options; 10056 10057 function filteredUi( ui ) { 10058 return { 10059 position: ui.position, 10060 offset: ui.offset 10061 }; 10062 } 10063 10064 this.uiDialog.draggable({ 10065 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 10066 handle: ".ui-dialog-titlebar", 10067 containment: "document", 10068 start: function( event, ui ) { 10069 $( this ).addClass("ui-dialog-dragging"); 10070 that._blockFrames(); 10071 that._trigger( "dragStart", event, filteredUi( ui ) ); 10072 }, 10073 drag: function( event, ui ) { 10074 that._trigger( "drag", event, filteredUi( ui ) ); 10075 }, 10076 stop: function( event, ui ) { 10077 options.position = [ 10078 ui.position.left - that.document.scrollLeft(), 10079 ui.position.top - that.document.scrollTop() 10080 ]; 10081 $( this ).removeClass("ui-dialog-dragging"); 10082 that._unblockFrames(); 10083 that._trigger( "dragStop", event, filteredUi( ui ) ); 10084 } 10085 }); 10086 }, 10087 10088 _makeResizable: function() { 10089 var that = this, 10090 options = this.options, 10091 handles = options.resizable, 10092 // .ui-resizable has position: relative defined in the stylesheet 10093 // but dialogs have to use absolute or fixed positioning 10094 position = this.uiDialog.css("position"), 10095 resizeHandles = typeof handles === "string" ? 10096 handles : 10097 "n,e,s,w,se,sw,ne,nw"; 10098 10099 function filteredUi( ui ) { 10100 return { 10101 originalPosition: ui.originalPosition, 10102 originalSize: ui.originalSize, 10103 position: ui.position, 10104 size: ui.size 10105 }; 10106 } 10107 10108 this.uiDialog.resizable({ 10109 cancel: ".ui-dialog-content", 10110 containment: "document", 10111 alsoResize: this.element, 10112 maxWidth: options.maxWidth, 10113 maxHeight: options.maxHeight, 10114 minWidth: options.minWidth, 10115 minHeight: this._minHeight(), 10116 handles: resizeHandles, 10117 start: function( event, ui ) { 10118 $( this ).addClass("ui-dialog-resizing"); 10119 that._blockFrames(); 10120 that._trigger( "resizeStart", event, filteredUi( ui ) ); 10121 }, 10122 resize: function( event, ui ) { 10123 that._trigger( "resize", event, filteredUi( ui ) ); 10124 }, 10125 stop: function( event, ui ) { 10126 options.height = $( this ).height(); 10127 options.width = $( this ).width(); 10128 $( this ).removeClass("ui-dialog-resizing"); 10129 that._unblockFrames(); 10130 that._trigger( "resizeStop", event, filteredUi( ui ) ); 10131 } 10132 }) 10133 .css( "position", position ); 10134 }, 10135 10136 _minHeight: function() { 10137 var options = this.options; 10138 10139 return options.height === "auto" ? 10140 options.minHeight : 10141 Math.min( options.minHeight, options.height ); 10142 }, 10143 10144 _position: function() { 10145 // Need to show the dialog to get the actual offset in the position plugin 10146 var isVisible = this.uiDialog.is(":visible"); 10147 if ( !isVisible ) { 10148 this.uiDialog.show(); 10149 } 10150 this.uiDialog.position( this.options.position ); 10151 if ( !isVisible ) { 10152 this.uiDialog.hide(); 10153 } 10154 }, 10155 10156 _setOptions: function( options ) { 10157 var that = this, 10158 resize = false, 10159 resizableOptions = {}; 10160 10161 $.each( options, function( key, value ) { 10162 that._setOption( key, value ); 10163 10164 if ( key in sizeRelatedOptions ) { 10165 resize = true; 10166 } 10167 if ( key in resizableRelatedOptions ) { 10168 resizableOptions[ key ] = value; 10169 } 10170 }); 10171 10172 if ( resize ) { 10173 this._size(); 10174 this._position(); 10175 } 10176 if ( this.uiDialog.is(":data(ui-resizable)") ) { 10177 this.uiDialog.resizable( "option", resizableOptions ); 10178 } 10179 }, 10180 10181 _setOption: function( key, value ) { 10182 /*jshint maxcomplexity:15*/ 10183 var isDraggable, isResizable, 10184 uiDialog = this.uiDialog; 10185 10186 if ( key === "dialogClass" ) { 10187 uiDialog 10188 .removeClass( this.options.dialogClass ) 10189 .addClass( value ); 10190 } 10191 10192 if ( key === "disabled" ) { 10193 return; 10194 } 10195 10196 this._super( key, value ); 10197 10198 if ( key === "appendTo" ) { 10199 this.uiDialog.appendTo( this._appendTo() ); 10200 } 10201 10202 if ( key === "buttons" ) { 10203 this._createButtons(); 10204 } 10205 10206 if ( key === "closeText" ) { 10207 this.uiDialogTitlebarClose.button({ 10208 // Ensure that we always pass a string 10209 label: "" + value 10210 }); 10211 } 10212 10213 if ( key === "draggable" ) { 10214 isDraggable = uiDialog.is(":data(ui-draggable)"); 10215 if ( isDraggable && !value ) { 10216 uiDialog.draggable("destroy"); 10217 } 10218 10219 if ( !isDraggable && value ) { 10220 this._makeDraggable(); 10221 } 10222 } 10223 10224 if ( key === "position" ) { 10225 this._position(); 10226 } 10227 10228 if ( key === "resizable" ) { 10229 // currently resizable, becoming non-resizable 10230 isResizable = uiDialog.is(":data(ui-resizable)"); 10231 if ( isResizable && !value ) { 10232 uiDialog.resizable("destroy"); 10233 } 10234 10235 // currently resizable, changing handles 10236 if ( isResizable && typeof value === "string" ) { 10237 uiDialog.resizable( "option", "handles", value ); 10238 } 10239 10240 // currently non-resizable, becoming resizable 10241 if ( !isResizable && value !== false ) { 10242 this._makeResizable(); 10243 } 10244 } 10245 10246 if ( key === "title" ) { 10247 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); 10248 } 10249 }, 10250 10251 _size: function() { 10252 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 10253 // divs will both have width and height set, so we need to reset them 10254 var nonContentHeight, minContentHeight, maxContentHeight, 10255 options = this.options; 10256 10257 // Reset content sizing 10258 this.element.show().css({ 10259 width: "auto", 10260 minHeight: 0, 10261 maxHeight: "none", 10262 height: 0 10263 }); 10264 10265 if ( options.minWidth > options.width ) { 10266 options.width = options.minWidth; 10267 } 10268 10269 // reset wrapper sizing 10270 // determine the height of all the non-content elements 10271 nonContentHeight = this.uiDialog.css({ 10272 height: "auto", 10273 width: options.width 10274 }) 10275 .outerHeight(); 10276 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 10277 maxContentHeight = typeof options.maxHeight === "number" ? 10278 Math.max( 0, options.maxHeight - nonContentHeight ) : 10279 "none"; 10280 10281 if ( options.height === "auto" ) { 10282 this.element.css({ 10283 minHeight: minContentHeight, 10284 maxHeight: maxContentHeight, 10285 height: "auto" 10286 }); 10287 } else { 10288 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 10289 } 10290 10291 if (this.uiDialog.is(":data(ui-resizable)") ) { 10292 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 10293 } 10294 }, 10295 10296 _blockFrames: function() { 10297 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 10298 var iframe = $( this ); 10299 10300 return $( "<div>" ) 10301 .css({ 10302 position: "absolute",
vendor: 10,272 bytes, lines 10303-10715
10303 width: iframe.outerWidth(), 10304 height: iframe.outerHeight() 10305 }) 10306 .appendTo( iframe.parent() ) 10307 .offset( iframe.offset() )[0]; 10308 }); 10309 }, 10310 10311 _unblockFrames: function() { 10312 if ( this.iframeBlocks ) { 10313 this.iframeBlocks.remove(); 10314 delete this.iframeBlocks; 10315 } 10316 }, 10317 10318 _allowInteraction: function( event ) { 10319 if ( $( event.target ).closest(".ui-dialog").length ) { 10320 return true; 10321 } 10322 10323 // TODO: Remove hack when datepicker implements 10324 // the .ui-front logic (#8989) 10325 return !!$( event.target ).closest(".ui-datepicker").length; 10326 }, 10327 10328 _createOverlay: function() { 10329 if ( !this.options.modal ) { 10330 return; 10331 } 10332 10333 var that = this, 10334 widgetFullName = this.widgetFullName; 10335 if ( !$.ui.dialog.overlayInstances ) { 10336 // Prevent use of anchors and inputs. 10337 // We use a delay in case the overlay is created from an 10338 // event that we're going to be cancelling. (#2804) 10339 this._delay(function() { 10340 // Handle .dialog().dialog("close") (#4065) 10341 if ( $.ui.dialog.overlayInstances ) { 10342 this.document.bind( "focusin.dialog", function( event ) { 10343 if ( !that._allowInteraction( event ) ) { 10344 event.preventDefault(); 10345 $(".ui-dialog:visible:last .ui-dialog-content") 10346 .data( widgetFullName )._focusTabbable(); 10347 } 10348 }); 10349 } 10350 }); 10351 } 10352 10353 this.overlay = $("<div>") 10354 .addClass("ui-widget-overlay ui-front") 10355 .appendTo( this._appendTo() ); 10356 this._on( this.overlay, { 10357 mousedown: "_keepFocus" 10358 }); 10359 $.ui.dialog.overlayInstances++; 10360 }, 10361 10362 _destroyOverlay: function() { 10363 if ( !this.options.modal ) { 10364 return; 10365 } 10366 10367 if ( this.overlay ) { 10368 $.ui.dialog.overlayInstances--; 10369 10370 if ( !$.ui.dialog.overlayInstances ) { 10371 this.document.unbind( "focusin.dialog" ); 10372 } 10373 this.overlay.remove(); 10374 this.overlay = null; 10375 } 10376 } 10377}); 10378 10379$.ui.dialog.overlayInstances = 0; 10380 10381// DEPRECATED 10382if ( $.uiBackCompat !== false ) { 10383 // position option with array notation 10384 // just override with old implementation 10385 $.widget( "ui.dialog", $.ui.dialog, { 10386 _position: function() { 10387 var position = this.options.position, 10388 myAt = [], 10389 offset = [ 0, 0 ], 10390 isVisible; 10391 10392 if ( position ) { 10393 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 10394 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; 10395 if ( myAt.length === 1 ) { 10396 myAt[1] = myAt[0]; 10397 } 10398 10399 $.each( [ "left", "top" ], function( i, offsetPosition ) { 10400 if ( +myAt[ i ] === myAt[ i ] ) { 10401 offset[ i ] = myAt[ i ]; 10402 myAt[ i ] = offsetPosition; 10403 } 10404 }); 10405 10406 position = { 10407 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 10408 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 10409 at: myAt.join(" ") 10410 }; 10411 } 10412 10413 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 10414 } else { 10415 position = $.ui.dialog.prototype.options.position; 10416 } 10417 10418 // need to show the dialog to get the actual offset in the position plugin 10419 isVisible = this.uiDialog.is(":visible"); 10420 if ( !isVisible ) { 10421 this.uiDialog.show(); 10422 } 10423 this.uiDialog.position( position ); 10424 if ( !isVisible ) { 10425 this.uiDialog.hide(); 10426 } 10427 } 10428 }); 10429} 10430 10431}( jQuery ) ); 10432 10433(function( $, undefined ) { 10434 10435var rvertical = /up|down|vertical/, 10436 rpositivemotion = /up|left|vertical|horizontal/; 10437 10438$.effects.effect.blind = function( o, done ) { 10439 // Create element 10440 var el = $( this ), 10441 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10442 mode = $.effects.setMode( el, o.mode || "hide" ), 10443 direction = o.direction || "up", 10444 vertical = rvertical.test( direction ), 10445 ref = vertical ? "height" : "width", 10446 ref2 = vertical ? "top" : "left", 10447 motion = rpositivemotion.test( direction ), 10448 animation = {}, 10449 show = mode === "show", 10450 wrapper, distance, margin; 10451 10452 // if already wrapped, the wrapper's properties are my property. #6245 10453 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 10454 $.effects.save( el.parent(), props ); 10455 } else { 10456 $.effects.save( el, props ); 10457 } 10458 el.show(); 10459 wrapper = $.effects.createWrapper( el ).css({ 10460 overflow: "hidden" 10461 }); 10462 10463 distance = wrapper[ ref ](); 10464 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 10465 10466 animation[ ref ] = show ? distance : 0; 10467 if ( !motion ) { 10468 el 10469 .css( vertical ? "bottom" : "right", 0 ) 10470 .css( vertical ? "top" : "left", "auto" ) 10471 .css({ position: "absolute" }); 10472 10473 animation[ ref2 ] = show ? margin : distance + margin; 10474 } 10475 10476 // start at 0 if we are showing 10477 if ( show ) { 10478 wrapper.css( ref, 0 ); 10479 if ( ! motion ) { 10480 wrapper.css( ref2, margin + distance ); 10481 } 10482 } 10483 10484 // Animate 10485 wrapper.animate( animation, { 10486 duration: o.duration, 10487 easing: o.easing, 10488 queue: false, 10489 complete: function() { 10490 if ( mode === "hide" ) { 10491 el.hide(); 10492 } 10493 $.effects.restore( el, props ); 10494 $.effects.removeWrapper( el ); 10495 done(); 10496 } 10497 }); 10498 10499}; 10500 10501})(jQuery); 10502 10503(function( $, undefined ) { 10504 10505$.effects.effect.bounce = function( o, done ) { 10506 var el = $( this ), 10507 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10508 10509 // defaults: 10510 mode = $.effects.setMode( el, o.mode || "effect" ), 10511 hide = mode === "hide", 10512 show = mode === "show", 10513 direction = o.direction || "up", 10514 distance = o.distance, 10515 times = o.times || 5, 10516 10517 // number of internal animations 10518 anims = times * 2 + ( show || hide ? 1 : 0 ), 10519 speed = o.duration / anims, 10520 easing = o.easing, 10521 10522 // utility: 10523 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10524 motion = ( direction === "up" || direction === "left" ), 10525 i, 10526 upAnim, 10527 downAnim, 10528 10529 // we will need to re-assemble the queue to stack our animations in place 10530 queue = el.queue(), 10531 queuelen = queue.length; 10532 10533 // Avoid touching opacity to prevent clearType and PNG issues in IE 10534 if ( show || hide ) { 10535 props.push( "opacity" ); 10536 } 10537 10538 $.effects.save( el, props ); 10539 el.show(); 10540 $.effects.createWrapper( el ); // Create Wrapper 10541 10542 // default distance for the BIGGEST bounce is the outer Distance / 3 10543 if ( !distance ) { 10544 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 10545 } 10546 10547 if ( show ) { 10548 downAnim = { opacity: 1 }; 10549 downAnim[ ref ] = 0; 10550 10551 // if we are showing, force opacity 0 and set the initial position 10552 // then do the "first" animation 10553 el.css( "opacity", 0 ) 10554 .css( ref, motion ? -distance * 2 : distance * 2 ) 10555 .animate( downAnim, speed, easing ); 10556 } 10557 10558 // start at the smallest distance if we are hiding 10559 if ( hide ) { 10560 distance = distance / Math.pow( 2, times - 1 ); 10561 } 10562 10563 downAnim = {}; 10564 downAnim[ ref ] = 0; 10565 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 10566 for ( i = 0; i < times; i++ ) { 10567 upAnim = {}; 10568 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10569 10570 el.animate( upAnim, speed, easing ) 10571 .animate( downAnim, speed, easing ); 10572 10573 distance = hide ? distance * 2 : distance / 2; 10574 } 10575 10576 // Last Bounce when Hiding 10577 if ( hide ) { 10578 upAnim = { opacity: 0 }; 10579 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10580 10581 el.animate( upAnim, speed, easing ); 10582 } 10583 10584 el.queue(function() { 10585 if ( hide ) { 10586 el.hide(); 10587 } 10588 $.effects.restore( el, props ); 10589 $.effects.removeWrapper( el ); 10590 done(); 10591 }); 10592 10593 // inject all the animations we just queued to be first in line (after "inprogress") 10594 if ( queuelen > 1) { 10595 queue.splice.apply( queue, 10596 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10597 } 10598 el.dequeue(); 10599 10600}; 10601 10602})(jQuery); 10603 10604(function( $, undefined ) { 10605 10606$.effects.effect.clip = function( o, done ) { 10607 // Create element 10608 var el = $( this ), 10609 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10610 mode = $.effects.setMode( el, o.mode || "hide" ), 10611 show = mode === "show", 10612 direction = o.direction || "vertical", 10613 vert = direction === "vertical", 10614 size = vert ? "height" : "width", 10615 position = vert ? "top" : "left", 10616 animation = {}, 10617 wrapper, animate, distance; 10618 10619 // Save & Show 10620 $.effects.save( el, props ); 10621 el.show(); 10622 10623 // Create Wrapper 10624 wrapper = $.effects.createWrapper( el ).css({ 10625 overflow: "hidden" 10626 }); 10627 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 10628 distance = animate[ size ](); 10629 10630 // Shift 10631 if ( show ) { 10632 animate.css( size, 0 ); 10633 animate.css( position, distance / 2 ); 10634 } 10635 10636 // Create Animation Object: 10637 animation[ size ] = show ? distance : 0; 10638 animation[ position ] = show ? 0 : distance / 2; 10639 10640 // Animate 10641 animate.animate( animation, { 10642 queue: false, 10643 duration: o.duration, 10644 easing: o.easing, 10645 complete: function() { 10646 if ( !show ) { 10647 el.hide(); 10648 } 10649 $.effects.restore( el, props ); 10650 $.effects.removeWrapper( el ); 10651 done(); 10652 } 10653 }); 10654 10655}; 10656 10657})(jQuery); 10658 10659(function( $, undefined ) { 10660 10661$.effects.effect.drop = function( o, done ) { 10662 10663 var el = $( this ), 10664 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 10665 mode = $.effects.setMode( el, o.mode || "hide" ), 10666 show = mode === "show", 10667 direction = o.direction || "left", 10668 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10669 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 10670 animation = { 10671 opacity: show ? 1 : 0 10672 }, 10673 distance; 10674 10675 // Adjust 10676 $.effects.save( el, props ); 10677 el.show(); 10678 $.effects.createWrapper( el ); 10679 10680 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 10681 10682 if ( show ) { 10683 el 10684 .css( "opacity", 0 ) 10685 .css( ref, motion === "pos" ? -distance : distance ); 10686 } 10687 10688 // Animation 10689 animation[ ref ] = ( show ? 10690 ( motion === "pos" ? "+=" : "-=" ) : 10691 ( motion === "pos" ? "-=" : "+=" ) ) + 10692 distance; 10693 10694 // Animate 10695 el.animate( animation, { 10696 queue: false, 10697 duration: o.duration, 10698 easing: o.easing, 10699 complete: function() { 10700 if ( mode === "hide" ) { 10701 el.hide(); 10702 } 10703 $.effects.restore( el, props ); 10704 $.effects.removeWrapper( el ); 10705 done(); 10706 } 10707 }); 10708}; 10709 10710})(jQuery); 10711 10712(function( $, undefined ) { 10713 10714$.effects.effect.explode = function( o, done ) { 10715
vendor: 118,610 bytes, lines 10716-15007
10716 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 10717 cells = rows, 10718 el = $( this ), 10719 mode = $.effects.setMode( el, o.mode || "hide" ), 10720 show = mode === "show", 10721 10722 // show and then visibility:hidden the element before calculating offset 10723 offset = el.show().css( "visibility", "hidden" ).offset(), 10724 10725 // width and height of a piece 10726 width = Math.ceil( el.outerWidth() / cells ), 10727 height = Math.ceil( el.outerHeight() / rows ), 10728 pieces = [], 10729 10730 // loop 10731 i, j, left, top, mx, my; 10732 10733 // children animate complete: 10734 function childComplete() { 10735 pieces.push( this ); 10736 if ( pieces.length === rows * cells ) { 10737 animComplete(); 10738 } 10739 } 10740 10741 // clone the element for each row and cell. 10742 for( i = 0; i < rows ; i++ ) { // ===> 10743 top = offset.top + i * height; 10744 my = i - ( rows - 1 ) / 2 ; 10745 10746 for( j = 0; j < cells ; j++ ) { // ||| 10747 left = offset.left + j * width; 10748 mx = j - ( cells - 1 ) / 2 ; 10749 10750 // Create a clone of the now hidden main element that will be absolute positioned 10751 // within a wrapper div off the -left and -top equal to size of our pieces 10752 el 10753 .clone() 10754 .appendTo( "body" ) 10755 .wrap( "<div></div>" ) 10756 .css({ 10757 position: "absolute", 10758 visibility: "visible", 10759 left: -j * width, 10760 top: -i * height 10761 }) 10762 10763 // select the wrapper - make it overflow: hidden and absolute positioned based on 10764 // where the original was located +left and +top equal to the size of pieces 10765 .parent() 10766 .addClass( "ui-effects-explode" ) 10767 .css({ 10768 position: "absolute", 10769 overflow: "hidden", 10770 width: width, 10771 height: height, 10772 left: left + ( show ? mx * width : 0 ), 10773 top: top + ( show ? my * height : 0 ), 10774 opacity: show ? 0 : 1 10775 }).animate({ 10776 left: left + ( show ? 0 : mx * width ), 10777 top: top + ( show ? 0 : my * height ), 10778 opacity: show ? 1 : 0 10779 }, o.duration || 500, o.easing, childComplete ); 10780 } 10781 } 10782 10783 function animComplete() { 10784 el.css({ 10785 visibility: "visible" 10786 }); 10787 $( pieces ).remove(); 10788 if ( !show ) { 10789 el.hide(); 10790 } 10791 done(); 10792 } 10793}; 10794 10795})(jQuery); 10796 10797(function( $, undefined ) { 10798 10799$.effects.effect.fade = function( o, done ) { 10800 var el = $( this ), 10801 mode = $.effects.setMode( el, o.mode || "toggle" ); 10802 10803 el.animate({ 10804 opacity: mode 10805 }, { 10806 queue: false, 10807 duration: o.duration, 10808 easing: o.easing, 10809 complete: done 10810 }); 10811}; 10812 10813})( jQuery ); 10814 10815(function( $, undefined ) { 10816 10817$.effects.effect.fold = function( o, done ) { 10818 10819 // Create element 10820 var el = $( this ), 10821 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10822 mode = $.effects.setMode( el, o.mode || "hide" ), 10823 show = mode === "show", 10824 hide = mode === "hide", 10825 size = o.size || 15, 10826 percent = /([0-9]+)%/.exec( size ), 10827 horizFirst = !!o.horizFirst, 10828 widthFirst = show !== horizFirst, 10829 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 10830 duration = o.duration / 2, 10831 wrapper, distance, 10832 animation1 = {}, 10833 animation2 = {}; 10834 10835 $.effects.save( el, props ); 10836 el.show(); 10837 10838 // Create Wrapper 10839 wrapper = $.effects.createWrapper( el ).css({ 10840 overflow: "hidden" 10841 }); 10842 distance = widthFirst ? 10843 [ wrapper.width(), wrapper.height() ] : 10844 [ wrapper.height(), wrapper.width() ]; 10845 10846 if ( percent ) { 10847 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 10848 } 10849 if ( show ) { 10850 wrapper.css( horizFirst ? { 10851 height: 0, 10852 width: size 10853 } : { 10854 height: size, 10855 width: 0 10856 }); 10857 } 10858 10859 // Animation 10860 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 10861 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 10862 10863 // Animate 10864 wrapper 10865 .animate( animation1, duration, o.easing ) 10866 .animate( animation2, duration, o.easing, function() { 10867 if ( hide ) { 10868 el.hide(); 10869 } 10870 $.effects.restore( el, props ); 10871 $.effects.removeWrapper( el ); 10872 done(); 10873 }); 10874 10875}; 10876 10877})(jQuery); 10878 10879(function( $, undefined ) { 10880 10881$.effects.effect.highlight = function( o, done ) { 10882 var elem = $( this ), 10883 props = [ "backgroundImage", "backgroundColor", "opacity" ], 10884 mode = $.effects.setMode( elem, o.mode || "show" ), 10885 animation = { 10886 backgroundColor: elem.css( "backgroundColor" ) 10887 }; 10888 10889 if (mode === "hide") { 10890 animation.opacity = 0; 10891 } 10892 10893 $.effects.save( elem, props ); 10894 10895 elem 10896 .show() 10897 .css({ 10898 backgroundImage: "none", 10899 backgroundColor: o.color || "#ffff99" 10900 }) 10901 .animate( animation, { 10902 queue: false, 10903 duration: o.duration, 10904 easing: o.easing, 10905 complete: function() { 10906 if ( mode === "hide" ) { 10907 elem.hide(); 10908 } 10909 $.effects.restore( elem, props ); 10910 done(); 10911 } 10912 }); 10913}; 10914 10915})(jQuery); 10916 10917(function( $, undefined ) { 10918 10919$.effects.effect.pulsate = function( o, done ) { 10920 var elem = $( this ), 10921 mode = $.effects.setMode( elem, o.mode || "show" ), 10922 show = mode === "show", 10923 hide = mode === "hide", 10924 showhide = ( show || mode === "hide" ), 10925 10926 // showing or hiding leaves of the "last" animation 10927 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 10928 duration = o.duration / anims, 10929 animateTo = 0, 10930 queue = elem.queue(), 10931 queuelen = queue.length, 10932 i; 10933 10934 if ( show || !elem.is(":visible")) { 10935 elem.css( "opacity", 0 ).show(); 10936 animateTo = 1; 10937 } 10938 10939 // anims - 1 opacity "toggles" 10940 for ( i = 1; i < anims; i++ ) { 10941 elem.animate({ 10942 opacity: animateTo 10943 }, duration, o.easing ); 10944 animateTo = 1 - animateTo; 10945 } 10946 10947 elem.animate({ 10948 opacity: animateTo 10949 }, duration, o.easing); 10950 10951 elem.queue(function() { 10952 if ( hide ) { 10953 elem.hide(); 10954 } 10955 done(); 10956 }); 10957 10958 // We just queued up "anims" animations, we need to put them next in the queue 10959 if ( queuelen > 1 ) { 10960 queue.splice.apply( queue, 10961 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10962 } 10963 elem.dequeue(); 10964}; 10965 10966})(jQuery); 10967 10968(function( $, undefined ) { 10969 10970$.effects.effect.puff = function( o, done ) { 10971 var elem = $( this ), 10972 mode = $.effects.setMode( elem, o.mode || "hide" ), 10973 hide = mode === "hide", 10974 percent = parseInt( o.percent, 10 ) || 150, 10975 factor = percent / 100, 10976 original = { 10977 height: elem.height(), 10978 width: elem.width(), 10979 outerHeight: elem.outerHeight(), 10980 outerWidth: elem.outerWidth() 10981 }; 10982 10983 $.extend( o, { 10984 effect: "scale", 10985 queue: false, 10986 fade: true, 10987 mode: mode, 10988 complete: done, 10989 percent: hide ? percent : 100, 10990 from: hide ? 10991 original : 10992 { 10993 height: original.height * factor, 10994 width: original.width * factor, 10995 outerHeight: original.outerHeight * factor, 10996 outerWidth: original.outerWidth * factor 10997 } 10998 }); 10999 11000 elem.effect( o ); 11001}; 11002 11003$.effects.effect.scale = function( o, done ) { 11004 11005 // Create element 11006 var el = $( this ), 11007 options = $.extend( true, {}, o ), 11008 mode = $.effects.setMode( el, o.mode || "effect" ), 11009 percent = parseInt( o.percent, 10 ) || 11010 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 11011 direction = o.direction || "both", 11012 origin = o.origin, 11013 original = { 11014 height: el.height(), 11015 width: el.width(), 11016 outerHeight: el.outerHeight(), 11017 outerWidth: el.outerWidth() 11018 }, 11019 factor = { 11020 y: direction !== "horizontal" ? (percent / 100) : 1, 11021 x: direction !== "vertical" ? (percent / 100) : 1 11022 }; 11023 11024 // We are going to pass this effect to the size effect: 11025 options.effect = "size"; 11026 options.queue = false; 11027 options.complete = done; 11028 11029 // Set default origin and restore for show/hide 11030 if ( mode !== "effect" ) { 11031 options.origin = origin || ["middle","center"]; 11032 options.restore = true; 11033 } 11034 11035 options.from = o.from || ( mode === "show" ? { 11036 height: 0, 11037 width: 0, 11038 outerHeight: 0, 11039 outerWidth: 0 11040 } : original ); 11041 options.to = { 11042 height: original.height * factor.y, 11043 width: original.width * factor.x, 11044 outerHeight: original.outerHeight * factor.y, 11045 outerWidth: original.outerWidth * factor.x 11046 }; 11047 11048 // Fade option to support puff 11049 if ( options.fade ) { 11050 if ( mode === "show" ) { 11051 options.from.opacity = 0; 11052 options.to.opacity = 1; 11053 } 11054 if ( mode === "hide" ) { 11055 options.from.opacity = 1; 11056 options.to.opacity = 0; 11057 } 11058 } 11059 11060 // Animate 11061 el.effect( options ); 11062 11063}; 11064 11065$.effects.effect.size = function( o, done ) { 11066 11067 // Create element 11068 var original, baseline, factor, 11069 el = $( this ), 11070 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 11071 11072 // Always restore 11073 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 11074 11075 // Copy for children 11076 props2 = [ "width", "height", "overflow" ], 11077 cProps = [ "fontSize" ], 11078 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 11079 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 11080 11081 // Set options 11082 mode = $.effects.setMode( el, o.mode || "effect" ), 11083 restore = o.restore || mode !== "effect", 11084 scale = o.scale || "both", 11085 origin = o.origin || [ "middle", "center" ], 11086 position = el.css( "position" ), 11087 props = restore ? props0 : props1, 11088 zero = { 11089 height: 0, 11090 width: 0, 11091 outerHeight: 0, 11092 outerWidth: 0 11093 }; 11094 11095 if ( mode === "show" ) { 11096 el.show(); 11097 } 11098 original = { 11099 height: el.height(), 11100 width: el.width(), 11101 outerHeight: el.outerHeight(), 11102 outerWidth: el.outerWidth() 11103 }; 11104 11105 if ( o.mode === "toggle" && mode === "show" ) { 11106 el.from = o.to || zero; 11107 el.to = o.from || original; 11108 } else { 11109 el.from = o.from || ( mode === "show" ? zero : original ); 11110 el.to = o.to || ( mode === "hide" ? zero : original ); 11111 } 11112 11113 // Set scaling factor 11114 factor = { 11115 from: { 11116 y: el.from.height / original.height, 11117 x: el.from.width / original.width 11118 }, 11119 to: { 11120 y: el.to.height / original.height, 11121 x: el.to.width / original.width 11122 } 11123 }; 11124 11125 // Scale the css box 11126 if ( scale === "box" || scale === "both" ) { 11127 11128 // Vertical props scaling 11129 if ( factor.from.y !== factor.to.y ) { 11130 props = props.concat( vProps ); 11131 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 11132 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 11133 } 11134 11135 // Horizontal props scaling 11136 if ( factor.from.x !== factor.to.x ) { 11137 props = props.concat( hProps ); 11138 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 11139 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 11140 } 11141 } 11142 11143 // Scale the content 11144 if ( scale === "content" || scale === "both" ) { 11145 11146 // Vertical props scaling 11147 if ( factor.from.y !== factor.to.y ) { 11148 props = props.concat( cProps ).concat( props2 ); 11149 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 11150 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 11151 } 11152 } 11153 11154 $.effects.save( el, props ); 11155 el.show(); 11156 $.effects.createWrapper( el ); 11157 el.css( "overflow", "hidden" ).css( el.from ); 11158 11159 // Adjust 11160 if (origin) { // Calculate baseline shifts 11161 baseline = $.effects.getBaseline( origin, original ); 11162 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 11163 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 11164 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 11165 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 11166 } 11167 el.css( el.from ); // set top & left 11168 11169 // Animate 11170 if ( scale === "content" || scale === "both" ) { // Scale the children 11171 11172 // Add margins/font-size 11173 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 11174 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 11175 props2 = props0.concat(vProps).concat(hProps); 11176 11177 el.find( "*[width]" ).each( function(){ 11178 var child = $( this ), 11179 c_original = { 11180 height: child.height(), 11181 width: child.width(), 11182 outerHeight: child.outerHeight(), 11183 outerWidth: child.outerWidth() 11184 }; 11185 if (restore) { 11186 $.effects.save(child, props2); 11187 } 11188 11189 child.from = { 11190 height: c_original.height * factor.from.y, 11191 width: c_original.width * factor.from.x, 11192 outerHeight: c_original.outerHeight * factor.from.y, 11193 outerWidth: c_original.outerWidth * factor.from.x 11194 }; 11195 child.to = { 11196 height: c_original.height * factor.to.y, 11197 width: c_original.width * factor.to.x, 11198 outerHeight: c_original.height * factor.to.y, 11199 outerWidth: c_original.width * factor.to.x 11200 }; 11201 11202 // Vertical props scaling 11203 if ( factor.from.y !== factor.to.y ) { 11204 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 11205 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 11206 } 11207 11208 // Horizontal props scaling 11209 if ( factor.from.x !== factor.to.x ) { 11210 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 11211 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 11212 } 11213 11214 // Animate children 11215 child.css( child.from ); 11216 child.animate( child.to, o.duration, o.easing, function() { 11217 11218 // Restore children 11219 if ( restore ) { 11220 $.effects.restore( child, props2 ); 11221 } 11222 }); 11223 }); 11224 } 11225 11226 // Animate 11227 el.animate( el.to, { 11228 queue: false, 11229 duration: o.duration, 11230 easing: o.easing, 11231 complete: function() { 11232 if ( el.to.opacity === 0 ) { 11233 el.css( "opacity", el.from.opacity ); 11234 } 11235 if( mode === "hide" ) { 11236 el.hide(); 11237 } 11238 $.effects.restore( el, props ); 11239 if ( !restore ) { 11240 11241 // we need to calculate our new positioning based on the scaling 11242 if ( position === "static" ) { 11243 el.css({ 11244 position: "relative", 11245 top: el.to.top, 11246 left: el.to.left 11247 }); 11248 } else { 11249 $.each([ "top", "left" ], function( idx, pos ) { 11250 el.css( pos, function( _, str ) { 11251 var val = parseInt( str, 10 ), 11252 toRef = idx ? el.to.left : el.to.top; 11253 11254 // if original was "auto", recalculate the new value from wrapper 11255 if ( str === "auto" ) { 11256 return toRef + "px"; 11257 } 11258 11259 return val + toRef + "px"; 11260 }); 11261 }); 11262 } 11263 } 11264 11265 $.effects.removeWrapper( el ); 11266 done(); 11267 } 11268 }); 11269 11270}; 11271 11272})(jQuery); 11273 11274(function( $, undefined ) { 11275 11276$.effects.effect.shake = function( o, done ) { 11277 11278 var el = $( this ), 11279 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11280 mode = $.effects.setMode( el, o.mode || "effect" ), 11281 direction = o.direction || "left", 11282 distance = o.distance || 20, 11283 times = o.times || 3, 11284 anims = times * 2 + 1, 11285 speed = Math.round(o.duration/anims), 11286 ref = (direction === "up" || direction === "down") ? "top" : "left", 11287 positiveMotion = (direction === "up" || direction === "left"), 11288 animation = {}, 11289 animation1 = {}, 11290 animation2 = {}, 11291 i, 11292 11293 // we will need to re-assemble the queue to stack our animations in place 11294 queue = el.queue(), 11295 queuelen = queue.length; 11296 11297 $.effects.save( el, props ); 11298 el.show(); 11299 $.effects.createWrapper( el ); 11300 11301 // Animation 11302 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 11303 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 11304 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 11305 11306 // Animate 11307 el.animate( animation, speed, o.easing ); 11308 11309 // Shakes 11310 for ( i = 1; i < times; i++ ) { 11311 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 11312 } 11313 el 11314 .animate( animation1, speed, o.easing ) 11315 .animate( animation, speed / 2, o.easing ) 11316 .queue(function() { 11317 if ( mode === "hide" ) { 11318 el.hide(); 11319 } 11320 $.effects.restore( el, props ); 11321 $.effects.removeWrapper( el ); 11322 done(); 11323 }); 11324 11325 // inject all the animations we just queued to be first in line (after "inprogress") 11326 if ( queuelen > 1) { 11327 queue.splice.apply( queue, 11328 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11329 } 11330 el.dequeue(); 11331 11332}; 11333 11334})(jQuery); 11335 11336(function( $, undefined ) { 11337 11338$.effects.effect.slide = function( o, done ) { 11339 11340 // Create element 11341 var el = $( this ), 11342 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 11343 mode = $.effects.setMode( el, o.mode || "show" ), 11344 show = mode === "show", 11345 direction = o.direction || "left", 11346 ref = (direction === "up" || direction === "down") ? "top" : "left", 11347 positiveMotion = (direction === "up" || direction === "left"), 11348 distance, 11349 animation = {}; 11350 11351 // Adjust 11352 $.effects.save( el, props ); 11353 el.show(); 11354 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 11355 11356 $.effects.createWrapper( el ).css({ 11357 overflow: "hidden" 11358 }); 11359 11360 if ( show ) { 11361 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 11362 } 11363 11364 // Animation 11365 animation[ ref ] = ( show ? 11366 ( positiveMotion ? "+=" : "-=") : 11367 ( positiveMotion ? "-=" : "+=")) + 11368 distance; 11369 11370 // Animate 11371 el.animate( animation, { 11372 queue: false, 11373 duration: o.duration, 11374 easing: o.easing, 11375 complete: function() { 11376 if ( mode === "hide" ) { 11377 el.hide(); 11378 } 11379 $.effects.restore( el, props ); 11380 $.effects.removeWrapper( el ); 11381 done(); 11382 } 11383 }); 11384}; 11385 11386})(jQuery); 11387 11388(function( $, undefined ) { 11389 11390$.effects.effect.transfer = function( o, done ) { 11391 var elem = $( this ), 11392 target = $( o.to ), 11393 targetFixed = target.css( "position" ) === "fixed", 11394 body = $("body"), 11395 fixTop = targetFixed ? body.scrollTop() : 0, 11396 fixLeft = targetFixed ? body.scrollLeft() : 0, 11397 endPosition = target.offset(), 11398 animation = { 11399 top: endPosition.top - fixTop , 11400 left: endPosition.left - fixLeft , 11401 height: target.innerHeight(), 11402 width: target.innerWidth() 11403 }, 11404 startPosition = elem.offset(), 11405 transfer = $( "<div class='ui-effects-transfer'></div>" ) 11406 .appendTo( document.body ) 11407 .addClass( o.className ) 11408 .css({ 11409 top: startPosition.top - fixTop , 11410 left: startPosition.left - fixLeft , 11411 height: elem.innerHeight(), 11412 width: elem.innerWidth(), 11413 position: targetFixed ? "fixed" : "absolute" 11414 }) 11415 .animate( animation, o.duration, o.easing, function() { 11416 transfer.remove(); 11417 done(); 11418 }); 11419}; 11420 11421})(jQuery); 11422 11423(function( $, undefined ) { 11424 11425$.widget( "ui.menu", { 11426 version: "1.10.3", 11427 defaultElement: "<ul>", 11428 delay: 300, 11429 options: { 11430 icons: { 11431 submenu: "ui-icon-carat-1-e" 11432 }, 11433 menus: "ul", 11434 position: { 11435 my: "left top", 11436 at: "right top" 11437 }, 11438 role: "menu", 11439 11440 // callbacks 11441 blur: null, 11442 focus: null, 11443 select: null 11444 }, 11445 11446 _create: function() { 11447 this.activeMenu = this.element; 11448 // flag used to prevent firing of the click handler 11449 // as the event bubbles up through nested menus 11450 this.mouseHandled = false; 11451 this.element 11452 .uniqueId() 11453 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11454 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 11455 .attr({ 11456 role: this.options.role, 11457 tabIndex: 0 11458 }) 11459 // need to catch all clicks on disabled menu 11460 // not possible through _on 11461 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 11462 if ( this.options.disabled ) { 11463 event.preventDefault(); 11464 } 11465 }, this )); 11466 11467 if ( this.options.disabled ) { 11468 this.element 11469 .addClass( "ui-state-disabled" ) 11470 .attr( "aria-disabled", "true" ); 11471 } 11472 11473 this._on({ 11474 // Prevent focus from sticking to links inside menu after clicking 11475 // them (focus should always stay on UL during navigation). 11476 "mousedown .ui-menu-item > a": function( event ) { 11477 event.preventDefault(); 11478 }, 11479 "click .ui-state-disabled > a": function( event ) { 11480 event.preventDefault(); 11481 }, 11482 "click .ui-menu-item:has(a)": function( event ) { 11483 var target = $( event.target ).closest( ".ui-menu-item" ); 11484 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 11485 this.mouseHandled = true; 11486 11487 this.select( event ); 11488 // Open submenu on click 11489 if ( target.has( ".ui-menu" ).length ) { 11490 this.expand( event ); 11491 } else if ( !this.element.is( ":focus" ) ) { 11492 // Redirect focus to the menu 11493 this.element.trigger( "focus", [ true ] ); 11494 11495 // If the active item is on the top level, let it stay active. 11496 // Otherwise, blur the active item since it is no longer visible. 11497 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 11498 clearTimeout( this.timer ); 11499 } 11500 } 11501 } 11502 }, 11503 "mouseenter .ui-menu-item": function( event ) { 11504 var target = $( event.currentTarget ); 11505 // Remove ui-state-active class from siblings of the newly focused menu item 11506 // to avoid a jump caused by adjacent elements both having a class with a border 11507 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 11508 this.focus( event, target ); 11509 }, 11510 mouseleave: "collapseAll", 11511 "mouseleave .ui-menu": "collapseAll", 11512 focus: function( event, keepActiveItem ) { 11513 // If there's already an active item, keep it active 11514 // If not, activate the first item 11515 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 11516 11517 if ( !keepActiveItem ) { 11518 this.focus( event, item ); 11519 } 11520 }, 11521 blur: function( event ) { 11522 this._delay(function() { 11523 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 11524 this.collapseAll( event ); 11525 } 11526 }); 11527 }, 11528 keydown: "_keydown" 11529 }); 11530 11531 this.refresh(); 11532 11533 // Clicks outside of a menu collapse any open menus 11534 this._on( this.document, { 11535 click: function( event ) { 11536 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 11537 this.collapseAll( event ); 11538 } 11539 11540 // Reset the mouseHandled flag 11541 this.mouseHandled = false; 11542 } 11543 }); 11544 }, 11545 11546 _destroy: function() { 11547 // Destroy (sub)menus 11548 this.element 11549 .removeAttr( "aria-activedescendant" ) 11550 .find( ".ui-menu" ).addBack() 11551 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 11552 .removeAttr( "role" ) 11553 .removeAttr( "tabIndex" ) 11554 .removeAttr( "aria-labelledby" ) 11555 .removeAttr( "aria-expanded" ) 11556 .removeAttr( "aria-hidden" ) 11557 .removeAttr( "aria-disabled" ) 11558 .removeUniqueId() 11559 .show(); 11560 11561 // Destroy menu items 11562 this.element.find( ".ui-menu-item" ) 11563 .removeClass( "ui-menu-item" ) 11564 .removeAttr( "role" ) 11565 .removeAttr( "aria-disabled" ) 11566 .children( "a" ) 11567 .removeUniqueId() 11568 .removeClass( "ui-corner-all ui-state-hover" ) 11569 .removeAttr( "tabIndex" ) 11570 .removeAttr( "role" ) 11571 .removeAttr( "aria-haspopup" ) 11572 .children().each( function() { 11573 var elem = $( this ); 11574 if ( elem.data( "ui-menu-submenu-carat" ) ) { 11575 elem.remove(); 11576 } 11577 }); 11578 11579 // Destroy menu dividers 11580 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 11581 }, 11582 11583 _keydown: function( event ) { 11584 /*jshint maxcomplexity:20*/ 11585 var match, prev, character, skip, regex, 11586 preventDefault = true; 11587 11588 function escape( value ) { 11589 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 11590 } 11591 11592 switch ( event.keyCode ) { 11593 case $.ui.keyCode.PAGE_UP: 11594 this.previousPage( event ); 11595 break; 11596 case $.ui.keyCode.PAGE_DOWN: 11597 this.nextPage( event ); 11598 break; 11599 case $.ui.keyCode.HOME: 11600 this._move( "first", "first", event ); 11601 break; 11602 case $.ui.keyCode.END: 11603 this._move( "last", "last", event ); 11604 break; 11605 case $.ui.keyCode.UP: 11606 this.previous( event ); 11607 break; 11608 case $.ui.keyCode.DOWN: 11609 this.next( event ); 11610 break; 11611 case $.ui.keyCode.LEFT: 11612 this.collapse( event ); 11613 break; 11614 case $.ui.keyCode.RIGHT: 11615 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 11616 this.expand( event ); 11617 } 11618 break; 11619 case $.ui.keyCode.ENTER: 11620 case $.ui.keyCode.SPACE: 11621 this._activate( event ); 11622 break; 11623 case $.ui.keyCode.ESCAPE: 11624 this.collapse( event ); 11625 break; 11626 default: 11627 preventDefault = false; 11628 prev = this.previousFilter || ""; 11629 character = String.fromCharCode( event.keyCode ); 11630 skip = false; 11631 11632 clearTimeout( this.filterTimer ); 11633 11634 11635 if ( character === prev ) { 11636 skip = true; 11637 } else { 11638 character = prev + character; 11639 } 11640 11641 regex = new RegExp( "^" + escape( character ), "i" ); 11642 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11643 return regex.test( $( this ).children( "a" ).text() ); 11644 }); 11645 match = skip && match.index( this.active.next() ) !== -1 ? 11646 this.active.nextAll( ".ui-menu-item" ) : 11647 match; 11648 11649 // If no matches on the current filter, reset to the last character pressed 11650 // to move down the menu to the first item that starts with that character 11651 if ( !match.length ) { 11652 character = String.fromCharCode( event.keyCode ); 11653 regex = new RegExp( "^" + escape( character ), "i" ); 11654 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11655 return regex.test( $( this ).children( "a" ).text() ); 11656 }); 11657 } 11658 11659 if ( match.length ) { 11660 this.focus( event, match ); 11661 if ( match.length > 1 ) { 11662 this.previousFilter = character; 11663 this.filterTimer = this._delay(function() { 11664 delete this.previousFilter; 11665 }, 1000 ); 11666 } else { 11667 delete this.previousFilter; 11668 } 11669 } else { 11670 delete this.previousFilter; 11671 } 11672 } 11673 11674 if ( preventDefault ) { 11675 event.preventDefault(); 11676 } 11677 }, 11678 11679 _activate: function( event ) { 11680 if ( !this.active.is( ".ui-state-disabled" ) ) { 11681 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 11682 this.expand( event ); 11683 } else { 11684 this.select( event ); 11685 } 11686 } 11687 }, 11688 11689 refresh: function() { 11690 var menus, 11691 icon = this.options.icons.submenu, 11692 submenus = this.element.find( this.options.menus ); 11693 11694 // Initialize nested menus 11695 submenus.filter( ":not(.ui-menu)" ) 11696 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11697 .hide() 11698 .attr({ 11699 role: this.options.role, 11700 "aria-hidden": "true", 11701 "aria-expanded": "false" 11702 }) 11703 .each(function() { 11704 var menu = $( this ), 11705 item = menu.prev( "a" ), 11706 submenuCarat = $( "<span>" ) 11707 .addClass( "ui-menu-icon ui-icon " + icon ) 11708 .data( "ui-menu-submenu-carat", true ); 11709 11710 item 11711 .attr( "aria-haspopup", "true" ) 11712 .prepend( submenuCarat ); 11713 menu.attr( "aria-labelledby", item.attr( "id" ) ); 11714 }); 11715 11716 menus = submenus.add( this.element ); 11717 11718 // Don't refresh list items that are already adapted 11719 menus.children( ":not(.ui-menu-item):has(a)" ) 11720 .addClass( "ui-menu-item" ) 11721 .attr( "role", "presentation" ) 11722 .children( "a" ) 11723 .uniqueId() 11724 .addClass( "ui-corner-all" ) 11725 .attr({ 11726 tabIndex: -1, 11727 role: this._itemRole() 11728 }); 11729 11730 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 11731 menus.children( ":not(.ui-menu-item)" ).each(function() { 11732 var item = $( this ); 11733 // hyphen, em dash, en dash 11734 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 11735 item.addClass( "ui-widget-content ui-menu-divider" ); 11736 } 11737 }); 11738 11739 // Add aria-disabled attribute to any disabled menu item 11740 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 11741 11742 // If the active item has been removed, blur the menu 11743 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 11744 this.blur(); 11745 } 11746 }, 11747 11748 _itemRole: function() { 11749 return { 11750 menu: "menuitem", 11751 listbox: "option" 11752 }[ this.options.role ]; 11753 }, 11754 11755 _setOption: function( key, value ) { 11756 if ( key === "icons" ) { 11757 this.element.find( ".ui-menu-icon" ) 11758 .removeClass( this.options.icons.submenu ) 11759 .addClass( value.submenu ); 11760 } 11761 this._super( key, value ); 11762 }, 11763 11764 focus: function( event, item ) { 11765 var nested, focused; 11766 this.blur( event, event && event.type === "focus" ); 11767 11768 this._scrollIntoView( item ); 11769 11770 this.active = item.first(); 11771 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 11772 // Only update aria-activedescendant if there's a role 11773 // otherwise we assume focus is managed elsewhere 11774 if ( this.options.role ) { 11775 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 11776 } 11777 11778 // Highlight active parent menu item, if any 11779 this.active 11780 .parent() 11781 .closest( ".ui-menu-item" ) 11782 .children( "a:first" ) 11783 .addClass( "ui-state-active" ); 11784 11785 if ( event && event.type === "keydown" ) { 11786 this._close(); 11787 } else { 11788 this.timer = this._delay(function() { 11789 this._close(); 11790 }, this.delay ); 11791 } 11792 11793 nested = item.children( ".ui-menu" ); 11794 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 11795 this._startOpening(nested); 11796 } 11797 this.activeMenu = item.parent(); 11798 11799 this._trigger( "focus", event, { item: item } ); 11800 }, 11801 11802 _scrollIntoView: function( item ) { 11803 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 11804 if ( this._hasScroll() ) { 11805 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 11806 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 11807 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 11808 scroll = this.activeMenu.scrollTop(); 11809 elementHeight = this.activeMenu.height(); 11810 itemHeight = item.height(); 11811 11812 if ( offset < 0 ) { 11813 this.activeMenu.scrollTop( scroll + offset ); 11814 } else if ( offset + itemHeight > elementHeight ) { 11815 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 11816 } 11817 } 11818 }, 11819 11820 blur: function( event, fromFocus ) { 11821 if ( !fromFocus ) { 11822 clearTimeout( this.timer ); 11823 } 11824 11825 if ( !this.active ) { 11826 return; 11827 } 11828 11829 this.active.children( "a" ).removeClass( "ui-state-focus" ); 11830 this.active = null; 11831 11832 this._trigger( "blur", event, { item: this.active } ); 11833 }, 11834 11835 _startOpening: function( submenu ) { 11836 clearTimeout( this.timer ); 11837 11838 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 11839 // shift in the submenu position when mousing over the carat icon 11840 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 11841 return; 11842 } 11843 11844 this.timer = this._delay(function() { 11845 this._close(); 11846 this._open( submenu ); 11847 }, this.delay ); 11848 }, 11849 11850 _open: function( submenu ) { 11851 var position = $.extend({ 11852 of: this.active 11853 }, this.options.position ); 11854 11855 clearTimeout( this.timer ); 11856 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 11857 .hide() 11858 .attr( "aria-hidden", "true" ); 11859 11860 submenu 11861 .show() 11862 .removeAttr( "aria-hidden" ) 11863 .attr( "aria-expanded", "true" ) 11864 .position( position ); 11865 }, 11866 11867 collapseAll: function( event, all ) { 11868 clearTimeout( this.timer ); 11869 this.timer = this._delay(function() { 11870 // If we were passed an event, look for the submenu that contains the event 11871 var currentMenu = all ? this.element : 11872 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 11873 11874 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 11875 if ( !currentMenu.length ) { 11876 currentMenu = this.element; 11877 } 11878 11879 this._close( currentMenu ); 11880 11881 this.blur( event ); 11882 this.activeMenu = currentMenu; 11883 }, this.delay ); 11884 }, 11885 11886 // With no arguments, closes the currently active menu - if nothing is active 11887 // it closes all menus. If passed an argument, it will search for menus BELOW 11888 _close: function( startMenu ) { 11889 if ( !startMenu ) { 11890 startMenu = this.active ? this.active.parent() : this.element; 11891 } 11892 11893 startMenu 11894 .find( ".ui-menu" ) 11895 .hide() 11896 .attr( "aria-hidden", "true" ) 11897 .attr( "aria-expanded", "false" ) 11898 .end() 11899 .find( "a.ui-state-active" ) 11900 .removeClass( "ui-state-active" ); 11901 }, 11902 11903 collapse: function( event ) { 11904 var newItem = this.active && 11905 this.active.parent().closest( ".ui-menu-item", this.element ); 11906 if ( newItem && newItem.length ) { 11907 this._close(); 11908 this.focus( event, newItem ); 11909 } 11910 }, 11911 11912 expand: function( event ) { 11913 var newItem = this.active && 11914 this.active 11915 .children( ".ui-menu " ) 11916 .children( ".ui-menu-item" ) 11917 .first(); 11918 11919 if ( newItem && newItem.length ) { 11920 this._open( newItem.parent() ); 11921 11922 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 11923 this._delay(function() { 11924 this.focus( event, newItem ); 11925 }); 11926 } 11927 }, 11928 11929 next: function( event ) { 11930 this._move( "next", "first", event ); 11931 }, 11932 11933 previous: function( event ) { 11934 this._move( "prev", "last", event ); 11935 }, 11936 11937 isFirstItem: function() { 11938 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 11939 }, 11940 11941 isLastItem: function() { 11942 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 11943 }, 11944 11945 _move: function( direction, filter, event ) { 11946 var next; 11947 if ( this.active ) { 11948 if ( direction === "first" || direction === "last" ) { 11949 next = this.active 11950 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 11951 .eq( -1 ); 11952 } else { 11953 next = this.active 11954 [ direction + "All" ]( ".ui-menu-item" ) 11955 .eq( 0 ); 11956 } 11957 } 11958 if ( !next || !next.length || !this.active ) { 11959 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 11960 } 11961 11962 this.focus( event, next ); 11963 }, 11964 11965 nextPage: function( event ) { 11966 var item, base, height; 11967 11968 if ( !this.active ) { 11969 this.next( event ); 11970 return; 11971 } 11972 if ( this.isLastItem() ) { 11973 return; 11974 } 11975 if ( this._hasScroll() ) { 11976 base = this.active.offset().top; 11977 height = this.element.height(); 11978 this.active.nextAll( ".ui-menu-item" ).each(function() { 11979 item = $( this ); 11980 return item.offset().top - base - height < 0; 11981 }); 11982 11983 this.focus( event, item ); 11984 } else { 11985 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 11986 [ !this.active ? "first" : "last" ]() ); 11987 } 11988 }, 11989 11990 previousPage: function( event ) { 11991 var item, base, height; 11992 if ( !this.active ) { 11993 this.next( event ); 11994 return; 11995 } 11996 if ( this.isFirstItem() ) { 11997 return; 11998 } 11999 if ( this._hasScroll() ) { 12000 base = this.active.offset().top; 12001 height = this.element.height(); 12002 this.active.prevAll( ".ui-menu-item" ).each(function() { 12003 item = $( this ); 12004 return item.offset().top - base + height > 0; 12005 }); 12006 12007 this.focus( event, item ); 12008 } else { 12009 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 12010 } 12011 }, 12012 12013 _hasScroll: function() { 12014 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 12015 }, 12016 12017 select: function( event ) { 12018 // TODO: It should never be possible to not have an active item at this 12019 // point, but the tests don't trigger mouseenter before click. 12020 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 12021 var ui = { item: this.active }; 12022 if ( !this.active.has( ".ui-menu" ).length ) { 12023 this.collapseAll( event, true ); 12024 } 12025 this._trigger( "select", event, ui ); 12026 } 12027}); 12028 12029}( jQuery )); 12030 12031(function( $, undefined ) { 12032 12033$.ui = $.ui || {}; 12034 12035var cachedScrollbarWidth, 12036 max = Math.max, 12037 abs = Math.abs, 12038 round = Math.round, 12039 rhorizontal = /left|center|right/, 12040 rvertical = /top|center|bottom/, 12041 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 12042 rposition = /^\w+/, 12043 rpercent = /%$/, 12044 _position = $.fn.position; 12045 12046function getOffsets( offsets, width, height ) { 12047 return [ 12048 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 12049 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 12050 ]; 12051} 12052 12053function parseCss( element, property ) { 12054 return parseInt( $.css( element, property ), 10 ) || 0; 12055} 12056 12057function getDimensions( elem ) { 12058 var raw = elem[0]; 12059 if ( raw.nodeType === 9 ) { 12060 return { 12061 width: elem.width(), 12062 height: elem.height(), 12063 offset: { top: 0, left: 0 } 12064 }; 12065 } 12066 if ( $.isWindow( raw ) ) { 12067 return { 12068 width: elem.width(), 12069 height: elem.height(), 12070 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 12071 }; 12072 } 12073 if ( raw.preventDefault ) { 12074 return { 12075 width: 0, 12076 height: 0, 12077 offset: { top: raw.pageY, left: raw.pageX } 12078 }; 12079 } 12080 return { 12081 width: elem.outerWidth(), 12082 height: elem.outerHeight(), 12083 offset: elem.offset() 12084 }; 12085} 12086 12087$.position = { 12088 scrollbarWidth: function() { 12089 if ( cachedScrollbarWidth !== undefined ) { 12090 return cachedScrollbarWidth; 12091 } 12092 var w1, w2, 12093 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 12094 innerDiv = div.children()[0]; 12095 12096 $( "body" ).append( div ); 12097 w1 = innerDiv.offsetWidth; 12098 div.css( "overflow", "scroll" ); 12099 12100 w2 = innerDiv.offsetWidth; 12101 12102 if ( w1 === w2 ) { 12103 w2 = div[0].clientWidth; 12104 } 12105 12106 div.remove(); 12107 12108 return (cachedScrollbarWidth = w1 - w2); 12109 }, 12110 getScrollInfo: function( within ) { 12111 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 12112 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 12113 hasOverflowX = overflowX === "scroll" || 12114 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 12115 hasOverflowY = overflowY === "scroll" || 12116 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 12117 return { 12118 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 12119 height: hasOverflowX ? $.position.scrollbarWidth() : 0 12120 }; 12121 }, 12122 getWithinInfo: function( element ) { 12123 var withinElement = $( element || window ), 12124 isWindow = $.isWindow( withinElement[0] ); 12125 return { 12126 element: withinElement, 12127 isWindow: isWindow, 12128 offset: withinElement.offset() || { left: 0, top: 0 }, 12129 scrollLeft: withinElement.scrollLeft(), 12130 scrollTop: withinElement.scrollTop(), 12131 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 12132 height: isWindow ? withinElement.height() : withinElement.outerHeight() 12133 }; 12134 } 12135}; 12136 12137$.fn.position = function( options ) { 12138 if ( !options || !options.of ) { 12139 return _position.apply( this, arguments ); 12140 } 12141 12142 // make a copy, we don't want to modify arguments 12143 options = $.extend( {}, options ); 12144 12145 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 12146 target = $( options.of ), 12147 within = $.position.getWithinInfo( options.within ), 12148 scrollInfo = $.position.getScrollInfo( within ), 12149 collision = ( options.collision || "flip" ).split( " " ), 12150 offsets = {}; 12151 12152 dimensions = getDimensions( target ); 12153 if ( target[0].preventDefault ) { 12154 // force left top to allow flipping 12155 options.at = "left top"; 12156 } 12157 targetWidth = dimensions.width; 12158 targetHeight = dimensions.height; 12159 targetOffset = dimensions.offset; 12160 // clone to reuse original targetOffset later 12161 basePosition = $.extend( {}, targetOffset ); 12162 12163 // force my and at to have valid horizontal and vertical positions 12164 // if a value is missing or invalid, it will be converted to center 12165 $.each( [ "my", "at" ], function() { 12166 var pos = ( options[ this ] || "" ).split( " " ), 12167 horizontalOffset, 12168 verticalOffset; 12169 12170 if ( pos.length === 1) { 12171 pos = rhorizontal.test( pos[ 0 ] ) ? 12172 pos.concat( [ "center" ] ) : 12173 rvertical.test( pos[ 0 ] ) ? 12174 [ "center" ].concat( pos ) : 12175 [ "center", "center" ]; 12176 } 12177 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 12178 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 12179 12180 // calculate offsets 12181 horizontalOffset = roffset.exec( pos[ 0 ] ); 12182 verticalOffset = roffset.exec( pos[ 1 ] ); 12183 offsets[ this ] = [ 12184 horizontalOffset ? horizontalOffset[ 0 ] : 0, 12185 verticalOffset ? verticalOffset[ 0 ] : 0 12186 ]; 12187 12188 // reduce to just the positions without the offsets 12189 options[ this ] = [ 12190 rposition.exec( pos[ 0 ] )[ 0 ], 12191 rposition.exec( pos[ 1 ] )[ 0 ] 12192 ]; 12193 }); 12194 12195 // normalize collision option 12196 if ( collision.length === 1 ) { 12197 collision[ 1 ] = collision[ 0 ]; 12198 } 12199 12200 if ( options.at[ 0 ] === "right" ) { 12201 basePosition.left += targetWidth; 12202 } else if ( options.at[ 0 ] === "center" ) { 12203 basePosition.left += targetWidth / 2; 12204 } 12205 12206 if ( options.at[ 1 ] === "bottom" ) { 12207 basePosition.top += targetHeight; 12208 } else if ( options.at[ 1 ] === "center" ) { 12209 basePosition.top += targetHeight / 2; 12210 } 12211 12212 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 12213 basePosition.left += atOffset[ 0 ]; 12214 basePosition.top += atOffset[ 1 ]; 12215 12216 return this.each(function() { 12217 var collisionPosition, using, 12218 elem = $( this ), 12219 elemWidth = elem.outerWidth(), 12220 elemHeight = elem.outerHeight(), 12221 marginLeft = parseCss( this, "marginLeft" ), 12222 marginTop = parseCss( this, "marginTop" ), 12223 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 12224 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 12225 position = $.extend( {}, basePosition ), 12226 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 12227 12228 if ( options.my[ 0 ] === "right" ) { 12229 position.left -= elemWidth; 12230 } else if ( options.my[ 0 ] === "center" ) { 12231 position.left -= elemWidth / 2; 12232 } 12233 12234 if ( options.my[ 1 ] === "bottom" ) { 12235 position.top -= elemHeight; 12236 } else if ( options.my[ 1 ] === "center" ) { 12237 position.top -= elemHeight / 2; 12238 } 12239 12240 position.left += myOffset[ 0 ]; 12241 position.top += myOffset[ 1 ]; 12242 12243 // if the browser doesn't support fractions, then round for consistent results 12244 if ( !$.support.offsetFractions ) { 12245 position.left = round( position.left ); 12246 position.top = round( position.top ); 12247 } 12248 12249 collisionPosition = { 12250 marginLeft: marginLeft, 12251 marginTop: marginTop 12252 }; 12253 12254 $.each( [ "left", "top" ], function( i, dir ) { 12255 if ( $.ui.position[ collision[ i ] ] ) { 12256 $.ui.position[ collision[ i ] ][ dir ]( position, { 12257 targetWidth: targetWidth, 12258 targetHeight: targetHeight, 12259 elemWidth: elemWidth, 12260 elemHeight: elemHeight, 12261 collisionPosition: collisionPosition, 12262 collisionWidth: collisionWidth, 12263 collisionHeight: collisionHeight, 12264 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 12265 my: options.my, 12266 at: options.at, 12267 within: within, 12268 elem : elem 12269 }); 12270 } 12271 }); 12272 12273 if ( options.using ) { 12274 // adds feedback as second argument to using callback, if present 12275 using = function( props ) { 12276 var left = targetOffset.left - position.left, 12277 right = left + targetWidth - elemWidth, 12278 top = targetOffset.top - position.top, 12279 bottom = top + targetHeight - elemHeight, 12280 feedback = { 12281 target: { 12282 element: target, 12283 left: targetOffset.left, 12284 top: targetOffset.top, 12285 width: targetWidth, 12286 height: targetHeight 12287 }, 12288 element: { 12289 element: elem, 12290 left: position.left, 12291 top: position.top, 12292 width: elemWidth, 12293 height: elemHeight 12294 }, 12295 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 12296 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 12297 }; 12298 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 12299 feedback.horizontal = "center"; 12300 } 12301 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 12302 feedback.vertical = "middle"; 12303 } 12304 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 12305 feedback.important = "horizontal"; 12306 } else { 12307 feedback.important = "vertical"; 12308 } 12309 options.using.call( this, props, feedback ); 12310 }; 12311 } 12312 12313 elem.offset( $.extend( position, { using: using } ) ); 12314 }); 12315}; 12316 12317$.ui.position = { 12318 fit: { 12319 left: function( position, data ) { 12320 var within = data.within, 12321 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 12322 outerWidth = within.width, 12323 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12324 overLeft = withinOffset - collisionPosLeft, 12325 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 12326 newOverRight; 12327 12328 // element is wider than within 12329 if ( data.collisionWidth > outerWidth ) { 12330 // element is initially over the left side of within 12331 if ( overLeft > 0 && overRight <= 0 ) { 12332 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 12333 position.left += overLeft - newOverRight; 12334 // element is initially over right side of within 12335 } else if ( overRight > 0 && overLeft <= 0 ) { 12336 position.left = withinOffset; 12337 // element is initially over both left and right sides of within 12338 } else { 12339 if ( overLeft > overRight ) { 12340 position.left = withinOffset + outerWidth - data.collisionWidth; 12341 } else { 12342 position.left = withinOffset; 12343 } 12344 } 12345 // too far left -> align with left edge 12346 } else if ( overLeft > 0 ) { 12347 position.left += overLeft; 12348 // too far right -> align with right edge 12349 } else if ( overRight > 0 ) { 12350 position.left -= overRight; 12351 // adjust based on position and margin 12352 } else { 12353 position.left = max( position.left - collisionPosLeft, position.left ); 12354 } 12355 }, 12356 top: function( position, data ) { 12357 var within = data.within, 12358 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 12359 outerHeight = data.within.height, 12360 collisionPosTop = position.top - data.collisionPosition.marginTop, 12361 overTop = withinOffset - collisionPosTop, 12362 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 12363 newOverBottom; 12364 12365 // element is taller than within 12366 if ( data.collisionHeight > outerHeight ) { 12367 // element is initially over the top of within 12368 if ( overTop > 0 && overBottom <= 0 ) { 12369 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 12370 position.top += overTop - newOverBottom; 12371 // element is initially over bottom of within 12372 } else if ( overBottom > 0 && overTop <= 0 ) { 12373 position.top = withinOffset; 12374 // element is initially over both top and bottom of within 12375 } else { 12376 if ( overTop > overBottom ) { 12377 position.top = withinOffset + outerHeight - data.collisionHeight; 12378 } else { 12379 position.top = withinOffset; 12380 } 12381 } 12382 // too far up -> align with top 12383 } else if ( overTop > 0 ) { 12384 position.top += overTop; 12385 // too far down -> align with bottom edge 12386 } else if ( overBottom > 0 ) { 12387 position.top -= overBottom; 12388 // adjust based on position and margin 12389 } else { 12390 position.top = max( position.top - collisionPosTop, position.top ); 12391 } 12392 } 12393 }, 12394 flip: { 12395 left: function( position, data ) { 12396 var within = data.within, 12397 withinOffset = within.offset.left + within.scrollLeft, 12398 outerWidth = within.width, 12399 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 12400 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12401 overLeft = collisionPosLeft - offsetLeft, 12402 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 12403 myOffset = data.my[ 0 ] === "left" ? 12404 -data.elemWidth : 12405 data.my[ 0 ] === "right" ? 12406 data.elemWidth : 12407 0, 12408 atOffset = data.at[ 0 ] === "left" ? 12409 data.targetWidth : 12410 data.at[ 0 ] === "right" ? 12411 -data.targetWidth : 12412 0, 12413 offset = -2 * data.offset[ 0 ], 12414 newOverRight, 12415 newOverLeft; 12416 12417 if ( overLeft < 0 ) { 12418 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 12419 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 12420 position.left += myOffset + atOffset + offset; 12421 } 12422 } 12423 else if ( overRight > 0 ) { 12424 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 12425 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 12426 position.left += myOffset + atOffset + offset; 12427 } 12428 } 12429 }, 12430 top: function( position, data ) { 12431 var within = data.within, 12432 withinOffset = within.offset.top + within.scrollTop, 12433 outerHeight = within.height, 12434 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 12435 collisionPosTop = position.top - data.collisionPosition.marginTop, 12436 overTop = collisionPosTop - offsetTop, 12437 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 12438 top = data.my[ 1 ] === "top", 12439 myOffset = top ? 12440 -data.elemHeight : 12441 data.my[ 1 ] === "bottom" ? 12442 data.elemHeight : 12443 0, 12444 atOffset = data.at[ 1 ] === "top" ? 12445 data.targetHeight : 12446 data.at[ 1 ] === "bottom" ? 12447 -data.targetHeight : 12448 0, 12449 offset = -2 * data.offset[ 1 ], 12450 newOverTop, 12451 newOverBottom; 12452 if ( overTop < 0 ) { 12453 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 12454 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 12455 position.top += myOffset + atOffset + offset; 12456 } 12457 } 12458 else if ( overBottom > 0 ) { 12459 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 12460 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 12461 position.top += myOffset + atOffset + offset; 12462 } 12463 } 12464 } 12465 }, 12466 flipfit: { 12467 left: function() { 12468 $.ui.position.flip.left.apply( this, arguments ); 12469 $.ui.position.fit.left.apply( this, arguments ); 12470 }, 12471 top: function() { 12472 $.ui.position.flip.top.apply( this, arguments ); 12473 $.ui.position.fit.top.apply( this, arguments ); 12474 } 12475 } 12476}; 12477 12478// fraction support test 12479(function () { 12480 var testElement, testElementParent, testElementStyle, offsetLeft, i, 12481 body = document.getElementsByTagName( "body" )[ 0 ], 12482 div = document.createElement( "div" ); 12483 12484 //Create a "fake body" for testing based on method used in jQuery.support 12485 testElement = document.createElement( body ? "div" : "body" ); 12486 testElementStyle = { 12487 visibility: "hidden", 12488 width: 0, 12489 height: 0, 12490 border: 0, 12491 margin: 0, 12492 background: "none" 12493 }; 12494 if ( body ) { 12495 $.extend( testElementStyle, { 12496 position: "absolute", 12497 left: "-1000px", 12498 top: "-1000px" 12499 }); 12500 } 12501 for ( i in testElementStyle ) { 12502 testElement.style[ i ] = testElementStyle[ i ]; 12503 } 12504 testElement.appendChild( div ); 12505 testElementParent = body || document.documentElement; 12506 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 12507 12508 div.style.cssText = "position: absolute; left: 10.7432222px;"; 12509 12510 offsetLeft = $( div ).offset().left; 12511 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 12512 12513 testElement.innerHTML = ""; 12514 testElementParent.removeChild( testElement ); 12515})(); 12516 12517}( jQuery ) ); 12518 12519(function( $, undefined ) { 12520 12521$.widget( "ui.progressbar", { 12522 version: "1.10.3", 12523 options: { 12524 max: 100, 12525 value: 0, 12526 12527 change: null, 12528 complete: null 12529 }, 12530 12531 min: 0, 12532 12533 _create: function() { 12534 // Constrain initial value 12535 this.oldValue = this.options.value = this._constrainedValue(); 12536 12537 this.element 12538 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12539 .attr({ 12540 // Only set static values, aria-valuenow and aria-valuemax are 12541 // set inside _refreshValue() 12542 role: "progressbar", 12543 "aria-valuemin": this.min 12544 }); 12545 12546 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 12547 .appendTo( this.element ); 12548 12549 this._refreshValue(); 12550 }, 12551 12552 _destroy: function() { 12553 this.element 12554 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12555 .removeAttr( "role" ) 12556 .removeAttr( "aria-valuemin" ) 12557 .removeAttr( "aria-valuemax" ) 12558 .removeAttr( "aria-valuenow" ); 12559 12560 this.valueDiv.remove(); 12561 }, 12562 12563 value: function( newValue ) { 12564 if ( newValue === undefined ) { 12565 return this.options.value; 12566 } 12567 12568 this.options.value = this._constrainedValue( newValue ); 12569 this._refreshValue(); 12570 }, 12571 12572 _constrainedValue: function( newValue ) { 12573 if ( newValue === undefined ) { 12574 newValue = this.options.value; 12575 } 12576 12577 this.indeterminate = newValue === false; 12578 12579 // sanitize value 12580 if ( typeof newValue !== "number" ) { 12581 newValue = 0; 12582 } 12583 12584 return this.indeterminate ? false : 12585 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12586 }, 12587 12588 _setOptions: function( options ) { 12589 // Ensure "value" option is set after other values (like max) 12590 var value = options.value; 12591 delete options.value; 12592 12593 this._super( options ); 12594 12595 this.options.value = this._constrainedValue( value ); 12596 this._refreshValue(); 12597 }, 12598 12599 _setOption: function( key, value ) { 12600 if ( key === "max" ) { 12601 // Don't allow a max less than min 12602 value = Math.max( this.min, value ); 12603 } 12604 12605 this._super( key, value ); 12606 }, 12607 12608 _percentage: function() { 12609 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 12610 }, 12611 12612 _refreshValue: function() { 12613 var value = this.options.value, 12614 percentage = this._percentage(); 12615 12616 this.valueDiv 12617 .toggle( this.indeterminate || value > this.min ) 12618 .toggleClass( "ui-corner-right", value === this.options.max ) 12619 .width( percentage.toFixed(0) + "%" ); 12620 12621 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 12622 12623 if ( this.indeterminate ) { 12624 this.element.removeAttr( "aria-valuenow" ); 12625 if ( !this.overlayDiv ) { 12626 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 12627 } 12628 } else { 12629 this.element.attr({ 12630 "aria-valuemax": this.options.max, 12631 "aria-valuenow": value 12632 }); 12633 if ( this.overlayDiv ) { 12634 this.overlayDiv.remove(); 12635 this.overlayDiv = null; 12636 } 12637 } 12638 12639 if ( this.oldValue !== value ) { 12640 this.oldValue = value; 12641 this._trigger( "change" ); 12642 } 12643 if ( value === this.options.max ) { 12644 this._trigger( "complete" ); 12645 } 12646 } 12647}); 12648 12649})( jQuery ); 12650 12651(function( $, undefined ) { 12652 12653// number of pages in a slider 12654// (how many times can you page up/down to go through the whole range) 12655var numPages = 5; 12656 12657$.widget( "ui.slider", $.ui.mouse, { 12658 version: "1.10.3", 12659 widgetEventPrefix: "slide", 12660 12661 options: { 12662 animate: false, 12663 distance: 0, 12664 max: 100, 12665 min: 0, 12666 orientation: "horizontal", 12667 range: false, 12668 step: 1, 12669 value: 0, 12670 values: null, 12671 12672 // callbacks 12673 change: null, 12674 slide: null, 12675 start: null, 12676 stop: null 12677 }, 12678 12679 _create: function() { 12680 this._keySliding = false; 12681 this._mouseSliding = false; 12682 this._animateOff = true; 12683 this._handleIndex = null; 12684 this._detectOrientation(); 12685 this._mouseInit(); 12686 12687 this.element 12688 .addClass( "ui-slider" + 12689 " ui-slider-" + this.orientation + 12690 " ui-widget" + 12691 " ui-widget-content" + 12692 " ui-corner-all"); 12693 12694 this._refresh(); 12695 this._setOption( "disabled", this.options.disabled ); 12696 12697 this._animateOff = false; 12698 }, 12699 12700 _refresh: function() { 12701 this._createRange(); 12702 this._createHandles(); 12703 this._setupEvents(); 12704 this._refreshValue(); 12705 }, 12706 12707 _createHandles: function() { 12708 var i, handleCount, 12709 options = this.options, 12710 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 12711 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 12712 handles = []; 12713 12714 handleCount = ( options.values && options.values.length ) || 1; 12715 12716 if ( existingHandles.length > handleCount ) { 12717 existingHandles.slice( handleCount ).remove(); 12718 existingHandles = existingHandles.slice( 0, handleCount ); 12719 } 12720 12721 for ( i = existingHandles.length; i < handleCount; i++ ) { 12722 handles.push( handle ); 12723 } 12724 12725 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 12726 12727 this.handle = this.handles.eq( 0 ); 12728 12729 this.handles.each(function( i ) { 12730 $( this ).data( "ui-slider-handle-index", i ); 12731 }); 12732 }, 12733 12734 _createRange: function() { 12735 var options = this.options, 12736 classes = ""; 12737 12738 if ( options.range ) { 12739 if ( options.range === true ) { 12740 if ( !options.values ) { 12741 options.values = [ this._valueMin(), this._valueMin() ]; 12742 } else if ( options.values.length && options.values.length !== 2 ) { 12743 options.values = [ options.values[0], options.values[0] ]; 12744 } else if ( $.isArray( options.values ) ) { 12745 options.values = options.values.slice(0); 12746 } 12747 } 12748 12749 if ( !this.range || !this.range.length ) { 12750 this.range = $( "<div></div>" ) 12751 .appendTo( this.element ); 12752 12753 classes = "ui-slider-range" + 12754 // note: this isn't the most fittingly semantic framework class for this element, 12755 // but worked best visually with a variety of themes 12756 " ui-widget-header ui-corner-all"; 12757 } else { 12758 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 12759 // Handle range switching from true to min/max 12760 .css({ 12761 "left": "", 12762 "bottom": "" 12763 }); 12764 } 12765 12766 this.range.addClass( classes + 12767 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 12768 } else { 12769 this.range = $([]); 12770 } 12771 }, 12772 12773 _setupEvents: function() { 12774 var elements = this.handles.add( this.range ).filter( "a" ); 12775 this._off( elements ); 12776 this._on( elements, this._handleEvents ); 12777 this._hoverable( elements ); 12778 this._focusable( elements ); 12779 }, 12780 12781 _destroy: function() { 12782 this.handles.remove(); 12783 this.range.remove(); 12784 12785 this.element 12786 .removeClass( "ui-slider" + 12787 " ui-slider-horizontal" + 12788 " ui-slider-vertical" + 12789 " ui-widget" + 12790 " ui-widget-content" + 12791 " ui-corner-all" ); 12792 12793 this._mouseDestroy(); 12794 }, 12795 12796 _mouseCapture: function( event ) { 12797 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 12798 that = this, 12799 o = this.options; 12800 12801 if ( o.disabled ) { 12802 return false; 12803 } 12804 12805 this.elementSize = { 12806 width: this.element.outerWidth(), 12807 height: this.element.outerHeight() 12808 }; 12809 this.elementOffset = this.element.offset(); 12810 12811 position = { x: event.pageX, y: event.pageY }; 12812 normValue = this._normValueFromMouse( position ); 12813 distance = this._valueMax() - this._valueMin() + 1; 12814 this.handles.each(function( i ) { 12815 var thisDistance = Math.abs( normValue - that.values(i) ); 12816 if (( distance > thisDistance ) || 12817 ( distance === thisDistance && 12818 (i === that._lastChangedValue || that.values(i) === o.min ))) { 12819 distance = thisDistance; 12820 closestHandle = $( this ); 12821 index = i; 12822 } 12823 }); 12824 12825 allowed = this._start( event, index ); 12826 if ( allowed === false ) { 12827 return false; 12828 } 12829 this._mouseSliding = true; 12830 12831 this._handleIndex = index; 12832 12833 closestHandle 12834 .addClass( "ui-state-active" ) 12835 .focus(); 12836 12837 offset = closestHandle.offset(); 12838 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 12839 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 12840 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 12841 top: event.pageY - offset.top - 12842 ( closestHandle.height() / 2 ) - 12843 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 12844 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 12845 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 12846 }; 12847 12848 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 12849 this._slide( event, index, normValue ); 12850 } 12851 this._animateOff = true; 12852 return true; 12853 }, 12854 12855 _mouseStart: function() { 12856 return true; 12857 }, 12858 12859 _mouseDrag: function( event ) { 12860 var position = { x: event.pageX, y: event.pageY }, 12861 normValue = this._normValueFromMouse( position ); 12862 12863 this._slide( event, this._handleIndex, normValue ); 12864 12865 return false; 12866 }, 12867 12868 _mouseStop: function( event ) { 12869 this.handles.removeClass( "ui-state-active" ); 12870 this._mouseSliding = false; 12871 12872 this._stop( event, this._handleIndex ); 12873 this._change( event, this._handleIndex ); 12874 12875 this._handleIndex = null; 12876 this._clickOffset = null; 12877 this._animateOff = false; 12878 12879 return false; 12880 }, 12881 12882 _detectOrientation: function() { 12883 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 12884 }, 12885 12886 _normValueFromMouse: function( position ) { 12887 var pixelTotal, 12888 pixelMouse, 12889 percentMouse, 12890 valueTotal, 12891 valueMouse; 12892 12893 if ( this.orientation === "horizontal" ) { 12894 pixelTotal = this.elementSize.width; 12895 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 12896 } else { 12897 pixelTotal = this.elementSize.height; 12898 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 12899 } 12900 12901 percentMouse = ( pixelMouse / pixelTotal ); 12902 if ( percentMouse > 1 ) { 12903 percentMouse = 1; 12904 } 12905 if ( percentMouse < 0 ) { 12906 percentMouse = 0; 12907 } 12908 if ( this.orientation === "vertical" ) { 12909 percentMouse = 1 - percentMouse; 12910 } 12911 12912 valueTotal = this._valueMax() - this._valueMin(); 12913 valueMouse = this._valueMin() + percentMouse * valueTotal; 12914 12915 return this._trimAlignValue( valueMouse ); 12916 }, 12917 12918 _start: function( event, index ) { 12919 var uiHash = { 12920 handle: this.handles[ index ], 12921 value: this.value() 12922 }; 12923 if ( this.options.values && this.options.values.length ) { 12924 uiHash.value = this.values( index ); 12925 uiHash.values = this.values(); 12926 } 12927 return this._trigger( "start", event, uiHash ); 12928 }, 12929 12930 _slide: function( event, index, newVal ) { 12931 var otherVal, 12932 newValues, 12933 allowed; 12934 12935 if ( this.options.values && this.options.values.length ) { 12936 otherVal = this.values( index ? 0 : 1 ); 12937 12938 if ( ( this.options.values.length === 2 && this.options.range === true ) && 12939 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 12940 ) { 12941 newVal = otherVal; 12942 } 12943 12944 if ( newVal !== this.values( index ) ) { 12945 newValues = this.values(); 12946 newValues[ index ] = newVal; 12947 // A slide can be canceled by returning false from the slide callback 12948 allowed = this._trigger( "slide", event, { 12949 handle: this.handles[ index ], 12950 value: newVal, 12951 values: newValues 12952 } ); 12953 otherVal = this.values( index ? 0 : 1 ); 12954 if ( allowed !== false ) { 12955 this.values( index, newVal, true ); 12956 } 12957 } 12958 } else { 12959 if ( newVal !== this.value() ) { 12960 // A slide can be canceled by returning false from the slide callback 12961 allowed = this._trigger( "slide", event, { 12962 handle: this.handles[ index ], 12963 value: newVal 12964 } ); 12965 if ( allowed !== false ) { 12966 this.value( newVal ); 12967 } 12968 } 12969 } 12970 }, 12971 12972 _stop: function( event, index ) { 12973 var uiHash = { 12974 handle: this.handles[ index ], 12975 value: this.value() 12976 }; 12977 if ( this.options.values && this.options.values.length ) { 12978 uiHash.value = this.values( index ); 12979 uiHash.values = this.values(); 12980 } 12981 12982 this._trigger( "stop", event, uiHash ); 12983 }, 12984 12985 _change: function( event, index ) { 12986 if ( !this._keySliding && !this._mouseSliding ) { 12987 var uiHash = { 12988 handle: this.handles[ index ], 12989 value: this.value() 12990 }; 12991 if ( this.options.values && this.options.values.length ) { 12992 uiHash.value = this.values( index ); 12993 uiHash.values = this.values(); 12994 } 12995 12996 //store the last changed value index for reference when handles overlap 12997 this._lastChangedValue = index; 12998 12999 this._trigger( "change", event, uiHash ); 13000 } 13001 }, 13002 13003 value: function( newValue ) { 13004 if ( arguments.length ) { 13005 this.options.value = this._trimAlignValue( newValue ); 13006 this._refreshValue(); 13007 this._change( null, 0 ); 13008 return; 13009 } 13010 13011 return this._value(); 13012 }, 13013 13014 values: function( index, newValue ) { 13015 var vals, 13016 newValues, 13017 i; 13018 13019 if ( arguments.length > 1 ) { 13020 this.options.values[ index ] = this._trimAlignValue( newValue ); 13021 this._refreshValue(); 13022 this._change( null, index ); 13023 return; 13024 } 13025 13026 if ( arguments.length ) { 13027 if ( $.isArray( arguments[ 0 ] ) ) { 13028 vals = this.options.values; 13029 newValues = arguments[ 0 ]; 13030 for ( i = 0; i < vals.length; i += 1 ) { 13031 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13032 this._change( null, i ); 13033 } 13034 this._refreshValue(); 13035 } else { 13036 if ( this.options.values && this.options.values.length ) { 13037 return this._values( index ); 13038 } else { 13039 return this.value(); 13040 } 13041 } 13042 } else { 13043 return this._values(); 13044 } 13045 }, 13046 13047 _setOption: function( key, value ) { 13048 var i, 13049 valsLength = 0; 13050 13051 if ( key === "range" && this.options.range === true ) { 13052 if ( value === "min" ) { 13053 this.options.value = this._values( 0 ); 13054 this.options.values = null; 13055 } else if ( value === "max" ) { 13056 this.options.value = this._values( this.options.values.length-1 ); 13057 this.options.values = null; 13058 } 13059 } 13060 13061 if ( $.isArray( this.options.values ) ) { 13062 valsLength = this.options.values.length; 13063 } 13064 13065 $.Widget.prototype._setOption.apply( this, arguments ); 13066 13067 switch ( key ) { 13068 case "orientation": 13069 this._detectOrientation(); 13070 this.element 13071 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13072 .addClass( "ui-slider-" + this.orientation ); 13073 this._refreshValue(); 13074 break; 13075 case "value": 13076 this._animateOff = true; 13077 this._refreshValue(); 13078 this._change( null, 0 ); 13079 this._animateOff = false; 13080 break; 13081 case "values": 13082 this._animateOff = true; 13083 this._refreshValue(); 13084 for ( i = 0; i < valsLength; i += 1 ) { 13085 this._change( null, i ); 13086 } 13087 this._animateOff = false; 13088 break; 13089 case "min": 13090 case "max": 13091 this._animateOff = true; 13092 this._refreshValue(); 13093 this._animateOff = false; 13094 break; 13095 case "range": 13096 this._animateOff = true; 13097 this._refresh(); 13098 this._animateOff = false; 13099 break; 13100 } 13101 }, 13102 13103 //internal value getter 13104 // _value() returns value trimmed by min and max, aligned by step 13105 _value: function() { 13106 var val = this.options.value; 13107 val = this._trimAlignValue( val ); 13108 13109 return val; 13110 }, 13111 13112 //internal values getter 13113 // _values() returns array of values trimmed by min and max, aligned by step 13114 // _values( index ) returns single value trimmed by min and max, aligned by step 13115 _values: function( index ) { 13116 var val, 13117 vals, 13118 i; 13119 13120 if ( arguments.length ) { 13121 val = this.options.values[ index ]; 13122 val = this._trimAlignValue( val ); 13123 13124 return val; 13125 } else if ( this.options.values && this.options.values.length ) { 13126 // .slice() creates a copy of the array 13127 // this copy gets trimmed by min and max and then returned 13128 vals = this.options.values.slice(); 13129 for ( i = 0; i < vals.length; i+= 1) { 13130 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13131 } 13132 13133 return vals; 13134 } else { 13135 return []; 13136 } 13137 }, 13138 13139 // returns the step-aligned value that val is closest to, between (inclusive) min and max 13140 _trimAlignValue: function( val ) { 13141 if ( val <= this._valueMin() ) { 13142 return this._valueMin(); 13143 } 13144 if ( val >= this._valueMax() ) { 13145 return this._valueMax(); 13146 } 13147 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13148 valModStep = (val - this._valueMin()) % step, 13149 alignValue = val - valModStep; 13150 13151 if ( Math.abs(valModStep) * 2 >= step ) { 13152 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13153 } 13154 13155 // Since JavaScript has problems with large floats, round 13156 // the final value to 5 digits after the decimal point (see #4124) 13157 return parseFloat( alignValue.toFixed(5) ); 13158 }, 13159 13160 _valueMin: function() { 13161 return this.options.min; 13162 }, 13163 13164 _valueMax: function() { 13165 return this.options.max; 13166 }, 13167 13168 _refreshValue: function() { 13169 var lastValPercent, valPercent, value, valueMin, valueMax, 13170 oRange = this.options.range, 13171 o = this.options, 13172 that = this, 13173 animate = ( !this._animateOff ) ? o.animate : false, 13174 _set = {}; 13175 13176 if ( this.options.values && this.options.values.length ) { 13177 this.handles.each(function( i ) { 13178 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 13179 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13180 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13181 if ( that.options.range === true ) { 13182 if ( that.orientation === "horizontal" ) { 13183 if ( i === 0 ) { 13184 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 13185 } 13186 if ( i === 1 ) { 13187 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13188 } 13189 } else { 13190 if ( i === 0 ) { 13191 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 13192 } 13193 if ( i === 1 ) { 13194 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13195 } 13196 } 13197 } 13198 lastValPercent = valPercent; 13199 }); 13200 } else { 13201 value = this.value(); 13202 valueMin = this._valueMin(); 13203 valueMax = this._valueMax(); 13204 valPercent = ( valueMax !== valueMin ) ? 13205 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 13206 0; 13207 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13208 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13209 13210 if ( oRange === "min" && this.orientation === "horizontal" ) { 13211 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 13212 } 13213 if ( oRange === "max" && this.orientation === "horizontal" ) { 13214 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13215 } 13216 if ( oRange === "min" && this.orientation === "vertical" ) { 13217 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 13218 } 13219 if ( oRange === "max" && this.orientation === "vertical" ) { 13220 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13221 } 13222 } 13223 }, 13224 13225 _handleEvents: { 13226 keydown: function( event ) { 13227 /*jshint maxcomplexity:25*/ 13228 var allowed, curVal, newVal, step, 13229 index = $( event.target ).data( "ui-slider-handle-index" ); 13230 13231 switch ( event.keyCode ) { 13232 case $.ui.keyCode.HOME: 13233 case $.ui.keyCode.END: 13234 case $.ui.keyCode.PAGE_UP: 13235 case $.ui.keyCode.PAGE_DOWN: 13236 case $.ui.keyCode.UP: 13237 case $.ui.keyCode.RIGHT: 13238 case $.ui.keyCode.DOWN: 13239 case $.ui.keyCode.LEFT: 13240 event.preventDefault(); 13241 if ( !this._keySliding ) { 13242 this._keySliding = true; 13243 $( event.target ).addClass( "ui-state-active" ); 13244 allowed = this._start( event, index ); 13245 if ( allowed === false ) { 13246 return; 13247 } 13248 } 13249 break; 13250 } 13251 13252 step = this.options.step; 13253 if ( this.options.values && this.options.values.length ) { 13254 curVal = newVal = this.values( index ); 13255 } else { 13256 curVal = newVal = this.value(); 13257 } 13258 13259 switch ( event.keyCode ) { 13260 case $.ui.keyCode.HOME: 13261 newVal = this._valueMin(); 13262 break; 13263 case $.ui.keyCode.END: 13264 newVal = this._valueMax(); 13265 break; 13266 case $.ui.keyCode.PAGE_UP: 13267 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 13268 break; 13269 case $.ui.keyCode.PAGE_DOWN: 13270 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 13271 break; 13272 case $.ui.keyCode.UP: 13273 case $.ui.keyCode.RIGHT: 13274 if ( curVal === this._valueMax() ) { 13275 return; 13276 } 13277 newVal = this._trimAlignValue( curVal + step ); 13278 break; 13279 case $.ui.keyCode.DOWN: 13280 case $.ui.keyCode.LEFT: 13281 if ( curVal === this._valueMin() ) { 13282 return; 13283 } 13284 newVal = this._trimAlignValue( curVal - step ); 13285 break; 13286 } 13287 13288 this._slide( event, index, newVal ); 13289 }, 13290 click: function( event ) { 13291 event.preventDefault(); 13292 }, 13293 keyup: function( event ) { 13294 var index = $( event.target ).data( "ui-slider-handle-index" ); 13295 13296 if ( this._keySliding ) { 13297 this._keySliding = false; 13298 this._stop( event, index ); 13299 this._change( event, index ); 13300 $( event.target ).removeClass( "ui-state-active" ); 13301 } 13302 } 13303 } 13304 13305}); 13306 13307}(jQuery)); 13308 13309(function( $ ) { 13310 13311function modifier( fn ) { 13312 return function() { 13313 var previous = this.element.val(); 13314 fn.apply( this, arguments ); 13315 this._refresh(); 13316 if ( previous !== this.element.val() ) { 13317 this._trigger( "change" ); 13318 } 13319 }; 13320} 13321 13322$.widget( "ui.spinner", { 13323 version: "1.10.3", 13324 defaultElement: "<input>", 13325 widgetEventPrefix: "spin", 13326 options: { 13327 culture: null, 13328 icons: { 13329 down: "ui-icon-triangle-1-s", 13330 up: "ui-icon-triangle-1-n" 13331 }, 13332 incremental: true, 13333 max: null, 13334 min: null, 13335 numberFormat: null, 13336 page: 10, 13337 step: 1, 13338 13339 change: null, 13340 spin: null, 13341 start: null, 13342 stop: null 13343 }, 13344 13345 _create: function() { 13346 // handle string values that need to be parsed 13347 this._setOption( "max", this.options.max ); 13348 this._setOption( "min", this.options.min ); 13349 this._setOption( "step", this.options.step ); 13350 13351 // format the value, but don't constrain 13352 this._value( this.element.val(), true ); 13353 13354 this._draw(); 13355 this._on( this._events ); 13356 this._refresh(); 13357 13358 // turning off autocomplete prevents the browser from remembering the 13359 // value when navigating through history, so we re-enable autocomplete 13360 // if the page is unloaded before the widget is destroyed. #7790 13361 this._on( this.window, { 13362 beforeunload: function() { 13363 this.element.removeAttr( "autocomplete" ); 13364 } 13365 }); 13366 }, 13367 13368 _getCreateOptions: function() { 13369 var options = {}, 13370 element = this.element; 13371 13372 $.each( [ "min", "max", "step" ], function( i, option ) { 13373 var value = element.attr( option ); 13374 if ( value !== undefined && value.length ) { 13375 options[ option ] = value; 13376 } 13377 }); 13378 13379 return options; 13380 }, 13381 13382 _events: { 13383 keydown: function( event ) { 13384 if ( this._start( event ) && this._keydown( event ) ) { 13385 event.preventDefault(); 13386 } 13387 }, 13388 keyup: "_stop", 13389 focus: function() { 13390 this.previous = this.element.val(); 13391 }, 13392 blur: function( event ) { 13393 if ( this.cancelBlur ) { 13394 delete this.cancelBlur; 13395 return; 13396 } 13397 13398 this._stop(); 13399 this._refresh(); 13400 if ( this.previous !== this.element.val() ) { 13401 this._trigger( "change", event ); 13402 } 13403 }, 13404 mousewheel: function( event, delta ) { 13405 if ( !delta ) { 13406 return; 13407 } 13408 if ( !this.spinning && !this._start( event ) ) { 13409 return false; 13410 } 13411 13412 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 13413 clearTimeout( this.mousewheelTimer ); 13414 this.mousewheelTimer = this._delay(function() { 13415 if ( this.spinning ) { 13416 this._stop( event ); 13417 } 13418 }, 100 ); 13419 event.preventDefault(); 13420 }, 13421 "mousedown .ui-spinner-button": function( event ) { 13422 var previous; 13423 13424 // We never want the buttons to have focus; whenever the user is 13425 // interacting with the spinner, the focus should be on the input. 13426 // If the input is focused then this.previous is properly set from 13427 // when the input first received focus. If the input is not focused 13428 // then we need to set this.previous based on the value before spinning. 13429 previous = this.element[0] === this.document[0].activeElement ? 13430 this.previous : this.element.val(); 13431 function checkFocus() { 13432 var isActive = this.element[0] === this.document[0].activeElement; 13433 if ( !isActive ) { 13434 this.element.focus(); 13435 this.previous = previous; 13436 // support: IE 13437 // IE sets focus asynchronously, so we need to check if focus 13438 // moved off of the input because the user clicked on the button. 13439 this._delay(function() { 13440 this.previous = previous; 13441 }); 13442 } 13443 } 13444 13445 // ensure focus is on (or stays on) the text field 13446 event.preventDefault(); 13447 checkFocus.call( this ); 13448 13449 // support: IE 13450 // IE doesn't prevent moving focus even with event.preventDefault() 13451 // so we set a flag to know when we should ignore the blur event 13452 // and check (again) if focus moved off of the input. 13453 this.cancelBlur = true; 13454 this._delay(function() { 13455 delete this.cancelBlur; 13456 checkFocus.call( this ); 13457 }); 13458 13459 if ( this._start( event ) === false ) { 13460 return; 13461 } 13462 13463 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13464 }, 13465 "mouseup .ui-spinner-button": "_stop", 13466 "mouseenter .ui-spinner-button": function( event ) { 13467 // button will add ui-state-active if mouse was down while mouseleave and kept down 13468 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 13469 return; 13470 } 13471 13472 if ( this._start( event ) === false ) { 13473 return false; 13474 } 13475 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13476 }, 13477 // TODO: do we really want to consider this a stop? 13478 // shouldn't we just stop the repeater and wait until mouseup before 13479 // we trigger the stop event? 13480 "mouseleave .ui-spinner-button": "_stop" 13481 }, 13482 13483 _draw: function() { 13484 var uiSpinner = this.uiSpinner = this.element 13485 .addClass( "ui-spinner-input" ) 13486 .attr( "autocomplete", "off" ) 13487 .wrap( this._uiSpinnerHtml() ) 13488 .parent() 13489 // add buttons 13490 .append( this._buttonHtml() ); 13491 13492 this.element.attr( "role", "spinbutton" ); 13493 13494 // button bindings 13495 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 13496 .attr( "tabIndex", -1 ) 13497 .button() 13498 .removeClass( "ui-corner-all" ); 13499 13500 // IE 6 doesn't understand height: 50% for the buttons 13501 // unless the wrapper has an explicit height 13502 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 13503 uiSpinner.height() > 0 ) { 13504 uiSpinner.height( uiSpinner.height() ); 13505 } 13506 13507 // disable spinner if element was already disabled 13508 if ( this.options.disabled ) { 13509 this.disable(); 13510 } 13511 }, 13512 13513 _keydown: function( event ) { 13514 var options = this.options, 13515 keyCode = $.ui.keyCode; 13516 13517 switch ( event.keyCode ) { 13518 case keyCode.UP: 13519 this._repeat( null, 1, event ); 13520 return true; 13521 case keyCode.DOWN: 13522 this._repeat( null, -1, event ); 13523 return true; 13524 case keyCode.PAGE_UP: 13525 this._repeat( null, options.page, event ); 13526 return true; 13527 case keyCode.PAGE_DOWN: 13528 this._repeat( null, -options.page, event ); 13529 return true; 13530 } 13531 13532 return false; 13533 }, 13534 13535 _uiSpinnerHtml: function() { 13536 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 13537 }, 13538 13539 _buttonHtml: function() { 13540 return "" + 13541 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 13542 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 13543 "</a>" + 13544 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 13545 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 13546 "</a>"; 13547 }, 13548 13549 _start: function( event ) { 13550 if ( !this.spinning && this._trigger( "start", event ) === false ) { 13551 return false; 13552 } 13553 13554 if ( !this.counter ) { 13555 this.counter = 1; 13556 } 13557 this.spinning = true; 13558 return true; 13559 }, 13560 13561 _repeat: function( i, steps, event ) { 13562 i = i || 500; 13563 13564 clearTimeout( this.timer ); 13565 this.timer = this._delay(function() { 13566 this._repeat( 40, steps, event ); 13567 }, i ); 13568 13569 this._spin( steps * this.options.step, event ); 13570 }, 13571 13572 _spin: function( step, event ) { 13573 var value = this.value() || 0; 13574 13575 if ( !this.counter ) { 13576 this.counter = 1; 13577 } 13578 13579 value = this._adjustValue( value + step * this._increment( this.counter ) ); 13580 13581 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 13582 this._value( value ); 13583 this.counter++; 13584 } 13585 }, 13586 13587 _increment: function( i ) { 13588 var incremental = this.options.incremental; 13589 13590 if ( incremental ) { 13591 return $.isFunction( incremental ) ? 13592 incremental( i ) : 13593 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 13594 } 13595 13596 return 1; 13597 }, 13598 13599 _precision: function() { 13600 var precision = this._precisionOf( this.options.step ); 13601 if ( this.options.min !== null ) { 13602 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13603 } 13604 return precision; 13605 }, 13606 13607 _precisionOf: function( num ) { 13608 var str = num.toString(), 13609 decimal = str.indexOf( "." ); 13610 return decimal === -1 ? 0 : str.length - decimal - 1; 13611 }, 13612 13613 _adjustValue: function( value ) { 13614 var base, aboveMin, 13615 options = this.options; 13616 13617 // make sure we're at a valid step 13618 // - find out where we are relative to the base (min or 0) 13619 base = options.min !== null ? options.min : 0; 13620 aboveMin = value - base; 13621 // - round to the nearest step 13622 aboveMin = Math.round(aboveMin / options.step) * options.step; 13623 // - rounding is based on 0, so adjust back to our base 13624 value = base + aboveMin; 13625 13626 // fix precision from bad JS floating point math 13627 value = parseFloat( value.toFixed( this._precision() ) ); 13628 13629 // clamp the value 13630 if ( options.max !== null && value > options.max) { 13631 return options.max; 13632 } 13633 if ( options.min !== null && value < options.min ) { 13634 return options.min; 13635 } 13636 13637 return value; 13638 }, 13639 13640 _stop: function( event ) { 13641 if ( !this.spinning ) { 13642 return; 13643 } 13644 13645 clearTimeout( this.timer ); 13646 clearTimeout( this.mousewheelTimer ); 13647 this.counter = 0; 13648 this.spinning = false; 13649 this._trigger( "stop", event ); 13650 }, 13651 13652 _setOption: function( key, value ) { 13653 if ( key === "culture" || key === "numberFormat" ) { 13654 var prevValue = this._parse( this.element.val() ); 13655 this.options[ key ] = value; 13656 this.element.val( this._format( prevValue ) ); 13657 return; 13658 } 13659 13660 if ( key === "max" || key === "min" || key === "step" ) { 13661 if ( typeof value === "string" ) { 13662 value = this._parse( value ); 13663 } 13664 } 13665 if ( key === "icons" ) { 13666 this.buttons.first().find( ".ui-icon" ) 13667 .removeClass( this.options.icons.up ) 13668 .addClass( value.up ); 13669 this.buttons.last().find( ".ui-icon" ) 13670 .removeClass( this.options.icons.down ) 13671 .addClass( value.down ); 13672 } 13673 13674 this._super( key, value ); 13675 13676 if ( key === "disabled" ) { 13677 if ( value ) { 13678 this.element.prop( "disabled", true ); 13679 this.buttons.button( "disable" ); 13680 } else { 13681 this.element.prop( "disabled", false ); 13682 this.buttons.button( "enable" ); 13683 } 13684 } 13685 }, 13686 13687 _setOptions: modifier(function( options ) { 13688 this._super( options ); 13689 this._value( this.element.val() ); 13690 }), 13691 13692 _parse: function( val ) { 13693 if ( typeof val === "string" && val !== "" ) { 13694 val = window.Globalize && this.options.numberFormat ? 13695 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 13696 } 13697 return val === "" || isNaN( val ) ? null : val; 13698 }, 13699 13700 _format: function( value ) { 13701 if ( value === "" ) { 13702 return ""; 13703 } 13704 return window.Globalize && this.options.numberFormat ? 13705 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 13706 value; 13707 }, 13708 13709 _refresh: function() { 13710 this.element.attr({ 13711 "aria-valuemin": this.options.min, 13712 "aria-valuemax": this.options.max, 13713 // TODO: what should we do with values that can't be parsed? 13714 "aria-valuenow": this._parse( this.element.val() ) 13715 }); 13716 }, 13717 13718 // update the value without triggering change 13719 _value: function( value, allowAny ) { 13720 var parsed; 13721 if ( value !== "" ) { 13722 parsed = this._parse( value ); 13723 if ( parsed !== null ) { 13724 if ( !allowAny ) { 13725 parsed = this._adjustValue( parsed ); 13726 } 13727 value = this._format( parsed ); 13728 } 13729 } 13730 this.element.val( value ); 13731 this._refresh(); 13732 }, 13733 13734 _destroy: function() { 13735 this.element 13736 .removeClass( "ui-spinner-input" ) 13737 .prop( "disabled", false ) 13738 .removeAttr( "autocomplete" ) 13739 .removeAttr( "role" ) 13740 .removeAttr( "aria-valuemin" ) 13741 .removeAttr( "aria-valuemax" ) 13742 .removeAttr( "aria-valuenow" ); 13743 this.uiSpinner.replaceWith( this.element ); 13744 }, 13745 13746 stepUp: modifier(function( steps ) { 13747 this._stepUp( steps ); 13748 }), 13749 _stepUp: function( steps ) { 13750 if ( this._start() ) { 13751 this._spin( (steps || 1) * this.options.step ); 13752 this._stop(); 13753 } 13754 }, 13755 13756 stepDown: modifier(function( steps ) { 13757 this._stepDown( steps ); 13758 }), 13759 _stepDown: function( steps ) { 13760 if ( this._start() ) { 13761 this._spin( (steps || 1) * -this.options.step ); 13762 this._stop(); 13763 } 13764 }, 13765 13766 pageUp: modifier(function( pages ) { 13767 this._stepUp( (pages || 1) * this.options.page ); 13768 }), 13769 13770 pageDown: modifier(function( pages ) { 13771 this._stepDown( (pages || 1) * this.options.page ); 13772 }), 13773 13774 value: function( newVal ) { 13775 if ( !arguments.length ) { 13776 return this._parse( this.element.val() ); 13777 } 13778 modifier( this._value ).call( this, newVal ); 13779 }, 13780 13781 widget: function() { 13782 return this.uiSpinner; 13783 } 13784}); 13785 13786}( jQuery ) ); 13787 13788(function( $, undefined ) { 13789 13790var tabId = 0, 13791 rhash = /#.*$/; 13792 13793function getNextTabId() { 13794 return ++tabId; 13795} 13796 13797function isLocal( anchor ) { 13798 return anchor.hash.length > 1 && 13799 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 13800 decodeURIComponent( location.href.replace( rhash, "" ) ); 13801} 13802 13803$.widget( "ui.tabs", { 13804 version: "1.10.3", 13805 delay: 300, 13806 options: { 13807 active: null, 13808 collapsible: false, 13809 event: "click", 13810 heightStyle: "content", 13811 hide: null, 13812 show: null, 13813 13814 // callbacks 13815 activate: null, 13816 beforeActivate: null, 13817 beforeLoad: null, 13818 load: null 13819 }, 13820 13821 _create: function() { 13822 var that = this, 13823 options = this.options; 13824 13825 this.running = false; 13826 13827 this.element 13828 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 13829 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 13830 // Prevent users from focusing disabled tabs via click 13831 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 13832 if ( $( this ).is( ".ui-state-disabled" ) ) { 13833 event.preventDefault(); 13834 } 13835 }) 13836 // support: IE <9 13837 // Preventing the default action in mousedown doesn't prevent IE 13838 // from focusing the element, so if the anchor gets focused, blur. 13839 // We don't have to worry about focusing the previously focused 13840 // element since clicking on a non-focusable element should focus 13841 // the body anyway. 13842 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 13843 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 13844 this.blur(); 13845 } 13846 }); 13847 13848 this._processTabs(); 13849 options.active = this._initialActive(); 13850 13851 // Take disabling tabs via class attribute from HTML 13852 // into account and update option properly. 13853 if ( $.isArray( options.disabled ) ) { 13854 options.disabled = $.unique( options.disabled.concat( 13855 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 13856 return that.tabs.index( li ); 13857 }) 13858 ) ).sort(); 13859 } 13860 13861 // check for length avoids error when initializing empty list 13862 if ( this.options.active !== false && this.anchors.length ) { 13863 this.active = this._findActive( options.active ); 13864 } else { 13865 this.active = $(); 13866 } 13867 13868 this._refresh(); 13869 13870 if ( this.active.length ) { 13871 this.load( options.active ); 13872 } 13873 }, 13874 13875 _initialActive: function() { 13876 var active = this.options.active, 13877 collapsible = this.options.collapsible, 13878 locationHash = location.hash.substring( 1 ); 13879 13880 if ( active === null ) { 13881 // check the fragment identifier in the URL 13882 if ( locationHash ) { 13883 this.tabs.each(function( i, tab ) { 13884 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 13885 active = i; 13886 return false; 13887 } 13888 }); 13889 } 13890 13891 // check for a tab marked active via a class 13892 if ( active === null ) { 13893 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 13894 } 13895 13896 // no active tab, set to false 13897 if ( active === null || active === -1 ) { 13898 active = this.tabs.length ? 0 : false; 13899 } 13900 } 13901 13902 // handle numbers: negative, out of range 13903 if ( active !== false ) { 13904 active = this.tabs.index( this.tabs.eq( active ) ); 13905 if ( active === -1 ) { 13906 active = collapsible ? false : 0; 13907 } 13908 } 13909 13910 // don't allow collapsible: false and active: false 13911 if ( !collapsible && active === false && this.anchors.length ) { 13912 active = 0; 13913 } 13914 13915 return active; 13916 }, 13917 13918 _getCreateEventData: function() { 13919 return { 13920 tab: this.active, 13921 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 13922 }; 13923 }, 13924 13925 _tabKeydown: function( event ) { 13926 /*jshint maxcomplexity:15*/ 13927 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 13928 selectedIndex = this.tabs.index( focusedTab ), 13929 goingForward = true; 13930 13931 if ( this._handlePageNav( event ) ) { 13932 return; 13933 } 13934 13935 switch ( event.keyCode ) { 13936 case $.ui.keyCode.RIGHT: 13937 case $.ui.keyCode.DOWN: 13938 selectedIndex++; 13939 break; 13940 case $.ui.keyCode.UP: 13941 case $.ui.keyCode.LEFT: 13942 goingForward = false; 13943 selectedIndex--; 13944 break; 13945 case $.ui.keyCode.END: 13946 selectedIndex = this.anchors.length - 1; 13947 break; 13948 case $.ui.keyCode.HOME: 13949 selectedIndex = 0; 13950 break; 13951 case $.ui.keyCode.SPACE: 13952 // Activate only, no collapsing 13953 event.preventDefault(); 13954 clearTimeout( this.activating ); 13955 this._activate( selectedIndex ); 13956 return; 13957 case $.ui.keyCode.ENTER: 13958 // Toggle (cancel delayed activation, allow collapsing) 13959 event.preventDefault(); 13960 clearTimeout( this.activating ); 13961 // Determine if we should collapse or activate 13962 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 13963 return; 13964 default: 13965 return; 13966 } 13967 13968 // Focus the appropriate tab, based on which key was pressed 13969 event.preventDefault(); 13970 clearTimeout( this.activating ); 13971 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 13972 13973 // Navigating with control key will prevent automatic activation 13974 if ( !event.ctrlKey ) { 13975 // Update aria-selected immediately so that AT think the tab is already selected. 13976 // Otherwise AT may confuse the user by stating that they need to activate the tab, 13977 // but the tab will already be activated by the time the announcement finishes. 13978 focusedTab.attr( "aria-selected", "false" ); 13979 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 13980 13981 this.activating = this._delay(function() { 13982 this.option( "active", selectedIndex ); 13983 }, this.delay ); 13984 } 13985 }, 13986 13987 _panelKeydown: function( event ) { 13988 if ( this._handlePageNav( event ) ) { 13989 return; 13990 } 13991 13992 // Ctrl+up moves focus to the current tab 13993 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 13994 event.preventDefault(); 13995 this.active.focus(); 13996 } 13997 }, 13998 13999 // Alt+page up/down moves focus to the previous/next tab (and activates) 14000 _handlePageNav: function( event ) { 14001 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 14002 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 14003 return true; 14004 } 14005 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 14006 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 14007 return true; 14008 } 14009 }, 14010 14011 _findNextTab: function( index, goingForward ) { 14012 var lastTabIndex = this.tabs.length - 1; 14013 14014 function constrain() { 14015 if ( index > lastTabIndex ) { 14016 index = 0; 14017 } 14018 if ( index < 0 ) { 14019 index = lastTabIndex; 14020 } 14021 return index; 14022 } 14023 14024 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 14025 index = goingForward ? index + 1 : index - 1; 14026 } 14027 14028 return index; 14029 }, 14030 14031 _focusNextTab: function( index, goingForward ) { 14032 index = this._findNextTab( index, goingForward ); 14033 this.tabs.eq( index ).focus(); 14034 return index; 14035 }, 14036 14037 _setOption: function( key, value ) { 14038 if ( key === "active" ) { 14039 // _activate() will handle invalid values and update this.options 14040 this._activate( value ); 14041 return; 14042 } 14043 14044 if ( key === "disabled" ) { 14045 // don't use the widget factory's disabled handling 14046 this._setupDisabled( value ); 14047 return; 14048 } 14049 14050 this._super( key, value); 14051 14052 if ( key === "collapsible" ) { 14053 this.element.toggleClass( "ui-tabs-collapsible", value ); 14054 // Setting collapsible: false while collapsed; open first panel 14055 if ( !value && this.options.active === false ) { 14056 this._activate( 0 ); 14057 } 14058 } 14059 14060 if ( key === "event" ) { 14061 this._setupEvents( value ); 14062 } 14063 14064 if ( key === "heightStyle" ) { 14065 this._setupHeightStyle( value ); 14066 } 14067 }, 14068 14069 _tabId: function( tab ) { 14070 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 14071 }, 14072 14073 _sanitizeSelector: function( hash ) { 14074 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 14075 }, 14076 14077 refresh: function() { 14078 var options = this.options, 14079 lis = this.tablist.children( ":has(a[href])" ); 14080 14081 // get disabled tabs from class attribute from HTML 14082 // this will get converted to a boolean if needed in _refresh() 14083 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 14084 return lis.index( tab ); 14085 }); 14086 14087 this._processTabs(); 14088 14089 // was collapsed or no tabs 14090 if ( options.active === false || !this.anchors.length ) { 14091 options.active = false; 14092 this.active = $(); 14093 // was active, but active tab is gone 14094 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 14095 // all remaining tabs are disabled 14096 if ( this.tabs.length === options.disabled.length ) { 14097 options.active = false; 14098 this.active = $(); 14099 // activate previous tab 14100 } else { 14101 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 14102 } 14103 // was active, active tab still exists 14104 } else { 14105 // make sure active index is correct 14106 options.active = this.tabs.index( this.active ); 14107 } 14108 14109 this._refresh(); 14110 }, 14111 14112 _refresh: function() { 14113 this._setupDisabled( this.options.disabled ); 14114 this._setupEvents( this.options.event ); 14115 this._setupHeightStyle( this.options.heightStyle ); 14116 14117 this.tabs.not( this.active ).attr({ 14118 "aria-selected": "false", 14119 tabIndex: -1 14120 }); 14121 this.panels.not( this._getPanelForTab( this.active ) ) 14122 .hide() 14123 .attr({ 14124 "aria-expanded": "false", 14125 "aria-hidden": "true" 14126 }); 14127 14128 // Make sure one tab is in the tab order 14129 if ( !this.active.length ) { 14130 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 14131 } else { 14132 this.active 14133 .addClass( "ui-tabs-active ui-state-active" ) 14134 .attr({ 14135 "aria-selected": "true", 14136 tabIndex: 0 14137 }); 14138 this._getPanelForTab( this.active ) 14139 .show() 14140 .attr({ 14141 "aria-expanded": "true", 14142 "aria-hidden": "false" 14143 }); 14144 } 14145 }, 14146 14147 _processTabs: function() { 14148 var that = this; 14149 14150 this.tablist = this._getList() 14151 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14152 .attr( "role", "tablist" ); 14153 14154 this.tabs = this.tablist.find( "> li:has(a[href])" ) 14155 .addClass( "ui-state-default ui-corner-top" ) 14156 .attr({ 14157 role: "tab", 14158 tabIndex: -1 14159 }); 14160 14161 this.anchors = this.tabs.map(function() { 14162 return $( "a", this )[ 0 ]; 14163 }) 14164 .addClass( "ui-tabs-anchor" ) 14165 .attr({ 14166 role: "presentation", 14167 tabIndex: -1 14168 }); 14169 14170 this.panels = $(); 14171 14172 this.anchors.each(function( i, anchor ) { 14173 var selector, panel, panelId, 14174 anchorId = $( anchor ).uniqueId().attr( "id" ), 14175 tab = $( anchor ).closest( "li" ), 14176 originalAriaControls = tab.attr( "aria-controls" ); 14177 14178 // inline tab 14179 if ( isLocal( anchor ) ) { 14180 selector = anchor.hash; 14181 panel = that.element.find( that._sanitizeSelector( selector ) ); 14182 // remote tab 14183 } else { 14184 panelId = that._tabId( tab ); 14185 selector = "#" + panelId; 14186 panel = that.element.find( selector ); 14187 if ( !panel.length ) { 14188 panel = that._createPanel( panelId ); 14189 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 14190 } 14191 panel.attr( "aria-live", "polite" ); 14192 } 14193 14194 if ( panel.length) { 14195 that.panels = that.panels.add( panel ); 14196 } 14197 if ( originalAriaControls ) { 14198 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 14199 } 14200 tab.attr({ 14201 "aria-controls": selector.substring( 1 ), 14202 "aria-labelledby": anchorId 14203 }); 14204 panel.attr( "aria-labelledby", anchorId ); 14205 }); 14206 14207 this.panels 14208 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14209 .attr( "role", "tabpanel" ); 14210 }, 14211 14212 // allow overriding how to find the list for rare usage scenarios (#7715) 14213 _getList: function() { 14214 return this.element.find( "ol,ul" ).eq( 0 ); 14215 }, 14216 14217 _createPanel: function( id ) { 14218 return $( "<div>" ) 14219 .attr( "id", id ) 14220 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14221 .data( "ui-tabs-destroy", true ); 14222 }, 14223 14224 _setupDisabled: function( disabled ) { 14225 if ( $.isArray( disabled ) ) { 14226 if ( !disabled.length ) { 14227 disabled = false; 14228 } else if ( disabled.length === this.anchors.length ) { 14229 disabled = true; 14230 } 14231 } 14232 14233 // disable tabs 14234 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 14235 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 14236 $( li ) 14237 .addClass( "ui-state-disabled" ) 14238 .attr( "aria-disabled", "true" ); 14239 } else { 14240 $( li ) 14241 .removeClass( "ui-state-disabled" ) 14242 .removeAttr( "aria-disabled" ); 14243 } 14244 } 14245 14246 this.options.disabled = disabled; 14247 }, 14248 14249 _setupEvents: function( event ) { 14250 var events = { 14251 click: function( event ) { 14252 event.preventDefault(); 14253 } 14254 }; 14255 if ( event ) { 14256 $.each( event.split(" "), function( index, eventName ) { 14257 events[ eventName ] = "_eventHandler"; 14258 }); 14259 } 14260 14261 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 14262 this._on( this.anchors, events ); 14263 this._on( this.tabs, { keydown: "_tabKeydown" } ); 14264 this._on( this.panels, { keydown: "_panelKeydown" } ); 14265 14266 this._focusable( this.tabs ); 14267 this._hoverable( this.tabs ); 14268 }, 14269 14270 _setupHeightStyle: function( heightStyle ) { 14271 var maxHeight, 14272 parent = this.element.parent(); 14273 14274 if ( heightStyle === "fill" ) { 14275 maxHeight = parent.height(); 14276 maxHeight -= this.element.outerHeight() - this.element.height(); 14277 14278 this.element.siblings( ":visible" ).each(function() { 14279 var elem = $( this ), 14280 position = elem.css( "position" ); 14281 14282 if ( position === "absolute" || position === "fixed" ) { 14283 return; 14284 } 14285 maxHeight -= elem.outerHeight( true ); 14286 }); 14287 14288 this.element.children().not( this.panels ).each(function() { 14289 maxHeight -= $( this ).outerHeight( true ); 14290 }); 14291 14292 this.panels.each(function() { 14293 $( this ).height( Math.max( 0, maxHeight - 14294 $( this ).innerHeight() + $( this ).height() ) ); 14295 }) 14296 .css( "overflow", "auto" ); 14297 } else if ( heightStyle === "auto" ) { 14298 maxHeight = 0; 14299 this.panels.each(function() { 14300 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 14301 }).height( maxHeight ); 14302 } 14303 }, 14304 14305 _eventHandler: function( event ) { 14306 var options = this.options, 14307 active = this.active, 14308 anchor = $( event.currentTarget ), 14309 tab = anchor.closest( "li" ), 14310 clickedIsActive = tab[ 0 ] === active[ 0 ], 14311 collapsing = clickedIsActive && options.collapsible, 14312 toShow = collapsing ? $() : this._getPanelForTab( tab ), 14313 toHide = !active.length ? $() : this._getPanelForTab( active ), 14314 eventData = { 14315 oldTab: active, 14316 oldPanel: toHide, 14317 newTab: collapsing ? $() : tab, 14318 newPanel: toShow 14319 }; 14320 14321 event.preventDefault(); 14322 14323 if ( tab.hasClass( "ui-state-disabled" ) || 14324 // tab is already loading 14325 tab.hasClass( "ui-tabs-loading" ) || 14326 // can't switch durning an animation 14327 this.running || 14328 // click on active header, but not collapsible 14329 ( clickedIsActive && !options.collapsible ) || 14330 // allow canceling activation 14331 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 14332 return; 14333 } 14334 14335 options.active = collapsing ? false : this.tabs.index( tab ); 14336 14337 this.active = clickedIsActive ? $() : tab; 14338 if ( this.xhr ) { 14339 this.xhr.abort(); 14340 } 14341 14342 if ( !toHide.length && !toShow.length ) { 14343 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 14344 } 14345 14346 if ( toShow.length ) { 14347 this.load( this.tabs.index( tab ), event ); 14348 } 14349 this._toggle( event, eventData ); 14350 }, 14351 14352 // handles show/hide for selecting tabs 14353 _toggle: function( event, eventData ) { 14354 var that = this, 14355 toShow = eventData.newPanel, 14356 toHide = eventData.oldPanel; 14357 14358 this.running = true; 14359 14360 function complete() { 14361 that.running = false; 14362 that._trigger( "activate", event, eventData ); 14363 } 14364 14365 function show() { 14366 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 14367 14368 if ( toShow.length && that.options.show ) { 14369 that._show( toShow, that.options.show, complete ); 14370 } else { 14371 toShow.show(); 14372 complete(); 14373 } 14374 } 14375 14376 // start out by hiding, then showing, then completing 14377 if ( toHide.length && this.options.hide ) { 14378 this._hide( toHide, this.options.hide, function() { 14379 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14380 show(); 14381 }); 14382 } else { 14383 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14384 toHide.hide(); 14385 show(); 14386 } 14387 14388 toHide.attr({ 14389 "aria-expanded": "false", 14390 "aria-hidden": "true" 14391 }); 14392 eventData.oldTab.attr( "aria-selected", "false" ); 14393 // If we're switching tabs, remove the old tab from the tab order. 14394 // If we're opening from collapsed state, remove the previous tab from the tab order. 14395 // If we're collapsing, then keep the collapsing tab in the tab order. 14396 if ( toShow.length && toHide.length ) { 14397 eventData.oldTab.attr( "tabIndex", -1 ); 14398 } else if ( toShow.length ) { 14399 this.tabs.filter(function() { 14400 return $( this ).attr( "tabIndex" ) === 0; 14401 }) 14402 .attr( "tabIndex", -1 ); 14403 } 14404 14405 toShow.attr({ 14406 "aria-expanded": "true", 14407 "aria-hidden": "false" 14408 }); 14409 eventData.newTab.attr({ 14410 "aria-selected": "true", 14411 tabIndex: 0 14412 }); 14413 }, 14414 14415 _activate: function( index ) { 14416 var anchor, 14417 active = this._findActive( index ); 14418 14419 // trying to activate the already active panel 14420 if ( active[ 0 ] === this.active[ 0 ] ) { 14421 return; 14422 } 14423 14424 // trying to collapse, simulate a click on the current active header 14425 if ( !active.length ) { 14426 active = this.active; 14427 } 14428 14429 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 14430 this._eventHandler({ 14431 target: anchor, 14432 currentTarget: anchor, 14433 preventDefault: $.noop 14434 }); 14435 }, 14436 14437 _findActive: function( index ) { 14438 return index === false ? $() : this.tabs.eq( index ); 14439 }, 14440 14441 _getIndex: function( index ) { 14442 // meta-function to give users option to provide a href string instead of a numerical index. 14443 if ( typeof index === "string" ) { 14444 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 14445 } 14446 14447 return index; 14448 }, 14449 14450 _destroy: function() { 14451 if ( this.xhr ) { 14452 this.xhr.abort(); 14453 } 14454 14455 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 14456 14457 this.tablist 14458 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14459 .removeAttr( "role" ); 14460 14461 this.anchors 14462 .removeClass( "ui-tabs-anchor" ) 14463 .removeAttr( "role" ) 14464 .removeAttr( "tabIndex" ) 14465 .removeUniqueId(); 14466 14467 this.tabs.add( this.panels ).each(function() { 14468 if ( $.data( this, "ui-tabs-destroy" ) ) { 14469 $( this ).remove(); 14470 } else { 14471 $( this ) 14472 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 14473 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 14474 .removeAttr( "tabIndex" ) 14475 .removeAttr( "aria-live" ) 14476 .removeAttr( "aria-busy" ) 14477 .removeAttr( "aria-selected" ) 14478 .removeAttr( "aria-labelledby" ) 14479 .removeAttr( "aria-hidden" ) 14480 .removeAttr( "aria-expanded" ) 14481 .removeAttr( "role" ); 14482 } 14483 }); 14484 14485 this.tabs.each(function() { 14486 var li = $( this ), 14487 prev = li.data( "ui-tabs-aria-controls" ); 14488 if ( prev ) { 14489 li 14490 .attr( "aria-controls", prev ) 14491 .removeData( "ui-tabs-aria-controls" ); 14492 } else { 14493 li.removeAttr( "aria-controls" ); 14494 } 14495 }); 14496 14497 this.panels.show(); 14498 14499 if ( this.options.heightStyle !== "content" ) { 14500 this.panels.css( "height", "" ); 14501 } 14502 }, 14503 14504 enable: function( index ) { 14505 var disabled = this.options.disabled; 14506 if ( disabled === false ) { 14507 return; 14508 } 14509 14510 if ( index === undefined ) { 14511 disabled = false; 14512 } else { 14513 index = this._getIndex( index ); 14514 if ( $.isArray( disabled ) ) { 14515 disabled = $.map( disabled, function( num ) { 14516 return num !== index ? num : null; 14517 }); 14518 } else { 14519 disabled = $.map( this.tabs, function( li, num ) { 14520 return num !== index ? num : null; 14521 }); 14522 } 14523 } 14524 this._setupDisabled( disabled ); 14525 }, 14526 14527 disable: function( index ) { 14528 var disabled = this.options.disabled; 14529 if ( disabled === true ) { 14530 return; 14531 } 14532 14533 if ( index === undefined ) { 14534 disabled = true; 14535 } else { 14536 index = this._getIndex( index ); 14537 if ( $.inArray( index, disabled ) !== -1 ) { 14538 return; 14539 } 14540 if ( $.isArray( disabled ) ) { 14541 disabled = $.merge( [ index ], disabled ).sort(); 14542 } else { 14543 disabled = [ index ]; 14544 } 14545 } 14546 this._setupDisabled( disabled ); 14547 }, 14548 14549 load: function( index, event ) { 14550 index = this._getIndex( index ); 14551 var that = this, 14552 tab = this.tabs.eq( index ), 14553 anchor = tab.find( ".ui-tabs-anchor" ), 14554 panel = this._getPanelForTab( tab ), 14555 eventData = { 14556 tab: tab, 14557 panel: panel 14558 }; 14559 14560 // not remote 14561 if ( isLocal( anchor[ 0 ] ) ) { 14562 return; 14563 } 14564 14565 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 14566 14567 // support: jQuery <1.8 14568 // jQuery <1.8 returns false if the request is canceled in beforeSend, 14569 // but as of 1.8, $.ajax() always returns a jqXHR object. 14570 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 14571 tab.addClass( "ui-tabs-loading" ); 14572 panel.attr( "aria-busy", "true" ); 14573 14574 this.xhr 14575 .success(function( response ) { 14576 // support: jQuery <1.8 14577 // http://bugs.jquery.com/ticket/11778 14578 setTimeout(function() { 14579 panel.html( response ); 14580 that._trigger( "load", event, eventData ); 14581 }, 1 ); 14582 }) 14583 .complete(function( jqXHR, status ) { 14584 // support: jQuery <1.8 14585 // http://bugs.jquery.com/ticket/11778 14586 setTimeout(function() { 14587 if ( status === "abort" ) { 14588 that.panels.stop( false, true ); 14589 } 14590 14591 tab.removeClass( "ui-tabs-loading" ); 14592 panel.removeAttr( "aria-busy" ); 14593 14594 if ( jqXHR === that.xhr ) { 14595 delete that.xhr; 14596 } 14597 }, 1 ); 14598 }); 14599 } 14600 }, 14601 14602 _ajaxSettings: function( anchor, event, eventData ) { 14603 var that = this; 14604 return { 14605 url: anchor.attr( "href" ), 14606 beforeSend: function( jqXHR, settings ) { 14607 return that._trigger( "beforeLoad", event, 14608 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 14609 } 14610 }; 14611 }, 14612 14613 _getPanelForTab: function( tab ) { 14614 var id = $( tab ).attr( "aria-controls" ); 14615 return this.element.find( this._sanitizeSelector( "#" + id ) ); 14616 } 14617}); 14618 14619})( jQuery ); 14620 14621(function( $ ) { 14622 14623var increments = 0; 14624 14625function addDescribedBy( elem, id ) { 14626 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 14627 describedby.push( id ); 14628 elem 14629 .data( "ui-tooltip-id", id ) 14630 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 14631} 14632 14633function removeDescribedBy( elem ) { 14634 var id = elem.data( "ui-tooltip-id" ), 14635 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 14636 index = $.inArray( id, describedby ); 14637 if ( index !== -1 ) { 14638 describedby.splice( index, 1 ); 14639 } 14640 14641 elem.removeData( "ui-tooltip-id" ); 14642 describedby = $.trim( describedby.join( " " ) ); 14643 if ( describedby ) { 14644 elem.attr( "aria-describedby", describedby ); 14645 } else { 14646 elem.removeAttr( "aria-describedby" ); 14647 } 14648} 14649 14650$.widget( "ui.tooltip", { 14651 version: "1.10.3", 14652 options: { 14653 content: function() { 14654 // support: IE<9, Opera in jQuery <1.7 14655 // .text() can't accept undefined, so coerce to a string 14656 var title = $( this ).attr( "title" ) || ""; 14657 // Escape title, since we're going from an attribute to raw HTML 14658 return $( "<a>" ).text( title ).html(); 14659 }, 14660 hide: true, 14661 // Disabled elements have inconsistent behavior across browsers (#8661) 14662 items: "[title]:not([disabled])", 14663 position: { 14664 my: "left top+15", 14665 at: "left bottom", 14666 collision: "flipfit flip" 14667 }, 14668 show: true, 14669 tooltipClass: null, 14670 track: false, 14671 14672 // callbacks 14673 close: null, 14674 open: null 14675 }, 14676 14677 _create: function() { 14678 this._on({ 14679 mouseover: "open", 14680 focusin: "open" 14681 }); 14682 14683 // IDs of generated tooltips, needed for destroy 14684 this.tooltips = {}; 14685 // IDs of parent tooltips where we removed the title attribute 14686 this.parents = {}; 14687 14688 if ( this.options.disabled ) { 14689 this._disable(); 14690 } 14691 }, 14692 14693 _setOption: function( key, value ) { 14694 var that = this; 14695 14696 if ( key === "disabled" ) { 14697 this[ value ? "_disable" : "_enable" ](); 14698 this.options[ key ] = value; 14699 // disable element style changes 14700 return; 14701 } 14702 14703 this._super( key, value ); 14704 14705 if ( key === "content" ) { 14706 $.each( this.tooltips, function( id, element ) { 14707 that._updateContent( element ); 14708 }); 14709 } 14710 }, 14711 14712 _disable: function() { 14713 var that = this; 14714 14715 // close open tooltips 14716 $.each( this.tooltips, function( id, element ) { 14717 var event = $.Event( "blur" ); 14718 event.target = event.currentTarget = element[0]; 14719 that.close( event, true ); 14720 }); 14721 14722 // remove title attributes to prevent native tooltips 14723 this.element.find( this.options.items ).addBack().each(function() { 14724 var element = $( this ); 14725 if ( element.is( "[title]" ) ) { 14726 element 14727 .data( "ui-tooltip-title", element.attr( "title" ) ) 14728 .attr( "title", "" ); 14729 } 14730 }); 14731 }, 14732 14733 _enable: function() { 14734 // restore title attributes 14735 this.element.find( this.options.items ).addBack().each(function() { 14736 var element = $( this ); 14737 if ( element.data( "ui-tooltip-title" ) ) { 14738 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14739 } 14740 }); 14741 }, 14742 14743 open: function( event ) { 14744 var that = this, 14745 target = $( event ? event.target : this.element ) 14746 // we need closest here due to mouseover bubbling, 14747 // but always pointing at the same event target 14748 .closest( this.options.items ); 14749 14750 // No element to show a tooltip for or the tooltip is already open 14751 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 14752 return; 14753 } 14754 14755 if ( target.attr( "title" ) ) { 14756 target.data( "ui-tooltip-title", target.attr( "title" ) ); 14757 } 14758 14759 target.data( "ui-tooltip-open", true ); 14760 14761 // kill parent tooltips, custom or native, for hover 14762 if ( event && event.type === "mouseover" ) { 14763 target.parents().each(function() { 14764 var parent = $( this ), 14765 blurEvent; 14766 if ( parent.data( "ui-tooltip-open" ) ) { 14767 blurEvent = $.Event( "blur" ); 14768 blurEvent.target = blurEvent.currentTarget = this; 14769 that.close( blurEvent, true ); 14770 } 14771 if ( parent.attr( "title" ) ) { 14772 parent.uniqueId(); 14773 that.parents[ this.id ] = { 14774 element: this, 14775 title: parent.attr( "title" ) 14776 }; 14777 parent.attr( "title", "" ); 14778 } 14779 }); 14780 } 14781 14782 this._updateContent( target, event ); 14783 }, 14784 14785 _updateContent: function( target, event ) { 14786 var content, 14787 contentOption = this.options.content, 14788 that = this, 14789 eventType = event ? event.type : null; 14790 14791 if ( typeof contentOption === "string" ) { 14792 return this._open( event, target, contentOption ); 14793 } 14794 14795 content = contentOption.call( target[0], function( response ) { 14796 // ignore async response if tooltip was closed already 14797 if ( !target.data( "ui-tooltip-open" ) ) { 14798 return; 14799 } 14800 // IE may instantly serve a cached response for ajax requests 14801 // delay this call to _open so the other call to _open runs first 14802 that._delay(function() { 14803 // jQuery creates a special event for focusin when it doesn't 14804 // exist natively. To improve performance, the native event 14805 // object is reused and the type is changed. Therefore, we can't 14806 // rely on the type being correct after the event finished 14807 // bubbling, so we set it back to the previous value. (#8740) 14808 if ( event ) { 14809 event.type = eventType; 14810 } 14811 this._open( event, target, response ); 14812 }); 14813 }); 14814 if ( content ) { 14815 this._open( event, target, content ); 14816 } 14817 }, 14818 14819 _open: function( event, target, content ) { 14820 var tooltip, events, delayedShow, 14821 positionOption = $.extend( {}, this.options.position ); 14822 14823 if ( !content ) { 14824 return; 14825 } 14826 14827 // Content can be updated multiple times. If the tooltip already 14828 // exists, then just update the content and bail. 14829 tooltip = this._find( target ); 14830 if ( tooltip.length ) { 14831 tooltip.find( ".ui-tooltip-content" ).html( content ); 14832 return; 14833 } 14834 14835 // if we have a title, clear it to prevent the native tooltip 14836 // we have to check first to avoid defining a title if none exists 14837 // (we don't want to cause an element to start matching [title]) 14838 // 14839 // We use removeAttr only for key events, to allow IE to export the correct 14840 // accessible attributes. For mouse events, set to empty string to avoid 14841 // native tooltip showing up (happens only when removing inside mouseover). 14842 if ( target.is( "[title]" ) ) { 14843 if ( event && event.type === "mouseover" ) { 14844 target.attr( "title", "" ); 14845 } else { 14846 target.removeAttr( "title" ); 14847 } 14848 } 14849 14850 tooltip = this._tooltip( target ); 14851 addDescribedBy( target, tooltip.attr( "id" ) ); 14852 tooltip.find( ".ui-tooltip-content" ).html( content ); 14853 14854 function position( event ) { 14855 positionOption.of = event; 14856 if ( tooltip.is( ":hidden" ) ) { 14857 return; 14858 } 14859 tooltip.position( positionOption ); 14860 } 14861 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 14862 this._on( this.document, { 14863 mousemove: position 14864 }); 14865 // trigger once to override element-relative positioning 14866 position( event ); 14867 } else { 14868 tooltip.position( $.extend({ 14869 of: target 14870 }, this.options.position ) ); 14871 } 14872 14873 tooltip.hide(); 14874 14875 this._show( tooltip, this.options.show ); 14876 // Handle tracking tooltips that are shown with a delay (#8644). As soon 14877 // as the tooltip is visible, position the tooltip using the most recent 14878 // event. 14879 if ( this.options.show && this.options.show.delay ) { 14880 delayedShow = this.delayedShow = setInterval(function() { 14881 if ( tooltip.is( ":visible" ) ) { 14882 position( positionOption.of ); 14883 clearInterval( delayedShow ); 14884 } 14885 }, $.fx.interval ); 14886 } 14887 14888 this._trigger( "open", event, { tooltip: tooltip } ); 14889 14890 events = { 14891 keyup: function( event ) { 14892 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 14893 var fakeEvent = $.Event(event); 14894 fakeEvent.currentTarget = target[0]; 14895 this.close( fakeEvent, true ); 14896 } 14897 }, 14898 remove: function() { 14899 this._removeTooltip( tooltip ); 14900 } 14901 }; 14902 if ( !event || event.type === "mouseover" ) { 14903 events.mouseleave = "close"; 14904 } 14905 if ( !event || event.type === "focusin" ) { 14906 events.focusout = "close"; 14907 } 14908 this._on( true, target, events ); 14909 }, 14910 14911 close: function( event ) { 14912 var that = this, 14913 target = $( event ? event.currentTarget : this.element ), 14914 tooltip = this._find( target ); 14915 14916 // disabling closes the tooltip, so we need to track when we're closing 14917 // to avoid an infinite loop in case the tooltip becomes disabled on close 14918 if ( this.closing ) { 14919 return; 14920 } 14921 14922 // Clear the interval for delayed tracking tooltips 14923 clearInterval( this.delayedShow ); 14924 14925 // only set title if we had one before (see comment in _open()) 14926 if ( target.data( "ui-tooltip-title" ) ) { 14927 target.attr( "title", target.data( "ui-tooltip-title" ) ); 14928 } 14929 14930 removeDescribedBy( target ); 14931 14932 tooltip.stop( true ); 14933 this._hide( tooltip, this.options.hide, function() { 14934 that._removeTooltip( $( this ) ); 14935 }); 14936 14937 target.removeData( "ui-tooltip-open" ); 14938 this._off( target, "mouseleave focusout keyup" ); 14939 // Remove 'remove' binding only on delegated targets 14940 if ( target[0] !== this.element[0] ) { 14941 this._off( target, "remove" ); 14942 } 14943 this._off( this.document, "mousemove" ); 14944 14945 if ( event && event.type === "mouseleave" ) { 14946 $.each( this.parents, function( id, parent ) { 14947 $( parent.element ).attr( "title", parent.title ); 14948 delete that.parents[ id ]; 14949 }); 14950 } 14951 14952 this.closing = true; 14953 this._trigger( "close", event, { tooltip: tooltip } ); 14954 this.closing = false; 14955 }, 14956 14957 _tooltip: function( element ) { 14958 var id = "ui-tooltip-" + increments++, 14959 tooltip = $( "<div>" ) 14960 .attr({ 14961 id: id, 14962 role: "tooltip" 14963 }) 14964 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 14965 ( this.options.tooltipClass || "" ) ); 14966 $( "<div>" ) 14967 .addClass( "ui-tooltip-content" ) 14968 .appendTo( tooltip ); 14969 tooltip.appendTo( this.document[0].body ); 14970 this.tooltips[ id ] = element; 14971 return tooltip; 14972 }, 14973 14974 _find: function( target ) { 14975 var id = target.data( "ui-tooltip-id" ); 14976 return id ? $( "#" + id ) : $(); 14977 }, 14978 14979 _removeTooltip: function( tooltip ) { 14980 tooltip.remove(); 14981 delete this.tooltips[ tooltip.attr( "id" ) ]; 14982 }, 14983 14984 _destroy: function() { 14985 var that = this; 14986 14987 // close open tooltips 14988 $.each( this.tooltips, function( id, element ) { 14989 // Delegate to close method to handle common cleanup 14990 var event = $.Event( "blur" ); 14991 event.target = event.currentTarget = element[0]; 14992 that.close( event, true ); 14993 14994 // Remove immediately; destroying an open tooltip doesn't use the 14995 // hide animation 14996 $( "#" + id ).remove(); 14997 14998 // Restore the title 14999 if ( element.data( "ui-tooltip-title" ) ) { 15000 element.attr( "title", element.data( "ui-tooltip-title" ) ); 15001 element.removeData( "ui-tooltip-title" ); 15002 } 15003 }); 15004 } 15005}); 15006 15007}( 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.