vendor: 87,789 bytes, lines 1-3049
1/*! jQuery UI - v1.10.4 - 2014-01-17 2* http://jqueryui.com 3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.effect.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.progressbar.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.slider.js, jquery.ui.sortable.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js 4* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ 5 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11// $.ui might exist from components with no dependencies, e.g., $.ui.position 12$.ui = $.ui || {}; 13 14$.extend( $.ui, { 15 version: "1.10.4", 16 17 keyCode: { 18 BACKSPACE: 8, 19 COMMA: 188, 20 DELETE: 46, 21 DOWN: 40, 22 END: 35, 23 ENTER: 13, 24 ESCAPE: 27, 25 HOME: 36, 26 LEFT: 37, 27 NUMPAD_ADD: 107, 28 NUMPAD_DECIMAL: 110, 29 NUMPAD_DIVIDE: 111, 30 NUMPAD_ENTER: 108, 31 NUMPAD_MULTIPLY: 106, 32 NUMPAD_SUBTRACT: 109, 33 PAGE_DOWN: 34, 34 PAGE_UP: 33, 35 PERIOD: 190, 36 RIGHT: 39, 37 SPACE: 32, 38 TAB: 9, 39 UP: 38 40 } 41}); 42 43// plugins 44$.fn.extend({ 45 focus: (function( orig ) { 46 return function( delay, fn ) { 47 return typeof delay === "number" ? 48 this.each(function() { 49 var elem = this; 50 setTimeout(function() { 51 $( elem ).focus(); 52 if ( fn ) { 53 fn.call( elem ); 54 } 55 }, delay ); 56 }) : 57 orig.apply( this, arguments ); 58 }; 59 })( $.fn.focus ), 60 61 scrollParent: function() { 62 var scrollParent; 63 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 64 scrollParent = this.parents().filter(function() { 65 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 66 }).eq(0); 67 } else { 68 scrollParent = this.parents().filter(function() { 69 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 70 }).eq(0); 71 } 72 73 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 74 }, 75 76 zIndex: function( zIndex ) { 77 if ( zIndex !== undefined ) { 78 return this.css( "zIndex", zIndex ); 79 } 80 81 if ( this.length ) { 82 var elem = $( this[ 0 ] ), position, value; 83 while ( elem.length && elem[ 0 ] !== document ) { 84 // Ignore z-index if position is set to a value where z-index is ignored by the browser 85 // This makes behavior of this function consistent across browsers 86 // WebKit always returns auto if the element is positioned 87 position = elem.css( "position" ); 88 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 89 // IE returns 0 when zIndex is not specified 90 // other browsers return a string 91 // we ignore the case of nested elements with an explicit value of 0 92 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 93 value = parseInt( elem.css( "zIndex" ), 10 ); 94 if ( !isNaN( value ) && value !== 0 ) { 95 return value; 96 } 97 } 98 elem = elem.parent(); 99 } 100 } 101 102 return 0; 103 }, 104 105 uniqueId: function() { 106 return this.each(function() { 107 if ( !this.id ) { 108 this.id = "ui-id-" + (++uuid); 109 } 110 }); 111 }, 112 113 removeUniqueId: function() { 114 return this.each(function() { 115 if ( runiqueId.test( this.id ) ) { 116 $( this ).removeAttr( "id" ); 117 } 118 }); 119 } 120}); 121 122// selectors 123function focusable( element, isTabIndexNotNaN ) { 124 var map, mapName, img, 125 nodeName = element.nodeName.toLowerCase(); 126 if ( "area" === nodeName ) { 127 map = element.parentNode; 128 mapName = map.name; 129 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 130 return false; 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(function( $, undefined ) { 317 318var uuid = 0, 319 slice = Array.prototype.slice, 320 _cleanData = $.cleanData; 321$.cleanData = function( elems ) { 322 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 323 try { 324 $( elem ).triggerHandler( "remove" ); 325 // http://bugs.jquery.com/ticket/8235 326 } catch( e ) {} 327 } 328 _cleanData( elems ); 329}; 330 331$.widget = function( name, base, prototype ) { 332 var fullName, existingConstructor, constructor, basePrototype, 333 // proxiedPrototype allows the provided prototype to remain unmodified 334 // so that it can be used as a mixin for multiple widgets (#8876) 335 proxiedPrototype = {}, 336 namespace = name.split( "." )[ 0 ]; 337 338 name = name.split( "." )[ 1 ]; 339 fullName = namespace + "-" + name; 340 341 if ( !prototype ) { 342 prototype = base; 343 base = $.Widget; 344 } 345 346 // create selector for plugin 347 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 348 return !!$.data( elem, fullName ); 349 }; 350 351 $[ namespace ] = $[ namespace ] || {}; 352 existingConstructor = $[ namespace ][ name ]; 353 constructor = $[ namespace ][ name ] = function( options, element ) { 354 // allow instantiation without "new" keyword 355 if ( !this._createWidget ) { 356 return new constructor( options, element ); 357 } 358 359 // allow instantiation without initializing for simple inheritance 360 // must use "new" keyword (the code above always passes args) 361 if ( arguments.length ) { 362 this._createWidget( options, element ); 363 } 364 }; 365 // extend with the existing constructor to carry over any static properties 366 $.extend( constructor, existingConstructor, { 367 version: prototype.version, 368 // copy the object used to create the prototype in case we need to 369 // redefine the widget later 370 _proto: $.extend( {}, prototype ), 371 // track widgets that inherit from this widget in case this widget is 372 // redefined after a widget inherits from it 373 _childConstructors: [] 374 }); 375 376 basePrototype = new base(); 377 // we need to make the options hash a property directly on the new instance 378 // otherwise we'll modify the options hash on the prototype that we're 379 // inheriting from 380 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 381 $.each( prototype, function( prop, value ) { 382 if ( !$.isFunction( value ) ) { 383 proxiedPrototype[ prop ] = value; 384 return; 385 } 386 proxiedPrototype[ prop ] = (function() { 387 var _super = function() { 388 return base.prototype[ prop ].apply( this, arguments ); 389 }, 390 _superApply = function( args ) { 391 return base.prototype[ prop ].apply( this, args ); 392 }; 393 return function() { 394 var __super = this._super, 395 __superApply = this._superApply, 396 returnValue; 397 398 this._super = _super; 399 this._superApply = _superApply; 400 401 returnValue = value.apply( this, arguments ); 402 403 this._super = __super; 404 this._superApply = __superApply; 405 406 return returnValue; 407 }; 408 })(); 409 }); 410 constructor.prototype = $.widget.extend( basePrototype, { 411 // TODO: remove support for widgetEventPrefix 412 // always use the name + a colon as the prefix, e.g., draggable:start 413 // don't prefix for widgets that aren't DOM-based 414 widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name 415 }, proxiedPrototype, { 416 constructor: constructor, 417 namespace: namespace, 418 widgetName: name, 419 widgetFullName: fullName 420 }); 421 422 // If this widget is being redefined then we need to find all widgets that 423 // are inheriting from it and redefine all of them so that they inherit from 424 // the new version of this widget. We're essentially trying to replace one 425 // level in the prototype chain. 426 if ( existingConstructor ) { 427 $.each( existingConstructor._childConstructors, function( i, child ) { 428 var childPrototype = child.prototype; 429 430 // redefine the child widget using the same prototype that was 431 // originally used, but inherit from the new version of the base 432 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 433 }); 434 // remove the list of existing child constructors from the old constructor 435 // so the old child constructors can be garbage collected 436 delete existingConstructor._childConstructors; 437 } else { 438 base._childConstructors.push( constructor ); 439 } 440 441 $.widget.bridge( name, constructor ); 442}; 443 444$.widget.extend = function( target ) { 445 var input = slice.call( arguments, 1 ), 446 inputIndex = 0, 447 inputLength = input.length, 448 key, 449 value; 450 for ( ; inputIndex < inputLength; inputIndex++ ) { 451 for ( key in input[ inputIndex ] ) { 452 value = input[ inputIndex ][ key ]; 453 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 454 // Clone objects 455 if ( $.isPlainObject( value ) ) { 456 target[ key ] = $.isPlainObject( target[ key ] ) ? 457 $.widget.extend( {}, target[ key ], value ) : 458 // Don't extend strings, arrays, etc. with objects 459 $.widget.extend( {}, value ); 460 // Copy everything else by reference 461 } else { 462 target[ key ] = value; 463 } 464 } 465 } 466 } 467 return target; 468}; 469 470$.widget.bridge = function( name, object ) { 471 var fullName = object.prototype.widgetFullName || name; 472 $.fn[ name ] = function( options ) { 473 var isMethodCall = typeof options === "string", 474 args = slice.call( arguments, 1 ), 475 returnValue = this; 476 477 // allow multiple hashes to be passed on init 478 options = !isMethodCall && args.length ? 479 $.widget.extend.apply( null, [ options ].concat(args) ) : 480 options; 481 482 if ( isMethodCall ) { 483 this.each(function() { 484 var methodValue, 485 instance = $.data( this, fullName ); 486 if ( !instance ) { 487 return $.error( "cannot call methods on " + name + " prior to initialization; " + 488 "attempted to call method '" + options + "'" ); 489 } 490 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 491 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 492 } 493 methodValue = instance[ options ].apply( instance, args ); 494 if ( methodValue !== instance && methodValue !== undefined ) { 495 returnValue = methodValue && methodValue.jquery ? 496 returnValue.pushStack( methodValue.get() ) : 497 methodValue; 498 return false; 499 } 500 }); 501 } else { 502 this.each(function() { 503 var instance = $.data( this, fullName ); 504 if ( instance ) { 505 instance.option( options || {} )._init(); 506 } else { 507 $.data( this, fullName, new object( options, this ) ); 508 } 509 }); 510 } 511 512 return returnValue; 513 }; 514}; 515 516$.Widget = function( /* options, element */ ) {}; 517$.Widget._childConstructors = []; 518 519$.Widget.prototype = { 520 widgetName: "widget", 521 widgetEventPrefix: "", 522 defaultElement: "<div>", 523 options: { 524 disabled: false, 525 526 // callbacks 527 create: null 528 }, 529 _createWidget: function( options, element ) { 530 element = $( element || this.defaultElement || this )[ 0 ]; 531 this.element = $( element ); 532 this.uuid = uuid++; 533 this.eventNamespace = "." + this.widgetName + this.uuid; 534 this.options = $.widget.extend( {}, 535 this.options, 536 this._getCreateOptions(), 537 options ); 538 539 this.bindings = $(); 540 this.hoverable = $(); 541 this.focusable = $(); 542 543 if ( element !== this ) { 544 $.data( element, this.widgetFullName, this ); 545 this._on( true, this.element, { 546 remove: function( event ) { 547 if ( event.target === element ) { 548 this.destroy(); 549 } 550 } 551 }); 552 this.document = $( element.style ? 553 // element within the document 554 element.ownerDocument : 555 // element is window or document 556 element.document || element ); 557 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 558 } 559 560 this._create(); 561 this._trigger( "create", null, this._getCreateEventData() ); 562 this._init(); 563 }, 564 _getCreateOptions: $.noop, 565 _getCreateEventData: $.noop, 566 _create: $.noop, 567 _init: $.noop, 568 569 destroy: function() { 570 this._destroy(); 571 // we can probably remove the unbind calls in 2.0 572 // all event bindings should go through this._on() 573 this.element 574 .unbind( this.eventNamespace ) 575 // 1.9 BC for #7810 576 // TODO remove dual storage 577 .removeData( this.widgetName ) 578 .removeData( this.widgetFullName ) 579 // support: jquery <1.6.3 580 // http://bugs.jquery.com/ticket/9413 581 .removeData( $.camelCase( this.widgetFullName ) ); 582 this.widget() 583 .unbind( this.eventNamespace ) 584 .removeAttr( "aria-disabled" ) 585 .removeClass( 586 this.widgetFullName + "-disabled " + 587 "ui-state-disabled" ); 588 589 // clean up events and states 590 this.bindings.unbind( this.eventNamespace ); 591 this.hoverable.removeClass( "ui-state-hover" ); 592 this.focusable.removeClass( "ui-state-focus" ); 593 }, 594 _destroy: $.noop, 595 596 widget: function() { 597 return this.element; 598 }, 599 600 option: function( key, value ) { 601 var options = key, 602 parts, 603 curOption, 604 i; 605 606 if ( arguments.length === 0 ) { 607 // don't return a reference to the internal hash 608 return $.widget.extend( {}, this.options ); 609 } 610 611 if ( typeof key === "string" ) { 612 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 613 options = {}; 614 parts = key.split( "." ); 615 key = parts.shift(); 616 if ( parts.length ) { 617 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 618 for ( i = 0; i < parts.length - 1; i++ ) { 619 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 620 curOption = curOption[ parts[ i ] ]; 621 } 622 key = parts.pop(); 623 if ( arguments.length === 1 ) { 624 return curOption[ key ] === undefined ? null : curOption[ key ]; 625 } 626 curOption[ key ] = value; 627 } else { 628 if ( arguments.length === 1 ) { 629 return this.options[ key ] === undefined ? null : this.options[ key ]; 630 } 631 options[ key ] = value; 632 } 633 } 634 635 this._setOptions( options ); 636 637 return this; 638 }, 639 _setOptions: function( options ) { 640 var key; 641 642 for ( key in options ) { 643 this._setOption( key, options[ key ] ); 644 } 645 646 return this; 647 }, 648 _setOption: function( key, value ) { 649 this.options[ key ] = value; 650 651 if ( key === "disabled" ) { 652 this.widget() 653 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 654 .attr( "aria-disabled", value ); 655 this.hoverable.removeClass( "ui-state-hover" ); 656 this.focusable.removeClass( "ui-state-focus" ); 657 } 658 659 return this; 660 }, 661 662 enable: function() { 663 return this._setOption( "disabled", false ); 664 }, 665 disable: function() { 666 return this._setOption( "disabled", true ); 667 }, 668 669 _on: function( suppressDisabledCheck, element, handlers ) { 670 var delegateElement, 671 instance = this; 672 673 // no suppressDisabledCheck flag, shuffle arguments 674 if ( typeof suppressDisabledCheck !== "boolean" ) { 675 handlers = element; 676 element = suppressDisabledCheck; 677 suppressDisabledCheck = false; 678 } 679 680 // no element argument, shuffle and use this.element 681 if ( !handlers ) { 682 handlers = element; 683 element = this.element; 684 delegateElement = this.widget(); 685 } else { 686 // accept selectors, DOM elements 687 element = delegateElement = $( element ); 688 this.bindings = this.bindings.add( element ); 689 } 690 691 $.each( handlers, function( event, handler ) { 692 function handlerProxy() { 693 // allow widgets to customize the disabled handling 694 // - disabled as an array instead of boolean 695 // - disabled class as method for disabling individual parts 696 if ( !suppressDisabledCheck && 697 ( instance.options.disabled === true || 698 $( this ).hasClass( "ui-state-disabled" ) ) ) { 699 return; 700 } 701 return ( typeof handler === "string" ? instance[ handler ] : handler ) 702 .apply( instance, arguments ); 703 } 704 705 // copy the guid so direct unbinding works 706 if ( typeof handler !== "string" ) { 707 handlerProxy.guid = handler.guid = 708 handler.guid || handlerProxy.guid || $.guid++; 709 } 710 711 var match = event.match( /^(\w+)\s*(.*)$/ ), 712 eventName = match[1] + instance.eventNamespace, 713 selector = match[2]; 714 if ( selector ) { 715 delegateElement.delegate( selector, eventName, handlerProxy ); 716 } else { 717 element.bind( eventName, handlerProxy ); 718 } 719 }); 720 }, 721 722 _off: function( element, eventName ) { 723 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 724 element.unbind( eventName ).undelegate( eventName ); 725 }, 726 727 _delay: function( handler, delay ) { 728 function handlerProxy() { 729 return ( typeof handler === "string" ? instance[ handler ] : handler ) 730 .apply( instance, arguments ); 731 } 732 var instance = this; 733 return setTimeout( handlerProxy, delay || 0 ); 734 }, 735 736 _hoverable: function( element ) { 737 this.hoverable = this.hoverable.add( element ); 738 this._on( element, { 739 mouseenter: function( event ) { 740 $( event.currentTarget ).addClass( "ui-state-hover" ); 741 }, 742 mouseleave: function( event ) { 743 $( event.currentTarget ).removeClass( "ui-state-hover" ); 744 } 745 }); 746 }, 747 748 _focusable: function( element ) { 749 this.focusable = this.focusable.add( element ); 750 this._on( element, { 751 focusin: function( event ) { 752 $( event.currentTarget ).addClass( "ui-state-focus" ); 753 }, 754 focusout: function( event ) { 755 $( event.currentTarget ).removeClass( "ui-state-focus" ); 756 } 757 }); 758 }, 759 760 _trigger: function( type, event, data ) { 761 var prop, orig, 762 callback = this.options[ type ]; 763 764 data = data || {}; 765 event = $.Event( event ); 766 event.type = ( type === this.widgetEventPrefix ? 767 type : 768 this.widgetEventPrefix + type ).toLowerCase(); 769 // the original event may come from any element 770 // so we need to reset the target on the new event 771 event.target = this.element[ 0 ]; 772 773 // copy original event properties over to the new event 774 orig = event.originalEvent; 775 if ( orig ) { 776 for ( prop in orig ) { 777 if ( !( prop in event ) ) { 778 event[ prop ] = orig[ prop ]; 779 } 780 } 781 } 782 783 this.element.trigger( event, data ); 784 return !( $.isFunction( callback ) && 785 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 786 event.isDefaultPrevented() ); 787 } 788}; 789 790$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 791 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 792 if ( typeof options === "string" ) { 793 options = { effect: options }; 794 } 795 var hasOptions, 796 effectName = !options ? 797 method : 798 options === true || typeof options === "number" ? 799 defaultEffect : 800 options.effect || defaultEffect; 801 options = options || {}; 802 if ( typeof options === "number" ) { 803 options = { duration: options }; 804 } 805 hasOptions = !$.isEmptyObject( options ); 806 options.complete = callback; 807 if ( options.delay ) { 808 element.delay( options.delay ); 809 } 810 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 811 element[ method ]( options ); 812 } else if ( effectName !== method && element[ effectName ] ) { 813 element[ effectName ]( options.duration, options.easing, callback ); 814 } else { 815 element.queue(function( next ) { 816 $( this )[ method ](); 817 if ( callback ) { 818 callback.call( element[ 0 ] ); 819 } 820 next(); 821 }); 822 } 823 }; 824}); 825 826})( jQuery ); 827(function( $, undefined ) { 828 829var mouseHandled = false; 830$( document ).mouseup( function() { 831 mouseHandled = false; 832}); 833 834$.widget("ui.mouse", { 835 version: "1.10.4", 836 options: { 837 cancel: "input,textarea,button,select,option", 838 distance: 1, 839 delay: 0 840 }, 841 _mouseInit: function() { 842 var that = this; 843 844 this.element 845 .bind("mousedown."+this.widgetName, function(event) { 846 return that._mouseDown(event); 847 }) 848 .bind("click."+this.widgetName, function(event) { 849 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 850 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 851 event.stopImmediatePropagation(); 852 return false; 853 } 854 }); 855 856 this.started = false; 857 }, 858 859 // TODO: make sure destroying one instance of mouse doesn't mess with 860 // other instances of mouse 861 _mouseDestroy: function() { 862 this.element.unbind("."+this.widgetName); 863 if ( this._mouseMoveDelegate ) { 864 $(document) 865 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 866 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 867 } 868 }, 869 870 _mouseDown: function(event) { 871 // don't let more than one widget handle mouseStart 872 if( mouseHandled ) { return; } 873 874 // we may have missed mouseup (out of window) 875 (this._mouseStarted && this._mouseUp(event)); 876 877 this._mouseDownEvent = event; 878 879 var that = this, 880 btnIsLeft = (event.which === 1), 881 // event.target.nodeName works around a bug in IE 8 with 882 // disabled inputs (#7620) 883 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 884 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 885 return true; 886 } 887 888 this.mouseDelayMet = !this.options.delay; 889 if (!this.mouseDelayMet) { 890 this._mouseDelayTimer = setTimeout(function() { 891 that.mouseDelayMet = true; 892 }, this.options.delay); 893 } 894 895 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 896 this._mouseStarted = (this._mouseStart(event) !== false); 897 if (!this._mouseStarted) { 898 event.preventDefault(); 899 return true; 900 } 901 } 902 903 // Click event may never have fired (Gecko & Opera) 904 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 905 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 906 } 907 908 // these delegates are required to keep context 909 this._mouseMoveDelegate = function(event) { 910 return that._mouseMove(event); 911 }; 912 this._mouseUpDelegate = function(event) { 913 return that._mouseUp(event); 914 }; 915 $(document) 916 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 917 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 918 919 event.preventDefault(); 920 921 mouseHandled = true; 922 return true; 923 }, 924 925 _mouseMove: function(event) { 926 // IE mouseup check - mouseup happened when mouse was out of window 927 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 928 return this._mouseUp(event); 929 } 930 931 if (this._mouseStarted) { 932 this._mouseDrag(event); 933 return event.preventDefault(); 934 } 935 936 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 937 this._mouseStarted = 938 (this._mouseStart(this._mouseDownEvent, event) !== false); 939 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 940 } 941 942 return !this._mouseStarted; 943 }, 944 945 _mouseUp: function(event) { 946 $(document) 947 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 948 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 949 950 if (this._mouseStarted) { 951 this._mouseStarted = false; 952 953 if (event.target === this._mouseDownEvent.target) { 954 $.data(event.target, this.widgetName + ".preventClickEvent", true); 955 } 956 957 this._mouseStop(event); 958 } 959 960 return false; 961 }, 962 963 _mouseDistanceMet: function(event) { 964 return (Math.max( 965 Math.abs(this._mouseDownEvent.pageX - event.pageX), 966 Math.abs(this._mouseDownEvent.pageY - event.pageY) 967 ) >= this.options.distance 968 ); 969 }, 970 971 _mouseDelayMet: function(/* event */) { 972 return this.mouseDelayMet; 973 }, 974 975 // These are placeholder methods, to be overriden by extending plugin 976 _mouseStart: function(/* event */) {}, 977 _mouseDrag: function(/* event */) {}, 978 _mouseStop: function(/* event */) {}, 979 _mouseCapture: function(/* event */) { return true; } 980}); 981 982})(jQuery); 983(function( $, undefined ) { 984 985$.ui = $.ui || {}; 986 987var cachedScrollbarWidth, 988 max = Math.max, 989 abs = Math.abs, 990 round = Math.round, 991 rhorizontal = /left|center|right/, 992 rvertical = /top|center|bottom/, 993 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 994 rposition = /^\w+/, 995 rpercent = /%$/, 996 _position = $.fn.position; 997 998function getOffsets( offsets, width, height ) { 999 return [ 1000 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1001 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1002 ]; 1003} 1004 1005function parseCss( element, property ) { 1006 return parseInt( $.css( element, property ), 10 ) || 0; 1007} 1008 1009function getDimensions( elem ) { 1010 var raw = elem[0]; 1011 if ( raw.nodeType === 9 ) { 1012 return { 1013 width: elem.width(), 1014 height: elem.height(), 1015 offset: { top: 0, left: 0 } 1016 }; 1017 } 1018 if ( $.isWindow( raw ) ) { 1019 return { 1020 width: elem.width(), 1021 height: elem.height(), 1022 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 1023 }; 1024 } 1025 if ( raw.preventDefault ) { 1026 return { 1027 width: 0, 1028 height: 0, 1029 offset: { top: raw.pageY, left: raw.pageX } 1030 }; 1031 } 1032 return { 1033 width: elem.outerWidth(), 1034 height: elem.outerHeight(), 1035 offset: elem.offset() 1036 }; 1037} 1038 1039$.position = { 1040 scrollbarWidth: function() { 1041 if ( cachedScrollbarWidth !== undefined ) { 1042 return cachedScrollbarWidth; 1043 } 1044 var w1, w2, 1045 div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1046 innerDiv = div.children()[0]; 1047 1048 $( "body" ).append( div ); 1049 w1 = innerDiv.offsetWidth; 1050 div.css( "overflow", "scroll" ); 1051 1052 w2 = innerDiv.offsetWidth; 1053 1054 if ( w1 === w2 ) { 1055 w2 = div[0].clientWidth; 1056 } 1057 1058 div.remove(); 1059 1060 return (cachedScrollbarWidth = w1 - w2); 1061 }, 1062 getScrollInfo: function( within ) { 1063 var overflowX = within.isWindow || within.isDocument ? "" : 1064 within.element.css( "overflow-x" ), 1065 overflowY = within.isWindow || within.isDocument ? "" : 1066 within.element.css( "overflow-y" ), 1067 hasOverflowX = overflowX === "scroll" || 1068 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1069 hasOverflowY = overflowY === "scroll" || 1070 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1071 return { 1072 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 1073 height: hasOverflowX ? $.position.scrollbarWidth() : 0 1074 }; 1075 }, 1076 getWithinInfo: function( element ) { 1077 var withinElement = $( element || window ), 1078 isWindow = $.isWindow( withinElement[0] ), 1079 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; 1080 return { 1081 element: withinElement, 1082 isWindow: isWindow, 1083 isDocument: isDocument, 1084 offset: withinElement.offset() || { left: 0, top: 0 }, 1085 scrollLeft: withinElement.scrollLeft(), 1086 scrollTop: withinElement.scrollTop(), 1087 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 1088 height: isWindow ? withinElement.height() : withinElement.outerHeight() 1089 }; 1090 } 1091}; 1092 1093$.fn.position = function( options ) { 1094 if ( !options || !options.of ) { 1095 return _position.apply( this, arguments ); 1096 } 1097 1098 // make a copy, we don't want to modify arguments 1099 options = $.extend( {}, options ); 1100 1101 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 1102 target = $( options.of ), 1103 within = $.position.getWithinInfo( options.within ), 1104 scrollInfo = $.position.getScrollInfo( within ), 1105 collision = ( options.collision || "flip" ).split( " " ), 1106 offsets = {}; 1107 1108 dimensions = getDimensions( target ); 1109 if ( target[0].preventDefault ) { 1110 // force left top to allow flipping 1111 options.at = "left top"; 1112 } 1113 targetWidth = dimensions.width; 1114 targetHeight = dimensions.height; 1115 targetOffset = dimensions.offset; 1116 // clone to reuse original targetOffset later 1117 basePosition = $.extend( {}, targetOffset ); 1118 1119 // force my and at to have valid horizontal and vertical positions 1120 // if a value is missing or invalid, it will be converted to center 1121 $.each( [ "my", "at" ], function() { 1122 var pos = ( options[ this ] || "" ).split( " " ), 1123 horizontalOffset, 1124 verticalOffset; 1125 1126 if ( pos.length === 1) { 1127 pos = rhorizontal.test( pos[ 0 ] ) ? 1128 pos.concat( [ "center" ] ) : 1129 rvertical.test( pos[ 0 ] ) ? 1130 [ "center" ].concat( pos ) : 1131 [ "center", "center" ]; 1132 } 1133 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1134 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1135 1136 // calculate offsets 1137 horizontalOffset = roffset.exec( pos[ 0 ] ); 1138 verticalOffset = roffset.exec( pos[ 1 ] ); 1139 offsets[ this ] = [ 1140 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1141 verticalOffset ? verticalOffset[ 0 ] : 0 1142 ]; 1143 1144 // reduce to just the positions without the offsets 1145 options[ this ] = [ 1146 rposition.exec( pos[ 0 ] )[ 0 ], 1147 rposition.exec( pos[ 1 ] )[ 0 ] 1148 ]; 1149 }); 1150 1151 // normalize collision option 1152 if ( collision.length === 1 ) { 1153 collision[ 1 ] = collision[ 0 ]; 1154 } 1155 1156 if ( options.at[ 0 ] === "right" ) { 1157 basePosition.left += targetWidth; 1158 } else if ( options.at[ 0 ] === "center" ) { 1159 basePosition.left += targetWidth / 2; 1160 } 1161 1162 if ( options.at[ 1 ] === "bottom" ) { 1163 basePosition.top += targetHeight; 1164 } else if ( options.at[ 1 ] === "center" ) { 1165 basePosition.top += targetHeight / 2; 1166 } 1167 1168 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1169 basePosition.left += atOffset[ 0 ]; 1170 basePosition.top += atOffset[ 1 ]; 1171 1172 return this.each(function() { 1173 var collisionPosition, using, 1174 elem = $( this ), 1175 elemWidth = elem.outerWidth(), 1176 elemHeight = elem.outerHeight(), 1177 marginLeft = parseCss( this, "marginLeft" ), 1178 marginTop = parseCss( this, "marginTop" ), 1179 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1180 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1181 position = $.extend( {}, basePosition ), 1182 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1183 1184 if ( options.my[ 0 ] === "right" ) { 1185 position.left -= elemWidth; 1186 } else if ( options.my[ 0 ] === "center" ) { 1187 position.left -= elemWidth / 2; 1188 } 1189 1190 if ( options.my[ 1 ] === "bottom" ) { 1191 position.top -= elemHeight; 1192 } else if ( options.my[ 1 ] === "center" ) { 1193 position.top -= elemHeight / 2; 1194 } 1195 1196 position.left += myOffset[ 0 ]; 1197 position.top += myOffset[ 1 ]; 1198 1199 // if the browser doesn't support fractions, then round for consistent results 1200 if ( !$.support.offsetFractions ) { 1201 position.left = round( position.left ); 1202 position.top = round( position.top ); 1203 } 1204 1205 collisionPosition = { 1206 marginLeft: marginLeft, 1207 marginTop: marginTop 1208 }; 1209 1210 $.each( [ "left", "top" ], function( i, dir ) { 1211 if ( $.ui.position[ collision[ i ] ] ) { 1212 $.ui.position[ collision[ i ] ][ dir ]( position, { 1213 targetWidth: targetWidth, 1214 targetHeight: targetHeight, 1215 elemWidth: elemWidth, 1216 elemHeight: elemHeight, 1217 collisionPosition: collisionPosition, 1218 collisionWidth: collisionWidth, 1219 collisionHeight: collisionHeight, 1220 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1221 my: options.my, 1222 at: options.at, 1223 within: within, 1224 elem : elem 1225 }); 1226 } 1227 }); 1228 1229 if ( options.using ) { 1230 // adds feedback as second argument to using callback, if present 1231 using = function( props ) { 1232 var left = targetOffset.left - position.left, 1233 right = left + targetWidth - elemWidth, 1234 top = targetOffset.top - position.top, 1235 bottom = top + targetHeight - elemHeight, 1236 feedback = { 1237 target: { 1238 element: target, 1239 left: targetOffset.left, 1240 top: targetOffset.top, 1241 width: targetWidth, 1242 height: targetHeight 1243 }, 1244 element: { 1245 element: elem, 1246 left: position.left, 1247 top: position.top, 1248 width: elemWidth, 1249 height: elemHeight 1250 }, 1251 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1252 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1253 }; 1254 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1255 feedback.horizontal = "center"; 1256 } 1257 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1258 feedback.vertical = "middle"; 1259 } 1260 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1261 feedback.important = "horizontal"; 1262 } else { 1263 feedback.important = "vertical"; 1264 } 1265 options.using.call( this, props, feedback ); 1266 }; 1267 } 1268 1269 elem.offset( $.extend( position, { using: using } ) ); 1270 }); 1271}; 1272 1273$.ui.position = { 1274 fit: { 1275 left: function( position, data ) { 1276 var within = data.within, 1277 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1278 outerWidth = within.width, 1279 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1280 overLeft = withinOffset - collisionPosLeft, 1281 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1282 newOverRight; 1283 1284 // element is wider than within 1285 if ( data.collisionWidth > outerWidth ) { 1286 // element is initially over the left side of within 1287 if ( overLeft > 0 && overRight <= 0 ) { 1288 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1289 position.left += overLeft - newOverRight; 1290 // element is initially over right side of within 1291 } else if ( overRight > 0 && overLeft <= 0 ) { 1292 position.left = withinOffset; 1293 // element is initially over both left and right sides of within 1294 } else { 1295 if ( overLeft > overRight ) { 1296 position.left = withinOffset + outerWidth - data.collisionWidth; 1297 } else { 1298 position.left = withinOffset; 1299 } 1300 } 1301 // too far left -> align with left edge 1302 } else if ( overLeft > 0 ) { 1303 position.left += overLeft; 1304 // too far right -> align with right edge 1305 } else if ( overRight > 0 ) { 1306 position.left -= overRight; 1307 // adjust based on position and margin 1308 } else { 1309 position.left = max( position.left - collisionPosLeft, position.left ); 1310 } 1311 }, 1312 top: function( position, data ) { 1313 var within = data.within, 1314 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1315 outerHeight = data.within.height, 1316 collisionPosTop = position.top - data.collisionPosition.marginTop, 1317 overTop = withinOffset - collisionPosTop, 1318 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1319 newOverBottom; 1320 1321 // element is taller than within 1322 if ( data.collisionHeight > outerHeight ) { 1323 // element is initially over the top of within 1324 if ( overTop > 0 && overBottom <= 0 ) { 1325 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1326 position.top += overTop - newOverBottom; 1327 // element is initially over bottom of within 1328 } else if ( overBottom > 0 && overTop <= 0 ) { 1329 position.top = withinOffset; 1330 // element is initially over both top and bottom of within 1331 } else { 1332 if ( overTop > overBottom ) { 1333 position.top = withinOffset + outerHeight - data.collisionHeight; 1334 } else { 1335 position.top = withinOffset; 1336 } 1337 } 1338 // too far up -> align with top 1339 } else if ( overTop > 0 ) { 1340 position.top += overTop; 1341 // too far down -> align with bottom edge 1342 } else if ( overBottom > 0 ) { 1343 position.top -= overBottom; 1344 // adjust based on position and margin 1345 } else { 1346 position.top = max( position.top - collisionPosTop, position.top ); 1347 } 1348 } 1349 }, 1350 flip: { 1351 left: function( position, data ) { 1352 var within = data.within, 1353 withinOffset = within.offset.left + within.scrollLeft, 1354 outerWidth = within.width, 1355 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1356 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1357 overLeft = collisionPosLeft - offsetLeft, 1358 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1359 myOffset = data.my[ 0 ] === "left" ? 1360 -data.elemWidth : 1361 data.my[ 0 ] === "right" ? 1362 data.elemWidth : 1363 0, 1364 atOffset = data.at[ 0 ] === "left" ? 1365 data.targetWidth : 1366 data.at[ 0 ] === "right" ? 1367 -data.targetWidth : 1368 0, 1369 offset = -2 * data.offset[ 0 ], 1370 newOverRight, 1371 newOverLeft; 1372 1373 if ( overLeft < 0 ) { 1374 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1375 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1376 position.left += myOffset + atOffset + offset; 1377 } 1378 } 1379 else if ( overRight > 0 ) { 1380 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1381 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1382 position.left += myOffset + atOffset + offset; 1383 } 1384 } 1385 }, 1386 top: function( position, data ) { 1387 var within = data.within, 1388 withinOffset = within.offset.top + within.scrollTop, 1389 outerHeight = within.height, 1390 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1391 collisionPosTop = position.top - data.collisionPosition.marginTop, 1392 overTop = collisionPosTop - offsetTop, 1393 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1394 top = data.my[ 1 ] === "top", 1395 myOffset = top ? 1396 -data.elemHeight : 1397 data.my[ 1 ] === "bottom" ? 1398 data.elemHeight : 1399 0, 1400 atOffset = data.at[ 1 ] === "top" ? 1401 data.targetHeight : 1402 data.at[ 1 ] === "bottom" ? 1403 -data.targetHeight : 1404 0, 1405 offset = -2 * data.offset[ 1 ], 1406 newOverTop, 1407 newOverBottom; 1408 if ( overTop < 0 ) { 1409 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1410 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1411 position.top += myOffset + atOffset + offset; 1412 } 1413 } 1414 else if ( overBottom > 0 ) { 1415 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1416 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1417 position.top += myOffset + atOffset + offset; 1418 } 1419 } 1420 } 1421 }, 1422 flipfit: { 1423 left: function() { 1424 $.ui.position.flip.left.apply( this, arguments ); 1425 $.ui.position.fit.left.apply( this, arguments ); 1426 }, 1427 top: function() { 1428 $.ui.position.flip.top.apply( this, arguments ); 1429 $.ui.position.fit.top.apply( this, arguments ); 1430 } 1431 } 1432}; 1433 1434// fraction support test 1435(function () { 1436 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1437 body = document.getElementsByTagName( "body" )[ 0 ], 1438 div = document.createElement( "div" ); 1439 1440 //Create a "fake body" for testing based on method used in jQuery.support 1441 testElement = document.createElement( body ? "div" : "body" ); 1442 testElementStyle = { 1443 visibility: "hidden", 1444 width: 0, 1445 height: 0, 1446 border: 0, 1447 margin: 0, 1448 background: "none" 1449 }; 1450 if ( body ) { 1451 $.extend( testElementStyle, { 1452 position: "absolute", 1453 left: "-1000px", 1454 top: "-1000px" 1455 }); 1456 } 1457 for ( i in testElementStyle ) { 1458 testElement.style[ i ] = testElementStyle[ i ]; 1459 } 1460 testElement.appendChild( div ); 1461 testElementParent = body || document.documentElement; 1462 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1463 1464 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1465 1466 offsetLeft = $( div ).offset().left; 1467 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 1468 1469 testElement.innerHTML = ""; 1470 testElementParent.removeChild( testElement ); 1471})(); 1472 1473}( jQuery ) ); 1474(function( $, undefined ) { 1475 1476var uid = 0, 1477 hideProps = {}, 1478 showProps = {}; 1479 1480hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 1481 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 1482showProps.height = showProps.paddingTop = showProps.paddingBottom = 1483 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 1484 1485$.widget( "ui.accordion", { 1486 version: "1.10.4", 1487 options: { 1488 active: 0, 1489 animate: {}, 1490 collapsible: false, 1491 event: "click", 1492 header: "> li > :first-child,> :not(li):even", 1493 heightStyle: "auto", 1494 icons: { 1495 activeHeader: "ui-icon-triangle-1-s", 1496 header: "ui-icon-triangle-1-e" 1497 }, 1498 1499 // callbacks 1500 activate: null, 1501 beforeActivate: null 1502 }, 1503 1504 _create: function() { 1505 var options = this.options; 1506 this.prevShow = this.prevHide = $(); 1507 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 1508 // ARIA 1509 .attr( "role", "tablist" ); 1510 1511 // don't allow collapsible: false and active: false / null 1512 if ( !options.collapsible && (options.active === false || options.active == null) ) { 1513 options.active = 0; 1514 } 1515 1516 this._processPanels(); 1517 // handle negative values 1518 if ( options.active < 0 ) { 1519 options.active += this.headers.length; 1520 } 1521 this._refresh(); 1522 }, 1523 1524 _getCreateEventData: function() { 1525 return { 1526 header: this.active, 1527 panel: !this.active.length ? $() : this.active.next(), 1528 content: !this.active.length ? $() : this.active.next() 1529 }; 1530 }, 1531 1532 _createIcons: function() { 1533 var icons = this.options.icons; 1534 if ( icons ) { 1535 $( "<span>" ) 1536 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 1537 .prependTo( this.headers ); 1538 this.active.children( ".ui-accordion-header-icon" ) 1539 .removeClass( icons.header ) 1540 .addClass( icons.activeHeader ); 1541 this.headers.addClass( "ui-accordion-icons" ); 1542 } 1543 }, 1544 1545 _destroyIcons: function() { 1546 this.headers 1547 .removeClass( "ui-accordion-icons" ) 1548 .children( ".ui-accordion-header-icon" ) 1549 .remove(); 1550 }, 1551 1552 _destroy: function() { 1553 var contents; 1554 1555 // clean up main element 1556 this.element 1557 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 1558 .removeAttr( "role" ); 1559 1560 // clean up headers 1561 this.headers 1562 .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" ) 1563 .removeAttr( "role" ) 1564 .removeAttr( "aria-expanded" ) 1565 .removeAttr( "aria-selected" ) 1566 .removeAttr( "aria-controls" ) 1567 .removeAttr( "tabIndex" ) 1568 .each(function() { 1569 if ( /^ui-accordion/.test( this.id ) ) { 1570 this.removeAttribute( "id" ); 1571 } 1572 }); 1573 this._destroyIcons(); 1574 1575 // clean up content panels 1576 contents = this.headers.next() 1577 .css( "display", "" ) 1578 .removeAttr( "role" ) 1579 .removeAttr( "aria-hidden" ) 1580 .removeAttr( "aria-labelledby" ) 1581 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 1582 .each(function() { 1583 if ( /^ui-accordion/.test( this.id ) ) { 1584 this.removeAttribute( "id" ); 1585 } 1586 }); 1587 if ( this.options.heightStyle !== "content" ) { 1588 contents.css( "height", "" ); 1589 } 1590 }, 1591 1592 _setOption: function( key, value ) { 1593 if ( key === "active" ) { 1594 // _activate() will handle invalid values and update this.options 1595 this._activate( value ); 1596 return; 1597 } 1598 1599 if ( key === "event" ) { 1600 if ( this.options.event ) { 1601 this._off( this.headers, this.options.event ); 1602 } 1603 this._setupEvents( value ); 1604 } 1605 1606 this._super( key, value ); 1607 1608 // setting collapsible: false while collapsed; open first panel 1609 if ( key === "collapsible" && !value && this.options.active === false ) { 1610 this._activate( 0 ); 1611 } 1612 1613 if ( key === "icons" ) { 1614 this._destroyIcons(); 1615 if ( value ) { 1616 this._createIcons(); 1617 } 1618 } 1619 1620 // #5332 - opacity doesn't cascade to positioned elements in IE 1621 // so we need to add the disabled class to the headers and panels 1622 if ( key === "disabled" ) { 1623 this.headers.add( this.headers.next() ) 1624 .toggleClass( "ui-state-disabled", !!value ); 1625 } 1626 }, 1627 1628 _keydown: function( event ) { 1629 if ( event.altKey || event.ctrlKey ) { 1630 return; 1631 } 1632 1633 var keyCode = $.ui.keyCode, 1634 length = this.headers.length, 1635 currentIndex = this.headers.index( event.target ), 1636 toFocus = false; 1637 1638 switch ( event.keyCode ) { 1639 case keyCode.RIGHT: 1640 case keyCode.DOWN: 1641 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 1642 break; 1643 case keyCode.LEFT: 1644 case keyCode.UP: 1645 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 1646 break; 1647 case keyCode.SPACE: 1648 case keyCode.ENTER: 1649 this._eventHandler( event ); 1650 break; 1651 case keyCode.HOME: 1652 toFocus = this.headers[ 0 ]; 1653 break; 1654 case keyCode.END: 1655 toFocus = this.headers[ length - 1 ]; 1656 break; 1657 } 1658 1659 if ( toFocus ) { 1660 $( event.target ).attr( "tabIndex", -1 ); 1661 $( toFocus ).attr( "tabIndex", 0 ); 1662 toFocus.focus(); 1663 event.preventDefault(); 1664 } 1665 }, 1666 1667 _panelKeyDown : function( event ) { 1668 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 1669 $( event.currentTarget ).prev().focus(); 1670 } 1671 }, 1672 1673 refresh: function() { 1674 var options = this.options; 1675 this._processPanels(); 1676 1677 // was collapsed or no panel 1678 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 1679 options.active = false; 1680 this.active = $(); 1681 // active false only when collapsible is true 1682 } else if ( options.active === false ) { 1683 this._activate( 0 ); 1684 // was active, but active panel is gone 1685 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 1686 // all remaining panel are disabled 1687 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 1688 options.active = false; 1689 this.active = $(); 1690 // activate previous panel 1691 } else { 1692 this._activate( Math.max( 0, options.active - 1 ) ); 1693 } 1694 // was active, active panel still exists 1695 } else { 1696 // make sure active index is correct 1697 options.active = this.headers.index( this.active ); 1698 } 1699 1700 this._destroyIcons(); 1701 1702 this._refresh(); 1703 }, 1704 1705 _processPanels: function() { 1706 this.headers = this.element.find( this.options.header ) 1707 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 1708 1709 this.headers.next() 1710 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 1711 .filter(":not(.ui-accordion-content-active)") 1712 .hide(); 1713 }, 1714 1715 _refresh: function() { 1716 var maxHeight, 1717 options = this.options, 1718 heightStyle = options.heightStyle, 1719 parent = this.element.parent(), 1720 accordionId = this.accordionId = "ui-accordion-" + 1721 (this.element.attr( "id" ) || ++uid); 1722 1723 this.active = this._findActive( options.active ) 1724 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 1725 .removeClass( "ui-corner-all" ); 1726 this.active.next() 1727 .addClass( "ui-accordion-content-active" ) 1728 .show(); 1729 1730 this.headers 1731 .attr( "role", "tab" ) 1732 .each(function( i ) { 1733 var header = $( this ), 1734 headerId = header.attr( "id" ), 1735 panel = header.next(), 1736 panelId = panel.attr( "id" ); 1737 if ( !headerId ) { 1738 headerId = accordionId + "-header-" + i; 1739 header.attr( "id", headerId ); 1740 } 1741 if ( !panelId ) { 1742 panelId = accordionId + "-panel-" + i; 1743 panel.attr( "id", panelId ); 1744 } 1745 header.attr( "aria-controls", panelId ); 1746 panel.attr( "aria-labelledby", headerId ); 1747 }) 1748 .next() 1749 .attr( "role", "tabpanel" ); 1750 1751 this.headers 1752 .not( this.active ) 1753 .attr({ 1754 "aria-selected": "false", 1755 "aria-expanded": "false", 1756 tabIndex: -1 1757 }) 1758 .next() 1759 .attr({ 1760 "aria-hidden": "true" 1761 }) 1762 .hide(); 1763 1764 // make sure at least one header is in the tab order 1765 if ( !this.active.length ) { 1766 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 1767 } else { 1768 this.active.attr({ 1769 "aria-selected": "true", 1770 "aria-expanded": "true", 1771 tabIndex: 0 1772 }) 1773 .next() 1774 .attr({ 1775 "aria-hidden": "false" 1776 }); 1777 } 1778 1779 this._createIcons(); 1780 1781 this._setupEvents( options.event ); 1782 1783 if ( heightStyle === "fill" ) { 1784 maxHeight = parent.height(); 1785 this.element.siblings( ":visible" ).each(function() { 1786 var elem = $( this ), 1787 position = elem.css( "position" ); 1788 1789 if ( position === "absolute" || position === "fixed" ) { 1790 return; 1791 } 1792 maxHeight -= elem.outerHeight( true ); 1793 }); 1794 1795 this.headers.each(function() { 1796 maxHeight -= $( this ).outerHeight( true ); 1797 }); 1798 1799 this.headers.next() 1800 .each(function() { 1801 $( this ).height( Math.max( 0, maxHeight - 1802 $( this ).innerHeight() + $( this ).height() ) ); 1803 }) 1804 .css( "overflow", "auto" ); 1805 } else if ( heightStyle === "auto" ) { 1806 maxHeight = 0; 1807 this.headers.next() 1808 .each(function() { 1809 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 1810 }) 1811 .height( maxHeight ); 1812 } 1813 }, 1814 1815 _activate: function( index ) { 1816 var active = this._findActive( index )[ 0 ]; 1817 1818 // trying to activate the already active panel 1819 if ( active === this.active[ 0 ] ) { 1820 return; 1821 } 1822 1823 // trying to collapse, simulate a click on the currently active header 1824 active = active || this.active[ 0 ]; 1825 1826 this._eventHandler({ 1827 target: active, 1828 currentTarget: active, 1829 preventDefault: $.noop 1830 }); 1831 }, 1832 1833 _findActive: function( selector ) { 1834 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 1835 }, 1836 1837 _setupEvents: function( event ) { 1838 var events = { 1839 keydown: "_keydown" 1840 }; 1841 if ( event ) { 1842 $.each( event.split(" "), function( index, eventName ) { 1843 events[ eventName ] = "_eventHandler"; 1844 }); 1845 } 1846 1847 this._off( this.headers.add( this.headers.next() ) ); 1848 this._on( this.headers, events ); 1849 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 1850 this._hoverable( this.headers ); 1851 this._focusable( this.headers ); 1852 }, 1853 1854 _eventHandler: function( event ) { 1855 var options = this.options, 1856 active = this.active, 1857 clicked = $( event.currentTarget ), 1858 clickedIsActive = clicked[ 0 ] === active[ 0 ], 1859 collapsing = clickedIsActive && options.collapsible, 1860 toShow = collapsing ? $() : clicked.next(), 1861 toHide = active.next(), 1862 eventData = { 1863 oldHeader: active, 1864 oldPanel: toHide, 1865 newHeader: collapsing ? $() : clicked, 1866 newPanel: toShow 1867 }; 1868 1869 event.preventDefault(); 1870 1871 if ( 1872 // click on active header, but not collapsible 1873 ( clickedIsActive && !options.collapsible ) || 1874 // allow canceling activation 1875 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 1876 return; 1877 } 1878 1879 options.active = collapsing ? false : this.headers.index( clicked ); 1880 1881 // when the call to ._toggle() comes after the class changes 1882 // it causes a very odd bug in IE 8 (see #6720) 1883 this.active = clickedIsActive ? $() : clicked; 1884 this._toggle( eventData ); 1885 1886 // switch classes 1887 // corner classes on the previously active header stay after the animation 1888 active.removeClass( "ui-accordion-header-active ui-state-active" ); 1889 if ( options.icons ) { 1890 active.children( ".ui-accordion-header-icon" ) 1891 .removeClass( options.icons.activeHeader ) 1892 .addClass( options.icons.header ); 1893 } 1894 1895 if ( !clickedIsActive ) { 1896 clicked 1897 .removeClass( "ui-corner-all" ) 1898 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 1899 if ( options.icons ) { 1900 clicked.children( ".ui-accordion-header-icon" ) 1901 .removeClass( options.icons.header ) 1902 .addClass( options.icons.activeHeader ); 1903 } 1904 1905 clicked 1906 .next() 1907 .addClass( "ui-accordion-content-active" ); 1908 } 1909 }, 1910 1911 _toggle: function( data ) { 1912 var toShow = data.newPanel, 1913 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 1914 1915 // handle activating a panel during the animation for another activation 1916 this.prevShow.add( this.prevHide ).stop( true, true ); 1917 this.prevShow = toShow; 1918 this.prevHide = toHide; 1919 1920 if ( this.options.animate ) { 1921 this._animate( toShow, toHide, data ); 1922 } else { 1923 toHide.hide(); 1924 toShow.show(); 1925 this._toggleComplete( data ); 1926 } 1927 1928 toHide.attr({ 1929 "aria-hidden": "true" 1930 }); 1931 toHide.prev().attr( "aria-selected", "false" ); 1932 // if we're switching panels, remove the old header from the tab order 1933 // if we're opening from collapsed state, remove the previous header from the tab order 1934 // if we're collapsing, then keep the collapsing header in the tab order 1935 if ( toShow.length && toHide.length ) { 1936 toHide.prev().attr({ 1937 "tabIndex": -1, 1938 "aria-expanded": "false" 1939 }); 1940 } else if ( toShow.length ) { 1941 this.headers.filter(function() { 1942 return $( this ).attr( "tabIndex" ) === 0; 1943 }) 1944 .attr( "tabIndex", -1 ); 1945 } 1946 1947 toShow 1948 .attr( "aria-hidden", "false" ) 1949 .prev() 1950 .attr({ 1951 "aria-selected": "true", 1952 tabIndex: 0, 1953 "aria-expanded": "true" 1954 }); 1955 }, 1956 1957 _animate: function( toShow, toHide, data ) { 1958 var total, easing, duration, 1959 that = this, 1960 adjust = 0, 1961 down = toShow.length && 1962 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 1963 animate = this.options.animate || {}, 1964 options = down && animate.down || animate, 1965 complete = function() { 1966 that._toggleComplete( data ); 1967 }; 1968 1969 if ( typeof options === "number" ) { 1970 duration = options; 1971 } 1972 if ( typeof options === "string" ) { 1973 easing = options; 1974 } 1975 // fall back from options to animation in case of partial down settings 1976 easing = easing || options.easing || animate.easing; 1977 duration = duration || options.duration || animate.duration; 1978 1979 if ( !toHide.length ) { 1980 return toShow.animate( showProps, duration, easing, complete ); 1981 } 1982 if ( !toShow.length ) { 1983 return toHide.animate( hideProps, duration, easing, complete ); 1984 } 1985 1986 total = toShow.show().outerHeight(); 1987 toHide.animate( hideProps, { 1988 duration: duration, 1989 easing: easing, 1990 step: function( now, fx ) { 1991 fx.now = Math.round( now ); 1992 } 1993 }); 1994 toShow 1995 .hide() 1996 .animate( showProps, { 1997 duration: duration, 1998 easing: easing, 1999 complete: complete, 2000 step: function( now, fx ) { 2001 fx.now = Math.round( now ); 2002 if ( fx.prop !== "height" ) { 2003 adjust += fx.now; 2004 } else if ( that.options.heightStyle !== "content" ) { 2005 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 2006 adjust = 0; 2007 } 2008 } 2009 }); 2010 }, 2011 2012 _toggleComplete: function( data ) { 2013 var toHide = data.oldPanel; 2014 2015 toHide 2016 .removeClass( "ui-accordion-content-active" ) 2017 .prev() 2018 .removeClass( "ui-corner-top" ) 2019 .addClass( "ui-corner-all" ); 2020 2021 // Work around for rendering bug in IE (#5421) 2022 if ( toHide.length ) { 2023 toHide.parent()[0].className = toHide.parent()[0].className; 2024 } 2025 this._trigger( "activate", null, data ); 2026 } 2027}); 2028 2029})( jQuery ); 2030(function( $, undefined ) { 2031 2032$.widget( "ui.autocomplete", { 2033 version: "1.10.4", 2034 defaultElement: "<input>", 2035 options: { 2036 appendTo: null, 2037 autoFocus: false, 2038 delay: 300, 2039 minLength: 1, 2040 position: { 2041 my: "left top", 2042 at: "left bottom", 2043 collision: "none" 2044 }, 2045 source: null, 2046 2047 // callbacks 2048 change: null, 2049 close: null, 2050 focus: null, 2051 open: null, 2052 response: null, 2053 search: null, 2054 select: null 2055 }, 2056 2057 requestIndex: 0, 2058 pending: 0, 2059 2060 _create: function() { 2061 // Some browsers only repeat keydown events, not keypress events, 2062 // so we use the suppressKeyPress flag to determine if we've already 2063 // handled the keydown event. #7269 2064 // Unfortunately the code for & in keypress is the same as the up arrow, 2065 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 2066 // events when we know the keydown event was used to modify the 2067 // search term. #7799 2068 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 2069 nodeName = this.element[0].nodeName.toLowerCase(), 2070 isTextarea = nodeName === "textarea", 2071 isInput = nodeName === "input"; 2072 2073 this.isMultiLine = 2074 // Textareas are always multi-line 2075 isTextarea ? true : 2076 // Inputs are always single-line, even if inside a contentEditable element 2077 // IE also treats inputs as contentEditable 2078 isInput ? false : 2079 // All other element types are determined by whether or not they're contentEditable 2080 this.element.prop( "isContentEditable" ); 2081 2082 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 2083 this.isNewMenu = true; 2084 2085 this.element 2086 .addClass( "ui-autocomplete-input" ) 2087 .attr( "autocomplete", "off" ); 2088 2089 this._on( this.element, { 2090 keydown: function( event ) { 2091 if ( this.element.prop( "readOnly" ) ) { 2092 suppressKeyPress = true; 2093 suppressInput = true; 2094 suppressKeyPressRepeat = true; 2095 return; 2096 } 2097 2098 suppressKeyPress = false; 2099 suppressInput = false; 2100 suppressKeyPressRepeat = false; 2101 var keyCode = $.ui.keyCode; 2102 switch( event.keyCode ) { 2103 case keyCode.PAGE_UP: 2104 suppressKeyPress = true; 2105 this._move( "previousPage", event ); 2106 break; 2107 case keyCode.PAGE_DOWN: 2108 suppressKeyPress = true; 2109 this._move( "nextPage", event ); 2110 break; 2111 case keyCode.UP: 2112 suppressKeyPress = true; 2113 this._keyEvent( "previous", event ); 2114 break; 2115 case keyCode.DOWN: 2116 suppressKeyPress = true; 2117 this._keyEvent( "next", event ); 2118 break; 2119 case keyCode.ENTER: 2120 case keyCode.NUMPAD_ENTER: 2121 // when menu is open and has focus 2122 if ( this.menu.active ) { 2123 // #6055 - Opera still allows the keypress to occur 2124 // which causes forms to submit 2125 suppressKeyPress = true; 2126 event.preventDefault(); 2127 this.menu.select( event ); 2128 } 2129 break; 2130 case keyCode.TAB: 2131 if ( this.menu.active ) { 2132 this.menu.select( event ); 2133 } 2134 break; 2135 case keyCode.ESCAPE: 2136 if ( this.menu.element.is( ":visible" ) ) { 2137 this._value( this.term ); 2138 this.close( event ); 2139 // Different browsers have different default behavior for escape 2140 // Single press can mean undo or clear 2141 // Double press in IE means clear the whole form 2142 event.preventDefault(); 2143 } 2144 break; 2145 default: 2146 suppressKeyPressRepeat = true; 2147 // search timeout should be triggered before the input value is changed 2148 this._searchTimeout( event ); 2149 break; 2150 } 2151 }, 2152 keypress: function( event ) { 2153 if ( suppressKeyPress ) { 2154 suppressKeyPress = false; 2155 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 2156 event.preventDefault(); 2157 } 2158 return; 2159 } 2160 if ( suppressKeyPressRepeat ) { 2161 return; 2162 } 2163 2164 // replicate some key handlers to allow them to repeat in Firefox and Opera 2165 var keyCode = $.ui.keyCode; 2166 switch( event.keyCode ) { 2167 case keyCode.PAGE_UP: 2168 this._move( "previousPage", event ); 2169 break; 2170 case keyCode.PAGE_DOWN: 2171 this._move( "nextPage", event ); 2172 break; 2173 case keyCode.UP: 2174 this._keyEvent( "previous", event ); 2175 break; 2176 case keyCode.DOWN: 2177 this._keyEvent( "next", event ); 2178 break; 2179 } 2180 }, 2181 input: function( event ) { 2182 if ( suppressInput ) { 2183 suppressInput = false; 2184 event.preventDefault(); 2185 return; 2186 } 2187 this._searchTimeout( event ); 2188 }, 2189 focus: function() { 2190 this.selectedItem = null; 2191 this.previous = this._value(); 2192 }, 2193 blur: function( event ) { 2194 if ( this.cancelBlur ) { 2195 delete this.cancelBlur; 2196 return; 2197 } 2198 2199 clearTimeout( this.searching ); 2200 this.close( event ); 2201 this._change( event ); 2202 } 2203 }); 2204 2205 this._initSource(); 2206 this.menu = $( "<ul>" ) 2207 .addClass( "ui-autocomplete ui-front" ) 2208 .appendTo( this._appendTo() ) 2209 .menu({ 2210 // disable ARIA support, the live region takes care of that 2211 role: null 2212 }) 2213 .hide() 2214 .data( "ui-menu" ); 2215 2216 this._on( this.menu.element, { 2217 mousedown: function( event ) { 2218 // prevent moving focus out of the text field 2219 event.preventDefault(); 2220 2221 // IE doesn't prevent moving focus even with event.preventDefault() 2222 // so we set a flag to know when we should ignore the blur event 2223 this.cancelBlur = true; 2224 this._delay(function() { 2225 delete this.cancelBlur; 2226 }); 2227 2228 // clicking on the scrollbar causes focus to shift to the body 2229 // but we can't detect a mouseup or a click immediately afterward 2230 // so we have to track the next mousedown and close the menu if 2231 // the user clicks somewhere outside of the autocomplete 2232 var menuElement = this.menu.element[ 0 ]; 2233 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 2234 this._delay(function() { 2235 var that = this; 2236 this.document.one( "mousedown", function( event ) { 2237 if ( event.target !== that.element[ 0 ] && 2238 event.target !== menuElement && 2239 !$.contains( menuElement, event.target ) ) { 2240 that.close(); 2241 } 2242 }); 2243 }); 2244 } 2245 }, 2246 menufocus: function( event, ui ) { 2247 // support: Firefox 2248 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 2249 if ( this.isNewMenu ) { 2250 this.isNewMenu = false; 2251 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 2252 this.menu.blur(); 2253 2254 this.document.one( "mousemove", function() { 2255 $( event.target ).trigger( event.originalEvent ); 2256 }); 2257 2258 return; 2259 } 2260 } 2261 2262 var item = ui.item.data( "ui-autocomplete-item" ); 2263 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 2264 // use value to match what will end up in the input, if it was a key event 2265 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 2266 this._value( item.value ); 2267 } 2268 } else { 2269 // Normally the input is populated with the item's value as the 2270 // menu is navigated, causing screen readers to notice a change and 2271 // announce the item. Since the focus event was canceled, this doesn't 2272 // happen, so we update the live region so that screen readers can 2273 // still notice the change and announce it. 2274 this.liveRegion.text( item.value ); 2275 } 2276 }, 2277 menuselect: function( event, ui ) { 2278 var item = ui.item.data( "ui-autocomplete-item" ), 2279 previous = this.previous; 2280 2281 // only trigger when focus was lost (click on menu) 2282 if ( this.element[0] !== this.document[0].activeElement ) { 2283 this.element.focus(); 2284 this.previous = previous; 2285 // #6109 - IE triggers two focus events and the second 2286 // is asynchronous, so we need to reset the previous 2287 // term synchronously and asynchronously :-( 2288 this._delay(function() { 2289 this.previous = previous; 2290 this.selectedItem = item; 2291 }); 2292 } 2293 2294 if ( false !== this._trigger( "select", event, { item: item } ) ) { 2295 this._value( item.value ); 2296 } 2297 // reset the term after the select event 2298 // this allows custom select handling to work properly 2299 this.term = this._value(); 2300 2301 this.close( event ); 2302 this.selectedItem = item; 2303 } 2304 }); 2305 2306 this.liveRegion = $( "<span>", { 2307 role: "status", 2308 "aria-live": "polite" 2309 }) 2310 .addClass( "ui-helper-hidden-accessible" ) 2311 .insertBefore( this.element ); 2312 2313 // turning off autocomplete prevents the browser from remembering the 2314 // value when navigating through history, so we re-enable autocomplete 2315 // if the page is unloaded before the widget is destroyed. #7790 2316 this._on( this.window, { 2317 beforeunload: function() { 2318 this.element.removeAttr( "autocomplete" ); 2319 } 2320 }); 2321 }, 2322 2323 _destroy: function() { 2324 clearTimeout( this.searching ); 2325 this.element 2326 .removeClass( "ui-autocomplete-input" ) 2327 .removeAttr( "autocomplete" ); 2328 this.menu.element.remove(); 2329 this.liveRegion.remove(); 2330 }, 2331 2332 _setOption: function( key, value ) { 2333 this._super( key, value ); 2334 if ( key === "source" ) { 2335 this._initSource(); 2336 } 2337 if ( key === "appendTo" ) { 2338 this.menu.element.appendTo( this._appendTo() ); 2339 } 2340 if ( key === "disabled" && value && this.xhr ) { 2341 this.xhr.abort(); 2342 } 2343 }, 2344 2345 _appendTo: function() { 2346 var element = this.options.appendTo; 2347 2348 if ( element ) { 2349 element = element.jquery || element.nodeType ? 2350 $( element ) : 2351 this.document.find( element ).eq( 0 ); 2352 } 2353 2354 if ( !element ) { 2355 element = this.element.closest( ".ui-front" ); 2356 } 2357 2358 if ( !element.length ) { 2359 element = this.document[0].body; 2360 } 2361 2362 return element; 2363 }, 2364 2365 _initSource: function() { 2366 var array, url, 2367 that = this; 2368 if ( $.isArray(this.options.source) ) { 2369 array = this.options.source; 2370 this.source = function( request, response ) { 2371 response( $.ui.autocomplete.filter( array, request.term ) ); 2372 }; 2373 } else if ( typeof this.options.source === "string" ) { 2374 url = this.options.source; 2375 this.source = function( request, response ) { 2376 if ( that.xhr ) { 2377 that.xhr.abort(); 2378 } 2379 that.xhr = $.ajax({ 2380 url: url, 2381 data: request, 2382 dataType: "json", 2383 success: function( data ) { 2384 response( data ); 2385 }, 2386 error: function() { 2387 response( [] ); 2388 } 2389 }); 2390 }; 2391 } else { 2392 this.source = this.options.source; 2393 } 2394 }, 2395 2396 _searchTimeout: function( event ) { 2397 clearTimeout( this.searching ); 2398 this.searching = this._delay(function() { 2399 // only search if the value has changed 2400 if ( this.term !== this._value() ) { 2401 this.selectedItem = null; 2402 this.search( null, event ); 2403 } 2404 }, this.options.delay ); 2405 }, 2406 2407 search: function( value, event ) { 2408 value = value != null ? value : this._value(); 2409 2410 // always save the actual value, not the one passed as an argument 2411 this.term = this._value(); 2412 2413 if ( value.length < this.options.minLength ) { 2414 return this.close( event ); 2415 } 2416 2417 if ( this._trigger( "search", event ) === false ) { 2418 return; 2419 } 2420 2421 return this._search( value ); 2422 }, 2423 2424 _search: function( value ) { 2425 this.pending++; 2426 this.element.addClass( "ui-autocomplete-loading" ); 2427 this.cancelSearch = false; 2428 2429 this.source( { term: value }, this._response() ); 2430 }, 2431 2432 _response: function() { 2433 var index = ++this.requestIndex; 2434 2435 return $.proxy(function( content ) { 2436 if ( index === this.requestIndex ) { 2437 this.__response( content ); 2438 } 2439 2440 this.pending--; 2441 if ( !this.pending ) { 2442 this.element.removeClass( "ui-autocomplete-loading" ); 2443 } 2444 }, this ); 2445 }, 2446 2447 __response: function( content ) { 2448 if ( content ) { 2449 content = this._normalize( content ); 2450 } 2451 this._trigger( "response", null, { content: content } ); 2452 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 2453 this._suggest( content ); 2454 this._trigger( "open" ); 2455 } else { 2456 // use ._close() instead of .close() so we don't cancel future searches 2457 this._close(); 2458 } 2459 }, 2460 2461 close: function( event ) { 2462 this.cancelSearch = true; 2463 this._close( event ); 2464 }, 2465 2466 _close: function( event ) { 2467 if ( this.menu.element.is( ":visible" ) ) { 2468 this.menu.element.hide(); 2469 this.menu.blur(); 2470 this.isNewMenu = true; 2471 this._trigger( "close", event ); 2472 } 2473 }, 2474 2475 _change: function( event ) { 2476 if ( this.previous !== this._value() ) { 2477 this._trigger( "change", event, { item: this.selectedItem } ); 2478 } 2479 }, 2480 2481 _normalize: function( items ) { 2482 // assume all items have the right format when the first item is complete 2483 if ( items.length && items[0].label && items[0].value ) { 2484 return items; 2485 } 2486 return $.map( items, function( item ) { 2487 if ( typeof item === "string" ) { 2488 return { 2489 label: item, 2490 value: item 2491 }; 2492 } 2493 return $.extend({ 2494 label: item.label || item.value, 2495 value: item.value || item.label 2496 }, item ); 2497 }); 2498 }, 2499 2500 _suggest: function( items ) { 2501 var ul = this.menu.element.empty(); 2502 this._renderMenu( ul, items ); 2503 this.isNewMenu = true; 2504 this.menu.refresh(); 2505 2506 // size and position menu 2507 ul.show(); 2508 this._resizeMenu(); 2509 ul.position( $.extend({ 2510 of: this.element 2511 }, this.options.position )); 2512 2513 if ( this.options.autoFocus ) { 2514 this.menu.next(); 2515 } 2516 }, 2517 2518 _resizeMenu: function() { 2519 var ul = this.menu.element; 2520 ul.outerWidth( Math.max( 2521 // Firefox wraps long text (possibly a rounding bug) 2522 // so we add 1px to avoid the wrapping (#7513) 2523 ul.width( "" ).outerWidth() + 1, 2524 this.element.outerWidth() 2525 ) ); 2526 }, 2527 2528 _renderMenu: function( ul, items ) { 2529 var that = this; 2530 $.each( items, function( index, item ) { 2531 that._renderItemData( ul, item ); 2532 }); 2533 }, 2534 2535 _renderItemData: function( ul, item ) { 2536 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 2537 }, 2538 2539 _renderItem: function( ul, item ) { 2540 return $( "<li>" ) 2541 .append( $( "<a>" ).text( item.label ) ) 2542 .appendTo( ul ); 2543 }, 2544 2545 _move: function( direction, event ) { 2546 if ( !this.menu.element.is( ":visible" ) ) { 2547 this.search( null, event ); 2548 return; 2549 } 2550 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 2551 this.menu.isLastItem() && /^next/.test( direction ) ) { 2552 this._value( this.term ); 2553 this.menu.blur(); 2554 return; 2555 } 2556 this.menu[ direction ]( event ); 2557 }, 2558 2559 widget: function() { 2560 return this.menu.element; 2561 }, 2562 2563 _value: function() { 2564 return this.valueMethod.apply( this.element, arguments ); 2565 }, 2566 2567 _keyEvent: function( keyEvent, event ) { 2568 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 2569 this._move( keyEvent, event ); 2570 2571 // prevents moving cursor to beginning/end of the text field in some browsers 2572 event.preventDefault(); 2573 } 2574 } 2575}); 2576 2577$.extend( $.ui.autocomplete, { 2578 escapeRegex: function( value ) { 2579 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 2580 }, 2581 filter: function(array, term) { 2582 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 2583 return $.grep( array, function(value) { 2584 return matcher.test( value.label || value.value || value ); 2585 }); 2586 } 2587}); 2588 2589 2590// live region extension, adding a `messages` option 2591// NOTE: This is an experimental API. We are still investigating 2592// a full solution for string manipulation and internationalization. 2593$.widget( "ui.autocomplete", $.ui.autocomplete, { 2594 options: { 2595 messages: { 2596 noResults: "No search results.", 2597 results: function( amount ) { 2598 return amount + ( amount > 1 ? " results are" : " result is" ) + 2599 " available, use up and down arrow keys to navigate."; 2600 } 2601 } 2602 }, 2603 2604 __response: function( content ) { 2605 var message; 2606 this._superApply( arguments ); 2607 if ( this.options.disabled || this.cancelSearch ) { 2608 return; 2609 } 2610 if ( content && content.length ) { 2611 message = this.options.messages.results( content.length ); 2612 } else { 2613 message = this.options.messages.noResults; 2614 } 2615 this.liveRegion.text( message ); 2616 } 2617}); 2618 2619}( jQuery )); 2620(function( $, undefined ) { 2621 2622var lastActive, 2623 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 2624 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", 2625 formResetHandler = function() { 2626 var form = $( this ); 2627 setTimeout(function() { 2628 form.find( ":ui-button" ).button( "refresh" ); 2629 }, 1 ); 2630 }, 2631 radioGroup = function( radio ) { 2632 var name = radio.name, 2633 form = radio.form, 2634 radios = $( [] ); 2635 if ( name ) { 2636 name = name.replace( /'/g, "\\'" ); 2637 if ( form ) { 2638 radios = $( form ).find( "[name='" + name + "']" ); 2639 } else { 2640 radios = $( "[name='" + name + "']", radio.ownerDocument ) 2641 .filter(function() { 2642 return !this.form; 2643 }); 2644 } 2645 } 2646 return radios; 2647 }; 2648 2649$.widget( "ui.button", { 2650 version: "1.10.4", 2651 defaultElement: "<button>", 2652 options: { 2653 disabled: null, 2654 text: true, 2655 label: null, 2656 icons: { 2657 primary: null, 2658 secondary: null 2659 } 2660 }, 2661 _create: function() { 2662 this.element.closest( "form" ) 2663 .unbind( "reset" + this.eventNamespace ) 2664 .bind( "reset" + this.eventNamespace, formResetHandler ); 2665 2666 if ( typeof this.options.disabled !== "boolean" ) { 2667 this.options.disabled = !!this.element.prop( "disabled" ); 2668 } else { 2669 this.element.prop( "disabled", this.options.disabled ); 2670 } 2671 2672 this._determineButtonType(); 2673 this.hasTitle = !!this.buttonElement.attr( "title" ); 2674 2675 var that = this, 2676 options = this.options, 2677 toggleButton = this.type === "checkbox" || this.type === "radio", 2678 activeClass = !toggleButton ? "ui-state-active" : ""; 2679 2680 if ( options.label === null ) { 2681 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 2682 } 2683 2684 this._hoverable( this.buttonElement ); 2685 2686 this.buttonElement 2687 .addClass( baseClasses ) 2688 .attr( "role", "button" ) 2689 .bind( "mouseenter" + this.eventNamespace, function() { 2690 if ( options.disabled ) { 2691 return; 2692 } 2693 if ( this === lastActive ) { 2694 $( this ).addClass( "ui-state-active" ); 2695 } 2696 }) 2697 .bind( "mouseleave" + this.eventNamespace, function() { 2698 if ( options.disabled ) { 2699 return; 2700 } 2701 $( this ).removeClass( activeClass ); 2702 }) 2703 .bind( "click" + this.eventNamespace, function( event ) { 2704 if ( options.disabled ) { 2705 event.preventDefault(); 2706 event.stopImmediatePropagation(); 2707 } 2708 }); 2709 2710 // Can't use _focusable() because the element that receives focus 2711 // and the element that gets the ui-state-focus class are different 2712 this._on({ 2713 focus: function() { 2714 this.buttonElement.addClass( "ui-state-focus" ); 2715 }, 2716 blur: function() { 2717 this.buttonElement.removeClass( "ui-state-focus" ); 2718 } 2719 }); 2720 2721 if ( toggleButton ) { 2722 this.element.bind( "change" + this.eventNamespace, function() { 2723 that.refresh(); 2724 }); 2725 } 2726 2727 if ( this.type === "checkbox" ) { 2728 this.buttonElement.bind( "click" + this.eventNamespace, function() { 2729 if ( options.disabled ) { 2730 return false; 2731 } 2732 }); 2733 } else if ( this.type === "radio" ) { 2734 this.buttonElement.bind( "click" + this.eventNamespace, function() { 2735 if ( options.disabled ) { 2736 return false; 2737 } 2738 $( this ).addClass( "ui-state-active" ); 2739 that.buttonElement.attr( "aria-pressed", "true" ); 2740 2741 var radio = that.element[ 0 ]; 2742 radioGroup( radio ) 2743 .not( radio ) 2744 .map(function() { 2745 return $( this ).button( "widget" )[ 0 ]; 2746 }) 2747 .removeClass( "ui-state-active" ) 2748 .attr( "aria-pressed", "false" ); 2749 }); 2750 } else { 2751 this.buttonElement 2752 .bind( "mousedown" + this.eventNamespace, function() { 2753 if ( options.disabled ) { 2754 return false; 2755 } 2756 $( this ).addClass( "ui-state-active" ); 2757 lastActive = this; 2758 that.document.one( "mouseup", function() { 2759 lastActive = null; 2760 }); 2761 }) 2762 .bind( "mouseup" + this.eventNamespace, function() { 2763 if ( options.disabled ) { 2764 return false; 2765 } 2766 $( this ).removeClass( "ui-state-active" ); 2767 }) 2768 .bind( "keydown" + this.eventNamespace, function(event) { 2769 if ( options.disabled ) { 2770 return false; 2771 } 2772 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 2773 $( this ).addClass( "ui-state-active" ); 2774 } 2775 }) 2776 // see #8559, we bind to blur here in case the button element loses 2777 // focus between keydown and keyup, it would be left in an "active" state 2778 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 2779 $( this ).removeClass( "ui-state-active" ); 2780 }); 2781 2782 if ( this.buttonElement.is("a") ) { 2783 this.buttonElement.keyup(function(event) { 2784 if ( event.keyCode === $.ui.keyCode.SPACE ) { 2785 // TODO pass through original event correctly (just as 2nd argument doesn't work) 2786 $( this ).click(); 2787 } 2788 }); 2789 } 2790 } 2791 2792 // TODO: pull out $.Widget's handling for the disabled option into 2793 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 2794 // be overridden by individual plugins 2795 this._setOption( "disabled", options.disabled ); 2796 this._resetButton(); 2797 }, 2798 2799 _determineButtonType: function() { 2800 var ancestor, labelSelector, checked; 2801 2802 if ( this.element.is("[type=checkbox]") ) { 2803 this.type = "checkbox"; 2804 } else if ( this.element.is("[type=radio]") ) { 2805 this.type = "radio"; 2806 } else if ( this.element.is("input") ) { 2807 this.type = "input"; 2808 } else { 2809 this.type = "button"; 2810 } 2811 2812 if ( this.type === "checkbox" || this.type === "radio" ) { 2813 // we don't search against the document in case the element 2814 // is disconnected from the DOM 2815 ancestor = this.element.parents().last(); 2816 labelSelector = "label[for='" + this.element.attr("id") + "']"; 2817 this.buttonElement = ancestor.find( labelSelector ); 2818 if ( !this.buttonElement.length ) { 2819 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 2820 this.buttonElement = ancestor.filter( labelSelector ); 2821 if ( !this.buttonElement.length ) { 2822 this.buttonElement = ancestor.find( labelSelector ); 2823 } 2824 } 2825 this.element.addClass( "ui-helper-hidden-accessible" ); 2826 2827 checked = this.element.is( ":checked" ); 2828 if ( checked ) { 2829 this.buttonElement.addClass( "ui-state-active" ); 2830 } 2831 this.buttonElement.prop( "aria-pressed", checked ); 2832 } else { 2833 this.buttonElement = this.element; 2834 } 2835 }, 2836 2837 widget: function() { 2838 return this.buttonElement; 2839 }, 2840 2841 _destroy: function() { 2842 this.element 2843 .removeClass( "ui-helper-hidden-accessible" ); 2844 this.buttonElement 2845 .removeClass( baseClasses + " ui-state-active " + typeClasses ) 2846 .removeAttr( "role" ) 2847 .removeAttr( "aria-pressed" ) 2848 .html( this.buttonElement.find(".ui-button-text").html() ); 2849 2850 if ( !this.hasTitle ) { 2851 this.buttonElement.removeAttr( "title" ); 2852 } 2853 }, 2854 2855 _setOption: function( key, value ) { 2856 this._super( key, value ); 2857 if ( key === "disabled" ) { 2858 this.element.prop( "disabled", !!value ); 2859 if ( value ) { 2860 this.buttonElement.removeClass( "ui-state-focus" ); 2861 } 2862 return; 2863 } 2864 this._resetButton(); 2865 }, 2866 2867 refresh: function() { 2868 //See #8237 & #8828 2869 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 2870 2871 if ( isDisabled !== this.options.disabled ) { 2872 this._setOption( "disabled", isDisabled ); 2873 } 2874 if ( this.type === "radio" ) { 2875 radioGroup( this.element[0] ).each(function() { 2876 if ( $( this ).is( ":checked" ) ) { 2877 $( this ).button( "widget" ) 2878 .addClass( "ui-state-active" ) 2879 .attr( "aria-pressed", "true" ); 2880 } else { 2881 $( this ).button( "widget" ) 2882 .removeClass( "ui-state-active" ) 2883 .attr( "aria-pressed", "false" ); 2884 } 2885 }); 2886 } else if ( this.type === "checkbox" ) { 2887 if ( this.element.is( ":checked" ) ) { 2888 this.buttonElement 2889 .addClass( "ui-state-active" ) 2890 .attr( "aria-pressed", "true" ); 2891 } else { 2892 this.buttonElement 2893 .removeClass( "ui-state-active" ) 2894 .attr( "aria-pressed", "false" ); 2895 } 2896 } 2897 }, 2898 2899 _resetButton: function() { 2900 if ( this.type === "input" ) { 2901 if ( this.options.label ) { 2902 this.element.val( this.options.label ); 2903 } 2904 return; 2905 } 2906 var buttonElement = this.buttonElement.removeClass( typeClasses ), 2907 buttonText = $( "<span></span>", this.document[0] ) 2908 .addClass( "ui-button-text" ) 2909 .html( this.options.label ) 2910 .appendTo( buttonElement.empty() ) 2911 .text(), 2912 icons = this.options.icons, 2913 multipleIcons = icons.primary && icons.secondary, 2914 buttonClasses = []; 2915 2916 if ( icons.primary || icons.secondary ) { 2917 if ( this.options.text ) { 2918 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 2919 } 2920 2921 if ( icons.primary ) { 2922 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 2923 } 2924 2925 if ( icons.secondary ) { 2926 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 2927 } 2928 2929 if ( !this.options.text ) { 2930 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 2931 2932 if ( !this.hasTitle ) { 2933 buttonElement.attr( "title", $.trim( buttonText ) ); 2934 } 2935 } 2936 } else { 2937 buttonClasses.push( "ui-button-text-only" ); 2938 } 2939 buttonElement.addClass( buttonClasses.join( " " ) ); 2940 } 2941}); 2942 2943$.widget( "ui.buttonset", { 2944 version: "1.10.4", 2945 options: { 2946 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 2947 }, 2948 2949 _create: function() { 2950 this.element.addClass( "ui-buttonset" ); 2951 }, 2952 2953 _init: function() { 2954 this.refresh(); 2955 }, 2956 2957 _setOption: function( key, value ) { 2958 if ( key === "disabled" ) { 2959 this.buttons.button( "option", key, value ); 2960 } 2961 2962 this._super( key, value ); 2963 }, 2964 2965 refresh: function() { 2966 var rtl = this.element.css( "direction" ) === "rtl"; 2967 2968 this.buttons = this.element.find( this.options.items ) 2969 .filter( ":ui-button" ) 2970 .button( "refresh" ) 2971 .end() 2972 .not( ":ui-button" ) 2973 .button() 2974 .end() 2975 .map(function() { 2976 return $( this ).button( "widget" )[ 0 ]; 2977 }) 2978 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 2979 .filter( ":first" ) 2980 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 2981 .end() 2982 .filter( ":last" ) 2983 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 2984 .end() 2985 .end(); 2986 }, 2987 2988 _destroy: function() { 2989 this.element.removeClass( "ui-buttonset" ); 2990 this.buttons 2991 .map(function() { 2992 return $( this ).button( "widget" )[ 0 ]; 2993 }) 2994 .removeClass( "ui-corner-left ui-corner-right" ) 2995 .end() 2996 .button( "destroy" ); 2997 } 2998}); 2999 3000}( jQuery ) ); 3001(function( $, undefined ) { 3002 3003$.extend($.ui, { datepicker: { version: "1.10.4" } }); 3004 3005var PROP_NAME = "datepicker", 3006 instActive; 3007 3008/* Date picker manager. 3009 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 3010 Settings for (groups of) date pickers are maintained in an instance object, 3011 allowing multiple different settings on the same page. */ 3012 3013function Datepicker() { 3014 this._curInst = null; // The current instance in use 3015 this._keyEvent = false; // If the last event was a key event 3016 this._disabledInputs = []; // List of date picker inputs that have been disabled 3017 this._datepickerShowing = false; // True if the popup picker is showing , false if not 3018 this._inDialog = false; // True if showing within a "dialog", false if not 3019 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 3020 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 3021 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 3022 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 3023 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 3024 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 3025 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 3026 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 3027 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 3028 this.regional = []; // Available regional settings, indexed by language code 3029 this.regional[""] = { // Default regional settings 3030 closeText: "Done", // Display text for close link 3031 prevText: "Prev", // Display text for previous month link 3032 nextText: "Next", // Display text for next month link 3033 currentText: "Today", // Display text for current month link 3034 monthNames: ["January","February","March","April","May","June", 3035 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 3036 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 3037 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 3038 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 3039 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 3040 weekHeader: "Wk", // Column header for week of the year 3041 dateFormat: "mm/dd/yy", // See format options on parseDate 3042 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 3043 isRTL: false, // True if right-to-left language, false if left-to-right 3044 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 3045 yearSuffix: "" // Additional text to append to the year in the month headers 3046 }; 3047 this._defaults = { // Global defaults for all the date picker instances 3048 showOn: "focus", // "focus" for popup on focus, 3049 // "button" for trigger button, or "both" for either
vendor: 6,360 bytes, lines 3050-3179
3050 showAnim: "fadeIn", // Name of jQuery animation for popup 3051 showOptions: {}, // Options for enhanced animations 3052 defaultDate: null, // Used when field is blank: actual date, 3053 // +/-number for offset from today, null for today 3054 appendText: "", // Display text following the input box, e.g. showing the format 3055 buttonText: "...", // Text for trigger button 3056 buttonImage: "", // URL for trigger button image 3057 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 3058 hideIfNoPrevNext: false, // True to hide next/previous month links 3059 // if not applicable, false to just disable them 3060 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 3061 gotoCurrent: false, // True if today link goes back to current selection instead 3062 changeMonth: false, // True if month can be selected directly, false if only prev/next 3063 changeYear: false, // True if year can be selected directly, false if only prev/next 3064 yearRange: "c-10:c+10", // Range of years to display in drop-down, 3065 // either relative to today's year (-nn:+nn), relative to currently displayed year 3066 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 3067 showOtherMonths: false, // True to show dates in other months, false to leave blank 3068 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 3069 showWeek: false, // True to show week of the year, false to not show it 3070 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 3071 // takes a Date and returns the number of the week for it 3072 shortYearCutoff: "+10", // Short year values < this are in the current century, 3073 // > this are in the previous century, 3074 // string value starting with "+" for current year + value 3075 minDate: null, // The earliest selectable date, or null for no limit 3076 maxDate: null, // The latest selectable date, or null for no limit 3077 duration: "fast", // Duration of display/closure 3078 beforeShowDay: null, // Function that takes a date and returns an array with 3079 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 3080 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 3081 beforeShow: null, // Function that takes an input field and 3082 // returns a set of custom settings for the date picker 3083 onSelect: null, // Define a callback function when a date is selected 3084 onChangeMonthYear: null, // Define a callback function when the month or year is changed 3085 onClose: null, // Define a callback function when the datepicker is closed 3086 numberOfMonths: 1, // Number of months to show at a time 3087 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 3088 stepMonths: 1, // Number of months to step back/forward 3089 stepBigMonths: 12, // Number of months to step back/forward for the big links 3090 altField: "", // Selector for an alternate field to store selected dates into 3091 altFormat: "", // The date format to use for the alternate field 3092 constrainInput: true, // The input is constrained by the current date format 3093 showButtonPanel: false, // True to show button panel, false to not show it 3094 autoSize: false, // True to size the input for the date format, false to leave as is 3095 disabled: false // The initial disabled state 3096 }; 3097 $.extend(this._defaults, this.regional[""]); 3098 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 3099} 3100 3101$.extend(Datepicker.prototype, { 3102 /* Class name added to elements to indicate already configured with a date picker. */ 3103 markerClassName: "hasDatepicker", 3104 3105 //Keep track of the maximum number of rows displayed (see #7043) 3106 maxRows: 4, 3107 3108 // TODO rename to "widget" when switching to widget factory 3109 _widgetDatepicker: function() { 3110 return this.dpDiv; 3111 }, 3112 3113 /* Override the default settings for all instances of the date picker. 3114 * @param settings object - the new settings to use as defaults (anonymous object) 3115 * @return the manager object 3116 */ 3117 setDefaults: function(settings) { 3118 extendRemove(this._defaults, settings || {}); 3119 return this; 3120 }, 3121 3122 /* Attach the date picker to a jQuery selection. 3123 * @param target element - the target input field or division or span 3124 * @param settings object - the new settings to use for this date picker instance (anonymous) 3125 */ 3126 _attachDatepicker: function(target, settings) { 3127 var nodeName, inline, inst; 3128 nodeName = target.nodeName.toLowerCase(); 3129 inline = (nodeName === "div" || nodeName === "span"); 3130 if (!target.id) { 3131 this.uuid += 1; 3132 target.id = "dp" + this.uuid; 3133 } 3134 inst = this._newInst($(target), inline); 3135 inst.settings = $.extend({}, settings || {}); 3136 if (nodeName === "input") { 3137 this._connectDatepicker(target, inst); 3138 } else if (inline) { 3139 this._inlineDatepicker(target, inst); 3140 } 3141 }, 3142 3143 /* Create a new instance object. */ 3144 _newInst: function(target, inline) { 3145 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 3146 return {id: id, input: target, // associated target 3147 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 3148 drawMonth: 0, drawYear: 0, // month being drawn 3149 inline: inline, // is datepicker inline or not 3150 dpDiv: (!inline ? this.dpDiv : // presentation div 3151 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 3152 }, 3153 3154 /* Attach the date picker to an input field. */ 3155 _connectDatepicker: function(target, inst) { 3156 var input = $(target); 3157 inst.append = $([]); 3158 inst.trigger = $([]); 3159 if (input.hasClass(this.markerClassName)) { 3160 return; 3161 } 3162 this._attachments(input, inst); 3163 input.addClass(this.markerClassName).keydown(this._doKeyDown). 3164 keypress(this._doKeyPress).keyup(this._doKeyUp); 3165 this._autoSize(inst); 3166 $.data(target, PROP_NAME, inst); 3167 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 3168 if( inst.settings.disabled ) { 3169 this._disableDatepicker( target ); 3170 } 3171 }, 3172 3173 /* Make attachments based on settings. */ 3174 _attachments: function(input, inst) { 3175 var showOn, buttonText, buttonImage, 3176 appendText = this._get(inst, "appendText"), 3177 isRTL = this._get(inst, "isRTL"); 3178 3179 if (inst.append) {
vendor: 5,777 bytes, lines 3180-3335
3180 inst.append.remove(); 3181 } 3182 if (appendText) { 3183 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 3184 input[isRTL ? "before" : "after"](inst.append); 3185 } 3186 3187 input.unbind("focus", this._showDatepicker); 3188 3189 if (inst.trigger) { 3190 inst.trigger.remove(); 3191 } 3192 3193 showOn = this._get(inst, "showOn"); 3194 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 3195 input.focus(this._showDatepicker); 3196 } 3197 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 3198 buttonText = this._get(inst, "buttonText"); 3199 buttonImage = this._get(inst, "buttonImage"); 3200 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 3201 $("<img/>").addClass(this._triggerClass). 3202 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 3203 $("<button type='button'></button>").addClass(this._triggerClass). 3204 html(!buttonImage ? buttonText : $("<img/>").attr( 3205 { src:buttonImage, alt:buttonText, title:buttonText }))); 3206 input[isRTL ? "before" : "after"](inst.trigger); 3207 inst.trigger.click(function() { 3208 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 3209 $.datepicker._hideDatepicker(); 3210 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 3211 $.datepicker._hideDatepicker(); 3212 $.datepicker._showDatepicker(input[0]); 3213 } else { 3214 $.datepicker._showDatepicker(input[0]); 3215 } 3216 return false; 3217 }); 3218 } 3219 }, 3220 3221 /* Apply the maximum length for the date format. */ 3222 _autoSize: function(inst) { 3223 if (this._get(inst, "autoSize") && !inst.inline) { 3224 var findMax, max, maxI, i, 3225 date = new Date(2009, 12 - 1, 20), // Ensure double digits 3226 dateFormat = this._get(inst, "dateFormat"); 3227 3228 if (dateFormat.match(/[DM]/)) { 3229 findMax = function(names) { 3230 max = 0; 3231 maxI = 0; 3232 for (i = 0; i < names.length; i++) { 3233 if (names[i].length > max) { 3234 max = names[i].length; 3235 maxI = i; 3236 } 3237 } 3238 return maxI; 3239 }; 3240 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 3241 "monthNames" : "monthNamesShort")))); 3242 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 3243 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 3244 } 3245 inst.input.attr("size", this._formatDate(inst, date).length); 3246 } 3247 }, 3248 3249 /* Attach an inline date picker to a div. */ 3250 _inlineDatepicker: function(target, inst) { 3251 var divSpan = $(target); 3252 if (divSpan.hasClass(this.markerClassName)) { 3253 return; 3254 } 3255 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 3256 $.data(target, PROP_NAME, inst); 3257 this._setDate(inst, this._getDefaultDate(inst), true); 3258 this._updateDatepicker(inst); 3259 this._updateAlternate(inst); 3260 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 3261 if( inst.settings.disabled ) { 3262 this._disableDatepicker( target ); 3263 } 3264 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 3265 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 3266 inst.dpDiv.css( "display", "block" ); 3267 }, 3268 3269 /* Pop-up the date picker in a "dialog" box. 3270 * @param input element - ignored 3271 * @param date string or Date - the initial date to display 3272 * @param onSelect function - the function to call when a date is selected 3273 * @param settings object - update the dialog date picker instance's settings (anonymous object) 3274 * @param pos int[2] - coordinates for the dialog's position within the screen or 3275 * event - with x/y coordinates or 3276 * leave empty for default (screen centre) 3277 * @return the manager object 3278 */ 3279 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 3280 var id, browserWidth, browserHeight, scrollX, scrollY, 3281 inst = this._dialogInst; // internal instance 3282 3283 if (!inst) { 3284 this.uuid += 1; 3285 id = "dp" + this.uuid; 3286 this._dialogInput = $("<input type='text' id='" + id + 3287 "' style='position: absolute; top: -100px; width: 0px;'/>"); 3288 this._dialogInput.keydown(this._doKeyDown); 3289 $("body").append(this._dialogInput); 3290 inst = this._dialogInst = this._newInst(this._dialogInput, false); 3291 inst.settings = {}; 3292 $.data(this._dialogInput[0], PROP_NAME, inst); 3293 } 3294 extendRemove(inst.settings, settings || {}); 3295 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 3296 this._dialogInput.val(date); 3297 3298 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 3299 if (!this._pos) { 3300 browserWidth = document.documentElement.clientWidth; 3301 browserHeight = document.documentElement.clientHeight; 3302 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 3303 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 3304 this._pos = // should use actual width/height below 3305 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 3306 } 3307 3308 // move input on screen for focus, but hidden behind dialog 3309 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 3310 inst.settings.onSelect = onSelect; 3311 this._inDialog = true; 3312 this.dpDiv.addClass(this._dialogClass); 3313 this._showDatepicker(this._dialogInput[0]); 3314 if ($.blockUI) { 3315 $.blockUI(this.dpDiv); 3316 } 3317 $.data(this._dialogInput[0], PROP_NAME, inst); 3318 return this; 3319 }, 3320 3321 /* Detach a datepicker from its control. 3322 * @param target element - the target input field or division or span 3323 */ 3324 _destroyDatepicker: function(target) { 3325 var nodeName, 3326 $target = $(target), 3327 inst = $.data(target, PROP_NAME); 3328 3329 if (!$target.hasClass(this.markerClassName)) { 3330 return; 3331 } 3332 3333 nodeName = target.nodeName.toLowerCase(); 3334 $.removeData(target, PROP_NAME); 3335 if (nodeName === "input") {
vendor: 4,434 bytes, lines 3336-3468
3336 inst.append.remove(); 3337 inst.trigger.remove(); 3338 $target.removeClass(this.markerClassName). 3339 unbind("focus", this._showDatepicker). 3340 unbind("keydown", this._doKeyDown). 3341 unbind("keypress", this._doKeyPress). 3342 unbind("keyup", this._doKeyUp); 3343 } else if (nodeName === "div" || nodeName === "span") { 3344 $target.removeClass(this.markerClassName).empty(); 3345 } 3346 }, 3347 3348 /* Enable the date picker to a jQuery selection. 3349 * @param target element - the target input field or division or span 3350 */ 3351 _enableDatepicker: function(target) { 3352 var nodeName, inline, 3353 $target = $(target), 3354 inst = $.data(target, PROP_NAME); 3355 3356 if (!$target.hasClass(this.markerClassName)) { 3357 return; 3358 } 3359 3360 nodeName = target.nodeName.toLowerCase(); 3361 if (nodeName === "input") { 3362 target.disabled = false; 3363 inst.trigger.filter("button"). 3364 each(function() { this.disabled = false; }).end(). 3365 filter("img").css({opacity: "1.0", cursor: ""}); 3366 } else if (nodeName === "div" || nodeName === "span") { 3367 inline = $target.children("." + this._inlineClass); 3368 inline.children().removeClass("ui-state-disabled"); 3369 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 3370 prop("disabled", false); 3371 } 3372 this._disabledInputs = $.map(this._disabledInputs, 3373 function(value) { return (value === target ? null : value); }); // delete entry 3374 }, 3375 3376 /* Disable the date picker to a jQuery selection. 3377 * @param target element - the target input field or division or span 3378 */ 3379 _disableDatepicker: function(target) { 3380 var nodeName, inline, 3381 $target = $(target), 3382 inst = $.data(target, PROP_NAME); 3383 3384 if (!$target.hasClass(this.markerClassName)) { 3385 return; 3386 } 3387 3388 nodeName = target.nodeName.toLowerCase(); 3389 if (nodeName === "input") { 3390 target.disabled = true; 3391 inst.trigger.filter("button"). 3392 each(function() { this.disabled = true; }).end(). 3393 filter("img").css({opacity: "0.5", cursor: "default"}); 3394 } else if (nodeName === "div" || nodeName === "span") { 3395 inline = $target.children("." + this._inlineClass); 3396 inline.children().addClass("ui-state-disabled"); 3397 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 3398 prop("disabled", true); 3399 } 3400 this._disabledInputs = $.map(this._disabledInputs, 3401 function(value) { return (value === target ? null : value); }); // delete entry 3402 this._disabledInputs[this._disabledInputs.length] = target; 3403 }, 3404 3405 /* Is the first field in a jQuery collection disabled as a datepicker? 3406 * @param target element - the target input field or division or span 3407 * @return boolean - true if disabled, false if enabled 3408 */ 3409 _isDisabledDatepicker: function(target) { 3410 if (!target) { 3411 return false; 3412 } 3413 for (var i = 0; i < this._disabledInputs.length; i++) { 3414 if (this._disabledInputs[i] === target) { 3415 return true; 3416 } 3417 } 3418 return false; 3419 }, 3420 3421 /* Retrieve the instance data for the target control. 3422 * @param target element - the target input field or division or span 3423 * @return object - the associated instance data 3424 * @throws error if a jQuery problem getting data 3425 */ 3426 _getInst: function(target) { 3427 try { 3428 return $.data(target, PROP_NAME); 3429 } 3430 catch (err) { 3431 throw "Missing instance data for this datepicker"; 3432 } 3433 }, 3434 3435 /* Update or retrieve the settings for a date picker attached to an input field or division. 3436 * @param target element - the target input field or division or span 3437 * @param name object - the new settings to update or 3438 * string - the name of the setting to change or retrieve, 3439 * when retrieving also "all" for all instance settings or 3440 * "defaults" for all global defaults 3441 * @param value any - the new value for the setting 3442 * (omit if above is an object or to retrieve a value) 3443 */ 3444 _optionDatepicker: function(target, name, value) { 3445 var settings, date, minDate, maxDate, 3446 inst = this._getInst(target); 3447 3448 if (arguments.length === 2 && typeof name === "string") { 3449 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 3450 (inst ? (name === "all" ? $.extend({}, inst.settings) : 3451 this._get(inst, name)) : null)); 3452 } 3453 3454 settings = name || {}; 3455 if (typeof name === "string") { 3456 settings = {}; 3457 settings[name] = value; 3458 } 3459 3460 if (inst) { 3461 if (this._curInst === inst) { 3462 this._hideDatepicker(); 3463 } 3464 3465 date = this._getDateDatepicker(target, true); 3466 minDate = this._getMinMaxDate(inst, "min"); 3467 maxDate = this._getMinMaxDate(inst, "max"); 3468
vendor: 7,816 bytes, lines 3468-3696
3468extendRemove(inst.settings, settings); 3469 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 3470 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 3471 inst.settings.minDate = this._formatDate(inst, minDate); 3472 } 3473 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 3474 inst.settings.maxDate = this._formatDate(inst, maxDate); 3475 } 3476 if ( "disabled" in settings ) { 3477 if ( settings.disabled ) { 3478 this._disableDatepicker(target); 3479 } else { 3480 this._enableDatepicker(target); 3481 } 3482 } 3483 this._attachments($(target), inst); 3484 this._autoSize(inst); 3485 this._setDate(inst, date); 3486 this._updateAlternate(inst); 3487 this._updateDatepicker(inst); 3488 } 3489 }, 3490 3491 // change method deprecated 3492 _changeDatepicker: function(target, name, value) { 3493 this._optionDatepicker(target, name, value); 3494 }, 3495 3496 /* Redraw the date picker attached to an input field or division. 3497 * @param target element - the target input field or division or span 3498 */ 3499 _refreshDatepicker: function(target) { 3500 var inst = this._getInst(target); 3501 if (inst) { 3502 this._updateDatepicker(inst); 3503 } 3504 }, 3505 3506 /* Set the dates for a jQuery selection. 3507 * @param target element - the target input field or division or span 3508 * @param date Date - the new date 3509 */ 3510 _setDateDatepicker: function(target, date) { 3511 var inst = this._getInst(target); 3512 if (inst) { 3513 this._setDate(inst, date); 3514 this._updateDatepicker(inst); 3515 this._updateAlternate(inst); 3516 } 3517 }, 3518 3519 /* Get the date(s) for the first entry in a jQuery selection. 3520 * @param target element - the target input field or division or span 3521 * @param noDefault boolean - true if no default date is to be used 3522 * @return Date - the current date 3523 */ 3524 _getDateDatepicker: function(target, noDefault) { 3525 var inst = this._getInst(target); 3526 if (inst && !inst.inline) { 3527 this._setDateFromField(inst, noDefault); 3528 } 3529 return (inst ? this._getDate(inst) : null); 3530 }, 3531 3532 /* Handle keystrokes. */ 3533 _doKeyDown: function(event) { 3534 var onSelect, dateStr, sel, 3535 inst = $.datepicker._getInst(event.target), 3536 handled = true, 3537 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 3538 3539 inst._keyEvent = true; 3540 if ($.datepicker._datepickerShowing) { 3541 switch (event.keyCode) { 3542 case 9: $.datepicker._hideDatepicker(); 3543 handled = false; 3544 break; // hide on tab out 3545 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 3546 $.datepicker._currentClass + ")", inst.dpDiv); 3547 if (sel[0]) { 3548 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 3549 } 3550 3551 onSelect = $.datepicker._get(inst, "onSelect"); 3552 if (onSelect) { 3553 dateStr = $.datepicker._formatDate(inst); 3554 3555 // trigger custom callback 3556 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 3557 } else { 3558 $.datepicker._hideDatepicker(); 3559 } 3560 3561 return false; // don't submit the form 3562 case 27: $.datepicker._hideDatepicker(); 3563 break; // hide on escape 3564 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 3565 -$.datepicker._get(inst, "stepBigMonths") : 3566 -$.datepicker._get(inst, "stepMonths")), "M"); 3567 break; // previous month/year on page up/+ ctrl 3568 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 3569 +$.datepicker._get(inst, "stepBigMonths") : 3570 +$.datepicker._get(inst, "stepMonths")), "M"); 3571 break; // next month/year on page down/+ ctrl 3572 case 35: if (event.ctrlKey || event.metaKey) { 3573 $.datepicker._clearDate(event.target); 3574 } 3575 handled = event.ctrlKey || event.metaKey; 3576 break; // clear on ctrl or command +end 3577 case 36: if (event.ctrlKey || event.metaKey) { 3578 $.datepicker._gotoToday(event.target); 3579 } 3580 handled = event.ctrlKey || event.metaKey; 3581 break; // current on ctrl or command +home 3582 case 37: if (event.ctrlKey || event.metaKey) { 3583 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 3584 } 3585 handled = event.ctrlKey || event.metaKey; 3586 // -1 day on ctrl or command +left 3587 if (event.originalEvent.altKey) { 3588 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 3589 -$.datepicker._get(inst, "stepBigMonths") : 3590 -$.datepicker._get(inst, "stepMonths")), "M"); 3591 } 3592 // next month/year on alt +left on Mac 3593 break; 3594 case 38: if (event.ctrlKey || event.metaKey) { 3595 $.datepicker._adjustDate(event.target, -7, "D"); 3596 } 3597 handled = event.ctrlKey || event.metaKey; 3598 break; // -1 week on ctrl or command +up 3599 case 39: if (event.ctrlKey || event.metaKey) { 3600 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 3601 } 3602 handled = event.ctrlKey || event.metaKey; 3603 // +1 day on ctrl or command +right 3604 if (event.originalEvent.altKey) { 3605 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 3606 +$.datepicker._get(inst, "stepBigMonths") : 3607 +$.datepicker._get(inst, "stepMonths")), "M"); 3608 } 3609 // next month/year on alt +right 3610 break; 3611 case 40: if (event.ctrlKey || event.metaKey) { 3612 $.datepicker._adjustDate(event.target, +7, "D"); 3613 } 3614 handled = event.ctrlKey || event.metaKey; 3615 break; // +1 week on ctrl or command +down 3616 default: handled = false; 3617 } 3618 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 3619 $.datepicker._showDatepicker(this); 3620 } else { 3621 handled = false; 3622 } 3623 3624 if (handled) { 3625 event.preventDefault(); 3626 event.stopPropagation(); 3627 } 3628 }, 3629 3630 /* Filter entered characters - based on date format. */ 3631 _doKeyPress: function(event) { 3632 var chars, chr, 3633 inst = $.datepicker._getInst(event.target); 3634 3635 if ($.datepicker._get(inst, "constrainInput")) { 3636 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 3637 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 3638 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 3639 } 3640 }, 3641 3642 /* Synchronise manual entry and field/alternate field. */ 3643 _doKeyUp: function(event) { 3644 var date, 3645 inst = $.datepicker._getInst(event.target); 3646 3647 if (inst.input.val() !== inst.lastVal) { 3648 try { 3649 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 3650 (inst.input ? inst.input.val() : null), 3651 $.datepicker._getFormatConfig(inst)); 3652 3653 if (date) { // only if valid 3654 $.datepicker._setDateFromField(inst); 3655 $.datepicker._updateAlternate(inst); 3656 $.datepicker._updateDatepicker(inst); 3657 } 3658 } 3659 catch (err) { 3660 } 3661 } 3662 return true; 3663 }, 3664 3665 /* Pop-up the date picker for a given input field. 3666 * If false returned from beforeShow event handler do not show. 3667 * @param input element - the input field attached to the date picker or 3668 * event - if triggered by focus 3669 */ 3670 _showDatepicker: function(input) { 3671 input = input.target || input; 3672 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 3673 input = $("input", input.parentNode)[0]; 3674 } 3675 3676 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 3677 return; 3678 } 3679 3680 var inst, beforeShow, beforeShowSettings, isFixed, 3681 offset, showAnim, duration; 3682 3683 inst = $.datepicker._getInst(input); 3684 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 3685 $.datepicker._curInst.dpDiv.stop(true, true); 3686 if ( inst && $.datepicker._datepickerShowing ) { 3687 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 3688 } 3689 } 3690 3691 beforeShow = $.datepicker._get(inst, "beforeShow"); 3692 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 3693 if(beforeShowSettings === false){ 3694 return; 3695 } 3696
vendor: 3,274 bytes, lines 3696-3790
3696extendRemove(inst.settings, beforeShowSettings); 3697 3698 inst.lastVal = null; 3699 $.datepicker._lastInput = input; 3700 $.datepicker._setDateFromField(inst); 3701 3702 if ($.datepicker._inDialog) { // hide cursor 3703 input.value = ""; 3704 } 3705 if (!$.datepicker._pos) { // position below input 3706 $.datepicker._pos = $.datepicker._findPos(input); 3707 $.datepicker._pos[1] += input.offsetHeight; // add the height 3708 } 3709 3710 isFixed = false; 3711 $(input).parents().each(function() { 3712 isFixed |= $(this).css("position") === "fixed"; 3713 return !isFixed; 3714 }); 3715 3716 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 3717 $.datepicker._pos = null; 3718 //to avoid flashes on Firefox 3719 inst.dpDiv.empty(); 3720 // determine sizing offscreen 3721 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 3722 $.datepicker._updateDatepicker(inst); 3723 // fix width for dynamic number of date pickers 3724 // and adjust position before showing 3725 offset = $.datepicker._checkOffset(inst, offset, isFixed); 3726 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 3727 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 3728 left: offset.left + "px", top: offset.top + "px"}); 3729 3730 if (!inst.inline) { 3731 showAnim = $.datepicker._get(inst, "showAnim"); 3732 duration = $.datepicker._get(inst, "duration"); 3733 inst.dpDiv.zIndex($(input).zIndex()+1); 3734 $.datepicker._datepickerShowing = true; 3735 3736 if ( $.effects && $.effects.effect[ showAnim ] ) { 3737 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 3738 } else { 3739 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 3740 } 3741 3742 if ( $.datepicker._shouldFocusInput( inst ) ) { 3743 inst.input.focus(); 3744 } 3745 3746 $.datepicker._curInst = inst; 3747 } 3748 }, 3749 3750 /* Generate the date picker content. */ 3751 _updateDatepicker: function(inst) { 3752 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 3753 instActive = inst; // for delegate hover events 3754 inst.dpDiv.empty().append(this._generateHTML(inst)); 3755 this._attachHandlers(inst); 3756 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 3757 3758 var origyearshtml, 3759 numMonths = this._getNumberOfMonths(inst), 3760 cols = numMonths[1], 3761 width = 17; 3762 3763 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 3764 if (cols > 1) { 3765 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 3766 } 3767 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 3768 "Class"]("ui-datepicker-multi"); 3769 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 3770 "Class"]("ui-datepicker-rtl"); 3771 3772 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 3773 inst.input.focus(); 3774 } 3775 3776 // deffered render of the years select (to avoid flashes on Firefox) 3777 if( inst.yearshtml ){ 3778 origyearshtml = inst.yearshtml; 3779 setTimeout(function(){ 3780 //assure that inst.yearshtml didn't change. 3781 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 3782 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 3783 } 3784 origyearshtml = inst.yearshtml = null; 3785 }, 0); 3786 } 3787 }, 3788 3789 // #6694 - don't focus the input if it's already focused 3790 // this breaks the change event in IE
vendor: 2,059 bytes, lines 3791-3839
3791 // Support: IE and jQuery <1.9 3792 _shouldFocusInput: function( inst ) { 3793 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 3794 }, 3795 3796 /* Check positioning to remain on screen. */ 3797 _checkOffset: function(inst, offset, isFixed) { 3798 var dpWidth = inst.dpDiv.outerWidth(), 3799 dpHeight = inst.dpDiv.outerHeight(), 3800 inputWidth = inst.input ? inst.input.outerWidth() : 0, 3801 inputHeight = inst.input ? inst.input.outerHeight() : 0, 3802 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 3803 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 3804 3805 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 3806 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 3807 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 3808 3809 // now check if datepicker is showing outside window viewport - move to a better place if so. 3810 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 3811 Math.abs(offset.left + dpWidth - viewWidth) : 0); 3812 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 3813 Math.abs(dpHeight + inputHeight) : 0); 3814 3815 return offset; 3816 }, 3817 3818 /* Find an object's position on the screen. */ 3819 _findPos: function(obj) { 3820 var position, 3821 inst = this._getInst(obj), 3822 isRTL = this._get(inst, "isRTL"); 3823 3824 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 3825 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 3826 } 3827 3828 position = $(obj).offset(); 3829 return [position.left, position.top]; 3830 }, 3831 3832 /* Hide the date picker from view. 3833 * @param input element - the input field attached to the date picker 3834 */ 3835 _hideDatepicker: function(input) { 3836 var showAnim, duration, postProcess, onClose, 3837 inst = this._curInst; 3838 3839 if (!inst || (input && inst !== $.data(input, PROP_NAME
vendor: 8,428 bytes, lines 3839-4095
3839))) { 3840 return; 3841 } 3842 3843 if (this._datepickerShowing) { 3844 showAnim = this._get(inst, "showAnim"); 3845 duration = this._get(inst, "duration"); 3846 postProcess = function() { 3847 $.datepicker._tidyDialog(inst); 3848 }; 3849 3850 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 3851 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 3852 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 3853 } else { 3854 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 3855 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 3856 } 3857 3858 if (!showAnim) { 3859 postProcess(); 3860 } 3861 this._datepickerShowing = false; 3862 3863 onClose = this._get(inst, "onClose"); 3864 if (onClose) { 3865 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 3866 } 3867 3868 this._lastInput = null; 3869 if (this._inDialog) { 3870 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 3871 if ($.blockUI) { 3872 $.unblockUI(); 3873 $("body").append(this.dpDiv); 3874 } 3875 } 3876 this._inDialog = false; 3877 } 3878 }, 3879 3880 /* Tidy up after a dialog display. */ 3881 _tidyDialog: function(inst) { 3882 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 3883 }, 3884 3885 /* Close date picker if clicked elsewhere. */ 3886 _checkExternalClick: function(event) { 3887 if (!$.datepicker._curInst) { 3888 return; 3889 } 3890 3891 var $target = $(event.target), 3892 inst = $.datepicker._getInst($target[0]); 3893 3894 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 3895 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 3896 !$target.hasClass($.datepicker.markerClassName) && 3897 !$target.closest("." + $.datepicker._triggerClass).length && 3898 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 3899 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 3900 $.datepicker._hideDatepicker(); 3901 } 3902 }, 3903 3904 /* Adjust one of the date sub-fields. */ 3905 _adjustDate: function(id, offset, period) { 3906 var target = $(id), 3907 inst = this._getInst(target[0]); 3908 3909 if (this._isDisabledDatepicker(target[0])) { 3910 return; 3911 } 3912 this._adjustInstDate(inst, offset + 3913 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 3914 period); 3915 this._updateDatepicker(inst); 3916 }, 3917 3918 /* Action for current link. */ 3919 _gotoToday: function(id) { 3920 var date, 3921 target = $(id), 3922 inst = this._getInst(target[0]); 3923 3924 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 3925 inst.selectedDay = inst.currentDay; 3926 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 3927 inst.drawYear = inst.selectedYear = inst.currentYear; 3928 } else { 3929 date = new Date(); 3930 inst.selectedDay = date.getDate(); 3931 inst.drawMonth = inst.selectedMonth = date.getMonth(); 3932 inst.drawYear = inst.selectedYear = date.getFullYear(); 3933 } 3934 this._notifyChange(inst); 3935 this._adjustDate(target); 3936 }, 3937 3938 /* Action for selecting a new month/year. */ 3939 _selectMonthYear: function(id, select, period) { 3940 var target = $(id), 3941 inst = this._getInst(target[0]); 3942 3943 inst["selected" + (period === "M" ? "Month" : "Year")] = 3944 inst["draw" + (period === "M" ? "Month" : "Year")] = 3945 parseInt(select.options[select.selectedIndex].value,10); 3946 3947 this._notifyChange(inst); 3948 this._adjustDate(target); 3949 }, 3950 3951 /* Action for selecting a day. */ 3952 _selectDay: function(id, month, year, td) { 3953 var inst, 3954 target = $(id); 3955 3956 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 3957 return; 3958 } 3959 3960 inst = this._getInst(target[0]); 3961 inst.selectedDay = inst.currentDay = $("a", td).html(); 3962 inst.selectedMonth = inst.currentMonth = month; 3963 inst.selectedYear = inst.currentYear = year; 3964 this._selectDate(id, this._formatDate(inst, 3965 inst.currentDay, inst.currentMonth, inst.currentYear)); 3966 }, 3967 3968 /* Erase the input field and hide the date picker. */ 3969 _clearDate: function(id) { 3970 var target = $(id); 3971 this._selectDate(target, ""); 3972 }, 3973 3974 /* Update the input field with the selected date. */ 3975 _selectDate: function(id, dateStr) { 3976 var onSelect, 3977 target = $(id), 3978 inst = this._getInst(target[0]); 3979 3980 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 3981 if (inst.input) { 3982 inst.input.val(dateStr); 3983 } 3984 this._updateAlternate(inst); 3985 3986 onSelect = this._get(inst, "onSelect"); 3987 if (onSelect) { 3988 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 3989 } else if (inst.input) { 3990 inst.input.trigger("change"); // fire the change event 3991 } 3992 3993 if (inst.inline){ 3994 this._updateDatepicker(inst); 3995 } else { 3996 this._hideDatepicker(); 3997 this._lastInput = inst.input[0]; 3998 if (typeof(inst.input[0]) !== "object") { 3999 inst.input.focus(); // restore focus 4000 } 4001 this._lastInput = null; 4002 } 4003 }, 4004 4005 /* Update any alternate field to synchronise with the main field. */ 4006 _updateAlternate: function(inst) { 4007 var altFormat, date, dateStr, 4008 altField = this._get(inst, "altField"); 4009 4010 if (altField) { // update alternate field too 4011 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 4012 date = this._getDate(inst); 4013 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 4014 $(altField).each(function() { $(this).val(dateStr); }); 4015 } 4016 }, 4017 4018 /* Set as beforeShowDay function to prevent selection of weekends. 4019 * @param date Date - the date to customise 4020 * @return [boolean, string] - is this date selectable?, what is its CSS class? 4021 */ 4022 noWeekends: function(date) { 4023 var day = date.getDay(); 4024 return [(day > 0 && day < 6), ""]; 4025 }, 4026 4027 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 4028 * @param date Date - the date to get the week for 4029 * @return number - the number of the week within the year that contains this date 4030 */ 4031 iso8601Week: function(date) { 4032 var time, 4033 checkDate = new Date(date.getTime()); 4034 4035 // Find Thursday of this week starting on Monday 4036 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 4037 4038 time = checkDate.getTime(); 4039 checkDate.setMonth(0); // Compare with Jan 1 4040 checkDate.setDate(1); 4041 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 4042 }, 4043 4044 /* Parse a string value into a date object. 4045 * See formatDate below for the possible formats. 4046 * 4047 * @param format string - the expected format of the date 4048 * @param value string - the date in the above format 4049 * @param settings Object - attributes include: 4050 * shortYearCutoff number - the cutoff year for determining the century (optional) 4051 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 4052 * dayNames string[7] - names of the days from Sunday (optional) 4053 * monthNamesShort string[12] - abbreviated names of the months (optional) 4054 * monthNames string[12] - names of the months (optional) 4055 * @return Date - the extracted date value or null if value is blank 4056 */ 4057 parseDate: function (format, value, settings) { 4058 if (format == null || value == null) { 4059 throw "Invalid arguments"; 4060 } 4061 4062 value = (typeof value === "object" ? value.toString() : value + ""); 4063 if (value === "") { 4064 return null; 4065 } 4066 4067 var iFormat, dim, extra, 4068 iValue = 0, 4069 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 4070 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 4071 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 4072 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 4073 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 4074 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 4075 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 4076 year = -1, 4077 month = -1, 4078 day = -1, 4079 doy = -1, 4080 literal = false, 4081 date, 4082 // Check whether a format character is doubled 4083 lookAhead = function(match) { 4084 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 4085 if (matches) { 4086 iFormat++; 4087 } 4088 return matches; 4089 }, 4090 // Extract a number from the string value 4091 getNumber = function(match) { 4092 var isDoubled = lookAhead(match), 4093 size = (match === "@" ? 14 : (match === "!" ? 20 : 4094 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 4095
4095digits = new RegExp("^\\d{1
vendor: 31,812 bytes, lines 4095-4943
4095," + size + "}"), 4096 num = value.substring(iValue).match(digits); 4097 if (!num) { 4098 throw "Missing number at position " + iValue; 4099 } 4100 iValue += num[0].length; 4101 return parseInt(num[0], 10); 4102 }, 4103 // Extract a name from the string value and convert to an index 4104 getName = function(match, shortNames, longNames) { 4105 var index = -1, 4106 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 4107 return [ [k, v] ]; 4108 }).sort(function (a, b) { 4109 return -(a[1].length - b[1].length); 4110 }); 4111 4112 $.each(names, function (i, pair) { 4113 var name = pair[1]; 4114 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 4115 index = pair[0]; 4116 iValue += name.length; 4117 return false; 4118 } 4119 }); 4120 if (index !== -1) { 4121 return index + 1; 4122 } else { 4123 throw "Unknown name at position " + iValue; 4124 } 4125 }, 4126 // Confirm that a literal character matches the string value 4127 checkLiteral = function() { 4128 if (value.charAt(iValue) !== format.charAt(iFormat)) { 4129 throw "Unexpected literal at position " + iValue; 4130 } 4131 iValue++; 4132 }; 4133 4134 for (iFormat = 0; iFormat < format.length; iFormat++) { 4135 if (literal) { 4136 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 4137 literal = false; 4138 } else { 4139 checkLiteral(); 4140 } 4141 } else { 4142 switch (format.charAt(iFormat)) { 4143 case "d": 4144 day = getNumber("d"); 4145 break; 4146 case "D": 4147 getName("D", dayNamesShort, dayNames); 4148 break; 4149 case "o": 4150 doy = getNumber("o"); 4151 break; 4152 case "m": 4153 month = getNumber("m"); 4154 break; 4155 case "M": 4156 month = getName("M", monthNamesShort, monthNames); 4157 break; 4158 case "y": 4159 year = getNumber("y"); 4160 break; 4161 case "@": 4162 date = new Date(getNumber("@")); 4163 year = date.getFullYear(); 4164 month = date.getMonth() + 1; 4165 day = date.getDate(); 4166 break; 4167 case "!": 4168 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 4169 year = date.getFullYear(); 4170 month = date.getMonth() + 1; 4171 day = date.getDate(); 4172 break; 4173 case "'": 4174 if (lookAhead("'")){ 4175 checkLiteral(); 4176 } else { 4177 literal = true; 4178 } 4179 break; 4180 default: 4181 checkLiteral(); 4182 } 4183 } 4184 } 4185 4186 if (iValue < value.length){ 4187 extra = value.substr(iValue); 4188 if (!/^\s+/.test(extra)) { 4189 throw "Extra/unparsed characters found in date: " + extra; 4190 } 4191 } 4192 4193 if (year === -1) { 4194 year = new Date().getFullYear(); 4195 } else if (year < 100) { 4196 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 4197 (year <= shortYearCutoff ? 0 : -100); 4198 } 4199 4200 if (doy > -1) { 4201 month = 1; 4202 day = doy; 4203 do { 4204 dim = this._getDaysInMonth(year, month - 1); 4205 if (day <= dim) { 4206 break; 4207 } 4208 month++; 4209 day -= dim; 4210 } while (true); 4211 } 4212 4213 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 4214 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 4215 throw "Invalid date"; // E.g. 31/02/00 4216 } 4217 return date; 4218 }, 4219 4220 /* Standard date formats. */ 4221 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 4222 COOKIE: "D, dd M yy", 4223 ISO_8601: "yy-mm-dd", 4224 RFC_822: "D, d M y", 4225 RFC_850: "DD, dd-M-y", 4226 RFC_1036: "D, d M y", 4227 RFC_1123: "D, d M yy", 4228 RFC_2822: "D, d M yy", 4229 RSS: "D, d M y", // RFC 822 4230 TICKS: "!", 4231 TIMESTAMP: "@", 4232 W3C: "yy-mm-dd", // ISO 8601 4233 4234 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 4235 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 4236 4237 /* Format a date object into a string value. 4238 * The format can be combinations of the following: 4239 * d - day of month (no leading zero) 4240 * dd - day of month (two digit) 4241 * o - day of year (no leading zeros) 4242 * oo - day of year (three digit) 4243 * D - day name short 4244 * DD - day name long 4245 * m - month of year (no leading zero) 4246 * mm - month of year (two digit) 4247 * M - month name short 4248 * MM - month name long 4249 * y - year (two digit) 4250 * yy - year (four digit) 4251 * @ - Unix timestamp (ms since 01/01/1970) 4252 * ! - Windows ticks (100ns since 01/01/0001) 4253 * "..." - literal text 4254 * '' - single quote 4255 * 4256 * @param format string - the desired format of the date 4257 * @param date Date - the date value to format 4258 * @param settings Object - attributes include: 4259 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 4260 * dayNames string[7] - names of the days from Sunday (optional) 4261 * monthNamesShort string[12] - abbreviated names of the months (optional) 4262 * monthNames string[12] - names of the months (optional) 4263 * @return string - the date in the above format 4264 */ 4265 formatDate: function (format, date, settings) { 4266 if (!date) { 4267 return ""; 4268 } 4269 4270 var iFormat, 4271 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 4272 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 4273 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 4274 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 4275 // Check whether a format character is doubled 4276 lookAhead = function(match) { 4277 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 4278 if (matches) { 4279 iFormat++; 4280 } 4281 return matches; 4282 }, 4283 // Format a number, with leading zero if necessary 4284 formatNumber = function(match, value, len) { 4285 var num = "" + value; 4286 if (lookAhead(match)) { 4287 while (num.length < len) { 4288 num = "0" + num; 4289 } 4290 } 4291 return num; 4292 }, 4293 // Format a name, short or long as requested 4294 formatName = function(match, value, shortNames, longNames) { 4295 return (lookAhead(match) ? longNames[value] : shortNames[value]); 4296 }, 4297 output = "", 4298 literal = false; 4299 4300 if (date) { 4301 for (iFormat = 0; iFormat < format.length; iFormat++) { 4302 if (literal) { 4303 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 4304 literal = false; 4305 } else { 4306 output += format.charAt(iFormat); 4307 } 4308 } else { 4309 switch (format.charAt(iFormat)) { 4310 case "d": 4311 output += formatNumber("d", date.getDate(), 2); 4312 break; 4313 case "D": 4314 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 4315 break; 4316 case "o": 4317 output += formatNumber("o", 4318 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 4319 break; 4320 case "m": 4321 output += formatNumber("m", date.getMonth() + 1, 2); 4322 break; 4323 case "M": 4324 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 4325 break; 4326 case "y": 4327 output += (lookAhead("y") ? date.getFullYear() : 4328 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 4329 break; 4330 case "@": 4331 output += date.getTime(); 4332 break; 4333 case "!": 4334 output += date.getTime() * 10000 + this._ticksTo1970; 4335 break; 4336 case "'": 4337 if (lookAhead("'")) { 4338 output += "'"; 4339 } else { 4340 literal = true; 4341 } 4342 break; 4343 default: 4344 output += format.charAt(iFormat); 4345 } 4346 } 4347 } 4348 } 4349 return output; 4350 }, 4351 4352 /* Extract all possible characters from the date format. */ 4353 _possibleChars: function (format) { 4354 var iFormat, 4355 chars = "", 4356 literal = false, 4357 // Check whether a format character is doubled 4358 lookAhead = function(match) { 4359 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 4360 if (matches) { 4361 iFormat++; 4362 } 4363 return matches; 4364 }; 4365 4366 for (iFormat = 0; iFormat < format.length; iFormat++) { 4367 if (literal) { 4368 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 4369 literal = false; 4370 } else { 4371 chars += format.charAt(iFormat); 4372 } 4373 } else { 4374 switch (format.charAt(iFormat)) { 4375 case "d": case "m": case "y": case "@": 4376 chars += "0123456789"; 4377 break; 4378 case "D": case "M": 4379 return null; // Accept anything 4380 case "'": 4381 if (lookAhead("'")) { 4382 chars += "'"; 4383 } else { 4384 literal = true; 4385 } 4386 break; 4387 default: 4388 chars += format.charAt(iFormat); 4389 } 4390 } 4391 } 4392 return chars; 4393 }, 4394 4395 /* Get a setting value, defaulting if necessary. */ 4396 _get: function(inst, name) { 4397 return inst.settings[name] !== undefined ? 4398 inst.settings[name] : this._defaults[name]; 4399 }, 4400 4401 /* Parse existing date and initialise date picker. */ 4402 _setDateFromField: function(inst, noDefault) { 4403 if (inst.input.val() === inst.lastVal) { 4404 return; 4405 } 4406 4407 var dateFormat = this._get(inst, "dateFormat"), 4408 dates = inst.lastVal = inst.input ? inst.input.val() : null, 4409 defaultDate = this._getDefaultDate(inst), 4410 date = defaultDate, 4411 settings = this._getFormatConfig(inst); 4412 4413 try { 4414 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 4415 } catch (event) { 4416 dates = (noDefault ? "" : dates); 4417 } 4418 inst.selectedDay = date.getDate(); 4419 inst.drawMonth = inst.selectedMonth = date.getMonth(); 4420 inst.drawYear = inst.selectedYear = date.getFullYear(); 4421 inst.currentDay = (dates ? date.getDate() : 0); 4422 inst.currentMonth = (dates ? date.getMonth() : 0); 4423 inst.currentYear = (dates ? date.getFullYear() : 0); 4424 this._adjustInstDate(inst); 4425 }, 4426 4427 /* Retrieve the default date shown on opening. */ 4428 _getDefaultDate: function(inst) { 4429 return this._restrictMinMax(inst, 4430 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 4431 }, 4432 4433 /* A date may be specified as an exact value or a relative one. */ 4434 _determineDate: function(inst, date, defaultDate) { 4435 var offsetNumeric = function(offset) { 4436 var date = new Date(); 4437 date.setDate(date.getDate() + offset); 4438 return date; 4439 }, 4440 offsetString = function(offset) { 4441 try { 4442 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 4443 offset, $.datepicker._getFormatConfig(inst)); 4444 } 4445 catch (e) { 4446 // Ignore 4447 } 4448 4449 var date = (offset.toLowerCase().match(/^c/) ? 4450 $.datepicker._getDate(inst) : null) || new Date(), 4451 year = date.getFullYear(), 4452 month = date.getMonth(), 4453 day = date.getDate(), 4454 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 4455 matches = pattern.exec(offset); 4456 4457 while (matches) { 4458 switch (matches[2] || "d") { 4459 case "d" : case "D" : 4460 day += parseInt(matches[1],10); break; 4461 case "w" : case "W" : 4462 day += parseInt(matches[1],10) * 7; break; 4463 case "m" : case "M" : 4464 month += parseInt(matches[1],10); 4465 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 4466 break; 4467 case "y": case "Y" : 4468 year += parseInt(matches[1],10); 4469 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 4470 break; 4471 } 4472 matches = pattern.exec(offset); 4473 } 4474 return new Date(year, month, day); 4475 }, 4476 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 4477 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 4478 4479 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 4480 if (newDate) { 4481 newDate.setHours(0); 4482 newDate.setMinutes(0); 4483 newDate.setSeconds(0); 4484 newDate.setMilliseconds(0); 4485 } 4486 return this._daylightSavingAdjust(newDate); 4487 }, 4488 4489 /* Handle switch to/from daylight saving. 4490 * Hours may be non-zero on daylight saving cut-over: 4491 * > 12 when midnight changeover, but then cannot generate 4492 * midnight datetime, so jump to 1AM, otherwise reset. 4493 * @param date (Date) the date to check 4494 * @return (Date) the corrected date 4495 */ 4496 _daylightSavingAdjust: function(date) { 4497 if (!date) { 4498 return null; 4499 } 4500 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 4501 return date; 4502 }, 4503 4504 /* Set the date(s) directly. */ 4505 _setDate: function(inst, date, noChange) { 4506 var clear = !date, 4507 origMonth = inst.selectedMonth, 4508 origYear = inst.selectedYear, 4509 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 4510 4511 inst.selectedDay = inst.currentDay = newDate.getDate(); 4512 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 4513 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 4514 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 4515 this._notifyChange(inst); 4516 } 4517 this._adjustInstDate(inst); 4518 if (inst.input) { 4519 inst.input.val(clear ? "" : this._formatDate(inst)); 4520 } 4521 }, 4522 4523 /* Retrieve the date(s) directly. */ 4524 _getDate: function(inst) { 4525 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 4526 this._daylightSavingAdjust(new Date( 4527 inst.currentYear, inst.currentMonth, inst.currentDay))); 4528 return startDate; 4529 }, 4530 4531 /* Attach the onxxx handlers. These are declared statically so 4532 * they work with static code transformers like Caja. 4533 */ 4534 _attachHandlers: function(inst) { 4535 var stepMonths = this._get(inst, "stepMonths"), 4536 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 4537 inst.dpDiv.find("[data-handler]").map(function () { 4538 var handler = { 4539 prev: function () { 4540 $.datepicker._adjustDate(id, -stepMonths, "M"); 4541 }, 4542 next: function () { 4543 $.datepicker._adjustDate(id, +stepMonths, "M"); 4544 }, 4545 hide: function () { 4546 $.datepicker._hideDatepicker(); 4547 }, 4548 today: function () { 4549 $.datepicker._gotoToday(id); 4550 }, 4551 selectDay: function () { 4552 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 4553 return false; 4554 }, 4555 selectMonth: function () { 4556 $.datepicker._selectMonthYear(id, this, "M"); 4557 return false; 4558 }, 4559 selectYear: function () { 4560 $.datepicker._selectMonthYear(id, this, "Y"); 4561 return false; 4562 } 4563 }; 4564 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 4565 }); 4566 }, 4567 4568 /* Generate the HTML for the current state of the date picker. */ 4569 _generateHTML: function(inst) { 4570 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 4571 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 4572 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 4573 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 4574 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 4575 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 4576 tempDate = new Date(), 4577 today = this._daylightSavingAdjust( 4578 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 4579 isRTL = this._get(inst, "isRTL"), 4580 showButtonPanel = this._get(inst, "showButtonPanel"), 4581 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 4582 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 4583 numMonths = this._getNumberOfMonths(inst), 4584 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 4585 stepMonths = this._get(inst, "stepMonths"), 4586 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 4587 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 4588 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 4589 minDate = this._getMinMaxDate(inst, "min"), 4590 maxDate = this._getMinMaxDate(inst, "max"), 4591 drawMonth = inst.drawMonth - showCurrentAtPos, 4592 drawYear = inst.drawYear; 4593 4594 if (drawMonth < 0) { 4595 drawMonth += 12; 4596 drawYear--; 4597 } 4598 if (maxDate) { 4599 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 4600 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 4601 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 4602 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 4603 drawMonth--; 4604 if (drawMonth < 0) { 4605 drawMonth = 11; 4606 drawYear--; 4607 } 4608 } 4609 } 4610 inst.drawMonth = drawMonth; 4611 inst.drawYear = drawYear; 4612 4613 prevText = this._get(inst, "prevText"); 4614 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 4615 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 4616 this._getFormatConfig(inst))); 4617 4618 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 4619 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 4620 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 4621 (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>")); 4622 4623 nextText = this._get(inst, "nextText"); 4624 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 4625 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 4626 this._getFormatConfig(inst))); 4627 4628 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 4629 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 4630 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 4631 (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>")); 4632 4633 currentText = this._get(inst, "currentText"); 4634 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 4635 currentText = (!navigationAsDateFormat ? currentText : 4636 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 4637 4638 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'>" + 4639 this._get(inst, "closeText") + "</button>" : ""); 4640 4641 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 4642 (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'" + 4643 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 4644 4645 firstDay = parseInt(this._get(inst, "firstDay"),10); 4646 firstDay = (isNaN(firstDay) ? 0 : firstDay); 4647 4648 showWeek = this._get(inst, "showWeek"); 4649 dayNames = this._get(inst, "dayNames"); 4650 dayNamesMin = this._get(inst, "dayNamesMin"); 4651 monthNames = this._get(inst, "monthNames"); 4652 monthNamesShort = this._get(inst, "monthNamesShort"); 4653 beforeShowDay = this._get(inst, "beforeShowDay"); 4654 showOtherMonths = this._get(inst, "showOtherMonths"); 4655 selectOtherMonths = this._get(inst, "selectOtherMonths"); 4656 defaultDate = this._getDefaultDate(inst); 4657 html = ""; 4658 dow; 4659 for (row = 0; row < numMonths[0]; row++) { 4660 group = ""; 4661 this.maxRows = 4; 4662 for (col = 0; col < numMonths[1]; col++) { 4663 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 4664 cornerClass = " ui-corner-all"; 4665 calender = ""; 4666 if (isMultiMonth) { 4667 calender += "<div class='ui-datepicker-group"; 4668 if (numMonths[1] > 1) { 4669 switch (col) { 4670 case 0: calender += " ui-datepicker-group-first"; 4671 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 4672 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 4673 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 4674 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 4675 } 4676 } 4677 calender += "'>"; 4678 } 4679 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 4680 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 4681 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 4682 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 4683 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 4684 "</div><table class='ui-datepicker-calendar'><thead>" + 4685 "<tr>"; 4686 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 4687 for (dow = 0; dow < 7; dow++) { // days of the week 4688 day = (dow + firstDay) % 7; 4689 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 4690 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 4691 } 4692 calender += thead + "</tr></thead><tbody>"; 4693 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 4694 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 4695 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 4696 } 4697 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 4698 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 4699 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 4700 this.maxRows = numRows; 4701 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 4702 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 4703 calender += "<tr>"; 4704 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 4705 this._get(inst, "calculateWeek")(printDate) + "</td>"); 4706 for (dow = 0; dow < 7; dow++) { // create date picker days 4707 daySettings = (beforeShowDay ? 4708 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 4709 otherMonth = (printDate.getMonth() !== drawMonth); 4710 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 4711 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 4712 tbody += "<td class='" + 4713 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 4714 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 4715 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 4716 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 4717 // or defaultDate is current printedDate and defaultDate is selectedDate 4718 " " + this._dayOverClass : "") + // highlight selected day 4719 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 4720 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 4721 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 4722 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 4723 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 4724 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 4725 (otherMonth && !showOtherMonths ? " " : // display for other months 4726 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 4727 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 4728 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 4729 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 4730 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 4731 printDate.setDate(printDate.getDate() + 1); 4732 printDate = this._daylightSavingAdjust(printDate); 4733 } 4734 calender += tbody + "</tr>"; 4735 } 4736 drawMonth++; 4737 if (drawMonth > 11) { 4738 drawMonth = 0; 4739 drawYear++; 4740 } 4741 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 4742 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 4743 group += calender; 4744 } 4745 html += group; 4746 } 4747 html += buttonPanel; 4748 inst._keyEvent = false; 4749 return html; 4750 }, 4751 4752 /* Generate the month and year header. */ 4753 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 4754 secondary, monthNames, monthNamesShort) { 4755 4756 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 4757 changeMonth = this._get(inst, "changeMonth"), 4758 changeYear = this._get(inst, "changeYear"), 4759 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 4760 html = "<div class='ui-datepicker-title'>", 4761 monthHtml = ""; 4762 4763 // month selection 4764 if (secondary || !changeMonth) { 4765 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 4766 } else { 4767 inMinYear = (minDate && minDate.getFullYear() === drawYear); 4768 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 4769 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 4770 for ( month = 0; month < 12; month++) { 4771 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 4772 monthHtml += "<option value='" + month + "'" + 4773 (month === drawMonth ? " selected='selected'" : "") + 4774 ">" + monthNamesShort[month] + "</option>"; 4775 } 4776 } 4777 monthHtml += "</select>"; 4778 } 4779 4780 if (!showMonthAfterYear) { 4781 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 4782 } 4783 4784 // year selection 4785 if ( !inst.yearshtml ) { 4786 inst.yearshtml = ""; 4787 if (secondary || !changeYear) { 4788 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 4789 } else { 4790 // determine range of years to display 4791 years = this._get(inst, "yearRange").split(":"); 4792 thisYear = new Date().getFullYear(); 4793 determineYear = function(value) { 4794 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 4795 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 4796 parseInt(value, 10))); 4797 return (isNaN(year) ? thisYear : year); 4798 }; 4799 year = determineYear(years[0]); 4800 endYear = Math.max(year, determineYear(years[1] || "")); 4801 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 4802 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 4803 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 4804 for (; year <= endYear; year++) { 4805 inst.yearshtml += "<option value='" + year + "'" + 4806 (year === drawYear ? " selected='selected'" : "") + 4807 ">" + year + "</option>"; 4808 } 4809 inst.yearshtml += "</select>"; 4810 4811 html += inst.yearshtml; 4812 inst.yearshtml = null; 4813 } 4814 } 4815 4816 html += this._get(inst, "yearSuffix"); 4817 if (showMonthAfterYear) { 4818 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 4819 } 4820 html += "</div>"; // Close datepicker_header 4821 return html; 4822 }, 4823 4824 /* Adjust one of the date sub-fields. */ 4825 _adjustInstDate: function(inst, offset, period) { 4826 var year = inst.drawYear + (period === "Y" ? offset : 0), 4827 month = inst.drawMonth + (period === "M" ? offset : 0), 4828 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 4829 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 4830 4831 inst.selectedDay = date.getDate(); 4832 inst.drawMonth = inst.selectedMonth = date.getMonth(); 4833 inst.drawYear = inst.selectedYear = date.getFullYear(); 4834 if (period === "M" || period === "Y") { 4835 this._notifyChange(inst); 4836 } 4837 }, 4838 4839 /* Ensure a date is within any min/max bounds. */ 4840 _restrictMinMax: function(inst, date) { 4841 var minDate = this._getMinMaxDate(inst, "min"), 4842 maxDate = this._getMinMaxDate(inst, "max"), 4843 newDate = (minDate && date < minDate ? minDate : date); 4844 return (maxDate && newDate > maxDate ? maxDate : newDate); 4845 }, 4846 4847 /* Notify change of month/year. */ 4848 _notifyChange: function(inst) { 4849 var onChange = this._get(inst, "onChangeMonthYear"); 4850 if (onChange) { 4851 onChange.apply((inst.input ? inst.input[0] : null), 4852 [inst.selectedYear, inst.selectedMonth + 1, inst]); 4853 } 4854 }, 4855 4856 /* Determine the number of months to show. */ 4857 _getNumberOfMonths: function(inst) { 4858 var numMonths = this._get(inst, "numberOfMonths"); 4859 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 4860 }, 4861 4862 /* Determine the current maximum date - ensure no time components are set. */ 4863 _getMinMaxDate: function(inst, minMax) { 4864 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 4865 }, 4866 4867 /* Find the number of days in a given month. */ 4868 _getDaysInMonth: function(year, month) { 4869 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 4870 }, 4871 4872 /* Find the day of the week of the first of a month. */ 4873 _getFirstDayOfMonth: function(year, month) { 4874 return new Date(year, month, 1).getDay(); 4875 }, 4876 4877 /* Determines if we should allow a "next/prev" month display change. */ 4878 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 4879 var numMonths = this._getNumberOfMonths(inst), 4880 date = this._daylightSavingAdjust(new Date(curYear, 4881 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 4882 4883 if (offset < 0) { 4884 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 4885 } 4886 return this._isInRange(inst, date); 4887 }, 4888 4889 /* Is the given date in the accepted range? */ 4890 _isInRange: function(inst, date) { 4891 var yearSplit, currentYear, 4892 minDate = this._getMinMaxDate(inst, "min"), 4893 maxDate = this._getMinMaxDate(inst, "max"), 4894 minYear = null, 4895 maxYear = null, 4896 years = this._get(inst, "yearRange"); 4897 if (years){ 4898 yearSplit = years.split(":"); 4899 currentYear = new Date().getFullYear(); 4900 minYear = parseInt(yearSplit[0], 10); 4901 maxYear = parseInt(yearSplit[1], 10); 4902 if ( yearSplit[0].match(/[+\-].*/) ) { 4903 minYear += currentYear; 4904 } 4905 if ( yearSplit[1].match(/[+\-].*/) ) { 4906 maxYear += currentYear; 4907 } 4908 } 4909 4910 return ((!minDate || date.getTime() >= minDate.getTime()) && 4911 (!maxDate || date.getTime() <= maxDate.getTime()) && 4912 (!minYear || date.getFullYear() >= minYear) && 4913 (!maxYear || date.getFullYear() <= maxYear)); 4914 }, 4915 4916 /* Provide the configuration settings for formatting/parsing. */ 4917 _getFormatConfig: function(inst) { 4918 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 4919 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 4920 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 4921 return {shortYearCutoff: shortYearCutoff, 4922 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 4923 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 4924 }, 4925 4926 /* Format the given date for display. */ 4927 _formatDate: function(inst, day, month, year) { 4928 if (!day) { 4929 inst.currentDay = inst.selectedDay; 4930 inst.currentMonth = inst.selectedMonth; 4931 inst.currentYear = inst.selectedYear; 4932 } 4933 var date = (day ? (typeof day === "object" ? day : 4934 this._daylightSavingAdjust(new Date(year, month, day))) : 4935 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 4936 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 4937 } 4938}); 4939 4940/* 4941 * Bind hover events for datepicker elements. 4942 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 4943 * Global
vendor: 21,052 bytes, lines 4943-5750
4943instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 4944 */ 4945function bindHover(dpDiv) { 4946 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 4947 return dpDiv.delegate(selector, "mouseout", function() { 4948 $(this).removeClass("ui-state-hover"); 4949 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 4950 $(this).removeClass("ui-datepicker-prev-hover"); 4951 } 4952 if (this.className.indexOf("ui-datepicker-next") !== -1) { 4953 $(this).removeClass("ui-datepicker-next-hover"); 4954 } 4955 }) 4956 .delegate(selector, "mouseover", function(){ 4957 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 4958 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 4959 $(this).addClass("ui-state-hover"); 4960 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 4961 $(this).addClass("ui-datepicker-prev-hover"); 4962 } 4963 if (this.className.indexOf("ui-datepicker-next") !== -1) { 4964 $(this).addClass("ui-datepicker-next-hover"); 4965 } 4966 } 4967 }); 4968} 4969 4970/* jQuery extend now ignores nulls! */ 4971function extendRemove(target, props) { 4972 $.extend(target, props); 4973 for (var name in props) { 4974 if (props[name] == null) { 4975 target[name] = props[name]; 4976 } 4977 } 4978 return target; 4979} 4980 4981/* Invoke the datepicker functionality. 4982 @param options string - a command, optionally followed by additional parameters or 4983 Object - settings for attaching new datepicker functionality 4984 @return jQuery object */ 4985$.fn.datepicker = function(options){ 4986 4987 /* Verify an empty collection wasn't passed - Fixes #6976 */ 4988 if ( !this.length ) { 4989 return this; 4990 } 4991 4992 /* Initialise the date picker. */ 4993 if (!$.datepicker.initialized) { 4994 $(document).mousedown($.datepicker._checkExternalClick); 4995 $.datepicker.initialized = true; 4996 } 4997 4998 /* Append datepicker main container to body if not exist. */ 4999 if ($("#"+$.datepicker._mainDivId).length === 0) { 5000 $("body").append($.datepicker.dpDiv); 5001 } 5002 5003 var otherArgs = Array.prototype.slice.call(arguments, 1); 5004 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 5005 return $.datepicker["_" + options + "Datepicker"]. 5006 apply($.datepicker, [this[0]].concat(otherArgs)); 5007 } 5008 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 5009 return $.datepicker["_" + options + "Datepicker"]. 5010 apply($.datepicker, [this[0]].concat(otherArgs)); 5011 } 5012 return this.each(function() { 5013 typeof options === "string" ? 5014 $.datepicker["_" + options + "Datepicker"]. 5015 apply($.datepicker, [this].concat(otherArgs)) : 5016 $.datepicker._attachDatepicker(this, options); 5017 }); 5018}; 5019 5020$.datepicker = new Datepicker(); // singleton instance 5021$.datepicker.initialized = false; 5022$.datepicker.uuid = new Date().getTime(); 5023$.datepicker.version = "1.10.4"; 5024 5025})(jQuery); 5026(function( $, undefined ) { 5027 5028var sizeRelatedOptions = { 5029 buttons: true, 5030 height: true, 5031 maxHeight: true, 5032 maxWidth: true, 5033 minHeight: true, 5034 minWidth: true, 5035 width: true 5036 }, 5037 resizableRelatedOptions = { 5038 maxHeight: true, 5039 maxWidth: true, 5040 minHeight: true, 5041 minWidth: true 5042 }; 5043 5044$.widget( "ui.dialog", { 5045 version: "1.10.4", 5046 options: { 5047 appendTo: "body", 5048 autoOpen: true, 5049 buttons: [], 5050 closeOnEscape: true, 5051 closeText: "close", 5052 dialogClass: "", 5053 draggable: true, 5054 hide: null, 5055 height: "auto", 5056 maxHeight: null, 5057 maxWidth: null, 5058 minHeight: 150, 5059 minWidth: 150, 5060 modal: false, 5061 position: { 5062 my: "center", 5063 at: "center", 5064 of: window, 5065 collision: "fit", 5066 // Ensure the titlebar is always visible 5067 using: function( pos ) { 5068 var topOffset = $( this ).css( pos ).offset().top; 5069 if ( topOffset < 0 ) { 5070 $( this ).css( "top", pos.top - topOffset ); 5071 } 5072 } 5073 }, 5074 resizable: true, 5075 show: null, 5076 title: null, 5077 width: 300, 5078 5079 // callbacks 5080 beforeClose: null, 5081 close: null, 5082 drag: null, 5083 dragStart: null, 5084 dragStop: null, 5085 focus: null, 5086 open: null, 5087 resize: null, 5088 resizeStart: null, 5089 resizeStop: null 5090 }, 5091 5092 _create: function() { 5093 this.originalCss = { 5094 display: this.element[0].style.display, 5095 width: this.element[0].style.width, 5096 minHeight: this.element[0].style.minHeight, 5097 maxHeight: this.element[0].style.maxHeight, 5098 height: this.element[0].style.height 5099 }; 5100 this.originalPosition = { 5101 parent: this.element.parent(), 5102 index: this.element.parent().children().index( this.element ) 5103 }; 5104 this.originalTitle = this.element.attr("title"); 5105 this.options.title = this.options.title || this.originalTitle; 5106 5107 this._createWrapper(); 5108 5109 this.element 5110 .show() 5111 .removeAttr("title") 5112 .addClass("ui-dialog-content ui-widget-content") 5113 .appendTo( this.uiDialog ); 5114 5115 this._createTitlebar(); 5116 this._createButtonPane(); 5117 5118 if ( this.options.draggable && $.fn.draggable ) { 5119 this._makeDraggable(); 5120 } 5121 if ( this.options.resizable && $.fn.resizable ) { 5122 this._makeResizable(); 5123 } 5124 5125 this._isOpen = false; 5126 }, 5127 5128 _init: function() { 5129 if ( this.options.autoOpen ) { 5130 this.open(); 5131 } 5132 }, 5133 5134 _appendTo: function() { 5135 var element = this.options.appendTo; 5136 if ( element && (element.jquery || element.nodeType) ) { 5137 return $( element ); 5138 } 5139 return this.document.find( element || "body" ).eq( 0 ); 5140 }, 5141 5142 _destroy: function() { 5143 var next, 5144 originalPosition = this.originalPosition; 5145 5146 this._destroyOverlay(); 5147 5148 this.element 5149 .removeUniqueId() 5150 .removeClass("ui-dialog-content ui-widget-content") 5151 .css( this.originalCss ) 5152 // Without detaching first, the following becomes really slow 5153 .detach(); 5154 5155 this.uiDialog.stop( true, true ).remove(); 5156 5157 if ( this.originalTitle ) { 5158 this.element.attr( "title", this.originalTitle ); 5159 } 5160 5161 next = originalPosition.parent.children().eq( originalPosition.index ); 5162 // Don't try to place the dialog next to itself (#8613) 5163 if ( next.length && next[0] !== this.element[0] ) { 5164 next.before( this.element ); 5165 } else { 5166 originalPosition.parent.append( this.element ); 5167 } 5168 }, 5169 5170 widget: function() { 5171 return this.uiDialog; 5172 }, 5173 5174 disable: $.noop, 5175 enable: $.noop, 5176 5177 close: function( event ) { 5178 var activeElement, 5179 that = this; 5180 5181 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 5182 return; 5183 } 5184 5185 this._isOpen = false; 5186 this._destroyOverlay(); 5187 5188 if ( !this.opener.filter(":focusable").focus().length ) { 5189 5190 // support: IE9 5191 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 5192 try { 5193 activeElement = this.document[ 0 ].activeElement; 5194 5195 // Support: IE9, IE10 5196 // If the <body> is blurred, IE will switch windows, see #4520 5197 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { 5198 5199 // Hiding a focused element doesn't trigger blur in WebKit 5200 // so in case we have nothing to focus on, explicitly blur the active element 5201 // https://bugs.webkit.org/show_bug.cgi?id=47182 5202 $( activeElement ).blur(); 5203 } 5204 } catch ( error ) {} 5205 } 5206 5207 this._hide( this.uiDialog, this.options.hide, function() { 5208 that._trigger( "close", event ); 5209 }); 5210 }, 5211 5212 isOpen: function() { 5213 return this._isOpen; 5214 }, 5215 5216 moveToTop: function() { 5217 this._moveToTop(); 5218 }, 5219 5220 _moveToTop: function( event, silent ) { 5221 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; 5222 if ( moved && !silent ) { 5223 this._trigger( "focus", event ); 5224 } 5225 return moved; 5226 }, 5227 5228 open: function() { 5229 var that = this; 5230 if ( this._isOpen ) { 5231 if ( this._moveToTop() ) { 5232 this._focusTabbable(); 5233 } 5234 return; 5235 } 5236 5237 this._isOpen = true; 5238 this.opener = $( this.document[0].activeElement ); 5239 5240 this._size(); 5241 this._position(); 5242 this._createOverlay(); 5243 this._moveToTop( null, true ); 5244 this._show( this.uiDialog, this.options.show, function() { 5245 that._focusTabbable(); 5246 that._trigger("focus"); 5247 }); 5248 5249 this._trigger("open"); 5250 }, 5251 5252 _focusTabbable: function() { 5253 // Set focus to the first match: 5254 // 1. First element inside the dialog matching [autofocus] 5255 // 2. Tabbable element inside the content element 5256 // 3. Tabbable element inside the buttonpane 5257 // 4. The close button 5258 // 5. The dialog itself 5259 var hasFocus = this.element.find("[autofocus]"); 5260 if ( !hasFocus.length ) { 5261 hasFocus = this.element.find(":tabbable"); 5262 } 5263 if ( !hasFocus.length ) { 5264 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 5265 } 5266 if ( !hasFocus.length ) { 5267 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); 5268 } 5269 if ( !hasFocus.length ) { 5270 hasFocus = this.uiDialog; 5271 } 5272 hasFocus.eq( 0 ).focus(); 5273 }, 5274 5275 _keepFocus: function( event ) { 5276 function checkFocus() { 5277 var activeElement = this.document[0].activeElement, 5278 isActive = this.uiDialog[0] === activeElement || 5279 $.contains( this.uiDialog[0], activeElement ); 5280 if ( !isActive ) { 5281 this._focusTabbable(); 5282 } 5283 } 5284 event.preventDefault(); 5285 checkFocus.call( this ); 5286 // support: IE 5287 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 5288 // so we check again later 5289 this._delay( checkFocus ); 5290 }, 5291 5292 _createWrapper: function() { 5293 this.uiDialog = $("<div>") 5294 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 5295 this.options.dialogClass ) 5296 .hide() 5297 .attr({ 5298 // Setting tabIndex makes the div focusable 5299 tabIndex: -1, 5300 role: "dialog" 5301 }) 5302 .appendTo( this._appendTo() ); 5303 5304 this._on( this.uiDialog, { 5305 keydown: function( event ) { 5306 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 5307 event.keyCode === $.ui.keyCode.ESCAPE ) { 5308 event.preventDefault(); 5309 this.close( event ); 5310 return; 5311 } 5312 5313 // prevent tabbing out of dialogs 5314 if ( event.keyCode !== $.ui.keyCode.TAB ) { 5315 return; 5316 } 5317 var tabbables = this.uiDialog.find(":tabbable"), 5318 first = tabbables.filter(":first"), 5319 last = tabbables.filter(":last"); 5320 5321 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 5322 first.focus( 1 ); 5323 event.preventDefault(); 5324 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 5325 last.focus( 1 ); 5326 event.preventDefault(); 5327 } 5328 }, 5329 mousedown: function( event ) { 5330 if ( this._moveToTop( event ) ) { 5331 this._focusTabbable(); 5332 } 5333 } 5334 }); 5335 5336 // We assume that any existing aria-describedby attribute means 5337 // that the dialog content is marked up properly 5338 // otherwise we brute force the content as the description 5339 if ( !this.element.find("[aria-describedby]").length ) { 5340 this.uiDialog.attr({ 5341 "aria-describedby": this.element.uniqueId().attr("id") 5342 }); 5343 } 5344 }, 5345 5346 _createTitlebar: function() { 5347 var uiDialogTitle; 5348 5349 this.uiDialogTitlebar = $("<div>") 5350 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") 5351 .prependTo( this.uiDialog ); 5352 this._on( this.uiDialogTitlebar, { 5353 mousedown: function( event ) { 5354 // Don't prevent click on close button (#8838) 5355 // Focusing a dialog that is partially scrolled out of view 5356 // causes the browser to scroll it into view, preventing the click event 5357 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { 5358 // Dialog isn't getting focus when dragging (#8063) 5359 this.uiDialog.focus(); 5360 } 5361 } 5362 }); 5363 5364 // support: IE 5365 // Use type="button" to prevent enter keypresses in textboxes from closing the 5366 // dialog in IE (#9312) 5367 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 5368 .button({ 5369 label: this.options.closeText, 5370 icons: { 5371 primary: "ui-icon-closethick" 5372 }, 5373 text: false 5374 }) 5375 .addClass("ui-dialog-titlebar-close") 5376 .appendTo( this.uiDialogTitlebar ); 5377 this._on( this.uiDialogTitlebarClose, { 5378 click: function( event ) { 5379 event.preventDefault(); 5380 this.close( event ); 5381 } 5382 }); 5383 5384 uiDialogTitle = $("<span>") 5385 .uniqueId() 5386 .addClass("ui-dialog-title") 5387 .prependTo( this.uiDialogTitlebar ); 5388 this._title( uiDialogTitle ); 5389 5390 this.uiDialog.attr({ 5391 "aria-labelledby": uiDialogTitle.attr("id") 5392 }); 5393 }, 5394 5395 _title: function( title ) { 5396 if ( !this.options.title ) { 5397 title.html(" "); 5398 } 5399 title.text( this.options.title ); 5400 }, 5401 5402 _createButtonPane: function() { 5403 this.uiDialogButtonPane = $("<div>") 5404 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 5405 5406 this.uiButtonSet = $("<div>") 5407 .addClass("ui-dialog-buttonset") 5408 .appendTo( this.uiDialogButtonPane ); 5409 5410 this._createButtons(); 5411 }, 5412 5413 _createButtons: function() { 5414 var that = this, 5415 buttons = this.options.buttons; 5416 5417 // if we already have a button pane, remove it 5418 this.uiDialogButtonPane.remove(); 5419 this.uiButtonSet.empty(); 5420 5421 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 5422 this.uiDialog.removeClass("ui-dialog-buttons"); 5423 return; 5424 } 5425 5426 $.each( buttons, function( name, props ) { 5427 var click, buttonOptions; 5428 props = $.isFunction( props ) ? 5429 { click: props, text: name } : 5430 props; 5431 // Default to a non-submitting button 5432 props = $.extend( { type: "button" }, props ); 5433 // Change the context for the click callback to be the main element 5434 click = props.click; 5435 props.click = function() { 5436 click.apply( that.element[0], arguments ); 5437 }; 5438 buttonOptions = { 5439 icons: props.icons, 5440 text: props.showText 5441 }; 5442 delete props.icons; 5443 delete props.showText; 5444 $( "<button></button>", props ) 5445 .button( buttonOptions ) 5446 .appendTo( that.uiButtonSet ); 5447 }); 5448 this.uiDialog.addClass("ui-dialog-buttons"); 5449 this.uiDialogButtonPane.appendTo( this.uiDialog ); 5450 }, 5451 5452 _makeDraggable: function() { 5453 var that = this, 5454 options = this.options; 5455 5456 function filteredUi( ui ) { 5457 return { 5458 position: ui.position, 5459 offset: ui.offset 5460 }; 5461 } 5462 5463 this.uiDialog.draggable({ 5464 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 5465 handle: ".ui-dialog-titlebar", 5466 containment: "document", 5467 start: function( event, ui ) { 5468 $( this ).addClass("ui-dialog-dragging"); 5469 that._blockFrames(); 5470 that._trigger( "dragStart", event, filteredUi( ui ) ); 5471 }, 5472 drag: function( event, ui ) { 5473 that._trigger( "drag", event, filteredUi( ui ) ); 5474 }, 5475 stop: function( event, ui ) { 5476 options.position = [ 5477 ui.position.left - that.document.scrollLeft(), 5478 ui.position.top - that.document.scrollTop() 5479 ]; 5480 $( this ).removeClass("ui-dialog-dragging"); 5481 that._unblockFrames(); 5482 that._trigger( "dragStop", event, filteredUi( ui ) ); 5483 } 5484 }); 5485 }, 5486 5487 _makeResizable: function() { 5488 var that = this, 5489 options = this.options, 5490 handles = options.resizable, 5491 // .ui-resizable has position: relative defined in the stylesheet 5492 // but dialogs have to use absolute or fixed positioning 5493 position = this.uiDialog.css("position"), 5494 resizeHandles = typeof handles === "string" ? 5495 handles : 5496 "n,e,s,w,se,sw,ne,nw"; 5497 5498 function filteredUi( ui ) { 5499 return { 5500 originalPosition: ui.originalPosition, 5501 originalSize: ui.originalSize, 5502 position: ui.position, 5503 size: ui.size 5504 }; 5505 } 5506 5507 this.uiDialog.resizable({ 5508 cancel: ".ui-dialog-content", 5509 containment: "document", 5510 alsoResize: this.element, 5511 maxWidth: options.maxWidth, 5512 maxHeight: options.maxHeight, 5513 minWidth: options.minWidth, 5514 minHeight: this._minHeight(), 5515 handles: resizeHandles, 5516 start: function( event, ui ) { 5517 $( this ).addClass("ui-dialog-resizing"); 5518 that._blockFrames(); 5519 that._trigger( "resizeStart", event, filteredUi( ui ) ); 5520 }, 5521 resize: function( event, ui ) { 5522 that._trigger( "resize", event, filteredUi( ui ) ); 5523 }, 5524 stop: function( event, ui ) { 5525 options.height = $( this ).height(); 5526 options.width = $( this ).width(); 5527 $( this ).removeClass("ui-dialog-resizing"); 5528 that._unblockFrames(); 5529 that._trigger( "resizeStop", event, filteredUi( ui ) ); 5530 } 5531 }) 5532 .css( "position", position ); 5533 }, 5534 5535 _minHeight: function() { 5536 var options = this.options; 5537 5538 return options.height === "auto" ? 5539 options.minHeight : 5540 Math.min( options.minHeight, options.height ); 5541 }, 5542 5543 _position: function() { 5544 // Need to show the dialog to get the actual offset in the position plugin 5545 var isVisible = this.uiDialog.is(":visible"); 5546 if ( !isVisible ) { 5547 this.uiDialog.show(); 5548 } 5549 this.uiDialog.position( this.options.position ); 5550 if ( !isVisible ) { 5551 this.uiDialog.hide(); 5552 } 5553 }, 5554 5555 _setOptions: function( options ) { 5556 var that = this, 5557 resize = false, 5558 resizableOptions = {}; 5559 5560 $.each( options, function( key, value ) { 5561 that._setOption( key, value ); 5562 5563 if ( key in sizeRelatedOptions ) { 5564 resize = true; 5565 } 5566 if ( key in resizableRelatedOptions ) { 5567 resizableOptions[ key ] = value; 5568 } 5569 }); 5570 5571 if ( resize ) { 5572 this._size(); 5573 this._position(); 5574 } 5575 if ( this.uiDialog.is(":data(ui-resizable)") ) { 5576 this.uiDialog.resizable( "option", resizableOptions ); 5577 } 5578 }, 5579 5580 _setOption: function( key, value ) { 5581 var isDraggable, isResizable, 5582 uiDialog = this.uiDialog; 5583 5584 if ( key === "dialogClass" ) { 5585 uiDialog 5586 .removeClass( this.options.dialogClass ) 5587 .addClass( value ); 5588 } 5589 5590 if ( key === "disabled" ) { 5591 return; 5592 } 5593 5594 this._super( key, value ); 5595 5596 if ( key === "appendTo" ) { 5597 this.uiDialog.appendTo( this._appendTo() ); 5598 } 5599 5600 if ( key === "buttons" ) { 5601 this._createButtons(); 5602 } 5603 5604 if ( key === "closeText" ) { 5605 this.uiDialogTitlebarClose.button({ 5606 // Ensure that we always pass a string 5607 label: "" + value 5608 }); 5609 } 5610 5611 if ( key === "draggable" ) { 5612 isDraggable = uiDialog.is(":data(ui-draggable)"); 5613 if ( isDraggable && !value ) { 5614 uiDialog.draggable("destroy"); 5615 } 5616 5617 if ( !isDraggable && value ) { 5618 this._makeDraggable(); 5619 } 5620 } 5621 5622 if ( key === "position" ) { 5623 this._position(); 5624 } 5625 5626 if ( key === "resizable" ) { 5627 // currently resizable, becoming non-resizable 5628 isResizable = uiDialog.is(":data(ui-resizable)"); 5629 if ( isResizable && !value ) { 5630 uiDialog.resizable("destroy"); 5631 } 5632 5633 // currently resizable, changing handles 5634 if ( isResizable && typeof value === "string" ) { 5635 uiDialog.resizable( "option", "handles", value ); 5636 } 5637 5638 // currently non-resizable, becoming resizable 5639 if ( !isResizable && value !== false ) { 5640 this._makeResizable(); 5641 } 5642 } 5643 5644 if ( key === "title" ) { 5645 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); 5646 } 5647 }, 5648 5649 _size: function() { 5650 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 5651 // divs will both have width and height set, so we need to reset them 5652 var nonContentHeight, minContentHeight, maxContentHeight, 5653 options = this.options; 5654 5655 // Reset content sizing 5656 this.element.show().css({ 5657 width: "auto", 5658 minHeight: 0, 5659 maxHeight: "none", 5660 height: 0 5661 }); 5662 5663 if ( options.minWidth > options.width ) { 5664 options.width = options.minWidth; 5665 } 5666 5667 // reset wrapper sizing 5668 // determine the height of all the non-content elements 5669 nonContentHeight = this.uiDialog.css({ 5670 height: "auto", 5671 width: options.width 5672 }) 5673 .outerHeight(); 5674 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 5675 maxContentHeight = typeof options.maxHeight === "number" ? 5676 Math.max( 0, options.maxHeight - nonContentHeight ) : 5677 "none"; 5678 5679 if ( options.height === "auto" ) { 5680 this.element.css({ 5681 minHeight: minContentHeight, 5682 maxHeight: maxContentHeight, 5683 height: "auto" 5684 }); 5685 } else { 5686 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 5687 } 5688 5689 if (this.uiDialog.is(":data(ui-resizable)") ) { 5690 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 5691 } 5692 }, 5693 5694 _blockFrames: function() { 5695 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 5696 var iframe = $( this ); 5697 5698 return $( "<div>" ) 5699 .css({ 5700 position: "absolute", 5701 width: iframe.outerWidth(), 5702 height: iframe.outerHeight() 5703 }) 5704 .appendTo( iframe.parent() ) 5705 .offset( iframe.offset() )[0]; 5706 }); 5707 }, 5708 5709 _unblockFrames: function() { 5710 if ( this.iframeBlocks ) { 5711 this.iframeBlocks.remove(); 5712 delete this.iframeBlocks; 5713 } 5714 }, 5715 5716 _allowInteraction: function( event ) { 5717 if ( $( event.target ).closest(".ui-dialog").length ) { 5718 return true; 5719 } 5720 5721 // TODO: Remove hack when datepicker implements 5722 // the .ui-front logic (#8989) 5723 return !!$( event.target ).closest(".ui-datepicker").length; 5724 }, 5725 5726 _createOverlay: function() { 5727 if ( !this.options.modal ) { 5728 return; 5729 } 5730 5731 var that = this, 5732 widgetFullName = this.widgetFullName; 5733 if ( !$.ui.dialog.overlayInstances ) { 5734 // Prevent use of anchors and inputs. 5735 // We use a delay in case the overlay is created from an 5736 // event that we're going to be cancelling. (#2804) 5737 this._delay(function() { 5738 // Handle .dialog().dialog("close") (#4065) 5739 if ( $.ui.dialog.overlayInstances ) { 5740 this.document.bind( "focusin.dialog", function( event ) { 5741 if ( !that._allowInteraction( event ) ) { 5742 event.preventDefault(); 5743 $(".ui-dialog:visible:last .ui-dialog-content") 5744 .data( widgetFullName )._focusTabbable(); 5745 } 5746 }); 5747 } 5748 }); 5749 } 5750
5751 this.overlay = $("<div>") 5752 .addClass("ui-widget-overlay ui-front") 5753 .appendTo( this._appendTo() ); 5754 this._on( this.overlay, { 5755 mousedown: "_keepFocus" 5756 }); 5757 $.ui.dialog.overlayInstances++; 5758 }, 5759 5760 _destroyOverlay: function() { 5761 if ( !this.options.modal ) { 5762 return; 5763 } 5764 5765 if ( this.overlay ) { 5766 $.ui.dialog.overlayInstances--; 5767 5768 if ( !$.ui.dialog.overlayInstances ) { 5769 this.document.unbind( "focusin.dialog" ); 5770 } 5771 this.overlay.remove(); 5772 this.overlay = null; 5773 } 5774 } 5775}); 5776 5777$.ui.dialog.overlayInstances = 0; 5778 5779// DEPRECATED 5780if ( $.uiBackCompat !== false ) { 5781 // position option with array notation 5782 // just override with old implementation 5783 $.widget( "ui.dialog", $.ui.dialog, { 5784 _position: function() { 5785 var position = this.options.position, 5786 myAt = [], 5787 offset = [ 0, 0 ], 5788 isVisible; 5789 5790 if ( position ) { 5791 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 5792 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; 5793 if ( myAt.length === 1 ) { 5794 myAt[1] = myAt[0]; 5795 } 5796 5797 $.each( [ "left", "top" ], function( i, offsetPosition ) { 5798 if ( +myAt[ i ] === myAt[ i ] ) { 5799 offset[ i ] = myAt[ i ]; 5800 myAt[ i ] = offsetPosition; 5801 } 5802 }); 5803 5804 position = { 5805 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 5806 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 5807 at: myAt.join(" ") 5808 }; 5809 } 5810 5811 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 5812 } else { 5813 position = $.ui.dialog.prototype.options.position; 5814 } 5815 5816 // need to show the dialog to get the actual offset in the position plugin 5817 isVisible = this.uiDialog.is(":visible"); 5818 if ( !isVisible ) { 5819 this.uiDialog.show(); 5820 } 5821 this.uiDialog.position( position ); 5822 if ( !isVisible ) { 5823 this.uiDialog.hide(); 5824 } 5825 } 5826 }); 5827} 5828 5829}( jQuery ) ); 5830(function( $, undefined ) { 5831 5832$.widget("ui.draggable", $.ui.mouse, { 5833 version: "1.10.4", 5834 widgetEventPrefix: "drag", 5835 options: { 5836 addClasses: true, 5837 appendTo: "parent", 5838 axis: false, 5839 connectToSortable: false, 5840 containment: false, 5841 cursor: "auto", 5842 cursorAt: false, 5843 grid: false, 5844 handle: false, 5845 helper: "original", 5846 iframeFix: false, 5847 opacity: false, 5848 refreshPositions: false, 5849 revert: false, 5850 revertDuration: 500, 5851 scope: "default", 5852 scroll: true, 5853 scrollSensitivity: 20, 5854 scrollSpeed: 20, 5855 snap: false, 5856 snapMode: "both", 5857 snapTolerance: 20, 5858 stack: false, 5859 zIndex: false, 5860 5861 // callbacks 5862 drag: null, 5863 start: null, 5864 stop: null 5865 }, 5866 _create: function() { 5867 5868 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 5869 this.element[0].style.position = "relative"; 5870 } 5871 if (this.options.addClasses){ 5872 this.element.addClass("ui-draggable"); 5873 } 5874 if (this.options.disabled){ 5875 this.element.addClass("ui-draggable-disabled"); 5876 } 5877 5878 this._mouseInit(); 5879 5880 }, 5881 5882 _destroy: function() { 5883 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 5884 this._mouseDestroy(); 5885 }, 5886 5887 _mouseCapture: function(event) { 5888 5889 var o = this.options; 5890 5891 // among others, prevent a drag on a resizable-handle 5892 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 5893 return false; 5894 } 5895 5896 //Quit if we're not on a valid handle 5897 this.handle = this._getHandle(event); 5898 if (!this.handle) { 5899 return false; 5900 } 5901 5902 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 5903 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 5904 .css({ 5905 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 5906 position: "absolute", opacity: "0.001", zIndex: 1000 5907 }) 5908 .css($(this).offset()) 5909 .appendTo("body"); 5910 }); 5911 5912 return true; 5913 5914 }, 5915 5916 _mouseStart: function(event) { 5917 5918 var o = this.options; 5919 5920 //Create and append the visible helper 5921 this.helper = this._createHelper(event); 5922 5923 this.helper.addClass("ui-draggable-dragging"); 5924 5925 //Cache the helper size 5926 this._cacheHelperProportions(); 5927 5928 //If ddmanager is used for droppables, set the global draggable 5929 if($.ui.ddmanager) { 5930 $.ui.ddmanager.current = this; 5931 } 5932 5933 /* 5934 * - Position generation - 5935 * This block generates everything position related - it's the core of draggables. 5936 */ 5937 5938 //Cache the margins of the original element 5939 this._cacheMargins(); 5940 5941 //Store the helper's css position 5942 this.cssPosition = this.helper.css( "position" ); 5943 this.scrollParent = this.helper.scrollParent(); 5944 this.offsetParent = this.helper.offsetParent(); 5945 this.offsetParentCssPosition = this.offsetParent.css( "position" ); 5946 5947 //The element's absolute position on the page minus margins 5948 this.offset = this.positionAbs = this.element.offset(); 5949 this.offset = { 5950 top: this.offset.top - this.margins.top, 5951 left: this.offset.left - this.margins.left 5952 }; 5953 5954 //Reset scroll cache 5955 this.offset.scroll = false;
vendor: 14,361 bytes, lines 5956-6370
5956 5957 $.extend(this.offset, { 5958 click: { //Where the click happened, relative to the element 5959 left: event.pageX - this.offset.left, 5960 top: event.pageY - this.offset.top 5961 }, 5962 parent: this._getParentOffset(), 5963 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 5964 }); 5965 5966 //Generate the original position 5967 this.originalPosition = this.position = this._generatePosition(event); 5968 this.originalPageX = event.pageX; 5969 this.originalPageY = event.pageY; 5970 5971 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 5972 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 5973 5974 //Set a containment if given in the options 5975 this._setContainment(); 5976 5977 //Trigger event + callbacks 5978 if(this._trigger("start", event) === false) { 5979 this._clear(); 5980 return false; 5981 } 5982 5983 //Recache the helper size 5984 this._cacheHelperProportions(); 5985 5986 //Prepare the droppable offsets 5987 if ($.ui.ddmanager && !o.dropBehaviour) { 5988 $.ui.ddmanager.prepareOffsets(this, event); 5989 } 5990 5991 5992 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 5993 5994 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 5995 if ( $.ui.ddmanager ) { 5996 $.ui.ddmanager.dragStart(this, event); 5997 } 5998 5999 return true; 6000 }, 6001 6002 _mouseDrag: function(event, noPropagation) { 6003 // reset any necessary cached properties (see #5009) 6004 if ( this.offsetParentCssPosition === "fixed" ) { 6005 this.offset.parent = this._getParentOffset(); 6006 } 6007 6008 //Compute the helpers position 6009 this.position = this._generatePosition(event); 6010 this.positionAbs = this._convertPositionTo("absolute"); 6011 6012 //Call plugins and callbacks and use the resulting position if something is returned 6013 if (!noPropagation) { 6014 var ui = this._uiHash(); 6015 if(this._trigger("drag", event, ui) === false) { 6016 this._mouseUp({}); 6017 return false; 6018 } 6019 this.position = ui.position; 6020 } 6021 6022 if(!this.options.axis || this.options.axis !== "y") { 6023 this.helper[0].style.left = this.position.left+"px"; 6024 } 6025 if(!this.options.axis || this.options.axis !== "x") { 6026 this.helper[0].style.top = this.position.top+"px"; 6027 } 6028 if($.ui.ddmanager) { 6029 $.ui.ddmanager.drag(this, event); 6030 } 6031 6032 return false; 6033 }, 6034 6035 _mouseStop: function(event) { 6036 6037 //If we are using droppables, inform the manager about the drop 6038 var that = this, 6039 dropped = false; 6040 if ($.ui.ddmanager && !this.options.dropBehaviour) { 6041 dropped = $.ui.ddmanager.drop(this, event); 6042 } 6043 6044 //if a drop comes from outside (a sortable) 6045 if(this.dropped) { 6046 dropped = this.dropped; 6047 this.dropped = false; 6048 } 6049 6050 //if the original element is no longer in the DOM don't bother to continue (see #8269) 6051 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { 6052 return false; 6053 } 6054 6055 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))) { 6056 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 6057 if(that._trigger("stop", event) !== false) { 6058 that._clear(); 6059 } 6060 }); 6061 } else { 6062 if(this._trigger("stop", event) !== false) { 6063 this._clear(); 6064 } 6065 } 6066 6067 return false; 6068 }, 6069 6070 _mouseUp: function(event) { 6071 //Remove frame helpers 6072 $("div.ui-draggable-iframeFix").each(function() { 6073 this.parentNode.removeChild(this); 6074 }); 6075 6076 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 6077 if( $.ui.ddmanager ) { 6078 $.ui.ddmanager.dragStop(this, event); 6079 } 6080 6081 return $.ui.mouse.prototype._mouseUp.call(this, event); 6082 }, 6083 6084 cancel: function() { 6085 6086 if(this.helper.is(".ui-draggable-dragging")) { 6087 this._mouseUp({}); 6088 } else { 6089 this._clear(); 6090 } 6091 6092 return this; 6093 6094 }, 6095 6096 _getHandle: function(event) { 6097 return this.options.handle ? 6098 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 6099 true; 6100 }, 6101 6102 _createHelper: function(event) { 6103 6104 var o = this.options, 6105 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 6106 6107 if(!helper.parents("body").length) { 6108 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 6109 } 6110 6111 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 6112 helper.css("position", "absolute"); 6113 } 6114 6115 return helper; 6116 6117 }, 6118 6119 _adjustOffsetFromHelper: function(obj) { 6120 if (typeof obj === "string") { 6121 obj = obj.split(" "); 6122 } 6123 if ($.isArray(obj)) { 6124 obj = {left: +obj[0], top: +obj[1] || 0}; 6125 } 6126 if ("left" in obj) { 6127 this.offset.click.left = obj.left + this.margins.left; 6128 } 6129 if ("right" in obj) { 6130 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 6131 } 6132 if ("top" in obj) { 6133 this.offset.click.top = obj.top + this.margins.top; 6134 } 6135 if ("bottom" in obj) { 6136 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 6137 } 6138 }, 6139 6140 _getParentOffset: function() { 6141 6142 //Get the offsetParent and cache its position 6143 var po = this.offsetParent.offset(); 6144 6145 // This is a special case where we need to modify a offset calculated on start, since the following happened: 6146 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 6147 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 6148 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 6149 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 6150 po.left += this.scrollParent.scrollLeft(); 6151 po.top += this.scrollParent.scrollTop(); 6152 } 6153 6154 //This needs to be actually done for all browsers, since pageX/pageY includes this information 6155 //Ugly IE fix 6156 if((this.offsetParent[0] === document.body) || 6157 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 6158 po = { top: 0, left: 0 }; 6159 } 6160 6161 return { 6162 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 6163 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 6164 }; 6165 6166 }, 6167 6168 _getRelativeOffset: function() { 6169 6170 if(this.cssPosition === "relative") { 6171 var p = this.element.position(); 6172 return { 6173 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 6174 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 6175 }; 6176 } else { 6177 return { top: 0, left: 0 }; 6178 } 6179 6180 }, 6181 6182 _cacheMargins: function() { 6183 this.margins = { 6184 left: (parseInt(this.element.css("marginLeft"),10) || 0), 6185 top: (parseInt(this.element.css("marginTop"),10) || 0), 6186 right: (parseInt(this.element.css("marginRight"),10) || 0), 6187 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 6188 }; 6189 }, 6190 6191 _cacheHelperProportions: function() { 6192 this.helperProportions = { 6193 width: this.helper.outerWidth(), 6194 height: this.helper.outerHeight() 6195 }; 6196 }, 6197 6198 _setContainment: function() { 6199 6200 var over, c, ce, 6201 o = this.options; 6202 6203 if ( !o.containment ) { 6204 this.containment = null; 6205 return; 6206 } 6207 6208 if ( o.containment === "window" ) { 6209 this.containment = [ 6210 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 6211 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 6212 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 6213 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 6214 ]; 6215 return; 6216 } 6217 6218 if ( o.containment === "document") { 6219 this.containment = [ 6220 0, 6221 0, 6222 $( document ).width() - this.helperProportions.width - this.margins.left, 6223 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 6224 ]; 6225 return; 6226 } 6227 6228 if ( o.containment.constructor === Array ) { 6229 this.containment = o.containment; 6230 return; 6231 } 6232 6233 if ( o.containment === "parent" ) { 6234 o.containment = this.helper[ 0 ].parentNode; 6235 } 6236 6237 c = $( o.containment ); 6238 ce = c[ 0 ]; 6239 6240 if( !ce ) { 6241 return; 6242 } 6243 6244 over = c.css( "overflow" ) !== "hidden"; 6245 6246 this.containment = [ 6247 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 6248 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) , 6249 ( 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, 6250 ( 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 6251 ]; 6252 this.relative_container = c; 6253 }, 6254 6255 _convertPositionTo: function(d, pos) { 6256 6257 if(!pos) { 6258 pos = this.position; 6259 } 6260 6261 var mod = d === "absolute" ? 1 : -1, 6262 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; 6263 6264 //Cache the scroll 6265 if (!this.offset.scroll) { 6266 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 6267 } 6268 6269 return { 6270 top: ( 6271 pos.top + // The absolute mouse position 6272 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 6273 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 6274 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) 6275 ), 6276 left: ( 6277 pos.left + // The absolute mouse position 6278 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 6279 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 6280 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) 6281 ) 6282 }; 6283 6284 }, 6285 6286 _generatePosition: function(event) { 6287 6288 var containment, co, top, left, 6289 o = this.options, 6290 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, 6291 pageX = event.pageX, 6292 pageY = event.pageY; 6293 6294 //Cache the scroll 6295 if (!this.offset.scroll) { 6296 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 6297 } 6298 6299 /* 6300 * - Position constraining - 6301 * Constrain the position to a mix of grid, containment. 6302 */ 6303 6304 // If we are not dragging yet, we won't check for options 6305 if ( this.originalPosition ) { 6306 if ( this.containment ) { 6307 if ( this.relative_container ){ 6308 co = this.relative_container.offset(); 6309 containment = [ 6310 this.containment[ 0 ] + co.left, 6311 this.containment[ 1 ] + co.top, 6312 this.containment[ 2 ] + co.left, 6313 this.containment[ 3 ] + co.top 6314 ]; 6315 } 6316 else { 6317 containment = this.containment; 6318 } 6319 6320 if(event.pageX - this.offset.click.left < containment[0]) { 6321 pageX = containment[0] + this.offset.click.left; 6322 } 6323 if(event.pageY - this.offset.click.top < containment[1]) { 6324 pageY = containment[1] + this.offset.click.top; 6325 } 6326 if(event.pageX - this.offset.click.left > containment[2]) { 6327 pageX = containment[2] + this.offset.click.left; 6328 } 6329 if(event.pageY - this.offset.click.top > containment[3]) { 6330 pageY = containment[3] + this.offset.click.top; 6331 } 6332 } 6333 6334 if(o.grid) { 6335 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 6336 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 6337 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; 6338 6339 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 6340 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; 6341 } 6342 6343 } 6344 6345 return { 6346 top: ( 6347 pageY - // The absolute mouse position 6348 this.offset.click.top - // Click offset (relative to the element) 6349 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 6350 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 6351 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) 6352 ), 6353 left: ( 6354 pageX - // The absolute mouse position 6355 this.offset.click.left - // Click offset (relative to the element) 6356 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 6357 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 6358 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) 6359 ) 6360 }; 6361 6362 }, 6363 6364 _clear: function() { 6365 this.helper.removeClass("ui-draggable-dragging"); 6366 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 6367 this.helper.remove(); 6368 } 6369 this.helper = null; 6370 this.cancelHelperRemoval = false;
6371 }, 6372 6373 // From now on bulk stuff - mainly helpers 6374 6375 _trigger: function(type, event, ui) { 6376 ui = ui || this._uiHash(); 6377 $.ui.plugin.call(this, type, [event, ui]); 6378 //The absolute position has to be recalculated after plugins 6379 if(type === "drag") { 6380 this.positionAbs = this._convertPositionTo("absolute"); 6381 } 6382 return $.Widget.prototype._trigger.call(this, type, event, ui); 6383 }, 6384 6385 plugins: {}, 6386 6387 _uiHash: function() { 6388 return { 6389 helper: this.helper, 6390 position: this.position, 6391 originalPosition: this.originalPosition, 6392 offset: this.positionAbs 6393 }; 6394 } 6395 6396}); 6397 6398$.ui.plugin.add("draggable", "connectToSortable", { 6399 start: function(event, ui) { 6400 6401 var inst = $(this).data("ui-draggable"), o = inst.options, 6402 uiSortable = $.extend({}, ui, { item: inst.element }); 6403 inst.sortables = []; 6404 $(o.connectToSortable).each(function() { 6405 var sortable = $.data(this, "ui-sortable"); 6406 if (sortable && !sortable.options.disabled) { 6407 inst.sortables.push({ 6408 instance: sortable, 6409 shouldRevert: sortable.options.revert 6410 }); 6411 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). 6412 sortable._trigger("activate", event, uiSortable); 6413 } 6414 }); 6415 6416 }, 6417 stop: function(event, ui) { 6418 6419 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 6420 var inst = $(this).data("ui-draggable"), 6421 uiSortable = $.extend({}, ui, { item: inst.element }); 6422 6423 $.each(inst.sortables, function() { 6424 if(this.instance.isOver) { 6425 6426 this.instance.isOver = 0; 6427 6428 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 6429 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 6430 6431 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 6432 if(this.shouldRevert) { 6433 this.instance.options.revert = this.shouldRevert; 6434 } 6435 6436 //Trigger the stop of the sortable 6437 this.instance._mouseStop(event); 6438 6439 this.instance.options.helper = this.instance.options._helper; 6440 6441 //If the helper has been the original item, restore properties in the sortable 6442 if(inst.options.helper === "original") { 6443 this.instance.currentItem.css({ top: "auto", left: "auto" }); 6444 } 6445 6446 } else { 6447 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 6448 this.instance._trigger("deactivate", event, uiSortable); 6449 } 6450 6451 }); 6452 6453 }, 6454 drag: function(event, ui) { 6455 6456 var inst = $(this).data("ui-draggable"), that = this; 6457 6458 $.each(inst.sortables, function() { 6459 6460 var innermostIntersecting = false, 6461 thisSortable = this; 6462 6463 //Copy over some variables to allow calling the sortable's native _intersectsWith 6464 this.instance.positionAbs = inst.positionAbs; 6465 this.instance.helperProportions = inst.helperProportions; 6466 this.instance.offset.click = inst.offset.click; 6467 6468 if(this.instance._intersectsWith(this.instance.containerCache)) { 6469 innermostIntersecting = true; 6470 $.each(inst.sortables, function () { 6471 this.instance.positionAbs = inst.positionAbs; 6472 this.instance.helperProportions = inst.helperProportions; 6473 this.instance.offset.click = inst.offset.click; 6474 if (this !== thisSortable && 6475 this.instance._intersectsWith(this.instance.containerCache) && 6476 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 6477 ) { 6478 innermostIntersecting = false; 6479 } 6480 return innermostIntersecting; 6481 }); 6482 } 6483 6484 6485 if(innermostIntersecting) { 6486 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 6487 if(!this.instance.isOver) { 6488 6489 this.instance.isOver = 1; 6490 //Now we fake the start of dragging for the sortable instance, 6491 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 6492 //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) 6493 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 6494 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 6495 this.instance.options.helper = function() { return ui.helper[0]; }; 6496 6497 event.target = this.instance.currentItem[0]; 6498 this.instance._mouseCapture(event, true); 6499 this.instance._mouseStart(event, true, true); 6500
6501 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 6502 this.instance.offset.click.top = inst.offset.click.top; 6503 this.instance.offset.click.left = inst.offset.click.left; 6504 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 6505 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 6506 6507 inst._trigger("toSortable", event); 6508 inst.dropped = this.instance.element; //draggable revert needs that 6509 //hack so receive/update callbacks work (mostly) 6510 inst.currentItem = inst.element; 6511 this.instance.fromOutside = inst; 6512 6513 } 6514 6515 //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 6516 if(this.instance.currentItem) { 6517 this.instance._mouseDrag(event); 6518 } 6519 6520 } else { 6521 6522 //If it doesn't intersect with the sortable, and it intersected before, 6523 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 6524 if(this.instance.isOver) { 6525 6526 this.instance.isOver = 0; 6527 this.instance.cancelHelperRemoval = true; 6528 6529 //Prevent reverting on this forced stop 6530 this.instance.options.revert = false; 6531 6532 // The out event needs to be triggered independently 6533 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 6534 6535 this.instance._mouseStop(event, true); 6536 this.instance.options.helper = this.instance.options._helper; 6537 6538 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 6539 this.instance.currentItem.remove(); 6540 if(this.instance.placeholder) { 6541 this.instance.placeholder.remove(); 6542 } 6543 6544 inst._trigger("fromSortable", event); 6545 inst.dropped = false; //draggable revert needs that 6546 } 6547 6548 } 6549 6550 }); 6551 6552 } 6553}); 6554 6555$.ui.plugin.add("draggable", "cursor", { 6556 start: function() { 6557 var t = $("body"), o = $(this).data("ui-draggable").options; 6558 if (t.css("cursor")) { 6559 o._cursor = t.css("cursor"); 6560 } 6561 t.css("cursor", o.cursor); 6562 }, 6563 stop: function() { 6564 var o = $(this).data("ui-draggable").options; 6565 if (o._cursor) { 6566 $("body").css("cursor", o._cursor); 6567 } 6568 } 6569}); 6570 6571$.ui.plugin.add("draggable", "opacity", { 6572 start: function(event, ui) { 6573 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 6574 if(t.css("opacity")) { 6575 o._opacity = t.css("opacity"); 6576 } 6577 t.css("opacity", o.opacity); 6578 }, 6579 stop: function(event, ui) { 6580 var o = $(this).data("ui-draggable").options; 6581 if(o._opacity) { 6582 $(ui.helper).css("opacity", o._opacity); 6583 } 6584 } 6585}); 6586 6587$.ui.plugin.add("draggable", "scroll", { 6588 start: function() { 6589 var i = $(this).data("ui-draggable"); 6590 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 6591 i.overflowOffset = i.scrollParent.offset(); 6592 } 6593 }, 6594 drag: function( event ) { 6595 6596 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 6597 6598 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 6599 6600 if(!o.axis || o.axis !== "x") { 6601 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 6602 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 6603 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 6604 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 6605 } 6606 } 6607 6608 if(!o.axis || o.axis !== "y") { 6609 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 6610 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 6611 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 6612 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 6613 } 6614 } 6615 6616 } else { 6617 6618 if(!o.axis || o.axis !== "x") { 6619 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 6620 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 6621 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 6622 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 6623 } 6624 } 6625 6626 if(!o.axis || o.axis !== "y") { 6627 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 6628 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 6629 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 6630 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 6631 } 6632 } 6633 6634 } 6635 6636 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 6637 $.ui.ddmanager.prepareOffsets(i, event); 6638 } 6639 6640 } 6641}); 6642 6643$.ui.plugin.add("draggable", "snap", { 6644 start: function() { 6645 6646 var i = $(this).data("ui-draggable"), 6647 o = i.options; 6648 6649 i.snapElements = []; 6650 6651 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 6652 var $t = $(this), 6653 $o = $t.offset(); 6654 if(this !== i.element[0]) { 6655 i.snapElements.push({ 6656 item: this, 6657 width: $t.outerWidth(), height: $t.outerHeight(), 6658 top: $o.top, left: $o.left 6659 }); 6660 } 6661 }); 6662 6663 }, 6664 drag: function(event, ui) { 6665 6666 var ts, bs, ls, rs, l, r, t, b, i, first, 6667 inst = $(this).data("ui-draggable"), 6668 o = inst.options, 6669 d = o.snapTolerance, 6670 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 6671 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 6672 6673 for (i = inst.snapElements.length - 1; i >= 0; i--){ 6674 6675 l = inst.snapElements[i].left; 6676 r = l + inst.snapElements[i].width; 6677 t = inst.snapElements[i].top; 6678 b = t + inst.snapElements[i].height; 6679 6680 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 6681 if(inst.snapElements[i].snapping) { 6682 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 6683 } 6684 inst.snapElements[i].snapping = false;
vendor: 108,179 bytes, lines 6685-10841
6685 continue; 6686 } 6687 6688 if(o.snapMode !== "inner") { 6689 ts = Math.abs(t - y2) <= d; 6690 bs = Math.abs(b - y1) <= d; 6691 ls = Math.abs(l - x2) <= d; 6692 rs = Math.abs(r - x1) <= d; 6693 if(ts) { 6694 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 6695 } 6696 if(bs) { 6697 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 6698 } 6699 if(ls) { 6700 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 6701 } 6702 if(rs) { 6703 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 6704 } 6705 } 6706 6707 first = (ts || bs || ls || rs); 6708 6709 if(o.snapMode !== "outer") { 6710 ts = Math.abs(t - y1) <= d; 6711 bs = Math.abs(b - y2) <= d; 6712 ls = Math.abs(l - x1) <= d; 6713 rs = Math.abs(r - x2) <= d; 6714 if(ts) { 6715 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 6716 } 6717 if(bs) { 6718 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 6719 } 6720 if(ls) { 6721 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 6722 } 6723 if(rs) { 6724 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 6725 } 6726 } 6727 6728 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 6729 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 6730 } 6731 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 6732 6733 } 6734 6735 } 6736}); 6737 6738$.ui.plugin.add("draggable", "stack", { 6739 start: function() { 6740 var min, 6741 o = this.data("ui-draggable").options, 6742 group = $.makeArray($(o.stack)).sort(function(a,b) { 6743 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 6744 }); 6745 6746 if (!group.length) { return; } 6747 6748 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 6749 $(group).each(function(i) { 6750 $(this).css("zIndex", min + i); 6751 }); 6752 this.css("zIndex", (min + group.length)); 6753 } 6754}); 6755 6756$.ui.plugin.add("draggable", "zIndex", { 6757 start: function(event, ui) { 6758 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 6759 if(t.css("zIndex")) { 6760 o._zIndex = t.css("zIndex"); 6761 } 6762 t.css("zIndex", o.zIndex); 6763 }, 6764 stop: function(event, ui) { 6765 var o = $(this).data("ui-draggable").options; 6766 if(o._zIndex) { 6767 $(ui.helper).css("zIndex", o._zIndex); 6768 } 6769 } 6770}); 6771 6772})(jQuery); 6773(function( $, undefined ) { 6774 6775function isOverAxis( x, reference, size ) { 6776 return ( x > reference ) && ( x < ( reference + size ) ); 6777} 6778 6779$.widget("ui.droppable", { 6780 version: "1.10.4", 6781 widgetEventPrefix: "drop", 6782 options: { 6783 accept: "*", 6784 activeClass: false, 6785 addClasses: true, 6786 greedy: false, 6787 hoverClass: false, 6788 scope: "default", 6789 tolerance: "intersect", 6790 6791 // callbacks 6792 activate: null, 6793 deactivate: null, 6794 drop: null, 6795 out: null, 6796 over: null 6797 }, 6798 _create: function() { 6799 6800 var proportions, 6801 o = this.options, 6802 accept = o.accept; 6803 6804 this.isover = false; 6805 this.isout = true; 6806 6807 this.accept = $.isFunction(accept) ? accept : function(d) { 6808 return d.is(accept); 6809 }; 6810 6811 this.proportions = function( /* valueToWrite */ ) { 6812 if ( arguments.length ) { 6813 // Store the droppable's proportions 6814 proportions = arguments[ 0 ]; 6815 } else { 6816 // Retrieve or derive the droppable's proportions 6817 return proportions ? 6818 proportions : 6819 proportions = { 6820 width: this.element[ 0 ].offsetWidth, 6821 height: this.element[ 0 ].offsetHeight 6822 }; 6823 } 6824 }; 6825 6826 // Add the reference and positions to the manager 6827 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 6828 $.ui.ddmanager.droppables[o.scope].push(this); 6829 6830 (o.addClasses && this.element.addClass("ui-droppable")); 6831 6832 }, 6833 6834 _destroy: function() { 6835 var i = 0, 6836 drop = $.ui.ddmanager.droppables[this.options.scope]; 6837 6838 for ( ; i < drop.length; i++ ) { 6839 if ( drop[i] === this ) { 6840 drop.splice(i, 1); 6841 } 6842 } 6843 6844 this.element.removeClass("ui-droppable ui-droppable-disabled"); 6845 }, 6846 6847 _setOption: function(key, value) { 6848 6849 if(key === "accept") { 6850 this.accept = $.isFunction(value) ? value : function(d) { 6851 return d.is(value); 6852 }; 6853 } 6854 $.Widget.prototype._setOption.apply(this, arguments); 6855 }, 6856 6857 _activate: function(event) { 6858 var draggable = $.ui.ddmanager.current; 6859 if(this.options.activeClass) { 6860 this.element.addClass(this.options.activeClass); 6861 } 6862 if(draggable){ 6863 this._trigger("activate", event, this.ui(draggable)); 6864 } 6865 }, 6866 6867 _deactivate: function(event) { 6868 var draggable = $.ui.ddmanager.current; 6869 if(this.options.activeClass) { 6870 this.element.removeClass(this.options.activeClass); 6871 } 6872 if(draggable){ 6873 this._trigger("deactivate", event, this.ui(draggable)); 6874 } 6875 }, 6876 6877 _over: function(event) { 6878 6879 var draggable = $.ui.ddmanager.current; 6880 6881 // Bail if draggable and droppable are same element 6882 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 6883 return; 6884 } 6885 6886 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 6887 if(this.options.hoverClass) { 6888 this.element.addClass(this.options.hoverClass); 6889 } 6890 this._trigger("over", event, this.ui(draggable)); 6891 } 6892 6893 }, 6894 6895 _out: function(event) { 6896 6897 var draggable = $.ui.ddmanager.current; 6898 6899 // Bail if draggable and droppable are same element 6900 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 6901 return; 6902 } 6903 6904 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 6905 if(this.options.hoverClass) { 6906 this.element.removeClass(this.options.hoverClass); 6907 } 6908 this._trigger("out", event, this.ui(draggable)); 6909 } 6910 6911 }, 6912 6913 _drop: function(event,custom) { 6914 6915 var draggable = custom || $.ui.ddmanager.current, 6916 childrenIntersection = false; 6917 6918 // Bail if draggable and droppable are same element 6919 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 6920 return false; 6921 } 6922 6923 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 6924 var inst = $.data(this, "ui-droppable"); 6925 if( 6926 inst.options.greedy && 6927 !inst.options.disabled && 6928 inst.options.scope === draggable.options.scope && 6929 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 6930 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 6931 ) { childrenIntersection = true; return false; } 6932 }); 6933 if(childrenIntersection) { 6934 return false; 6935 } 6936 6937 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 6938 if(this.options.activeClass) { 6939 this.element.removeClass(this.options.activeClass); 6940 } 6941 if(this.options.hoverClass) { 6942 this.element.removeClass(this.options.hoverClass); 6943 } 6944 this._trigger("drop", event, this.ui(draggable)); 6945 return this.element; 6946 } 6947 6948 return false; 6949 6950 }, 6951 6952 ui: function(c) { 6953 return { 6954 draggable: (c.currentItem || c.element), 6955 helper: c.helper, 6956 position: c.position, 6957 offset: c.positionAbs 6958 }; 6959 } 6960 6961}); 6962 6963$.ui.intersect = function(draggable, droppable, toleranceMode) { 6964 6965 if (!droppable.offset) { 6966 return false; 6967 } 6968 6969 var draggableLeft, draggableTop, 6970 x1 = (draggable.positionAbs || draggable.position.absolute).left, 6971 y1 = (draggable.positionAbs || draggable.position.absolute).top, 6972 x2 = x1 + draggable.helperProportions.width, 6973 y2 = y1 + draggable.helperProportions.height, 6974 l = droppable.offset.left, 6975 t = droppable.offset.top, 6976 r = l + droppable.proportions().width, 6977 b = t + droppable.proportions().height; 6978 6979 switch (toleranceMode) { 6980 case "fit": 6981 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 6982 case "intersect": 6983 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half 6984 x2 - (draggable.helperProportions.width / 2) < r && // Left Half 6985 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half 6986 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 6987 case "pointer": 6988 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 6989 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 6990 return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width ); 6991 case "touch": 6992 return ( 6993 (y1 >= t && y1 <= b) || // Top edge touching 6994 (y2 >= t && y2 <= b) || // Bottom edge touching 6995 (y1 < t && y2 > b) // Surrounded vertically 6996 ) && ( 6997 (x1 >= l && x1 <= r) || // Left edge touching 6998 (x2 >= l && x2 <= r) || // Right edge touching 6999 (x1 < l && x2 > r) // Surrounded horizontally 7000 ); 7001 default: 7002 return false; 7003 } 7004 7005}; 7006 7007/* 7008 This manager tracks offsets of draggables and droppables 7009*/ 7010$.ui.ddmanager = { 7011 current: null, 7012 droppables: { "default": [] }, 7013 prepareOffsets: function(t, event) { 7014 7015 var i, j, 7016 m = $.ui.ddmanager.droppables[t.options.scope] || [], 7017 type = event ? event.type : null, // workaround for #2317 7018 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 7019 7020 droppablesLoop: for (i = 0; i < m.length; i++) { 7021 7022 //No disabled and non-accepted 7023 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 7024 continue; 7025 } 7026 7027 // Filter out elements in the current dragged item 7028 for (j=0; j < list.length; j++) { 7029 if(list[j] === m[i].element[0]) { 7030 m[i].proportions().height = 0; 7031 continue droppablesLoop; 7032 } 7033 } 7034 7035 m[i].visible = m[i].element.css("display") !== "none"; 7036 if(!m[i].visible) { 7037 continue; 7038 } 7039 7040 //Activate the droppable if used directly from draggables 7041 if(type === "mousedown") { 7042 m[i]._activate.call(m[i], event); 7043 } 7044 7045 m[ i ].offset = m[ i ].element.offset(); 7046 m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); 7047 7048 } 7049 7050 }, 7051 drop: function(draggable, event) { 7052 7053 var dropped = false; 7054 // Create a copy of the droppables in case the list changes during the drop (#9116) 7055 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { 7056 7057 if(!this.options) { 7058 return; 7059 } 7060 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 7061 dropped = this._drop.call(this, event) || dropped; 7062 } 7063 7064 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 7065 this.isout = true; 7066 this.isover = false; 7067 this._deactivate.call(this, event); 7068 } 7069 7070 }); 7071 return dropped; 7072 7073 }, 7074 dragStart: function( draggable, event ) { 7075 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 7076 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 7077 if( !draggable.options.refreshPositions ) { 7078 $.ui.ddmanager.prepareOffsets( draggable, event ); 7079 } 7080 }); 7081 }, 7082 drag: function(draggable, event) { 7083 7084 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 7085 if(draggable.options.refreshPositions) { 7086 $.ui.ddmanager.prepareOffsets(draggable, event); 7087 } 7088 7089 //Run through all droppables and check their positions based on specific tolerance options 7090 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 7091 7092 if(this.options.disabled || this.greedyChild || !this.visible) { 7093 return; 7094 } 7095 7096 var parentInstance, scope, parent, 7097 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 7098 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 7099 if(!c) { 7100 return; 7101 } 7102 7103 if (this.options.greedy) { 7104 // find droppable parents with same scope 7105 scope = this.options.scope; 7106 parent = this.element.parents(":data(ui-droppable)").filter(function () { 7107 return $.data(this, "ui-droppable").options.scope === scope; 7108 }); 7109 7110 if (parent.length) { 7111 parentInstance = $.data(parent[0], "ui-droppable"); 7112 parentInstance.greedyChild = (c === "isover"); 7113 } 7114 } 7115 7116 // we just moved into a greedy child 7117 if (parentInstance && c === "isover") { 7118 parentInstance.isover = false; 7119 parentInstance.isout = true; 7120 parentInstance._out.call(parentInstance, event); 7121 } 7122 7123 this[c] = true; 7124 this[c === "isout" ? "isover" : "isout"] = false; 7125 this[c === "isover" ? "_over" : "_out"].call(this, event); 7126 7127 // we just moved out of a greedy child 7128 if (parentInstance && c === "isout") { 7129 parentInstance.isout = false; 7130 parentInstance.isover = true; 7131 parentInstance._over.call(parentInstance, event); 7132 } 7133 }); 7134 7135 }, 7136 dragStop: function( draggable, event ) { 7137 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 7138 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 7139 if( !draggable.options.refreshPositions ) { 7140 $.ui.ddmanager.prepareOffsets( draggable, event ); 7141 } 7142 } 7143}; 7144 7145})(jQuery); 7146(function($, undefined) { 7147 7148var dataSpace = "ui-effects-"; 7149 7150$.effects = { 7151 effect: {} 7152}; 7153 7154/*! 7155 * jQuery Color Animations v2.1.2 7156 * https://github.com/jquery/jquery-color 7157 * 7158 * Copyright 2013 jQuery Foundation and other contributors 7159 * Released under the MIT license. 7160 * http://jquery.org/license 7161 * 7162 * Date: Wed Jan 16 08:47:09 2013 -0600 7163 */ 7164(function( jQuery, undefined ) { 7165 7166 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 7167 7168 // plusequals test for += 100 -= 100 7169 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 7170 // a set of RE's that can match strings and generate color tuples. 7171 stringParsers = [{ 7172 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 7173 parse: function( execResult ) { 7174 return [ 7175 execResult[ 1 ], 7176 execResult[ 2 ], 7177 execResult[ 3 ], 7178 execResult[ 4 ] 7179 ]; 7180 } 7181 }, { 7182 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 7183 parse: function( execResult ) { 7184 return [ 7185 execResult[ 1 ] * 2.55, 7186 execResult[ 2 ] * 2.55, 7187 execResult[ 3 ] * 2.55, 7188 execResult[ 4 ] 7189 ]; 7190 } 7191 }, { 7192 // this regex ignores A-F because it's compared against an already lowercased string 7193 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 7194 parse: function( execResult ) { 7195 return [ 7196 parseInt( execResult[ 1 ], 16 ), 7197 parseInt( execResult[ 2 ], 16 ), 7198 parseInt( execResult[ 3 ], 16 ) 7199 ]; 7200 } 7201 }, { 7202 // this regex ignores A-F because it's compared against an already lowercased string 7203 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 7204 parse: function( execResult ) { 7205 return [ 7206 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 7207 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 7208 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 7209 ]; 7210 } 7211 }, { 7212 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 7213 space: "hsla", 7214 parse: function( execResult ) { 7215 return [ 7216 execResult[ 1 ], 7217 execResult[ 2 ] / 100, 7218 execResult[ 3 ] / 100, 7219 execResult[ 4 ] 7220 ]; 7221 } 7222 }], 7223 7224 // jQuery.Color( ) 7225 color = jQuery.Color = function( color, green, blue, alpha ) { 7226 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 7227 }, 7228 spaces = { 7229 rgba: { 7230 props: { 7231 red: { 7232 idx: 0, 7233 type: "byte" 7234 }, 7235 green: { 7236 idx: 1, 7237 type: "byte" 7238 }, 7239 blue: { 7240 idx: 2, 7241 type: "byte" 7242 } 7243 } 7244 }, 7245 7246 hsla: { 7247 props: { 7248 hue: { 7249 idx: 0, 7250 type: "degrees" 7251 }, 7252 saturation: { 7253 idx: 1, 7254 type: "percent" 7255 }, 7256 lightness: { 7257 idx: 2, 7258 type: "percent" 7259 } 7260 } 7261 } 7262 }, 7263 propTypes = { 7264 "byte": { 7265 floor: true, 7266 max: 255 7267 }, 7268 "percent": { 7269 max: 1 7270 }, 7271 "degrees": { 7272 mod: 360, 7273 floor: true 7274 } 7275 }, 7276 support = color.support = {}, 7277 7278 // element for support tests 7279 supportElem = jQuery( "<p>" )[ 0 ], 7280 7281 // colors = jQuery.Color.names 7282 colors, 7283 7284 // local aliases of functions called often 7285 each = jQuery.each; 7286 7287// determine rgba support immediately 7288supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 7289support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 7290 7291// define cache name and alpha properties 7292// for rgba and hsla spaces 7293each( spaces, function( spaceName, space ) { 7294 space.cache = "_" + spaceName; 7295 space.props.alpha = { 7296 idx: 3, 7297 type: "percent", 7298 def: 1 7299 }; 7300}); 7301 7302function clamp( value, prop, allowEmpty ) { 7303 var type = propTypes[ prop.type ] || {}; 7304 7305 if ( value == null ) { 7306 return (allowEmpty || !prop.def) ? null : prop.def; 7307 } 7308 7309 // ~~ is an short way of doing floor for positive numbers 7310 value = type.floor ? ~~value : parseFloat( value ); 7311 7312 // IE will pass in empty strings as value for alpha, 7313 // which will hit this case 7314 if ( isNaN( value ) ) { 7315 return prop.def; 7316 } 7317 7318 if ( type.mod ) { 7319 // we add mod before modding to make sure that negatives values 7320 // get converted properly: -10 -> 350 7321 return (value + type.mod) % type.mod; 7322 } 7323 7324 // for now all property types without mod have min and max 7325 return 0 > value ? 0 : type.max < value ? type.max : value; 7326} 7327 7328function stringParse( string ) { 7329 var inst = color(), 7330 rgba = inst._rgba = []; 7331 7332 string = string.toLowerCase(); 7333 7334 each( stringParsers, function( i, parser ) { 7335 var parsed, 7336 match = parser.re.exec( string ), 7337 values = match && parser.parse( match ), 7338 spaceName = parser.space || "rgba"; 7339 7340 if ( values ) { 7341 parsed = inst[ spaceName ]( values ); 7342 7343 // if this was an rgba parse the assignment might happen twice 7344 // oh well.... 7345 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 7346 rgba = inst._rgba = parsed._rgba; 7347 7348 // exit each( stringParsers ) here because we matched 7349 return false; 7350 } 7351 }); 7352 7353 // Found a stringParser that handled it 7354 if ( rgba.length ) { 7355 7356 // if this came from a parsed string, force "transparent" when alpha is 0 7357 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 7358 if ( rgba.join() === "0,0,0,0" ) { 7359 jQuery.extend( rgba, colors.transparent ); 7360 } 7361 return inst; 7362 } 7363 7364 // named colors 7365 return colors[ string ]; 7366} 7367 7368color.fn = jQuery.extend( color.prototype, { 7369 parse: function( red, green, blue, alpha ) { 7370 if ( red === undefined ) { 7371 this._rgba = [ null, null, null, null ]; 7372 return this; 7373 } 7374 if ( red.jquery || red.nodeType ) { 7375 red = jQuery( red ).css( green ); 7376 green = undefined; 7377 } 7378 7379 var inst = this, 7380 type = jQuery.type( red ), 7381 rgba = this._rgba = []; 7382 7383 // more than 1 argument specified - assume ( red, green, blue, alpha ) 7384 if ( green !== undefined ) { 7385 red = [ red, green, blue, alpha ]; 7386 type = "array"; 7387 } 7388 7389 if ( type === "string" ) { 7390 return this.parse( stringParse( red ) || colors._default ); 7391 } 7392 7393 if ( type === "array" ) { 7394 each( spaces.rgba.props, function( key, prop ) { 7395 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 7396 }); 7397 return this; 7398 } 7399 7400 if ( type === "object" ) { 7401 if ( red instanceof color ) { 7402 each( spaces, function( spaceName, space ) { 7403 if ( red[ space.cache ] ) { 7404 inst[ space.cache ] = red[ space.cache ].slice(); 7405 } 7406 }); 7407 } else { 7408 each( spaces, function( spaceName, space ) { 7409 var cache = space.cache; 7410 each( space.props, function( key, prop ) { 7411 7412 // if the cache doesn't exist, and we know how to convert 7413 if ( !inst[ cache ] && space.to ) { 7414 7415 // if the value was null, we don't need to copy it 7416 // if the key was alpha, we don't need to copy it either 7417 if ( key === "alpha" || red[ key ] == null ) { 7418 return; 7419 } 7420 inst[ cache ] = space.to( inst._rgba ); 7421 } 7422 7423 // this is the only case where we allow nulls for ALL properties. 7424 // call clamp with alwaysAllowEmpty 7425 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 7426 }); 7427 7428 // everything defined but alpha? 7429 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 7430 // use the default of 1 7431 inst[ cache ][ 3 ] = 1; 7432 if ( space.from ) { 7433 inst._rgba = space.from( inst[ cache ] ); 7434 } 7435 } 7436 }); 7437 } 7438 return this; 7439 } 7440 }, 7441 is: function( compare ) { 7442 var is = color( compare ), 7443 same = true, 7444 inst = this; 7445 7446 each( spaces, function( _, space ) { 7447 var localCache, 7448 isCache = is[ space.cache ]; 7449 if (isCache) { 7450 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 7451 each( space.props, function( _, prop ) { 7452 if ( isCache[ prop.idx ] != null ) { 7453 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 7454 return same; 7455 } 7456 }); 7457 } 7458 return same; 7459 }); 7460 return same; 7461 }, 7462 _space: function() { 7463 var used = [], 7464 inst = this; 7465 each( spaces, function( spaceName, space ) { 7466 if ( inst[ space.cache ] ) { 7467 used.push( spaceName ); 7468 } 7469 }); 7470 return used.pop(); 7471 }, 7472 transition: function( other, distance ) { 7473 var end = color( other ), 7474 spaceName = end._space(), 7475 space = spaces[ spaceName ], 7476 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 7477 start = startColor[ space.cache ] || space.to( startColor._rgba ), 7478 result = start.slice(); 7479 7480 end = end[ space.cache ]; 7481 each( space.props, function( key, prop ) { 7482 var index = prop.idx, 7483 startValue = start[ index ], 7484 endValue = end[ index ], 7485 type = propTypes[ prop.type ] || {}; 7486 7487 // if null, don't override start value 7488 if ( endValue === null ) { 7489 return; 7490 } 7491 // if null - use end 7492 if ( startValue === null ) { 7493 result[ index ] = endValue; 7494 } else { 7495 if ( type.mod ) { 7496 if ( endValue - startValue > type.mod / 2 ) { 7497 startValue += type.mod; 7498 } else if ( startValue - endValue > type.mod / 2 ) { 7499 startValue -= type.mod; 7500 } 7501 } 7502 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 7503 } 7504 }); 7505 return this[ spaceName ]( result ); 7506 }, 7507 blend: function( opaque ) { 7508 // if we are already opaque - return ourself 7509 if ( this._rgba[ 3 ] === 1 ) { 7510 return this; 7511 } 7512 7513 var rgb = this._rgba.slice(), 7514 a = rgb.pop(), 7515 blend = color( opaque )._rgba; 7516 7517 return color( jQuery.map( rgb, function( v, i ) { 7518 return ( 1 - a ) * blend[ i ] + a * v; 7519 })); 7520 }, 7521 toRgbaString: function() { 7522 var prefix = "rgba(", 7523 rgba = jQuery.map( this._rgba, function( v, i ) { 7524 return v == null ? ( i > 2 ? 1 : 0 ) : v; 7525 }); 7526 7527 if ( rgba[ 3 ] === 1 ) { 7528 rgba.pop(); 7529 prefix = "rgb("; 7530 } 7531 7532 return prefix + rgba.join() + ")"; 7533 }, 7534 toHslaString: function() { 7535 var prefix = "hsla(", 7536 hsla = jQuery.map( this.hsla(), function( v, i ) { 7537 if ( v == null ) { 7538 v = i > 2 ? 1 : 0; 7539 } 7540 7541 // catch 1 and 2 7542 if ( i && i < 3 ) { 7543 v = Math.round( v * 100 ) + "%"; 7544 } 7545 return v; 7546 }); 7547 7548 if ( hsla[ 3 ] === 1 ) { 7549 hsla.pop(); 7550 prefix = "hsl("; 7551 } 7552 return prefix + hsla.join() + ")"; 7553 }, 7554 toHexString: function( includeAlpha ) { 7555 var rgba = this._rgba.slice(), 7556 alpha = rgba.pop(); 7557 7558 if ( includeAlpha ) { 7559 rgba.push( ~~( alpha * 255 ) ); 7560 } 7561 7562 return "#" + jQuery.map( rgba, function( v ) { 7563 7564 // default to 0 when nulls exist 7565 v = ( v || 0 ).toString( 16 ); 7566 return v.length === 1 ? "0" + v : v; 7567 }).join(""); 7568 }, 7569 toString: function() { 7570 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 7571 } 7572}); 7573color.fn.parse.prototype = color.fn; 7574 7575// hsla conversions adapted from: 7576// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 7577 7578function hue2rgb( p, q, h ) { 7579 h = ( h + 1 ) % 1; 7580 if ( h * 6 < 1 ) { 7581 return p + (q - p) * h * 6; 7582 } 7583 if ( h * 2 < 1) { 7584 return q; 7585 } 7586 if ( h * 3 < 2 ) { 7587 return p + (q - p) * ((2/3) - h) * 6; 7588 } 7589 return p; 7590} 7591 7592spaces.hsla.to = function ( rgba ) { 7593 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 7594 return [ null, null, null, rgba[ 3 ] ]; 7595 } 7596 var r = rgba[ 0 ] / 255, 7597 g = rgba[ 1 ] / 255, 7598 b = rgba[ 2 ] / 255, 7599 a = rgba[ 3 ], 7600 max = Math.max( r, g, b ), 7601 min = Math.min( r, g, b ), 7602 diff = max - min, 7603 add = max + min, 7604 l = add * 0.5, 7605 h, s; 7606 7607 if ( min === max ) { 7608 h = 0; 7609 } else if ( r === max ) { 7610 h = ( 60 * ( g - b ) / diff ) + 360; 7611 } else if ( g === max ) { 7612 h = ( 60 * ( b - r ) / diff ) + 120; 7613 } else { 7614 h = ( 60 * ( r - g ) / diff ) + 240; 7615 } 7616 7617 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 7618 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 7619 if ( diff === 0 ) { 7620 s = 0; 7621 } else if ( l <= 0.5 ) { 7622 s = diff / add; 7623 } else { 7624 s = diff / ( 2 - add ); 7625 } 7626 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 7627}; 7628 7629spaces.hsla.from = function ( hsla ) { 7630 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 7631 return [ null, null, null, hsla[ 3 ] ]; 7632 } 7633 var h = hsla[ 0 ] / 360, 7634 s = hsla[ 1 ], 7635 l = hsla[ 2 ], 7636 a = hsla[ 3 ], 7637 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 7638 p = 2 * l - q; 7639 7640 return [ 7641 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 7642 Math.round( hue2rgb( p, q, h ) * 255 ), 7643 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 7644 a 7645 ]; 7646}; 7647 7648 7649each( spaces, function( spaceName, space ) { 7650 var props = space.props, 7651 cache = space.cache, 7652 to = space.to, 7653 from = space.from; 7654 7655 // makes rgba() and hsla() 7656 color.fn[ spaceName ] = function( value ) { 7657 7658 // generate a cache for this space if it doesn't exist 7659 if ( to && !this[ cache ] ) { 7660 this[ cache ] = to( this._rgba ); 7661 } 7662 if ( value === undefined ) { 7663 return this[ cache ].slice(); 7664 } 7665 7666 var ret, 7667 type = jQuery.type( value ), 7668 arr = ( type === "array" || type === "object" ) ? value : arguments, 7669 local = this[ cache ].slice(); 7670 7671 each( props, function( key, prop ) { 7672 var val = arr[ type === "object" ? key : prop.idx ]; 7673 if ( val == null ) { 7674 val = local[ prop.idx ]; 7675 } 7676 local[ prop.idx ] = clamp( val, prop ); 7677 }); 7678 7679 if ( from ) { 7680 ret = color( from( local ) ); 7681 ret[ cache ] = local; 7682 return ret; 7683 } else { 7684 return color( local ); 7685 } 7686 }; 7687 7688 // makes red() green() blue() alpha() hue() saturation() lightness() 7689 each( props, function( key, prop ) { 7690 // alpha is included in more than one space 7691 if ( color.fn[ key ] ) { 7692 return; 7693 } 7694 color.fn[ key ] = function( value ) { 7695 var vtype = jQuery.type( value ), 7696 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 7697 local = this[ fn ](), 7698 cur = local[ prop.idx ], 7699 match; 7700 7701 if ( vtype === "undefined" ) { 7702 return cur; 7703 } 7704 7705 if ( vtype === "function" ) { 7706 value = value.call( this, cur ); 7707 vtype = jQuery.type( value ); 7708 } 7709 if ( value == null && prop.empty ) { 7710 return this; 7711 } 7712 if ( vtype === "string" ) { 7713 match = rplusequals.exec( value ); 7714 if ( match ) { 7715 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 7716 } 7717 } 7718 local[ prop.idx ] = value; 7719 return this[ fn ]( local ); 7720 }; 7721 }); 7722}); 7723 7724// add cssHook and .fx.step function for each named hook. 7725// accept a space separated string of properties 7726color.hook = function( hook ) { 7727 var hooks = hook.split( " " ); 7728 each( hooks, function( i, hook ) { 7729 jQuery.cssHooks[ hook ] = { 7730 set: function( elem, value ) { 7731 var parsed, curElem, 7732 backgroundColor = ""; 7733 7734 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 7735 value = color( parsed || value ); 7736 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 7737 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 7738 while ( 7739 (backgroundColor === "" || backgroundColor === "transparent") && 7740 curElem && curElem.style 7741 ) { 7742 try { 7743 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 7744 curElem = curElem.parentNode; 7745 } catch ( e ) { 7746 } 7747 } 7748 7749 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 7750 backgroundColor : 7751 "_default" ); 7752 } 7753 7754 value = value.toRgbaString(); 7755 } 7756 try { 7757 elem.style[ hook ] = value; 7758 } catch( e ) { 7759 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 7760 } 7761 } 7762 }; 7763 jQuery.fx.step[ hook ] = function( fx ) { 7764 if ( !fx.colorInit ) { 7765 fx.start = color( fx.elem, hook ); 7766 fx.end = color( fx.end ); 7767 fx.colorInit = true; 7768 } 7769 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 7770 }; 7771 }); 7772 7773}; 7774 7775color.hook( stepHooks ); 7776 7777jQuery.cssHooks.borderColor = { 7778 expand: function( value ) { 7779 var expanded = {}; 7780 7781 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 7782 expanded[ "border" + part + "Color" ] = value; 7783 }); 7784 return expanded; 7785 } 7786}; 7787 7788// Basic color names only. 7789// Usage of any of the other color names requires adding yourself or including 7790// jquery.color.svg-names.js. 7791colors = jQuery.Color.names = { 7792 // 4.1. Basic color keywords 7793 aqua: "#00ffff", 7794 black: "#000000", 7795 blue: "#0000ff", 7796 fuchsia: "#ff00ff", 7797 gray: "#808080", 7798 green: "#008000", 7799 lime: "#00ff00", 7800 maroon: "#800000", 7801 navy: "#000080", 7802 olive: "#808000", 7803 purple: "#800080", 7804 red: "#ff0000", 7805 silver: "#c0c0c0", 7806 teal: "#008080", 7807 white: "#ffffff", 7808 yellow: "#ffff00", 7809 7810 // 4.2.3. "transparent" color keyword 7811 transparent: [ null, null, null, 0 ], 7812 7813 _default: "#ffffff" 7814}; 7815 7816})( jQuery ); 7817 7818 7819/******************************************************************************/ 7820/****************************** CLASS ANIMATIONS ******************************/ 7821/******************************************************************************/ 7822(function() { 7823 7824var classAnimationActions = [ "add", "remove", "toggle" ], 7825 shorthandStyles = { 7826 border: 1, 7827 borderBottom: 1, 7828 borderColor: 1, 7829 borderLeft: 1, 7830 borderRight: 1, 7831 borderTop: 1, 7832 borderWidth: 1, 7833 margin: 1, 7834 padding: 1 7835 }; 7836 7837$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 7838 $.fx.step[ prop ] = function( fx ) { 7839 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 7840 jQuery.style( fx.elem, prop, fx.end ); 7841 fx.setAttr = true; 7842 } 7843 }; 7844}); 7845 7846function getElementStyles( elem ) { 7847 var key, len, 7848 style = elem.ownerDocument.defaultView ? 7849 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 7850 elem.currentStyle, 7851 styles = {}; 7852 7853 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 7854 len = style.length; 7855 while ( len-- ) { 7856 key = style[ len ]; 7857 if ( typeof style[ key ] === "string" ) { 7858 styles[ $.camelCase( key ) ] = style[ key ]; 7859 } 7860 } 7861 // support: Opera, IE <9 7862 } else { 7863 for ( key in style ) { 7864 if ( typeof style[ key ] === "string" ) { 7865 styles[ key ] = style[ key ]; 7866 } 7867 } 7868 } 7869 7870 return styles; 7871} 7872 7873 7874function styleDifference( oldStyle, newStyle ) { 7875 var diff = {}, 7876 name, value; 7877 7878 for ( name in newStyle ) { 7879 value = newStyle[ name ]; 7880 if ( oldStyle[ name ] !== value ) { 7881 if ( !shorthandStyles[ name ] ) { 7882 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 7883 diff[ name ] = value; 7884 } 7885 } 7886 } 7887 } 7888 7889 return diff; 7890} 7891 7892// support: jQuery <1.8 7893if ( !$.fn.addBack ) { 7894 $.fn.addBack = function( selector ) { 7895 return this.add( selector == null ? 7896 this.prevObject : this.prevObject.filter( selector ) 7897 ); 7898 }; 7899} 7900 7901$.effects.animateClass = function( value, duration, easing, callback ) { 7902 var o = $.speed( duration, easing, callback ); 7903 7904 return this.queue( function() { 7905 var animated = $( this ), 7906 baseClass = animated.attr( "class" ) || "", 7907 applyClassChange, 7908 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 7909 7910 // map the animated objects to store the original styles. 7911 allAnimations = allAnimations.map(function() { 7912 var el = $( this ); 7913 return { 7914 el: el, 7915 start: getElementStyles( this ) 7916 }; 7917 }); 7918 7919 // apply class change 7920 applyClassChange = function() { 7921 $.each( classAnimationActions, function(i, action) { 7922 if ( value[ action ] ) { 7923 animated[ action + "Class" ]( value[ action ] ); 7924 } 7925 }); 7926 }; 7927 applyClassChange(); 7928 7929 // map all animated objects again - calculate new styles and diff 7930 allAnimations = allAnimations.map(function() { 7931 this.end = getElementStyles( this.el[ 0 ] ); 7932 this.diff = styleDifference( this.start, this.end ); 7933 return this; 7934 }); 7935 7936 // apply original class 7937 animated.attr( "class", baseClass ); 7938 7939 // map all animated objects again - this time collecting a promise 7940 allAnimations = allAnimations.map(function() { 7941 var styleInfo = this, 7942 dfd = $.Deferred(), 7943 opts = $.extend({}, o, { 7944 queue: false, 7945 complete: function() { 7946 dfd.resolve( styleInfo ); 7947 } 7948 }); 7949 7950 this.el.animate( this.diff, opts ); 7951 return dfd.promise(); 7952 }); 7953 7954 // once all animations have completed: 7955 $.when.apply( $, allAnimations.get() ).done(function() { 7956 7957 // set the final class 7958 applyClassChange(); 7959 7960 // for each animated element, 7961 // clear all css properties that were animated 7962 $.each( arguments, function() { 7963 var el = this.el; 7964 $.each( this.diff, function(key) { 7965 el.css( key, "" ); 7966 }); 7967 }); 7968 7969 // this is guarnteed to be there if you use jQuery.speed() 7970 // it also handles dequeuing the next anim... 7971 o.complete.call( animated[ 0 ] ); 7972 }); 7973 }); 7974}; 7975 7976$.fn.extend({ 7977 addClass: (function( orig ) { 7978 return function( classNames, speed, easing, callback ) { 7979 return speed ? 7980 $.effects.animateClass.call( this, 7981 { add: classNames }, speed, easing, callback ) : 7982 orig.apply( this, arguments ); 7983 }; 7984 })( $.fn.addClass ), 7985 7986 removeClass: (function( orig ) { 7987 return function( classNames, speed, easing, callback ) { 7988 return arguments.length > 1 ? 7989 $.effects.animateClass.call( this, 7990 { remove: classNames }, speed, easing, callback ) : 7991 orig.apply( this, arguments ); 7992 }; 7993 })( $.fn.removeClass ), 7994 7995 toggleClass: (function( orig ) { 7996 return function( classNames, force, speed, easing, callback ) { 7997 if ( typeof force === "boolean" || force === undefined ) { 7998 if ( !speed ) { 7999 // without speed parameter 8000 return orig.apply( this, arguments ); 8001 } else { 8002 return $.effects.animateClass.call( this, 8003 (force ? { add: classNames } : { remove: classNames }), 8004 speed, easing, callback ); 8005 } 8006 } else { 8007 // without force parameter 8008 return $.effects.animateClass.call( this, 8009 { toggle: classNames }, force, speed, easing ); 8010 } 8011 }; 8012 })( $.fn.toggleClass ), 8013 8014 switchClass: function( remove, add, speed, easing, callback) { 8015 return $.effects.animateClass.call( this, { 8016 add: add, 8017 remove: remove 8018 }, speed, easing, callback ); 8019 } 8020}); 8021 8022})(); 8023 8024/******************************************************************************/ 8025/*********************************** EFFECTS **********************************/ 8026/******************************************************************************/ 8027 8028(function() { 8029 8030$.extend( $.effects, { 8031 version: "1.10.4", 8032 8033 // Saves a set of properties in a data storage 8034 save: function( element, set ) { 8035 for( var i=0; i < set.length; i++ ) { 8036 if ( set[ i ] !== null ) { 8037 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 8038 } 8039 } 8040 }, 8041 8042 // Restores a set of previously saved properties from a data storage 8043 restore: function( element, set ) { 8044 var val, i; 8045 for( i=0; i < set.length; i++ ) { 8046 if ( set[ i ] !== null ) { 8047 val = element.data( dataSpace + set[ i ] ); 8048 // support: jQuery 1.6.2 8049 // http://bugs.jquery.com/ticket/9917 8050 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 8051 // We can't differentiate between "" and 0 here, so we just assume 8052 // empty string since it's likely to be a more common value... 8053 if ( val === undefined ) { 8054 val = ""; 8055 } 8056 element.css( set[ i ], val ); 8057 } 8058 } 8059 }, 8060 8061 setMode: function( el, mode ) { 8062 if (mode === "toggle") { 8063 mode = el.is( ":hidden" ) ? "show" : "hide"; 8064 } 8065 return mode; 8066 }, 8067 8068 // Translates a [top,left] array into a baseline value 8069 // this should be a little more flexible in the future to handle a string & hash 8070 getBaseline: function( origin, original ) { 8071 var y, x; 8072 switch ( origin[ 0 ] ) { 8073 case "top": y = 0; break; 8074 case "middle": y = 0.5; break; 8075 case "bottom": y = 1; break; 8076 default: y = origin[ 0 ] / original.height; 8077 } 8078 switch ( origin[ 1 ] ) { 8079 case "left": x = 0; break; 8080 case "center": x = 0.5; break; 8081 case "right": x = 1; break; 8082 default: x = origin[ 1 ] / original.width; 8083 } 8084 return { 8085 x: x, 8086 y: y 8087 }; 8088 }, 8089 8090 // Wraps the element around a wrapper that copies position properties 8091 createWrapper: function( element ) { 8092 8093 // if the element is already wrapped, return it 8094 if ( element.parent().is( ".ui-effects-wrapper" )) { 8095 return element.parent(); 8096 } 8097 8098 // wrap the element 8099 var props = { 8100 width: element.outerWidth(true), 8101 height: element.outerHeight(true), 8102 "float": element.css( "float" ) 8103 }, 8104 wrapper = $( "<div></div>" ) 8105 .addClass( "ui-effects-wrapper" ) 8106 .css({ 8107 fontSize: "100%", 8108 background: "transparent", 8109 border: "none", 8110 margin: 0, 8111 padding: 0 8112 }), 8113 // Store the size in case width/height are defined in % - Fixes #5245 8114 size = { 8115 width: element.width(), 8116 height: element.height() 8117 }, 8118 active = document.activeElement; 8119 8120 // support: Firefox 8121 // Firefox incorrectly exposes anonymous content 8122 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 8123 try { 8124 active.id; 8125 } catch( e ) { 8126 active = document.body; 8127 } 8128 8129 element.wrap( wrapper ); 8130 8131 // Fixes #7595 - Elements lose focus when wrapped. 8132 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 8133 $( active ).focus(); 8134 } 8135 8136 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 8137 8138 // transfer positioning properties to the wrapper 8139 if ( element.css( "position" ) === "static" ) { 8140 wrapper.css({ position: "relative" }); 8141 element.css({ position: "relative" }); 8142 } else { 8143 $.extend( props, { 8144 position: element.css( "position" ), 8145 zIndex: element.css( "z-index" ) 8146 }); 8147 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 8148 props[ pos ] = element.css( pos ); 8149 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 8150 props[ pos ] = "auto"; 8151 } 8152 }); 8153 element.css({ 8154 position: "relative", 8155 top: 0, 8156 left: 0, 8157 right: "auto", 8158 bottom: "auto" 8159 }); 8160 } 8161 element.css(size); 8162 8163 return wrapper.css( props ).show(); 8164 }, 8165 8166 removeWrapper: function( element ) { 8167 var active = document.activeElement; 8168 8169 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 8170 element.parent().replaceWith( element ); 8171 8172 // Fixes #7595 - Elements lose focus when wrapped. 8173 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 8174 $( active ).focus(); 8175 } 8176 } 8177 8178 8179 return element; 8180 }, 8181 8182 setTransition: function( element, list, factor, value ) { 8183 value = value || {}; 8184 $.each( list, function( i, x ) { 8185 var unit = element.cssUnit( x ); 8186 if ( unit[ 0 ] > 0 ) { 8187 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 8188 } 8189 }); 8190 return value; 8191 } 8192}); 8193 8194// return an effect options object for the given parameters: 8195function _normalizeArguments( effect, options, speed, callback ) { 8196 8197 // allow passing all options as the first parameter 8198 if ( $.isPlainObject( effect ) ) { 8199 options = effect; 8200 effect = effect.effect; 8201 } 8202 8203 // convert to an object 8204 effect = { effect: effect }; 8205 8206 // catch (effect, null, ...) 8207 if ( options == null ) { 8208 options = {}; 8209 } 8210 8211 // catch (effect, callback) 8212 if ( $.isFunction( options ) ) { 8213 callback = options; 8214 speed = null; 8215 options = {}; 8216 } 8217 8218 // catch (effect, speed, ?) 8219 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 8220 callback = speed; 8221 speed = options; 8222 options = {}; 8223 } 8224 8225 // catch (effect, options, callback) 8226 if ( $.isFunction( speed ) ) { 8227 callback = speed; 8228 speed = null; 8229 } 8230 8231 // add options to effect 8232 if ( options ) { 8233 $.extend( effect, options ); 8234 } 8235 8236 speed = speed || options.duration; 8237 effect.duration = $.fx.off ? 0 : 8238 typeof speed === "number" ? speed : 8239 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 8240 $.fx.speeds._default; 8241 8242 effect.complete = callback || options.complete; 8243 8244 return effect; 8245} 8246 8247function standardAnimationOption( option ) { 8248 // Valid standard speeds (nothing, number, named speed) 8249 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 8250 return true; 8251 } 8252 8253 // Invalid strings - treat as "normal" speed 8254 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 8255 return true; 8256 } 8257 8258 // Complete callback 8259 if ( $.isFunction( option ) ) { 8260 return true; 8261 } 8262 8263 // Options hash (but not naming an effect) 8264 if ( typeof option === "object" && !option.effect ) { 8265 return true; 8266 } 8267 8268 // Didn't match any standard API 8269 return false; 8270} 8271 8272$.fn.extend({ 8273 effect: function( /* effect, options, speed, callback */ ) { 8274 var args = _normalizeArguments.apply( this, arguments ), 8275 mode = args.mode, 8276 queue = args.queue, 8277 effectMethod = $.effects.effect[ args.effect ]; 8278 8279 if ( $.fx.off || !effectMethod ) { 8280 // delegate to the original method (e.g., .show()) if possible 8281 if ( mode ) { 8282 return this[ mode ]( args.duration, args.complete ); 8283 } else { 8284 return this.each( function() { 8285 if ( args.complete ) { 8286 args.complete.call( this ); 8287 } 8288 }); 8289 } 8290 } 8291 8292 function run( next ) { 8293 var elem = $( this ), 8294 complete = args.complete, 8295 mode = args.mode; 8296 8297 function done() { 8298 if ( $.isFunction( complete ) ) { 8299 complete.call( elem[0] ); 8300 } 8301 if ( $.isFunction( next ) ) { 8302 next(); 8303 } 8304 } 8305 8306 // If the element already has the correct final state, delegate to 8307 // the core methods so the internal tracking of "olddisplay" works. 8308 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 8309 elem[ mode ](); 8310 done(); 8311 } else { 8312 effectMethod.call( elem[0], args, done ); 8313 } 8314 } 8315 8316 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 8317 }, 8318 8319 show: (function( orig ) { 8320 return function( option ) { 8321 if ( standardAnimationOption( option ) ) { 8322 return orig.apply( this, arguments ); 8323 } else { 8324 var args = _normalizeArguments.apply( this, arguments ); 8325 args.mode = "show"; 8326 return this.effect.call( this, args ); 8327 } 8328 }; 8329 })( $.fn.show ), 8330 8331 hide: (function( orig ) { 8332 return function( option ) { 8333 if ( standardAnimationOption( option ) ) { 8334 return orig.apply( this, arguments ); 8335 } else { 8336 var args = _normalizeArguments.apply( this, arguments ); 8337 args.mode = "hide"; 8338 return this.effect.call( this, args ); 8339 } 8340 }; 8341 })( $.fn.hide ), 8342 8343 toggle: (function( orig ) { 8344 return function( option ) { 8345 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 8346 return orig.apply( this, arguments ); 8347 } else { 8348 var args = _normalizeArguments.apply( this, arguments ); 8349 args.mode = "toggle"; 8350 return this.effect.call( this, args ); 8351 } 8352 }; 8353 })( $.fn.toggle ), 8354 8355 // helper functions 8356 cssUnit: function(key) { 8357 var style = this.css( key ), 8358 val = []; 8359 8360 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 8361 if ( style.indexOf( unit ) > 0 ) { 8362 val = [ parseFloat( style ), unit ]; 8363 } 8364 }); 8365 return val; 8366 } 8367}); 8368 8369})(); 8370 8371/******************************************************************************/ 8372/*********************************** EASING ***********************************/ 8373/******************************************************************************/ 8374 8375(function() { 8376 8377// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 8378 8379var baseEasings = {}; 8380 8381$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 8382 baseEasings[ name ] = function( p ) { 8383 return Math.pow( p, i + 2 ); 8384 }; 8385}); 8386 8387$.extend( baseEasings, { 8388 Sine: function ( p ) { 8389 return 1 - Math.cos( p * Math.PI / 2 ); 8390 }, 8391 Circ: function ( p ) { 8392 return 1 - Math.sqrt( 1 - p * p ); 8393 }, 8394 Elastic: function( p ) { 8395 return p === 0 || p === 1 ? p : 8396 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 8397 }, 8398 Back: function( p ) { 8399 return p * p * ( 3 * p - 2 ); 8400 }, 8401 Bounce: function ( p ) { 8402 var pow2, 8403 bounce = 4; 8404 8405 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 8406 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 8407 } 8408}); 8409 8410$.each( baseEasings, function( name, easeIn ) { 8411 $.easing[ "easeIn" + name ] = easeIn; 8412 $.easing[ "easeOut" + name ] = function( p ) { 8413 return 1 - easeIn( 1 - p ); 8414 }; 8415 $.easing[ "easeInOut" + name ] = function( p ) { 8416 return p < 0.5 ? 8417 easeIn( p * 2 ) / 2 : 8418 1 - easeIn( p * -2 + 2 ) / 2; 8419 }; 8420}); 8421 8422})(); 8423 8424})(jQuery); 8425(function( $, undefined ) { 8426 8427var rvertical = /up|down|vertical/, 8428 rpositivemotion = /up|left|vertical|horizontal/; 8429 8430$.effects.effect.blind = function( o, done ) { 8431 // Create element 8432 var el = $( this ), 8433 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 8434 mode = $.effects.setMode( el, o.mode || "hide" ), 8435 direction = o.direction || "up", 8436 vertical = rvertical.test( direction ), 8437 ref = vertical ? "height" : "width", 8438 ref2 = vertical ? "top" : "left", 8439 motion = rpositivemotion.test( direction ), 8440 animation = {}, 8441 show = mode === "show", 8442 wrapper, distance, margin; 8443 8444 // if already wrapped, the wrapper's properties are my property. #6245 8445 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 8446 $.effects.save( el.parent(), props ); 8447 } else { 8448 $.effects.save( el, props ); 8449 } 8450 el.show(); 8451 wrapper = $.effects.createWrapper( el ).css({ 8452 overflow: "hidden" 8453 }); 8454 8455 distance = wrapper[ ref ](); 8456 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 8457 8458 animation[ ref ] = show ? distance : 0; 8459 if ( !motion ) { 8460 el 8461 .css( vertical ? "bottom" : "right", 0 ) 8462 .css( vertical ? "top" : "left", "auto" ) 8463 .css({ position: "absolute" }); 8464 8465 animation[ ref2 ] = show ? margin : distance + margin; 8466 } 8467 8468 // start at 0 if we are showing 8469 if ( show ) { 8470 wrapper.css( ref, 0 ); 8471 if ( ! motion ) { 8472 wrapper.css( ref2, margin + distance ); 8473 } 8474 } 8475 8476 // Animate 8477 wrapper.animate( animation, { 8478 duration: o.duration, 8479 easing: o.easing, 8480 queue: false, 8481 complete: function() { 8482 if ( mode === "hide" ) { 8483 el.hide(); 8484 } 8485 $.effects.restore( el, props ); 8486 $.effects.removeWrapper( el ); 8487 done(); 8488 } 8489 }); 8490 8491}; 8492 8493})(jQuery); 8494(function( $, undefined ) { 8495 8496$.effects.effect.bounce = function( o, done ) { 8497 var el = $( this ), 8498 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 8499 8500 // defaults: 8501 mode = $.effects.setMode( el, o.mode || "effect" ), 8502 hide = mode === "hide", 8503 show = mode === "show", 8504 direction = o.direction || "up", 8505 distance = o.distance, 8506 times = o.times || 5, 8507 8508 // number of internal animations 8509 anims = times * 2 + ( show || hide ? 1 : 0 ), 8510 speed = o.duration / anims, 8511 easing = o.easing, 8512 8513 // utility: 8514 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 8515 motion = ( direction === "up" || direction === "left" ), 8516 i, 8517 upAnim, 8518 downAnim, 8519 8520 // we will need to re-assemble the queue to stack our animations in place 8521 queue = el.queue(), 8522 queuelen = queue.length; 8523 8524 // Avoid touching opacity to prevent clearType and PNG issues in IE 8525 if ( show || hide ) { 8526 props.push( "opacity" ); 8527 } 8528 8529 $.effects.save( el, props ); 8530 el.show(); 8531 $.effects.createWrapper( el ); // Create Wrapper 8532 8533 // default distance for the BIGGEST bounce is the outer Distance / 3 8534 if ( !distance ) { 8535 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 8536 } 8537 8538 if ( show ) { 8539 downAnim = { opacity: 1 }; 8540 downAnim[ ref ] = 0; 8541 8542 // if we are showing, force opacity 0 and set the initial position 8543 // then do the "first" animation 8544 el.css( "opacity", 0 ) 8545 .css( ref, motion ? -distance * 2 : distance * 2 ) 8546 .animate( downAnim, speed, easing ); 8547 } 8548 8549 // start at the smallest distance if we are hiding 8550 if ( hide ) { 8551 distance = distance / Math.pow( 2, times - 1 ); 8552 } 8553 8554 downAnim = {}; 8555 downAnim[ ref ] = 0; 8556 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 8557 for ( i = 0; i < times; i++ ) { 8558 upAnim = {}; 8559 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 8560 8561 el.animate( upAnim, speed, easing ) 8562 .animate( downAnim, speed, easing ); 8563 8564 distance = hide ? distance * 2 : distance / 2; 8565 } 8566 8567 // Last Bounce when Hiding 8568 if ( hide ) { 8569 upAnim = { opacity: 0 }; 8570 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 8571 8572 el.animate( upAnim, speed, easing ); 8573 } 8574 8575 el.queue(function() { 8576 if ( hide ) { 8577 el.hide(); 8578 } 8579 $.effects.restore( el, props ); 8580 $.effects.removeWrapper( el ); 8581 done(); 8582 }); 8583 8584 // inject all the animations we just queued to be first in line (after "inprogress") 8585 if ( queuelen > 1) { 8586 queue.splice.apply( queue, 8587 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 8588 } 8589 el.dequeue(); 8590 8591}; 8592 8593})(jQuery); 8594(function( $, undefined ) { 8595 8596$.effects.effect.clip = function( o, done ) { 8597 // Create element 8598 var el = $( this ), 8599 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 8600 mode = $.effects.setMode( el, o.mode || "hide" ), 8601 show = mode === "show", 8602 direction = o.direction || "vertical", 8603 vert = direction === "vertical", 8604 size = vert ? "height" : "width", 8605 position = vert ? "top" : "left", 8606 animation = {}, 8607 wrapper, animate, distance; 8608 8609 // Save & Show 8610 $.effects.save( el, props ); 8611 el.show(); 8612 8613 // Create Wrapper 8614 wrapper = $.effects.createWrapper( el ).css({ 8615 overflow: "hidden" 8616 }); 8617 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 8618 distance = animate[ size ](); 8619 8620 // Shift 8621 if ( show ) { 8622 animate.css( size, 0 ); 8623 animate.css( position, distance / 2 ); 8624 } 8625 8626 // Create Animation Object: 8627 animation[ size ] = show ? distance : 0; 8628 animation[ position ] = show ? 0 : distance / 2; 8629 8630 // Animate 8631 animate.animate( animation, { 8632 queue: false, 8633 duration: o.duration, 8634 easing: o.easing, 8635 complete: function() { 8636 if ( !show ) { 8637 el.hide(); 8638 } 8639 $.effects.restore( el, props ); 8640 $.effects.removeWrapper( el ); 8641 done(); 8642 } 8643 }); 8644 8645}; 8646 8647})(jQuery); 8648(function( $, undefined ) { 8649 8650$.effects.effect.drop = function( o, done ) { 8651 8652 var el = $( this ), 8653 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 8654 mode = $.effects.setMode( el, o.mode || "hide" ), 8655 show = mode === "show", 8656 direction = o.direction || "left", 8657 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 8658 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 8659 animation = { 8660 opacity: show ? 1 : 0 8661 }, 8662 distance; 8663 8664 // Adjust 8665 $.effects.save( el, props ); 8666 el.show(); 8667 $.effects.createWrapper( el ); 8668 8669 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 8670 8671 if ( show ) { 8672 el 8673 .css( "opacity", 0 ) 8674 .css( ref, motion === "pos" ? -distance : distance ); 8675 } 8676 8677 // Animation 8678 animation[ ref ] = ( show ? 8679 ( motion === "pos" ? "+=" : "-=" ) : 8680 ( motion === "pos" ? "-=" : "+=" ) ) + 8681 distance; 8682 8683 // Animate 8684 el.animate( animation, { 8685 queue: false, 8686 duration: o.duration, 8687 easing: o.easing, 8688 complete: function() { 8689 if ( mode === "hide" ) { 8690 el.hide(); 8691 } 8692 $.effects.restore( el, props ); 8693 $.effects.removeWrapper( el ); 8694 done(); 8695 } 8696 }); 8697}; 8698 8699})(jQuery); 8700(function( $, undefined ) { 8701 8702$.effects.effect.explode = function( o, done ) { 8703 8704 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 8705 cells = rows, 8706 el = $( this ), 8707 mode = $.effects.setMode( el, o.mode || "hide" ), 8708 show = mode === "show", 8709 8710 // show and then visibility:hidden the element before calculating offset 8711 offset = el.show().css( "visibility", "hidden" ).offset(), 8712 8713 // width and height of a piece 8714 width = Math.ceil( el.outerWidth() / cells ), 8715 height = Math.ceil( el.outerHeight() / rows ), 8716 pieces = [], 8717 8718 // loop 8719 i, j, left, top, mx, my; 8720 8721 // children animate complete: 8722 function childComplete() { 8723 pieces.push( this ); 8724 if ( pieces.length === rows * cells ) { 8725 animComplete(); 8726 } 8727 } 8728 8729 // clone the element for each row and cell. 8730 for( i = 0; i < rows ; i++ ) { // ===> 8731 top = offset.top + i * height; 8732 my = i - ( rows - 1 ) / 2 ; 8733 8734 for( j = 0; j < cells ; j++ ) { // ||| 8735 left = offset.left + j * width; 8736 mx = j - ( cells - 1 ) / 2 ; 8737 8738 // Create a clone of the now hidden main element that will be absolute positioned 8739 // within a wrapper div off the -left and -top equal to size of our pieces 8740 el 8741 .clone() 8742 .appendTo( "body" ) 8743 .wrap( "<div></div>" ) 8744 .css({ 8745 position: "absolute", 8746 visibility: "visible", 8747 left: -j * width, 8748 top: -i * height 8749 }) 8750 8751 // select the wrapper - make it overflow: hidden and absolute positioned based on 8752 // where the original was located +left and +top equal to the size of pieces 8753 .parent() 8754 .addClass( "ui-effects-explode" ) 8755 .css({ 8756 position: "absolute", 8757 overflow: "hidden", 8758 width: width, 8759 height: height, 8760 left: left + ( show ? mx * width : 0 ), 8761 top: top + ( show ? my * height : 0 ), 8762 opacity: show ? 0 : 1 8763 }).animate({ 8764 left: left + ( show ? 0 : mx * width ), 8765 top: top + ( show ? 0 : my * height ), 8766 opacity: show ? 1 : 0 8767 }, o.duration || 500, o.easing, childComplete ); 8768 } 8769 } 8770 8771 function animComplete() { 8772 el.css({ 8773 visibility: "visible" 8774 }); 8775 $( pieces ).remove(); 8776 if ( !show ) { 8777 el.hide(); 8778 } 8779 done(); 8780 } 8781}; 8782 8783})(jQuery); 8784(function( $, undefined ) { 8785 8786$.effects.effect.fade = function( o, done ) { 8787 var el = $( this ), 8788 mode = $.effects.setMode( el, o.mode || "toggle" ); 8789 8790 el.animate({ 8791 opacity: mode 8792 }, { 8793 queue: false, 8794 duration: o.duration, 8795 easing: o.easing, 8796 complete: done 8797 }); 8798}; 8799 8800})( jQuery ); 8801(function( $, undefined ) { 8802 8803$.effects.effect.fold = function( o, done ) { 8804 8805 // Create element 8806 var el = $( this ), 8807 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 8808 mode = $.effects.setMode( el, o.mode || "hide" ), 8809 show = mode === "show", 8810 hide = mode === "hide", 8811 size = o.size || 15, 8812 percent = /([0-9]+)%/.exec( size ), 8813 horizFirst = !!o.horizFirst, 8814 widthFirst = show !== horizFirst, 8815 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 8816 duration = o.duration / 2, 8817 wrapper, distance, 8818 animation1 = {}, 8819 animation2 = {}; 8820 8821 $.effects.save( el, props ); 8822 el.show(); 8823 8824 // Create Wrapper 8825 wrapper = $.effects.createWrapper( el ).css({ 8826 overflow: "hidden" 8827 }); 8828 distance = widthFirst ? 8829 [ wrapper.width(), wrapper.height() ] : 8830 [ wrapper.height(), wrapper.width() ]; 8831 8832 if ( percent ) { 8833 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 8834 } 8835 if ( show ) { 8836 wrapper.css( horizFirst ? { 8837 height: 0, 8838 width: size 8839 } : { 8840 height: size, 8841 width: 0 8842 }); 8843 } 8844 8845 // Animation 8846 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 8847 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 8848 8849 // Animate 8850 wrapper 8851 .animate( animation1, duration, o.easing ) 8852 .animate( animation2, duration, o.easing, function() { 8853 if ( hide ) { 8854 el.hide(); 8855 } 8856 $.effects.restore( el, props ); 8857 $.effects.removeWrapper( el ); 8858 done(); 8859 }); 8860 8861}; 8862 8863})(jQuery); 8864(function( $, undefined ) { 8865 8866$.effects.effect.highlight = function( o, done ) { 8867 var elem = $( this ), 8868 props = [ "backgroundImage", "backgroundColor", "opacity" ], 8869 mode = $.effects.setMode( elem, o.mode || "show" ), 8870 animation = { 8871 backgroundColor: elem.css( "backgroundColor" ) 8872 }; 8873 8874 if (mode === "hide") { 8875 animation.opacity = 0; 8876 } 8877 8878 $.effects.save( elem, props ); 8879 8880 elem 8881 .show() 8882 .css({ 8883 backgroundImage: "none", 8884 backgroundColor: o.color || "#ffff99" 8885 }) 8886 .animate( animation, { 8887 queue: false, 8888 duration: o.duration, 8889 easing: o.easing, 8890 complete: function() { 8891 if ( mode === "hide" ) { 8892 elem.hide(); 8893 } 8894 $.effects.restore( elem, props ); 8895 done(); 8896 } 8897 }); 8898}; 8899 8900})(jQuery); 8901(function( $, undefined ) { 8902 8903$.effects.effect.pulsate = function( o, done ) { 8904 var elem = $( this ), 8905 mode = $.effects.setMode( elem, o.mode || "show" ), 8906 show = mode === "show", 8907 hide = mode === "hide", 8908 showhide = ( show || mode === "hide" ), 8909 8910 // showing or hiding leaves of the "last" animation 8911 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 8912 duration = o.duration / anims, 8913 animateTo = 0, 8914 queue = elem.queue(), 8915 queuelen = queue.length, 8916 i; 8917 8918 if ( show || !elem.is(":visible")) { 8919 elem.css( "opacity", 0 ).show(); 8920 animateTo = 1; 8921 } 8922 8923 // anims - 1 opacity "toggles" 8924 for ( i = 1; i < anims; i++ ) { 8925 elem.animate({ 8926 opacity: animateTo 8927 }, duration, o.easing ); 8928 animateTo = 1 - animateTo; 8929 } 8930 8931 elem.animate({ 8932 opacity: animateTo 8933 }, duration, o.easing); 8934 8935 elem.queue(function() { 8936 if ( hide ) { 8937 elem.hide(); 8938 } 8939 done(); 8940 }); 8941 8942 // We just queued up "anims" animations, we need to put them next in the queue 8943 if ( queuelen > 1 ) { 8944 queue.splice.apply( queue, 8945 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 8946 } 8947 elem.dequeue(); 8948}; 8949 8950})(jQuery); 8951(function( $, undefined ) { 8952 8953$.effects.effect.puff = function( o, done ) { 8954 var elem = $( this ), 8955 mode = $.effects.setMode( elem, o.mode || "hide" ), 8956 hide = mode === "hide", 8957 percent = parseInt( o.percent, 10 ) || 150, 8958 factor = percent / 100, 8959 original = { 8960 height: elem.height(), 8961 width: elem.width(), 8962 outerHeight: elem.outerHeight(), 8963 outerWidth: elem.outerWidth() 8964 }; 8965 8966 $.extend( o, { 8967 effect: "scale", 8968 queue: false, 8969 fade: true, 8970 mode: mode, 8971 complete: done, 8972 percent: hide ? percent : 100, 8973 from: hide ? 8974 original : 8975 { 8976 height: original.height * factor, 8977 width: original.width * factor, 8978 outerHeight: original.outerHeight * factor, 8979 outerWidth: original.outerWidth * factor 8980 } 8981 }); 8982 8983 elem.effect( o ); 8984}; 8985 8986$.effects.effect.scale = function( o, done ) { 8987 8988 // Create element 8989 var el = $( this ), 8990 options = $.extend( true, {}, o ), 8991 mode = $.effects.setMode( el, o.mode || "effect" ), 8992 percent = parseInt( o.percent, 10 ) || 8993 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 8994 direction = o.direction || "both", 8995 origin = o.origin, 8996 original = { 8997 height: el.height(), 8998 width: el.width(), 8999 outerHeight: el.outerHeight(), 9000 outerWidth: el.outerWidth() 9001 }, 9002 factor = { 9003 y: direction !== "horizontal" ? (percent / 100) : 1, 9004 x: direction !== "vertical" ? (percent / 100) : 1 9005 }; 9006 9007 // We are going to pass this effect to the size effect: 9008 options.effect = "size"; 9009 options.queue = false; 9010 options.complete = done; 9011 9012 // Set default origin and restore for show/hide 9013 if ( mode !== "effect" ) { 9014 options.origin = origin || ["middle","center"]; 9015 options.restore = true; 9016 } 9017 9018 options.from = o.from || ( mode === "show" ? { 9019 height: 0, 9020 width: 0, 9021 outerHeight: 0, 9022 outerWidth: 0 9023 } : original ); 9024 options.to = { 9025 height: original.height * factor.y, 9026 width: original.width * factor.x, 9027 outerHeight: original.outerHeight * factor.y, 9028 outerWidth: original.outerWidth * factor.x 9029 }; 9030 9031 // Fade option to support puff 9032 if ( options.fade ) { 9033 if ( mode === "show" ) { 9034 options.from.opacity = 0; 9035 options.to.opacity = 1; 9036 } 9037 if ( mode === "hide" ) { 9038 options.from.opacity = 1; 9039 options.to.opacity = 0; 9040 } 9041 } 9042 9043 // Animate 9044 el.effect( options ); 9045 9046}; 9047 9048$.effects.effect.size = function( o, done ) { 9049 9050 // Create element 9051 var original, baseline, factor, 9052 el = $( this ), 9053 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 9054 9055 // Always restore 9056 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 9057 9058 // Copy for children 9059 props2 = [ "width", "height", "overflow" ], 9060 cProps = [ "fontSize" ], 9061 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 9062 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 9063 9064 // Set options 9065 mode = $.effects.setMode( el, o.mode || "effect" ), 9066 restore = o.restore || mode !== "effect", 9067 scale = o.scale || "both", 9068 origin = o.origin || [ "middle", "center" ], 9069 position = el.css( "position" ), 9070 props = restore ? props0 : props1, 9071 zero = { 9072 height: 0, 9073 width: 0, 9074 outerHeight: 0, 9075 outerWidth: 0 9076 }; 9077 9078 if ( mode === "show" ) { 9079 el.show(); 9080 } 9081 original = { 9082 height: el.height(), 9083 width: el.width(), 9084 outerHeight: el.outerHeight(), 9085 outerWidth: el.outerWidth() 9086 }; 9087 9088 if ( o.mode === "toggle" && mode === "show" ) { 9089 el.from = o.to || zero; 9090 el.to = o.from || original; 9091 } else { 9092 el.from = o.from || ( mode === "show" ? zero : original ); 9093 el.to = o.to || ( mode === "hide" ? zero : original ); 9094 } 9095 9096 // Set scaling factor 9097 factor = { 9098 from: { 9099 y: el.from.height / original.height, 9100 x: el.from.width / original.width 9101 }, 9102 to: { 9103 y: el.to.height / original.height, 9104 x: el.to.width / original.width 9105 } 9106 }; 9107 9108 // Scale the css box 9109 if ( scale === "box" || scale === "both" ) { 9110 9111 // Vertical props scaling 9112 if ( factor.from.y !== factor.to.y ) { 9113 props = props.concat( vProps ); 9114 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 9115 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 9116 } 9117 9118 // Horizontal props scaling 9119 if ( factor.from.x !== factor.to.x ) { 9120 props = props.concat( hProps ); 9121 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 9122 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 9123 } 9124 } 9125 9126 // Scale the content 9127 if ( scale === "content" || scale === "both" ) { 9128 9129 // Vertical props scaling 9130 if ( factor.from.y !== factor.to.y ) { 9131 props = props.concat( cProps ).concat( props2 ); 9132 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 9133 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 9134 } 9135 } 9136 9137 $.effects.save( el, props ); 9138 el.show(); 9139 $.effects.createWrapper( el ); 9140 el.css( "overflow", "hidden" ).css( el.from ); 9141 9142 // Adjust 9143 if (origin) { // Calculate baseline shifts 9144 baseline = $.effects.getBaseline( origin, original ); 9145 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 9146 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 9147 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 9148 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 9149 } 9150 el.css( el.from ); // set top & left 9151 9152 // Animate 9153 if ( scale === "content" || scale === "both" ) { // Scale the children 9154 9155 // Add margins/font-size 9156 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 9157 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 9158 props2 = props0.concat(vProps).concat(hProps); 9159 9160 el.find( "*[width]" ).each( function(){ 9161 var child = $( this ), 9162 c_original = { 9163 height: child.height(), 9164 width: child.width(), 9165 outerHeight: child.outerHeight(), 9166 outerWidth: child.outerWidth() 9167 }; 9168 if (restore) { 9169 $.effects.save(child, props2); 9170 } 9171 9172 child.from = { 9173 height: c_original.height * factor.from.y, 9174 width: c_original.width * factor.from.x, 9175 outerHeight: c_original.outerHeight * factor.from.y, 9176 outerWidth: c_original.outerWidth * factor.from.x 9177 }; 9178 child.to = { 9179 height: c_original.height * factor.to.y, 9180 width: c_original.width * factor.to.x, 9181 outerHeight: c_original.height * factor.to.y, 9182 outerWidth: c_original.width * factor.to.x 9183 }; 9184 9185 // Vertical props scaling 9186 if ( factor.from.y !== factor.to.y ) { 9187 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 9188 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 9189 } 9190 9191 // Horizontal props scaling 9192 if ( factor.from.x !== factor.to.x ) { 9193 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 9194 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 9195 } 9196 9197 // Animate children 9198 child.css( child.from ); 9199 child.animate( child.to, o.duration, o.easing, function() { 9200 9201 // Restore children 9202 if ( restore ) { 9203 $.effects.restore( child, props2 ); 9204 } 9205 }); 9206 }); 9207 } 9208 9209 // Animate 9210 el.animate( el.to, { 9211 queue: false, 9212 duration: o.duration, 9213 easing: o.easing, 9214 complete: function() { 9215 if ( el.to.opacity === 0 ) { 9216 el.css( "opacity", el.from.opacity ); 9217 } 9218 if( mode === "hide" ) { 9219 el.hide(); 9220 } 9221 $.effects.restore( el, props ); 9222 if ( !restore ) { 9223 9224 // we need to calculate our new positioning based on the scaling 9225 if ( position === "static" ) { 9226 el.css({ 9227 position: "relative", 9228 top: el.to.top, 9229 left: el.to.left 9230 }); 9231 } else { 9232 $.each([ "top", "left" ], function( idx, pos ) { 9233 el.css( pos, function( _, str ) { 9234 var val = parseInt( str, 10 ), 9235 toRef = idx ? el.to.left : el.to.top; 9236 9237 // if original was "auto", recalculate the new value from wrapper 9238 if ( str === "auto" ) { 9239 return toRef + "px"; 9240 } 9241 9242 return val + toRef + "px"; 9243 }); 9244 }); 9245 } 9246 } 9247 9248 $.effects.removeWrapper( el ); 9249 done(); 9250 } 9251 }); 9252 9253}; 9254 9255})(jQuery); 9256(function( $, undefined ) { 9257 9258$.effects.effect.shake = function( o, done ) { 9259 9260 var el = $( this ), 9261 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 9262 mode = $.effects.setMode( el, o.mode || "effect" ), 9263 direction = o.direction || "left", 9264 distance = o.distance || 20, 9265 times = o.times || 3, 9266 anims = times * 2 + 1, 9267 speed = Math.round(o.duration/anims), 9268 ref = (direction === "up" || direction === "down") ? "top" : "left", 9269 positiveMotion = (direction === "up" || direction === "left"), 9270 animation = {}, 9271 animation1 = {}, 9272 animation2 = {}, 9273 i, 9274 9275 // we will need to re-assemble the queue to stack our animations in place 9276 queue = el.queue(), 9277 queuelen = queue.length; 9278 9279 $.effects.save( el, props ); 9280 el.show(); 9281 $.effects.createWrapper( el ); 9282 9283 // Animation 9284 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 9285 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 9286 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 9287 9288 // Animate 9289 el.animate( animation, speed, o.easing ); 9290 9291 // Shakes 9292 for ( i = 1; i < times; i++ ) { 9293 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 9294 } 9295 el 9296 .animate( animation1, speed, o.easing ) 9297 .animate( animation, speed / 2, o.easing ) 9298 .queue(function() { 9299 if ( mode === "hide" ) { 9300 el.hide(); 9301 } 9302 $.effects.restore( el, props ); 9303 $.effects.removeWrapper( el ); 9304 done(); 9305 }); 9306 9307 // inject all the animations we just queued to be first in line (after "inprogress") 9308 if ( queuelen > 1) { 9309 queue.splice.apply( queue, 9310 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 9311 } 9312 el.dequeue(); 9313 9314}; 9315 9316})(jQuery); 9317(function( $, undefined ) { 9318 9319$.effects.effect.slide = function( o, done ) { 9320 9321 // Create element 9322 var el = $( this ), 9323 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 9324 mode = $.effects.setMode( el, o.mode || "show" ), 9325 show = mode === "show", 9326 direction = o.direction || "left", 9327 ref = (direction === "up" || direction === "down") ? "top" : "left", 9328 positiveMotion = (direction === "up" || direction === "left"), 9329 distance, 9330 animation = {}; 9331 9332 // Adjust 9333 $.effects.save( el, props ); 9334 el.show(); 9335 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 9336 9337 $.effects.createWrapper( el ).css({ 9338 overflow: "hidden" 9339 }); 9340 9341 if ( show ) { 9342 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 9343 } 9344 9345 // Animation 9346 animation[ ref ] = ( show ? 9347 ( positiveMotion ? "+=" : "-=") : 9348 ( positiveMotion ? "-=" : "+=")) + 9349 distance; 9350 9351 // Animate 9352 el.animate( animation, { 9353 queue: false, 9354 duration: o.duration, 9355 easing: o.easing, 9356 complete: function() { 9357 if ( mode === "hide" ) { 9358 el.hide(); 9359 } 9360 $.effects.restore( el, props ); 9361 $.effects.removeWrapper( el ); 9362 done(); 9363 } 9364 }); 9365}; 9366 9367})(jQuery); 9368(function( $, undefined ) { 9369 9370$.effects.effect.transfer = function( o, done ) { 9371 var elem = $( this ), 9372 target = $( o.to ), 9373 targetFixed = target.css( "position" ) === "fixed", 9374 body = $("body"), 9375 fixTop = targetFixed ? body.scrollTop() : 0, 9376 fixLeft = targetFixed ? body.scrollLeft() : 0, 9377 endPosition = target.offset(), 9378 animation = { 9379 top: endPosition.top - fixTop , 9380 left: endPosition.left - fixLeft , 9381 height: target.innerHeight(), 9382 width: target.innerWidth() 9383 }, 9384 startPosition = elem.offset(), 9385 transfer = $( "<div class='ui-effects-transfer'></div>" ) 9386 .appendTo( document.body ) 9387 .addClass( o.className ) 9388 .css({ 9389 top: startPosition.top - fixTop , 9390 left: startPosition.left - fixLeft , 9391 height: elem.innerHeight(), 9392 width: elem.innerWidth(), 9393 position: targetFixed ? "fixed" : "absolute" 9394 }) 9395 .animate( animation, o.duration, o.easing, function() { 9396 transfer.remove(); 9397 done(); 9398 }); 9399}; 9400 9401})(jQuery); 9402(function( $, undefined ) { 9403 9404$.widget( "ui.menu", { 9405 version: "1.10.4", 9406 defaultElement: "<ul>", 9407 delay: 300, 9408 options: { 9409 icons: { 9410 submenu: "ui-icon-carat-1-e" 9411 }, 9412 menus: "ul", 9413 position: { 9414 my: "left top", 9415 at: "right top" 9416 }, 9417 role: "menu", 9418 9419 // callbacks 9420 blur: null, 9421 focus: null, 9422 select: null 9423 }, 9424 9425 _create: function() { 9426 this.activeMenu = this.element; 9427 // flag used to prevent firing of the click handler 9428 // as the event bubbles up through nested menus 9429 this.mouseHandled = false; 9430 this.element 9431 .uniqueId() 9432 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9433 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 9434 .attr({ 9435 role: this.options.role, 9436 tabIndex: 0 9437 }) 9438 // need to catch all clicks on disabled menu 9439 // not possible through _on 9440 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 9441 if ( this.options.disabled ) { 9442 event.preventDefault(); 9443 } 9444 }, this )); 9445 9446 if ( this.options.disabled ) { 9447 this.element 9448 .addClass( "ui-state-disabled" ) 9449 .attr( "aria-disabled", "true" ); 9450 } 9451 9452 this._on({ 9453 // Prevent focus from sticking to links inside menu after clicking 9454 // them (focus should always stay on UL during navigation). 9455 "mousedown .ui-menu-item > a": function( event ) { 9456 event.preventDefault(); 9457 }, 9458 "click .ui-state-disabled > a": function( event ) { 9459 event.preventDefault(); 9460 }, 9461 "click .ui-menu-item:has(a)": function( event ) { 9462 var target = $( event.target ).closest( ".ui-menu-item" ); 9463 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 9464 this.select( event ); 9465 9466 // Only set the mouseHandled flag if the event will bubble, see #9469. 9467 if ( !event.isPropagationStopped() ) { 9468 this.mouseHandled = true; 9469 } 9470 9471 // Open submenu on click 9472 if ( target.has( ".ui-menu" ).length ) { 9473 this.expand( event ); 9474 } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { 9475 9476 // Redirect focus to the menu 9477 this.element.trigger( "focus", [ true ] ); 9478 9479 // If the active item is on the top level, let it stay active. 9480 // Otherwise, blur the active item since it is no longer visible. 9481 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 9482 clearTimeout( this.timer ); 9483 } 9484 } 9485 } 9486 }, 9487 "mouseenter .ui-menu-item": function( event ) { 9488 var target = $( event.currentTarget ); 9489 // Remove ui-state-active class from siblings of the newly focused menu item 9490 // to avoid a jump caused by adjacent elements both having a class with a border 9491 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 9492 this.focus( event, target ); 9493 }, 9494 mouseleave: "collapseAll", 9495 "mouseleave .ui-menu": "collapseAll", 9496 focus: function( event, keepActiveItem ) { 9497 // If there's already an active item, keep it active 9498 // If not, activate the first item 9499 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 9500 9501 if ( !keepActiveItem ) { 9502 this.focus( event, item ); 9503 } 9504 }, 9505 blur: function( event ) { 9506 this._delay(function() { 9507 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 9508 this.collapseAll( event ); 9509 } 9510 }); 9511 }, 9512 keydown: "_keydown" 9513 }); 9514 9515 this.refresh(); 9516 9517 // Clicks outside of a menu collapse any open menus 9518 this._on( this.document, { 9519 click: function( event ) { 9520 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 9521 this.collapseAll( event ); 9522 } 9523 9524 // Reset the mouseHandled flag 9525 this.mouseHandled = false; 9526 } 9527 }); 9528 }, 9529 9530 _destroy: function() { 9531 // Destroy (sub)menus 9532 this.element 9533 .removeAttr( "aria-activedescendant" ) 9534 .find( ".ui-menu" ).addBack() 9535 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 9536 .removeAttr( "role" ) 9537 .removeAttr( "tabIndex" ) 9538 .removeAttr( "aria-labelledby" ) 9539 .removeAttr( "aria-expanded" ) 9540 .removeAttr( "aria-hidden" ) 9541 .removeAttr( "aria-disabled" ) 9542 .removeUniqueId() 9543 .show(); 9544 9545 // Destroy menu items 9546 this.element.find( ".ui-menu-item" ) 9547 .removeClass( "ui-menu-item" ) 9548 .removeAttr( "role" ) 9549 .removeAttr( "aria-disabled" ) 9550 .children( "a" ) 9551 .removeUniqueId() 9552 .removeClass( "ui-corner-all ui-state-hover" ) 9553 .removeAttr( "tabIndex" ) 9554 .removeAttr( "role" ) 9555 .removeAttr( "aria-haspopup" ) 9556 .children().each( function() { 9557 var elem = $( this ); 9558 if ( elem.data( "ui-menu-submenu-carat" ) ) { 9559 elem.remove(); 9560 } 9561 }); 9562 9563 // Destroy menu dividers 9564 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 9565 }, 9566 9567 _keydown: function( event ) { 9568 var match, prev, character, skip, regex, 9569 preventDefault = true; 9570 9571 function escape( value ) { 9572 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 9573 } 9574 9575 switch ( event.keyCode ) { 9576 case $.ui.keyCode.PAGE_UP: 9577 this.previousPage( event ); 9578 break; 9579 case $.ui.keyCode.PAGE_DOWN: 9580 this.nextPage( event ); 9581 break; 9582 case $.ui.keyCode.HOME: 9583 this._move( "first", "first", event ); 9584 break; 9585 case $.ui.keyCode.END: 9586 this._move( "last", "last", event ); 9587 break; 9588 case $.ui.keyCode.UP: 9589 this.previous( event ); 9590 break; 9591 case $.ui.keyCode.DOWN: 9592 this.next( event ); 9593 break; 9594 case $.ui.keyCode.LEFT: 9595 this.collapse( event ); 9596 break; 9597 case $.ui.keyCode.RIGHT: 9598 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 9599 this.expand( event ); 9600 } 9601 break; 9602 case $.ui.keyCode.ENTER: 9603 case $.ui.keyCode.SPACE: 9604 this._activate( event ); 9605 break; 9606 case $.ui.keyCode.ESCAPE: 9607 this.collapse( event ); 9608 break; 9609 default: 9610 preventDefault = false; 9611 prev = this.previousFilter || ""; 9612 character = String.fromCharCode( event.keyCode ); 9613 skip = false; 9614 9615 clearTimeout( this.filterTimer ); 9616 9617 if ( character === prev ) { 9618 skip = true; 9619 } else { 9620 character = prev + character; 9621 } 9622 9623 regex = new RegExp( "^" + escape( character ), "i" ); 9624 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9625 return regex.test( $( this ).children( "a" ).text() ); 9626 }); 9627 match = skip && match.index( this.active.next() ) !== -1 ? 9628 this.active.nextAll( ".ui-menu-item" ) : 9629 match; 9630 9631 // If no matches on the current filter, reset to the last character pressed 9632 // to move down the menu to the first item that starts with that character 9633 if ( !match.length ) { 9634 character = String.fromCharCode( event.keyCode ); 9635 regex = new RegExp( "^" + escape( character ), "i" ); 9636 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9637 return regex.test( $( this ).children( "a" ).text() ); 9638 }); 9639 } 9640 9641 if ( match.length ) { 9642 this.focus( event, match ); 9643 if ( match.length > 1 ) { 9644 this.previousFilter = character; 9645 this.filterTimer = this._delay(function() { 9646 delete this.previousFilter; 9647 }, 1000 ); 9648 } else { 9649 delete this.previousFilter; 9650 } 9651 } else { 9652 delete this.previousFilter; 9653 } 9654 } 9655 9656 if ( preventDefault ) { 9657 event.preventDefault(); 9658 } 9659 }, 9660 9661 _activate: function( event ) { 9662 if ( !this.active.is( ".ui-state-disabled" ) ) { 9663 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 9664 this.expand( event ); 9665 } else { 9666 this.select( event ); 9667 } 9668 } 9669 }, 9670 9671 refresh: function() { 9672 var menus, 9673 icon = this.options.icons.submenu, 9674 submenus = this.element.find( this.options.menus ); 9675 9676 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); 9677 9678 // Initialize nested menus 9679 submenus.filter( ":not(.ui-menu)" ) 9680 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9681 .hide() 9682 .attr({ 9683 role: this.options.role, 9684 "aria-hidden": "true", 9685 "aria-expanded": "false" 9686 }) 9687 .each(function() { 9688 var menu = $( this ), 9689 item = menu.prev( "a" ), 9690 submenuCarat = $( "<span>" ) 9691 .addClass( "ui-menu-icon ui-icon " + icon ) 9692 .data( "ui-menu-submenu-carat", true ); 9693 9694 item 9695 .attr( "aria-haspopup", "true" ) 9696 .prepend( submenuCarat ); 9697 menu.attr( "aria-labelledby", item.attr( "id" ) ); 9698 }); 9699 9700 menus = submenus.add( this.element ); 9701 9702 // Don't refresh list items that are already adapted 9703 menus.children( ":not(.ui-menu-item):has(a)" ) 9704 .addClass( "ui-menu-item" ) 9705 .attr( "role", "presentation" ) 9706 .children( "a" ) 9707 .uniqueId() 9708 .addClass( "ui-corner-all" ) 9709 .attr({ 9710 tabIndex: -1, 9711 role: this._itemRole() 9712 }); 9713 9714 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 9715 menus.children( ":not(.ui-menu-item)" ).each(function() { 9716 var item = $( this ); 9717 // hyphen, em dash, en dash 9718 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 9719 item.addClass( "ui-widget-content ui-menu-divider" ); 9720 } 9721 }); 9722 9723 // Add aria-disabled attribute to any disabled menu item 9724 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 9725 9726 // If the active item has been removed, blur the menu 9727 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 9728 this.blur(); 9729 } 9730 }, 9731 9732 _itemRole: function() { 9733 return { 9734 menu: "menuitem", 9735 listbox: "option" 9736 }[ this.options.role ]; 9737 }, 9738 9739 _setOption: function( key, value ) { 9740 if ( key === "icons" ) { 9741 this.element.find( ".ui-menu-icon" ) 9742 .removeClass( this.options.icons.submenu ) 9743 .addClass( value.submenu ); 9744 } 9745 this._super( key, value ); 9746 }, 9747 9748 focus: function( event, item ) { 9749 var nested, focused; 9750 this.blur( event, event && event.type === "focus" ); 9751 9752 this._scrollIntoView( item ); 9753 9754 this.active = item.first(); 9755 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 9756 // Only update aria-activedescendant if there's a role 9757 // otherwise we assume focus is managed elsewhere 9758 if ( this.options.role ) { 9759 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 9760 } 9761 9762 // Highlight active parent menu item, if any 9763 this.active 9764 .parent() 9765 .closest( ".ui-menu-item" ) 9766 .children( "a:first" ) 9767 .addClass( "ui-state-active" ); 9768 9769 if ( event && event.type === "keydown" ) { 9770 this._close(); 9771 } else { 9772 this.timer = this._delay(function() { 9773 this._close(); 9774 }, this.delay ); 9775 } 9776 9777 nested = item.children( ".ui-menu" ); 9778 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 9779 this._startOpening(nested); 9780 } 9781 this.activeMenu = item.parent(); 9782 9783 this._trigger( "focus", event, { item: item } ); 9784 }, 9785 9786 _scrollIntoView: function( item ) { 9787 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 9788 if ( this._hasScroll() ) { 9789 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 9790 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 9791 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 9792 scroll = this.activeMenu.scrollTop(); 9793 elementHeight = this.activeMenu.height(); 9794 itemHeight = item.height(); 9795 9796 if ( offset < 0 ) { 9797 this.activeMenu.scrollTop( scroll + offset ); 9798 } else if ( offset + itemHeight > elementHeight ) { 9799 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 9800 } 9801 } 9802 }, 9803 9804 blur: function( event, fromFocus ) { 9805 if ( !fromFocus ) { 9806 clearTimeout( this.timer ); 9807 } 9808 9809 if ( !this.active ) { 9810 return; 9811 } 9812 9813 this.active.children( "a" ).removeClass( "ui-state-focus" ); 9814 this.active = null; 9815 9816 this._trigger( "blur", event, { item: this.active } ); 9817 }, 9818 9819 _startOpening: function( submenu ) { 9820 clearTimeout( this.timer ); 9821 9822 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 9823 // shift in the submenu position when mousing over the carat icon 9824 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 9825 return; 9826 } 9827 9828 this.timer = this._delay(function() { 9829 this._close(); 9830 this._open( submenu ); 9831 }, this.delay ); 9832 }, 9833 9834 _open: function( submenu ) { 9835 var position = $.extend({ 9836 of: this.active 9837 }, this.options.position ); 9838 9839 clearTimeout( this.timer ); 9840 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 9841 .hide() 9842 .attr( "aria-hidden", "true" ); 9843 9844 submenu 9845 .show() 9846 .removeAttr( "aria-hidden" ) 9847 .attr( "aria-expanded", "true" ) 9848 .position( position ); 9849 }, 9850 9851 collapseAll: function( event, all ) { 9852 clearTimeout( this.timer ); 9853 this.timer = this._delay(function() { 9854 // If we were passed an event, look for the submenu that contains the event 9855 var currentMenu = all ? this.element : 9856 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 9857 9858 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 9859 if ( !currentMenu.length ) { 9860 currentMenu = this.element; 9861 } 9862 9863 this._close( currentMenu ); 9864 9865 this.blur( event ); 9866 this.activeMenu = currentMenu; 9867 }, this.delay ); 9868 }, 9869 9870 // With no arguments, closes the currently active menu - if nothing is active 9871 // it closes all menus. If passed an argument, it will search for menus BELOW 9872 _close: function( startMenu ) { 9873 if ( !startMenu ) { 9874 startMenu = this.active ? this.active.parent() : this.element; 9875 } 9876 9877 startMenu 9878 .find( ".ui-menu" ) 9879 .hide() 9880 .attr( "aria-hidden", "true" ) 9881 .attr( "aria-expanded", "false" ) 9882 .end() 9883 .find( "a.ui-state-active" ) 9884 .removeClass( "ui-state-active" ); 9885 }, 9886 9887 collapse: function( event ) { 9888 var newItem = this.active && 9889 this.active.parent().closest( ".ui-menu-item", this.element ); 9890 if ( newItem && newItem.length ) { 9891 this._close(); 9892 this.focus( event, newItem ); 9893 } 9894 }, 9895 9896 expand: function( event ) { 9897 var newItem = this.active && 9898 this.active 9899 .children( ".ui-menu " ) 9900 .children( ".ui-menu-item" ) 9901 .first(); 9902 9903 if ( newItem && newItem.length ) { 9904 this._open( newItem.parent() ); 9905 9906 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 9907 this._delay(function() { 9908 this.focus( event, newItem ); 9909 }); 9910 } 9911 }, 9912 9913 next: function( event ) { 9914 this._move( "next", "first", event ); 9915 }, 9916 9917 previous: function( event ) { 9918 this._move( "prev", "last", event ); 9919 }, 9920 9921 isFirstItem: function() { 9922 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 9923 }, 9924 9925 isLastItem: function() { 9926 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 9927 }, 9928 9929 _move: function( direction, filter, event ) { 9930 var next; 9931 if ( this.active ) { 9932 if ( direction === "first" || direction === "last" ) { 9933 next = this.active 9934 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 9935 .eq( -1 ); 9936 } else { 9937 next = this.active 9938 [ direction + "All" ]( ".ui-menu-item" ) 9939 .eq( 0 ); 9940 } 9941 } 9942 if ( !next || !next.length || !this.active ) { 9943 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 9944 } 9945 9946 this.focus( event, next ); 9947 }, 9948 9949 nextPage: function( event ) { 9950 var item, base, height; 9951 9952 if ( !this.active ) { 9953 this.next( event ); 9954 return; 9955 } 9956 if ( this.isLastItem() ) { 9957 return; 9958 } 9959 if ( this._hasScroll() ) { 9960 base = this.active.offset().top; 9961 height = this.element.height(); 9962 this.active.nextAll( ".ui-menu-item" ).each(function() { 9963 item = $( this ); 9964 return item.offset().top - base - height < 0; 9965 }); 9966 9967 this.focus( event, item ); 9968 } else { 9969 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 9970 [ !this.active ? "first" : "last" ]() ); 9971 } 9972 }, 9973 9974 previousPage: function( event ) { 9975 var item, base, height; 9976 if ( !this.active ) { 9977 this.next( event ); 9978 return; 9979 } 9980 if ( this.isFirstItem() ) { 9981 return; 9982 } 9983 if ( this._hasScroll() ) { 9984 base = this.active.offset().top; 9985 height = this.element.height(); 9986 this.active.prevAll( ".ui-menu-item" ).each(function() { 9987 item = $( this ); 9988 return item.offset().top - base + height > 0; 9989 }); 9990 9991 this.focus( event, item ); 9992 } else { 9993 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 9994 } 9995 }, 9996 9997 _hasScroll: function() { 9998 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 9999 }, 10000 10001 select: function( event ) { 10002 // TODO: It should never be possible to not have an active item at this 10003 // point, but the tests don't trigger mouseenter before click. 10004 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 10005 var ui = { item: this.active }; 10006 if ( !this.active.has( ".ui-menu" ).length ) { 10007 this.collapseAll( event, true ); 10008 } 10009 this._trigger( "select", event, ui ); 10010 } 10011}); 10012 10013}( jQuery )); 10014(function( $, undefined ) { 10015 10016$.widget( "ui.progressbar", { 10017 version: "1.10.4", 10018 options: { 10019 max: 100, 10020 value: 0, 10021 10022 change: null, 10023 complete: null 10024 }, 10025 10026 min: 0, 10027 10028 _create: function() { 10029 // Constrain initial value 10030 this.oldValue = this.options.value = this._constrainedValue(); 10031 10032 this.element 10033 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10034 .attr({ 10035 // Only set static values, aria-valuenow and aria-valuemax are 10036 // set inside _refreshValue() 10037 role: "progressbar", 10038 "aria-valuemin": this.min 10039 }); 10040 10041 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 10042 .appendTo( this.element ); 10043 10044 this._refreshValue(); 10045 }, 10046 10047 _destroy: function() { 10048 this.element 10049 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10050 .removeAttr( "role" ) 10051 .removeAttr( "aria-valuemin" ) 10052 .removeAttr( "aria-valuemax" ) 10053 .removeAttr( "aria-valuenow" ); 10054 10055 this.valueDiv.remove(); 10056 }, 10057 10058 value: function( newValue ) { 10059 if ( newValue === undefined ) { 10060 return this.options.value; 10061 } 10062 10063 this.options.value = this._constrainedValue( newValue ); 10064 this._refreshValue(); 10065 }, 10066 10067 _constrainedValue: function( newValue ) { 10068 if ( newValue === undefined ) { 10069 newValue = this.options.value; 10070 } 10071 10072 this.indeterminate = newValue === false; 10073 10074 // sanitize value 10075 if ( typeof newValue !== "number" ) { 10076 newValue = 0; 10077 } 10078 10079 return this.indeterminate ? false : 10080 Math.min( this.options.max, Math.max( this.min, newValue ) ); 10081 }, 10082 10083 _setOptions: function( options ) { 10084 // Ensure "value" option is set after other values (like max) 10085 var value = options.value; 10086 delete options.value; 10087 10088 this._super( options ); 10089 10090 this.options.value = this._constrainedValue( value ); 10091 this._refreshValue(); 10092 }, 10093 10094 _setOption: function( key, value ) { 10095 if ( key === "max" ) { 10096 // Don't allow a max less than min 10097 value = Math.max( this.min, value ); 10098 } 10099 10100 this._super( key, value ); 10101 }, 10102 10103 _percentage: function() { 10104 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 10105 }, 10106 10107 _refreshValue: function() { 10108 var value = this.options.value, 10109 percentage = this._percentage(); 10110 10111 this.valueDiv 10112 .toggle( this.indeterminate || value > this.min ) 10113 .toggleClass( "ui-corner-right", value === this.options.max ) 10114 .width( percentage.toFixed(0) + "%" ); 10115 10116 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 10117 10118 if ( this.indeterminate ) { 10119 this.element.removeAttr( "aria-valuenow" ); 10120 if ( !this.overlayDiv ) { 10121 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 10122 } 10123 } else { 10124 this.element.attr({ 10125 "aria-valuemax": this.options.max, 10126 "aria-valuenow": value 10127 }); 10128 if ( this.overlayDiv ) { 10129 this.overlayDiv.remove(); 10130 this.overlayDiv = null; 10131 } 10132 } 10133 10134 if ( this.oldValue !== value ) { 10135 this.oldValue = value; 10136 this._trigger( "change" ); 10137 } 10138 if ( value === this.options.max ) { 10139 this._trigger( "complete" ); 10140 } 10141 } 10142}); 10143 10144})( jQuery ); 10145(function( $, undefined ) { 10146 10147function num(v) { 10148 return parseInt(v, 10) || 0; 10149} 10150 10151function isNumber(value) { 10152 return !isNaN(parseInt(value, 10)); 10153} 10154 10155$.widget("ui.resizable", $.ui.mouse, { 10156 version: "1.10.4", 10157 widgetEventPrefix: "resize", 10158 options: { 10159 alsoResize: false, 10160 animate: false, 10161 animateDuration: "slow", 10162 animateEasing: "swing", 10163 aspectRatio: false, 10164 autoHide: false, 10165 containment: false, 10166 ghost: false, 10167 grid: false, 10168 handles: "e,s,se", 10169 helper: false, 10170 maxHeight: null, 10171 maxWidth: null, 10172 minHeight: 10, 10173 minWidth: 10, 10174 // See #7960 10175 zIndex: 90, 10176 10177 // callbacks 10178 resize: null, 10179 start: null, 10180 stop: null 10181 }, 10182 _create: function() { 10183 10184 var n, i, handle, axis, hname, 10185 that = this, 10186 o = this.options; 10187 this.element.addClass("ui-resizable"); 10188 10189 $.extend(this, { 10190 _aspectRatio: !!(o.aspectRatio), 10191 aspectRatio: o.aspectRatio, 10192 originalElement: this.element, 10193 _proportionallyResizeElements: [], 10194 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 10195 }); 10196 10197 //Wrap the element if it cannot hold child nodes 10198 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 10199 10200 //Create a wrapper element and set the wrapper to the new current internal element 10201 this.element.wrap( 10202 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 10203 position: this.element.css("position"), 10204 width: this.element.outerWidth(), 10205 height: this.element.outerHeight(), 10206 top: this.element.css("top"), 10207 left: this.element.css("left") 10208 }) 10209 ); 10210 10211 //Overwrite the original this.element 10212 this.element = this.element.parent().data( 10213 "ui-resizable", this.element.data("ui-resizable") 10214 ); 10215 10216 this.elementIsWrapper = true; 10217 10218 //Move margins to the wrapper 10219 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 10220 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 10221 10222 //Prevent Safari textarea resize 10223 this.originalResizeStyle = this.originalElement.css("resize"); 10224 this.originalElement.css("resize", "none"); 10225 10226 //Push the actual element to our proportionallyResize internal array 10227 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 10228 10229 // avoid IE jump (hard set the margin) 10230 this.originalElement.css({ margin: this.originalElement.css("margin") }); 10231 10232 // fix handlers offset 10233 this._proportionallyResize(); 10234 10235 } 10236 10237 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" }); 10238 if(this.handles.constructor === String) { 10239 10240 if ( this.handles === "all") { 10241 this.handles = "n,e,s,w,se,sw,ne,nw"; 10242 } 10243 10244 n = this.handles.split(","); 10245 this.handles = {}; 10246 10247 for(i = 0; i < n.length; i++) { 10248 10249 handle = $.trim(n[i]); 10250 hname = "ui-resizable-"+handle; 10251 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 10252 10253 // Apply zIndex to all handles - see #7960 10254 axis.css({ zIndex: o.zIndex }); 10255 10256 //TODO : What's going on here? 10257 if ("se" === handle) { 10258 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 10259 } 10260 10261 //Insert into internal handles object and append to element 10262 this.handles[handle] = ".ui-resizable-"+handle; 10263 this.element.append(axis); 10264 } 10265 10266 } 10267 10268 this._renderAxis = function(target) { 10269 10270 var i, axis, padPos, padWrapper; 10271 10272 target = target || this.element; 10273 10274 for(i in this.handles) { 10275 10276 if(this.handles[i].constructor === String) { 10277 this.handles[i] = $(this.handles[i], this.element).show(); 10278 } 10279 10280 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 10281 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 10282 10283 axis = $(this.handles[i], this.element); 10284 10285 //Checking the correct pad and border 10286 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 10287 10288 //The padding type i have to apply... 10289 padPos = [ "padding", 10290 /ne|nw|n/.test(i) ? "Top" : 10291 /se|sw|s/.test(i) ? "Bottom" : 10292 /^e$/.test(i) ? "Right" : "Left" ].join(""); 10293 10294 target.css(padPos, padWrapper); 10295 10296 this._proportionallyResize(); 10297 10298 } 10299 10300 //TODO: What's that good for? There's not anything to be executed left 10301 if(!$(this.handles[i]).length) { 10302 continue; 10303 } 10304 } 10305 }; 10306 10307 //TODO: make renderAxis a prototype function 10308 this._renderAxis(this.element); 10309 10310 this._handles = $(".ui-resizable-handle", this.element) 10311 .disableSelection(); 10312 10313 //Matching axis name 10314 this._handles.mouseover(function() { 10315 if (!that.resizing) { 10316 if (this.className) { 10317 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 10318 } 10319 //Axis, default = se 10320 that.axis = axis && axis[1] ? axis[1] : "se"; 10321 } 10322 }); 10323 10324 //If we want to auto hide the elements 10325 if (o.autoHide) { 10326 this._handles.hide(); 10327 $(this.element) 10328 .addClass("ui-resizable-autohide") 10329 .mouseenter(function() { 10330 if (o.disabled) { 10331 return; 10332 } 10333 $(this).removeClass("ui-resizable-autohide"); 10334 that._handles.show(); 10335 }) 10336 .mouseleave(function(){ 10337 if (o.disabled) { 10338 return; 10339 } 10340 if (!that.resizing) { 10341 $(this).addClass("ui-resizable-autohide"); 10342 that._handles.hide(); 10343 } 10344 }); 10345 } 10346 10347 //Initialize the mouse interaction 10348 this._mouseInit(); 10349 10350 }, 10351 10352 _destroy: function() { 10353 10354 this._mouseDestroy(); 10355 10356 var wrapper, 10357 _destroy = function(exp) { 10358 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 10359 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 10360 }; 10361 10362 //TODO: Unwrap at same DOM position 10363 if (this.elementIsWrapper) { 10364 _destroy(this.element); 10365 wrapper = this.element; 10366 this.originalElement.css({ 10367 position: wrapper.css("position"), 10368 width: wrapper.outerWidth(), 10369 height: wrapper.outerHeight(), 10370 top: wrapper.css("top"), 10371 left: wrapper.css("left") 10372 }).insertAfter( wrapper ); 10373 wrapper.remove(); 10374 } 10375 10376 this.originalElement.css("resize", this.originalResizeStyle); 10377 _destroy(this.originalElement); 10378 10379 return this; 10380 }, 10381 10382 _mouseCapture: function(event) { 10383 var i, handle, 10384 capture = false; 10385 10386 for (i in this.handles) { 10387 handle = $(this.handles[i])[0]; 10388 if (handle === event.target || $.contains(handle, event.target)) { 10389 capture = true; 10390 } 10391 } 10392 10393 return !this.options.disabled && capture; 10394 }, 10395 10396 _mouseStart: function(event) { 10397 10398 var curleft, curtop, cursor, 10399 o = this.options, 10400 iniPos = this.element.position(), 10401 el = this.element; 10402 10403 this.resizing = true; 10404 10405 // bugfix for http://dev.jquery.com/ticket/1749 10406 if ( (/absolute/).test( el.css("position") ) ) { 10407 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 10408 } else if (el.is(".ui-draggable")) { 10409 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 10410 } 10411 10412 this._renderProxy(); 10413 10414 curleft = num(this.helper.css("left")); 10415 curtop = num(this.helper.css("top")); 10416 10417 if (o.containment) { 10418 curleft += $(o.containment).scrollLeft() || 0; 10419 curtop += $(o.containment).scrollTop() || 0; 10420 } 10421 10422 //Store needed variables 10423 this.offset = this.helper.offset(); 10424 this.position = { left: curleft, top: curtop }; 10425 this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() }; 10426 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 10427 this.originalPosition = { left: curleft, top: curtop }; 10428 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 10429 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 10430 10431 //Aspect Ratio 10432 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 10433 10434 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 10435 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 10436 10437 el.addClass("ui-resizable-resizing"); 10438 this._propagate("start", event); 10439 return true; 10440 }, 10441 10442 _mouseDrag: function(event) { 10443 10444 //Increase performance, avoid regex 10445 var data, 10446 el = this.helper, props = {}, 10447 smp = this.originalMousePosition, 10448 a = this.axis, 10449 prevTop = this.position.top, 10450 prevLeft = this.position.left, 10451 prevWidth = this.size.width, 10452 prevHeight = this.size.height, 10453 dx = (event.pageX-smp.left)||0, 10454 dy = (event.pageY-smp.top)||0, 10455 trigger = this._change[a]; 10456 10457 if (!trigger) { 10458 return false; 10459 } 10460 10461 // Calculate the attrs that will be change 10462 data = trigger.apply(this, [event, dx, dy]); 10463 10464 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 10465 this._updateVirtualBoundaries(event.shiftKey); 10466 if (this._aspectRatio || event.shiftKey) { 10467 data = this._updateRatio(data, event); 10468 } 10469 10470 data = this._respectSize(data, event); 10471 10472 this._updateCache(data); 10473 10474 // plugins callbacks need to be called first 10475 this._propagate("resize", event); 10476 10477 if (this.position.top !== prevTop) { 10478 props.top = this.position.top + "px"; 10479 } 10480 if (this.position.left !== prevLeft) { 10481 props.left = this.position.left + "px"; 10482 } 10483 if (this.size.width !== prevWidth) { 10484 props.width = this.size.width + "px"; 10485 } 10486 if (this.size.height !== prevHeight) { 10487 props.height = this.size.height + "px"; 10488 } 10489 el.css(props); 10490 10491 if (!this._helper && this._proportionallyResizeElements.length) { 10492 this._proportionallyResize(); 10493 } 10494 10495 // Call the user callback if the element was resized 10496 if ( ! $.isEmptyObject(props) ) { 10497 this._trigger("resize", event, this.ui()); 10498 } 10499 10500 return false; 10501 }, 10502 10503 _mouseStop: function(event) { 10504 10505 this.resizing = false; 10506 var pr, ista, soffseth, soffsetw, s, left, top, 10507 o = this.options, that = this; 10508 10509 if(this._helper) { 10510 10511 pr = this._proportionallyResizeElements; 10512 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 10513 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 10514 soffsetw = ista ? 0 : that.sizeDiff.width; 10515 10516 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 10517 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 10518 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 10519 10520 if (!o.animate) { 10521 this.element.css($.extend(s, { top: top, left: left })); 10522 } 10523 10524 that.helper.height(that.size.height); 10525 that.helper.width(that.size.width); 10526 10527 if (this._helper && !o.animate) { 10528 this._proportionallyResize(); 10529 } 10530 } 10531 10532 $("body").css("cursor", "auto"); 10533 10534 this.element.removeClass("ui-resizable-resizing"); 10535 10536 this._propagate("stop", event); 10537 10538 if (this._helper) { 10539 this.helper.remove(); 10540 } 10541 10542 return false; 10543 10544 }, 10545 10546 _updateVirtualBoundaries: function(forceAspectRatio) { 10547 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 10548 o = this.options; 10549 10550 b = { 10551 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 10552 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 10553 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 10554 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 10555 }; 10556 10557 if(this._aspectRatio || forceAspectRatio) { 10558 // We want to create an enclosing box whose aspect ration is the requested one 10559 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 10560 pMinWidth = b.minHeight * this.aspectRatio; 10561 pMinHeight = b.minWidth / this.aspectRatio; 10562 pMaxWidth = b.maxHeight * this.aspectRatio; 10563 pMaxHeight = b.maxWidth / this.aspectRatio; 10564 10565 if(pMinWidth > b.minWidth) { 10566 b.minWidth = pMinWidth; 10567 } 10568 if(pMinHeight > b.minHeight) { 10569 b.minHeight = pMinHeight; 10570 } 10571 if(pMaxWidth < b.maxWidth) { 10572 b.maxWidth = pMaxWidth; 10573 } 10574 if(pMaxHeight < b.maxHeight) { 10575 b.maxHeight = pMaxHeight; 10576 } 10577 } 10578 this._vBoundaries = b; 10579 }, 10580 10581 _updateCache: function(data) { 10582 this.offset = this.helper.offset(); 10583 if (isNumber(data.left)) { 10584 this.position.left = data.left; 10585 } 10586 if (isNumber(data.top)) { 10587 this.position.top = data.top; 10588 } 10589 if (isNumber(data.height)) { 10590 this.size.height = data.height; 10591 } 10592 if (isNumber(data.width)) { 10593 this.size.width = data.width; 10594 } 10595 }, 10596 10597 _updateRatio: function( data ) { 10598 10599 var cpos = this.position, 10600 csize = this.size, 10601 a = this.axis; 10602 10603 if (isNumber(data.height)) { 10604 data.width = (data.height * this.aspectRatio); 10605 } else if (isNumber(data.width)) { 10606 data.height = (data.width / this.aspectRatio); 10607 } 10608 10609 if (a === "sw") { 10610 data.left = cpos.left + (csize.width - data.width); 10611 data.top = null; 10612 } 10613 if (a === "nw") { 10614 data.top = cpos.top + (csize.height - data.height); 10615 data.left = cpos.left + (csize.width - data.width); 10616 } 10617 10618 return data; 10619 }, 10620 10621 _respectSize: function( data ) { 10622 10623 var o = this._vBoundaries, 10624 a = this.axis, 10625 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 10626 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 10627 dw = this.originalPosition.left + this.originalSize.width, 10628 dh = this.position.top + this.size.height, 10629 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 10630 if (isminw) { 10631 data.width = o.minWidth; 10632 } 10633 if (isminh) { 10634 data.height = o.minHeight; 10635 } 10636 if (ismaxw) { 10637 data.width = o.maxWidth; 10638 } 10639 if (ismaxh) { 10640 data.height = o.maxHeight; 10641 } 10642 10643 if (isminw && cw) { 10644 data.left = dw - o.minWidth; 10645 } 10646 if (ismaxw && cw) { 10647 data.left = dw - o.maxWidth; 10648 } 10649 if (isminh && ch) { 10650 data.top = dh - o.minHeight; 10651 } 10652 if (ismaxh && ch) { 10653 data.top = dh - o.maxHeight; 10654 } 10655 10656 // fixing jump error on top/left - bug #2330 10657 if (!data.width && !data.height && !data.left && data.top) { 10658 data.top = null; 10659 } else if (!data.width && !data.height && !data.top && data.left) { 10660 data.left = null; 10661 } 10662 10663 return data; 10664 }, 10665 10666 _proportionallyResize: function() { 10667 10668 if (!this._proportionallyResizeElements.length) { 10669 return; 10670 } 10671 10672 var i, j, borders, paddings, prel, 10673 element = this.helper || this.element; 10674 10675 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 10676 10677 prel = this._proportionallyResizeElements[i]; 10678 10679 if (!this.borderDif) { 10680 this.borderDif = []; 10681 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 10682 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 10683 10684 for ( j = 0; j < borders.length; j++ ) { 10685 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 10686 } 10687 } 10688 10689 prel.css({ 10690 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 10691 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 10692 }); 10693 10694 } 10695 10696 }, 10697 10698 _renderProxy: function() { 10699 10700 var el = this.element, o = this.options; 10701 this.elementOffset = el.offset(); 10702 10703 if(this._helper) { 10704 10705 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 10706 10707 this.helper.addClass(this._helper).css({ 10708 width: this.element.outerWidth() - 1, 10709 height: this.element.outerHeight() - 1, 10710 position: "absolute", 10711 left: this.elementOffset.left +"px", 10712 top: this.elementOffset.top +"px", 10713 zIndex: ++o.zIndex //TODO: Don't modify option 10714 }); 10715 10716 this.helper 10717 .appendTo("body") 10718 .disableSelection(); 10719 10720 } else { 10721 this.helper = this.element; 10722 } 10723 10724 }, 10725 10726 _change: { 10727 e: function(event, dx) { 10728 return { width: this.originalSize.width + dx }; 10729 }, 10730 w: function(event, dx) { 10731 var cs = this.originalSize, sp = this.originalPosition; 10732 return { left: sp.left + dx, width: cs.width - dx }; 10733 }, 10734 n: function(event, dx, dy) { 10735 var cs = this.originalSize, sp = this.originalPosition; 10736 return { top: sp.top + dy, height: cs.height - dy }; 10737 }, 10738 s: function(event, dx, dy) { 10739 return { height: this.originalSize.height + dy }; 10740 }, 10741 se: function(event, dx, dy) { 10742 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 10743 }, 10744 sw: function(event, dx, dy) { 10745 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 10746 }, 10747 ne: function(event, dx, dy) { 10748 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 10749 }, 10750 nw: function(event, dx, dy) { 10751 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 10752 } 10753 }, 10754 10755 _propagate: function(n, event) { 10756 $.ui.plugin.call(this, n, [event, this.ui()]); 10757 (n !== "resize" && this._trigger(n, event, this.ui())); 10758 }, 10759 10760 plugins: {}, 10761 10762 ui: function() { 10763 return { 10764 originalElement: this.originalElement, 10765 element: this.element, 10766 helper: this.helper, 10767 position: this.position, 10768 size: this.size, 10769 originalSize: this.originalSize, 10770 originalPosition: this.originalPosition 10771 }; 10772 } 10773 10774}); 10775 10776/* 10777 * Resizable Extensions 10778 */ 10779 10780$.ui.plugin.add("resizable", "animate", { 10781 10782 stop: function( event ) { 10783 var that = $(this).data("ui-resizable"), 10784 o = that.options, 10785 pr = that._proportionallyResizeElements, 10786 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 10787 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 10788 soffsetw = ista ? 0 : that.sizeDiff.width, 10789 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 10790 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 10791 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 10792 10793 that.element.animate( 10794 $.extend(style, top && left ? { top: top, left: left } : {}), { 10795 duration: o.animateDuration, 10796 easing: o.animateEasing, 10797 step: function() { 10798 10799 var data = { 10800 width: parseInt(that.element.css("width"), 10), 10801 height: parseInt(that.element.css("height"), 10), 10802 top: parseInt(that.element.css("top"), 10), 10803 left: parseInt(that.element.css("left"), 10) 10804 }; 10805 10806 if (pr && pr.length) { 10807 $(pr[0]).css({ width: data.width, height: data.height }); 10808 } 10809 10810 // propagating resize, and updating values for each animation step 10811 that._updateCache(data); 10812 that._propagate("resize", event); 10813 10814 } 10815 } 10816 ); 10817 } 10818 10819}); 10820 10821$.ui.plugin.add("resizable", "containment", { 10822 10823 start: function() { 10824 var element, p, co, ch, cw, width, height, 10825 that = $(this).data("ui-resizable"), 10826 o = that.options, 10827 el = that.element, 10828 oc = o.containment, 10829 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 10830 10831 if (!ce) { 10832 return; 10833 } 10834 10835 that.containerElement = $(ce); 10836 10837 if (/document/.test(oc) || oc === document) { 10838 that.containerOffset = { left: 0, top: 0 }; 10839 that.containerPosition = { left: 0, top: 0 }; 10840 10841 that.parentData = {
10842 element: $(document), left: 0, top: 0, 10843 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 10844 }; 10845 } 10846 10847 // i'm a node, so compute top, left, right, bottom 10848 else { 10849 element = $(ce); 10850 p = []; 10851 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 10852 10853 that.containerOffset = element.offset(); 10854 that.containerPosition = element.position(); 10855 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 10856 10857 co = that.containerOffset; 10858 ch = that.containerSize.height; 10859 cw = that.containerSize.width; 10860 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 10861 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 10862 10863 that.parentData = { 10864 element: ce, left: co.left, top: co.top, width: width, height: height 10865 }; 10866 } 10867 }, 10868 10869 resize: function( event ) { 10870 var woset, hoset, isParent, isOffsetRelative, 10871 that = $(this).data("ui-resizable"), 10872 o = that.options, 10873 co = that.containerOffset, cp = that.position, 10874 pRatio = that._aspectRatio || event.shiftKey, 10875 cop = { top:0, left:0 }, ce = that.containerElement; 10876 10877 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 10878 cop = co; 10879 } 10880 10881 if (cp.left < (that._helper ? co.left : 0)) { 10882 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 10883 if (pRatio) { 10884 that.size.height = that.size.width / that.aspectRatio; 10885 } 10886 that.position.left = o.helper ? co.left : 0; 10887 } 10888 10889 if (cp.top < (that._helper ? co.top : 0)) { 10890 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 10891 if (pRatio) { 10892 that.size.width = that.size.height * that.aspectRatio; 10893 } 10894 that.position.top = that._helper ? co.top : 0; 10895 } 10896 10897 that.offset.left = that.parentData.left+that.position.left; 10898 that.offset.top = that.parentData.top+that.position.top; 10899 10900 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 10901 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 10902 10903 isParent = that.containerElement.get(0) === that.element.parent().get(0); 10904 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 10905 10906 if ( isParent && isOffsetRelative ) { 10907 woset -= Math.abs( that.parentData.left ); 10908 } 10909 10910 if (woset + that.size.width >= that.parentData.width) { 10911 that.size.width = that.parentData.width - woset; 10912 if (pRatio) { 10913 that.size.height = that.size.width / that.aspectRatio; 10914 } 10915 } 10916 10917 if (hoset + that.size.height >= that.parentData.height) { 10918 that.size.height = that.parentData.height - hoset; 10919 if (pRatio) { 10920 that.size.width = that.size.height * that.aspectRatio; 10921 } 10922 } 10923 }, 10924 10925 stop: function(){ 10926 var that = $(this).data("ui-resizable"), 10927 o = that.options, 10928 co = that.containerOffset, 10929 cop = that.containerPosition, 10930 ce = that.containerElement, 10931 helper = $(that.helper), 10932 ho = helper.offset(), 10933 w = helper.outerWidth() - that.sizeDiff.width, 10934 h = helper.outerHeight() - that.sizeDiff.height; 10935 10936 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 10937 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 10938 } 10939 10940 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 10941 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 10942 } 10943 10944 } 10945}); 10946 10947$.ui.plugin.add("resizable", "alsoResize", { 10948 10949 start: function () { 10950 var that = $(this).data("ui-resizable"), 10951 o = that.options, 10952 _store = function (exp) { 10953 $(exp).each(function() { 10954 var el = $(this); 10955 el.data("ui-resizable-alsoresize", { 10956 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 10957 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 10958 }); 10959 }); 10960 }; 10961 10962 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 10963 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 10964 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 10965 }else{ 10966 _store(o.alsoResize); 10967 } 10968 }, 10969 10970 resize: function (event, ui) { 10971 var that = $(this).data("ui-resizable"), 10972 o = that.options, 10973 os = that.originalSize, 10974 op = that.originalPosition, 10975 delta = { 10976 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 10977 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 10978 }, 10979 10980 _alsoResize = function (exp, c) { 10981 $(exp).each(function() { 10982 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 10983 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 10984
vendor: 55,689 bytes, lines 10985-12937
10985 $.each(css, function (i, prop) { 10986 var sum = (start[prop]||0) + (delta[prop]||0); 10987 if (sum && sum >= 0) { 10988 style[prop] = sum || null; 10989 } 10990 }); 10991 10992 el.css(style); 10993 }); 10994 }; 10995 10996 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 10997 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 10998 }else{ 10999 _alsoResize(o.alsoResize); 11000 } 11001 }, 11002 11003 stop: function () { 11004 $(this).removeData("resizable-alsoresize"); 11005 } 11006}); 11007 11008$.ui.plugin.add("resizable", "ghost", { 11009 11010 start: function() { 11011 11012 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 11013 11014 that.ghost = that.originalElement.clone(); 11015 that.ghost 11016 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 11017 .addClass("ui-resizable-ghost") 11018 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 11019 11020 that.ghost.appendTo(that.helper); 11021 11022 }, 11023 11024 resize: function(){ 11025 var that = $(this).data("ui-resizable"); 11026 if (that.ghost) { 11027 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 11028 } 11029 }, 11030 11031 stop: function() { 11032 var that = $(this).data("ui-resizable"); 11033 if (that.ghost && that.helper) { 11034 that.helper.get(0).removeChild(that.ghost.get(0)); 11035 } 11036 } 11037 11038}); 11039 11040$.ui.plugin.add("resizable", "grid", { 11041 11042 resize: function() { 11043 var that = $(this).data("ui-resizable"), 11044 o = that.options, 11045 cs = that.size, 11046 os = that.originalSize, 11047 op = that.originalPosition, 11048 a = that.axis, 11049 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 11050 gridX = (grid[0]||1), 11051 gridY = (grid[1]||1), 11052 ox = Math.round((cs.width - os.width) / gridX) * gridX, 11053 oy = Math.round((cs.height - os.height) / gridY) * gridY, 11054 newWidth = os.width + ox, 11055 newHeight = os.height + oy, 11056 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 11057 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 11058 isMinWidth = o.minWidth && (o.minWidth > newWidth), 11059 isMinHeight = o.minHeight && (o.minHeight > newHeight); 11060 11061 o.grid = grid; 11062 11063 if (isMinWidth) { 11064 newWidth = newWidth + gridX; 11065 } 11066 if (isMinHeight) { 11067 newHeight = newHeight + gridY; 11068 } 11069 if (isMaxWidth) { 11070 newWidth = newWidth - gridX; 11071 } 11072 if (isMaxHeight) { 11073 newHeight = newHeight - gridY; 11074 } 11075 11076 if (/^(se|s|e)$/.test(a)) { 11077 that.size.width = newWidth; 11078 that.size.height = newHeight; 11079 } else if (/^(ne)$/.test(a)) { 11080 that.size.width = newWidth; 11081 that.size.height = newHeight; 11082 that.position.top = op.top - oy; 11083 } else if (/^(sw)$/.test(a)) { 11084 that.size.width = newWidth; 11085 that.size.height = newHeight; 11086 that.position.left = op.left - ox; 11087 } else { 11088 if ( newHeight - gridY > 0 ) { 11089 that.size.height = newHeight; 11090 that.position.top = op.top - oy; 11091 } else { 11092 that.size.height = gridY; 11093 that.position.top = op.top + os.height - gridY; 11094 } 11095 if ( newWidth - gridX > 0 ) { 11096 that.size.width = newWidth; 11097 that.position.left = op.left - ox; 11098 } else { 11099 that.size.width = gridX; 11100 that.position.left = op.left + os.width - gridX; 11101 } 11102 } 11103 } 11104 11105}); 11106 11107})(jQuery); 11108(function( $, undefined ) { 11109 11110$.widget("ui.selectable", $.ui.mouse, { 11111 version: "1.10.4", 11112 options: { 11113 appendTo: "body", 11114 autoRefresh: true, 11115 distance: 0, 11116 filter: "*", 11117 tolerance: "touch", 11118 11119 // callbacks 11120 selected: null, 11121 selecting: null, 11122 start: null, 11123 stop: null, 11124 unselected: null, 11125 unselecting: null 11126 }, 11127 _create: function() { 11128 var selectees, 11129 that = this; 11130 11131 this.element.addClass("ui-selectable"); 11132 11133 this.dragged = false; 11134 11135 // cache selectee children based on filter 11136 this.refresh = function() { 11137 selectees = $(that.options.filter, that.element[0]); 11138 selectees.addClass("ui-selectee"); 11139 selectees.each(function() { 11140 var $this = $(this), 11141 pos = $this.offset(); 11142 $.data(this, "selectable-item", { 11143 element: this, 11144 $element: $this, 11145 left: pos.left, 11146 top: pos.top, 11147 right: pos.left + $this.outerWidth(), 11148 bottom: pos.top + $this.outerHeight(), 11149 startselected: false, 11150 selected: $this.hasClass("ui-selected"), 11151 selecting: $this.hasClass("ui-selecting"), 11152 unselecting: $this.hasClass("ui-unselecting") 11153 }); 11154 }); 11155 }; 11156 this.refresh(); 11157 11158 this.selectees = selectees.addClass("ui-selectee"); 11159 11160 this._mouseInit(); 11161 11162 this.helper = $("<div class='ui-selectable-helper'></div>"); 11163 }, 11164 11165 _destroy: function() { 11166 this.selectees 11167 .removeClass("ui-selectee") 11168 .removeData("selectable-item"); 11169 this.element 11170 .removeClass("ui-selectable ui-selectable-disabled"); 11171 this._mouseDestroy(); 11172 }, 11173 11174 _mouseStart: function(event) { 11175 var that = this, 11176 options = this.options; 11177 11178 this.opos = [event.pageX, event.pageY]; 11179 11180 if (this.options.disabled) { 11181 return; 11182 } 11183 11184 this.selectees = $(options.filter, this.element[0]); 11185 11186 this._trigger("start", event); 11187 11188 $(options.appendTo).append(this.helper); 11189 // position helper (lasso) 11190 this.helper.css({ 11191 "left": event.pageX, 11192 "top": event.pageY, 11193 "width": 0, 11194 "height": 0 11195 }); 11196 11197 if (options.autoRefresh) { 11198 this.refresh(); 11199 } 11200 11201 this.selectees.filter(".ui-selected").each(function() { 11202 var selectee = $.data(this, "selectable-item"); 11203 selectee.startselected = true; 11204 if (!event.metaKey && !event.ctrlKey) { 11205 selectee.$element.removeClass("ui-selected"); 11206 selectee.selected = false; 11207 selectee.$element.addClass("ui-unselecting"); 11208 selectee.unselecting = true; 11209 // selectable UNSELECTING callback 11210 that._trigger("unselecting", event, { 11211 unselecting: selectee.element 11212 }); 11213 } 11214 }); 11215 11216 $(event.target).parents().addBack().each(function() { 11217 var doSelect, 11218 selectee = $.data(this, "selectable-item"); 11219 if (selectee) { 11220 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 11221 selectee.$element 11222 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 11223 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 11224 selectee.unselecting = !doSelect; 11225 selectee.selecting = doSelect; 11226 selectee.selected = doSelect; 11227 // selectable (UN)SELECTING callback 11228 if (doSelect) { 11229 that._trigger("selecting", event, { 11230 selecting: selectee.element 11231 }); 11232 } else { 11233 that._trigger("unselecting", event, { 11234 unselecting: selectee.element 11235 }); 11236 } 11237 return false; 11238 } 11239 }); 11240 11241 }, 11242 11243 _mouseDrag: function(event) { 11244 11245 this.dragged = true; 11246 11247 if (this.options.disabled) { 11248 return; 11249 } 11250 11251 var tmp, 11252 that = this, 11253 options = this.options, 11254 x1 = this.opos[0], 11255 y1 = this.opos[1], 11256 x2 = event.pageX, 11257 y2 = event.pageY; 11258 11259 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 11260 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 11261 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 11262 11263 this.selectees.each(function() { 11264 var selectee = $.data(this, "selectable-item"), 11265 hit = false; 11266 11267 //prevent helper from being selected if appendTo: selectable 11268 if (!selectee || selectee.element === that.element[0]) { 11269 return; 11270 } 11271 11272 if (options.tolerance === "touch") { 11273 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 11274 } else if (options.tolerance === "fit") { 11275 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 11276 } 11277 11278 if (hit) { 11279 // SELECT 11280 if (selectee.selected) { 11281 selectee.$element.removeClass("ui-selected"); 11282 selectee.selected = false; 11283 } 11284 if (selectee.unselecting) { 11285 selectee.$element.removeClass("ui-unselecting"); 11286 selectee.unselecting = false; 11287 } 11288 if (!selectee.selecting) { 11289 selectee.$element.addClass("ui-selecting"); 11290 selectee.selecting = true; 11291 // selectable SELECTING callback 11292 that._trigger("selecting", event, { 11293 selecting: selectee.element 11294 }); 11295 } 11296 } else { 11297 // UNSELECT 11298 if (selectee.selecting) { 11299 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 11300 selectee.$element.removeClass("ui-selecting"); 11301 selectee.selecting = false; 11302 selectee.$element.addClass("ui-selected"); 11303 selectee.selected = true; 11304 } else { 11305 selectee.$element.removeClass("ui-selecting"); 11306 selectee.selecting = false; 11307 if (selectee.startselected) { 11308 selectee.$element.addClass("ui-unselecting"); 11309 selectee.unselecting = true; 11310 } 11311 // selectable UNSELECTING callback 11312 that._trigger("unselecting", event, { 11313 unselecting: selectee.element 11314 }); 11315 } 11316 } 11317 if (selectee.selected) { 11318 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 11319 selectee.$element.removeClass("ui-selected"); 11320 selectee.selected = false; 11321 11322 selectee.$element.addClass("ui-unselecting"); 11323 selectee.unselecting = true; 11324 // selectable UNSELECTING callback 11325 that._trigger("unselecting", event, { 11326 unselecting: selectee.element 11327 }); 11328 } 11329 } 11330 } 11331 }); 11332 11333 return false; 11334 }, 11335 11336 _mouseStop: function(event) { 11337 var that = this; 11338 11339 this.dragged = false; 11340 11341 $(".ui-unselecting", this.element[0]).each(function() { 11342 var selectee = $.data(this, "selectable-item"); 11343 selectee.$element.removeClass("ui-unselecting"); 11344 selectee.unselecting = false; 11345 selectee.startselected = false; 11346 that._trigger("unselected", event, { 11347 unselected: selectee.element 11348 }); 11349 }); 11350 $(".ui-selecting", this.element[0]).each(function() { 11351 var selectee = $.data(this, "selectable-item"); 11352 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 11353 selectee.selecting = false; 11354 selectee.selected = true; 11355 selectee.startselected = true; 11356 that._trigger("selected", event, { 11357 selected: selectee.element 11358 }); 11359 }); 11360 this._trigger("stop", event); 11361 11362 this.helper.remove(); 11363 11364 return false; 11365 } 11366 11367}); 11368 11369})(jQuery); 11370(function( $, undefined ) { 11371 11372// number of pages in a slider 11373// (how many times can you page up/down to go through the whole range) 11374var numPages = 5; 11375 11376$.widget( "ui.slider", $.ui.mouse, { 11377 version: "1.10.4", 11378 widgetEventPrefix: "slide", 11379 11380 options: { 11381 animate: false, 11382 distance: 0, 11383 max: 100, 11384 min: 0, 11385 orientation: "horizontal", 11386 range: false, 11387 step: 1, 11388 value: 0, 11389 values: null, 11390 11391 // callbacks 11392 change: null, 11393 slide: null, 11394 start: null, 11395 stop: null 11396 }, 11397 11398 _create: function() { 11399 this._keySliding = false; 11400 this._mouseSliding = false; 11401 this._animateOff = true; 11402 this._handleIndex = null; 11403 this._detectOrientation(); 11404 this._mouseInit(); 11405 11406 this.element 11407 .addClass( "ui-slider" + 11408 " ui-slider-" + this.orientation + 11409 " ui-widget" + 11410 " ui-widget-content" + 11411 " ui-corner-all"); 11412 11413 this._refresh(); 11414 this._setOption( "disabled", this.options.disabled ); 11415 11416 this._animateOff = false; 11417 }, 11418 11419 _refresh: function() { 11420 this._createRange(); 11421 this._createHandles(); 11422 this._setupEvents(); 11423 this._refreshValue(); 11424 }, 11425 11426 _createHandles: function() { 11427 var i, handleCount, 11428 options = this.options, 11429 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 11430 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 11431 handles = []; 11432 11433 handleCount = ( options.values && options.values.length ) || 1; 11434 11435 if ( existingHandles.length > handleCount ) { 11436 existingHandles.slice( handleCount ).remove(); 11437 existingHandles = existingHandles.slice( 0, handleCount ); 11438 } 11439 11440 for ( i = existingHandles.length; i < handleCount; i++ ) { 11441 handles.push( handle ); 11442 } 11443 11444 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 11445 11446 this.handle = this.handles.eq( 0 ); 11447 11448 this.handles.each(function( i ) { 11449 $( this ).data( "ui-slider-handle-index", i ); 11450 }); 11451 }, 11452 11453 _createRange: function() { 11454 var options = this.options, 11455 classes = ""; 11456 11457 if ( options.range ) { 11458 if ( options.range === true ) { 11459 if ( !options.values ) { 11460 options.values = [ this._valueMin(), this._valueMin() ]; 11461 } else if ( options.values.length && options.values.length !== 2 ) { 11462 options.values = [ options.values[0], options.values[0] ]; 11463 } else if ( $.isArray( options.values ) ) { 11464 options.values = options.values.slice(0); 11465 } 11466 } 11467 11468 if ( !this.range || !this.range.length ) { 11469 this.range = $( "<div></div>" ) 11470 .appendTo( this.element ); 11471 11472 classes = "ui-slider-range" + 11473 // note: this isn't the most fittingly semantic framework class for this element, 11474 // but worked best visually with a variety of themes 11475 " ui-widget-header ui-corner-all"; 11476 } else { 11477 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 11478 // Handle range switching from true to min/max 11479 .css({ 11480 "left": "", 11481 "bottom": "" 11482 }); 11483 } 11484 11485 this.range.addClass( classes + 11486 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 11487 } else { 11488 if ( this.range ) { 11489 this.range.remove(); 11490 } 11491 this.range = null; 11492 } 11493 }, 11494 11495 _setupEvents: function() { 11496 var elements = this.handles.add( this.range ).filter( "a" ); 11497 this._off( elements ); 11498 this._on( elements, this._handleEvents ); 11499 this._hoverable( elements ); 11500 this._focusable( elements ); 11501 }, 11502 11503 _destroy: function() { 11504 this.handles.remove(); 11505 if ( this.range ) { 11506 this.range.remove(); 11507 } 11508 11509 this.element 11510 .removeClass( "ui-slider" + 11511 " ui-slider-horizontal" + 11512 " ui-slider-vertical" + 11513 " ui-widget" + 11514 " ui-widget-content" + 11515 " ui-corner-all" ); 11516 11517 this._mouseDestroy(); 11518 }, 11519 11520 _mouseCapture: function( event ) { 11521 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 11522 that = this, 11523 o = this.options; 11524 11525 if ( o.disabled ) { 11526 return false; 11527 } 11528 11529 this.elementSize = { 11530 width: this.element.outerWidth(), 11531 height: this.element.outerHeight() 11532 }; 11533 this.elementOffset = this.element.offset(); 11534 11535 position = { x: event.pageX, y: event.pageY }; 11536 normValue = this._normValueFromMouse( position ); 11537 distance = this._valueMax() - this._valueMin() + 1; 11538 this.handles.each(function( i ) { 11539 var thisDistance = Math.abs( normValue - that.values(i) ); 11540 if (( distance > thisDistance ) || 11541 ( distance === thisDistance && 11542 (i === that._lastChangedValue || that.values(i) === o.min ))) { 11543 distance = thisDistance; 11544 closestHandle = $( this ); 11545 index = i; 11546 } 11547 }); 11548 11549 allowed = this._start( event, index ); 11550 if ( allowed === false ) { 11551 return false; 11552 } 11553 this._mouseSliding = true; 11554 11555 this._handleIndex = index; 11556 11557 closestHandle 11558 .addClass( "ui-state-active" ) 11559 .focus(); 11560 11561 offset = closestHandle.offset(); 11562 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 11563 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 11564 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 11565 top: event.pageY - offset.top - 11566 ( closestHandle.height() / 2 ) - 11567 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 11568 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 11569 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 11570 }; 11571 11572 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 11573 this._slide( event, index, normValue ); 11574 } 11575 this._animateOff = true; 11576 return true; 11577 }, 11578 11579 _mouseStart: function() { 11580 return true; 11581 }, 11582 11583 _mouseDrag: function( event ) { 11584 var position = { x: event.pageX, y: event.pageY }, 11585 normValue = this._normValueFromMouse( position ); 11586 11587 this._slide( event, this._handleIndex, normValue ); 11588 11589 return false; 11590 }, 11591 11592 _mouseStop: function( event ) { 11593 this.handles.removeClass( "ui-state-active" ); 11594 this._mouseSliding = false; 11595 11596 this._stop( event, this._handleIndex ); 11597 this._change( event, this._handleIndex ); 11598 11599 this._handleIndex = null; 11600 this._clickOffset = null; 11601 this._animateOff = false; 11602 11603 return false; 11604 }, 11605 11606 _detectOrientation: function() { 11607 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 11608 }, 11609 11610 _normValueFromMouse: function( position ) { 11611 var pixelTotal, 11612 pixelMouse, 11613 percentMouse, 11614 valueTotal, 11615 valueMouse; 11616 11617 if ( this.orientation === "horizontal" ) { 11618 pixelTotal = this.elementSize.width; 11619 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 11620 } else { 11621 pixelTotal = this.elementSize.height; 11622 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 11623 } 11624 11625 percentMouse = ( pixelMouse / pixelTotal ); 11626 if ( percentMouse > 1 ) { 11627 percentMouse = 1; 11628 } 11629 if ( percentMouse < 0 ) { 11630 percentMouse = 0; 11631 } 11632 if ( this.orientation === "vertical" ) { 11633 percentMouse = 1 - percentMouse; 11634 } 11635 11636 valueTotal = this._valueMax() - this._valueMin(); 11637 valueMouse = this._valueMin() + percentMouse * valueTotal; 11638 11639 return this._trimAlignValue( valueMouse ); 11640 }, 11641 11642 _start: function( event, index ) { 11643 var uiHash = { 11644 handle: this.handles[ index ], 11645 value: this.value() 11646 }; 11647 if ( this.options.values && this.options.values.length ) { 11648 uiHash.value = this.values( index ); 11649 uiHash.values = this.values(); 11650 } 11651 return this._trigger( "start", event, uiHash ); 11652 }, 11653 11654 _slide: function( event, index, newVal ) { 11655 var otherVal, 11656 newValues, 11657 allowed; 11658 11659 if ( this.options.values && this.options.values.length ) { 11660 otherVal = this.values( index ? 0 : 1 ); 11661 11662 if ( ( this.options.values.length === 2 && this.options.range === true ) && 11663 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 11664 ) { 11665 newVal = otherVal; 11666 } 11667 11668 if ( newVal !== this.values( index ) ) { 11669 newValues = this.values(); 11670 newValues[ index ] = newVal; 11671 // A slide can be canceled by returning false from the slide callback 11672 allowed = this._trigger( "slide", event, { 11673 handle: this.handles[ index ], 11674 value: newVal, 11675 values: newValues 11676 } ); 11677 otherVal = this.values( index ? 0 : 1 ); 11678 if ( allowed !== false ) { 11679 this.values( index, newVal ); 11680 } 11681 } 11682 } else { 11683 if ( newVal !== this.value() ) { 11684 // A slide can be canceled by returning false from the slide callback 11685 allowed = this._trigger( "slide", event, { 11686 handle: this.handles[ index ], 11687 value: newVal 11688 } ); 11689 if ( allowed !== false ) { 11690 this.value( newVal ); 11691 } 11692 } 11693 } 11694 }, 11695 11696 _stop: function( event, index ) { 11697 var uiHash = { 11698 handle: this.handles[ index ], 11699 value: this.value() 11700 }; 11701 if ( this.options.values && this.options.values.length ) { 11702 uiHash.value = this.values( index ); 11703 uiHash.values = this.values(); 11704 } 11705 11706 this._trigger( "stop", event, uiHash ); 11707 }, 11708 11709 _change: function( event, index ) { 11710 if ( !this._keySliding && !this._mouseSliding ) { 11711 var uiHash = { 11712 handle: this.handles[ index ], 11713 value: this.value() 11714 }; 11715 if ( this.options.values && this.options.values.length ) { 11716 uiHash.value = this.values( index ); 11717 uiHash.values = this.values(); 11718 } 11719 11720 //store the last changed value index for reference when handles overlap 11721 this._lastChangedValue = index; 11722 11723 this._trigger( "change", event, uiHash ); 11724 } 11725 }, 11726 11727 value: function( newValue ) { 11728 if ( arguments.length ) { 11729 this.options.value = this._trimAlignValue( newValue ); 11730 this._refreshValue(); 11731 this._change( null, 0 ); 11732 return; 11733 } 11734 11735 return this._value(); 11736 }, 11737 11738 values: function( index, newValue ) { 11739 var vals, 11740 newValues, 11741 i; 11742 11743 if ( arguments.length > 1 ) { 11744 this.options.values[ index ] = this._trimAlignValue( newValue ); 11745 this._refreshValue(); 11746 this._change( null, index ); 11747 return; 11748 } 11749 11750 if ( arguments.length ) { 11751 if ( $.isArray( arguments[ 0 ] ) ) { 11752 vals = this.options.values; 11753 newValues = arguments[ 0 ]; 11754 for ( i = 0; i < vals.length; i += 1 ) { 11755 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 11756 this._change( null, i ); 11757 } 11758 this._refreshValue(); 11759 } else { 11760 if ( this.options.values && this.options.values.length ) { 11761 return this._values( index ); 11762 } else { 11763 return this.value(); 11764 } 11765 } 11766 } else { 11767 return this._values(); 11768 } 11769 }, 11770 11771 _setOption: function( key, value ) { 11772 var i, 11773 valsLength = 0; 11774 11775 if ( key === "range" && this.options.range === true ) { 11776 if ( value === "min" ) { 11777 this.options.value = this._values( 0 ); 11778 this.options.values = null; 11779 } else if ( value === "max" ) { 11780 this.options.value = this._values( this.options.values.length-1 ); 11781 this.options.values = null; 11782 } 11783 } 11784 11785 if ( $.isArray( this.options.values ) ) { 11786 valsLength = this.options.values.length; 11787 } 11788 11789 $.Widget.prototype._setOption.apply( this, arguments ); 11790 11791 switch ( key ) { 11792 case "orientation": 11793 this._detectOrientation(); 11794 this.element 11795 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 11796 .addClass( "ui-slider-" + this.orientation ); 11797 this._refreshValue(); 11798 break; 11799 case "value": 11800 this._animateOff = true; 11801 this._refreshValue(); 11802 this._change( null, 0 ); 11803 this._animateOff = false; 11804 break; 11805 case "values": 11806 this._animateOff = true; 11807 this._refreshValue(); 11808 for ( i = 0; i < valsLength; i += 1 ) { 11809 this._change( null, i ); 11810 } 11811 this._animateOff = false; 11812 break; 11813 case "min": 11814 case "max": 11815 this._animateOff = true; 11816 this._refreshValue(); 11817 this._animateOff = false; 11818 break; 11819 case "range": 11820 this._animateOff = true; 11821 this._refresh(); 11822 this._animateOff = false; 11823 break; 11824 } 11825 }, 11826 11827 //internal value getter 11828 // _value() returns value trimmed by min and max, aligned by step 11829 _value: function() { 11830 var val = this.options.value; 11831 val = this._trimAlignValue( val ); 11832 11833 return val; 11834 }, 11835 11836 //internal values getter 11837 // _values() returns array of values trimmed by min and max, aligned by step 11838 // _values( index ) returns single value trimmed by min and max, aligned by step 11839 _values: function( index ) { 11840 var val, 11841 vals, 11842 i; 11843 11844 if ( arguments.length ) { 11845 val = this.options.values[ index ]; 11846 val = this._trimAlignValue( val ); 11847 11848 return val; 11849 } else if ( this.options.values && this.options.values.length ) { 11850 // .slice() creates a copy of the array 11851 // this copy gets trimmed by min and max and then returned 11852 vals = this.options.values.slice(); 11853 for ( i = 0; i < vals.length; i+= 1) { 11854 vals[ i ] = this._trimAlignValue( vals[ i ] ); 11855 } 11856 11857 return vals; 11858 } else { 11859 return []; 11860 } 11861 }, 11862 11863 // returns the step-aligned value that val is closest to, between (inclusive) min and max 11864 _trimAlignValue: function( val ) { 11865 if ( val <= this._valueMin() ) { 11866 return this._valueMin(); 11867 } 11868 if ( val >= this._valueMax() ) { 11869 return this._valueMax(); 11870 } 11871 var step = ( this.options.step > 0 ) ? this.options.step : 1, 11872 valModStep = (val - this._valueMin()) % step, 11873 alignValue = val - valModStep; 11874 11875 if ( Math.abs(valModStep) * 2 >= step ) { 11876 alignValue += ( valModStep > 0 ) ? step : ( -step ); 11877 } 11878 11879 // Since JavaScript has problems with large floats, round 11880 // the final value to 5 digits after the decimal point (see #4124) 11881 return parseFloat( alignValue.toFixed(5) ); 11882 }, 11883 11884 _valueMin: function() { 11885 return this.options.min; 11886 }, 11887 11888 _valueMax: function() { 11889 return this.options.max; 11890 }, 11891 11892 _refreshValue: function() { 11893 var lastValPercent, valPercent, value, valueMin, valueMax, 11894 oRange = this.options.range, 11895 o = this.options, 11896 that = this, 11897 animate = ( !this._animateOff ) ? o.animate : false, 11898 _set = {}; 11899 11900 if ( this.options.values && this.options.values.length ) { 11901 this.handles.each(function( i ) { 11902 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 11903 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 11904 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 11905 if ( that.options.range === true ) { 11906 if ( that.orientation === "horizontal" ) { 11907 if ( i === 0 ) { 11908 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 11909 } 11910 if ( i === 1 ) { 11911 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 11912 } 11913 } else { 11914 if ( i === 0 ) { 11915 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 11916 } 11917 if ( i === 1 ) { 11918 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 11919 } 11920 } 11921 } 11922 lastValPercent = valPercent; 11923 }); 11924 } else { 11925 value = this.value(); 11926 valueMin = this._valueMin(); 11927 valueMax = this._valueMax(); 11928 valPercent = ( valueMax !== valueMin ) ? 11929 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 11930 0; 11931 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 11932 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 11933 11934 if ( oRange === "min" && this.orientation === "horizontal" ) { 11935 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 11936 } 11937 if ( oRange === "max" && this.orientation === "horizontal" ) { 11938 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 11939 } 11940 if ( oRange === "min" && this.orientation === "vertical" ) { 11941 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 11942 } 11943 if ( oRange === "max" && this.orientation === "vertical" ) { 11944 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 11945 } 11946 } 11947 }, 11948 11949 _handleEvents: { 11950 keydown: function( event ) { 11951 var allowed, curVal, newVal, step, 11952 index = $( event.target ).data( "ui-slider-handle-index" ); 11953 11954 switch ( event.keyCode ) { 11955 case $.ui.keyCode.HOME: 11956 case $.ui.keyCode.END: 11957 case $.ui.keyCode.PAGE_UP: 11958 case $.ui.keyCode.PAGE_DOWN: 11959 case $.ui.keyCode.UP: 11960 case $.ui.keyCode.RIGHT: 11961 case $.ui.keyCode.DOWN: 11962 case $.ui.keyCode.LEFT: 11963 event.preventDefault(); 11964 if ( !this._keySliding ) { 11965 this._keySliding = true; 11966 $( event.target ).addClass( "ui-state-active" ); 11967 allowed = this._start( event, index ); 11968 if ( allowed === false ) { 11969 return; 11970 } 11971 } 11972 break; 11973 } 11974 11975 step = this.options.step; 11976 if ( this.options.values && this.options.values.length ) { 11977 curVal = newVal = this.values( index ); 11978 } else { 11979 curVal = newVal = this.value(); 11980 } 11981 11982 switch ( event.keyCode ) { 11983 case $.ui.keyCode.HOME: 11984 newVal = this._valueMin(); 11985 break; 11986 case $.ui.keyCode.END: 11987 newVal = this._valueMax(); 11988 break; 11989 case $.ui.keyCode.PAGE_UP: 11990 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 11991 break; 11992 case $.ui.keyCode.PAGE_DOWN: 11993 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 11994 break; 11995 case $.ui.keyCode.UP: 11996 case $.ui.keyCode.RIGHT: 11997 if ( curVal === this._valueMax() ) { 11998 return; 11999 } 12000 newVal = this._trimAlignValue( curVal + step ); 12001 break; 12002 case $.ui.keyCode.DOWN: 12003 case $.ui.keyCode.LEFT: 12004 if ( curVal === this._valueMin() ) { 12005 return; 12006 } 12007 newVal = this._trimAlignValue( curVal - step ); 12008 break; 12009 } 12010 12011 this._slide( event, index, newVal ); 12012 }, 12013 click: function( event ) { 12014 event.preventDefault(); 12015 }, 12016 keyup: function( event ) { 12017 var index = $( event.target ).data( "ui-slider-handle-index" ); 12018 12019 if ( this._keySliding ) { 12020 this._keySliding = false; 12021 this._stop( event, index ); 12022 this._change( event, index ); 12023 $( event.target ).removeClass( "ui-state-active" ); 12024 } 12025 } 12026 } 12027 12028}); 12029 12030}(jQuery)); 12031(function( $, undefined ) { 12032 12033function isOverAxis( x, reference, size ) { 12034 return ( x > reference ) && ( x < ( reference + size ) ); 12035} 12036 12037function isFloating(item) { 12038 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 12039} 12040 12041$.widget("ui.sortable", $.ui.mouse, { 12042 version: "1.10.4", 12043 widgetEventPrefix: "sort", 12044 ready: false, 12045 options: { 12046 appendTo: "parent", 12047 axis: false, 12048 connectWith: false, 12049 containment: false, 12050 cursor: "auto", 12051 cursorAt: false, 12052 dropOnEmpty: true, 12053 forcePlaceholderSize: false, 12054 forceHelperSize: false, 12055 grid: false, 12056 handle: false, 12057 helper: "original", 12058 items: "> *", 12059 opacity: false, 12060 placeholder: false, 12061 revert: false, 12062 scroll: true, 12063 scrollSensitivity: 20, 12064 scrollSpeed: 20, 12065 scope: "default", 12066 tolerance: "intersect", 12067 zIndex: 1000, 12068 12069 // callbacks 12070 activate: null, 12071 beforeStop: null, 12072 change: null, 12073 deactivate: null, 12074 out: null, 12075 over: null, 12076 receive: null, 12077 remove: null, 12078 sort: null, 12079 start: null, 12080 stop: null, 12081 update: null 12082 }, 12083 _create: function() { 12084 12085 var o = this.options; 12086 this.containerCache = {}; 12087 this.element.addClass("ui-sortable"); 12088 12089 //Get the items 12090 this.refresh(); 12091 12092 //Let's determine if the items are being displayed horizontally 12093 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; 12094 12095 //Let's determine the parent's offset 12096 this.offset = this.element.offset(); 12097 12098 //Initialize mouse events for interaction 12099 this._mouseInit(); 12100 12101 //We're ready to go 12102 this.ready = true; 12103 12104 }, 12105 12106 _destroy: function() { 12107 this.element 12108 .removeClass("ui-sortable ui-sortable-disabled"); 12109 this._mouseDestroy(); 12110 12111 for ( var i = this.items.length - 1; i >= 0; i-- ) { 12112 this.items[i].item.removeData(this.widgetName + "-item"); 12113 } 12114 12115 return this; 12116 }, 12117 12118 _setOption: function(key, value){ 12119 if ( key === "disabled" ) { 12120 this.options[ key ] = value; 12121 12122 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 12123 } else { 12124 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 12125 $.Widget.prototype._setOption.apply(this, arguments); 12126 } 12127 }, 12128 12129 _mouseCapture: function(event, overrideHandle) { 12130 var currentItem = null, 12131 validHandle = false, 12132 that = this; 12133 12134 if (this.reverting) { 12135 return false; 12136 } 12137 12138 if(this.options.disabled || this.options.type === "static") { 12139 return false; 12140 } 12141 12142 //We have to refresh the items data once first 12143 this._refreshItems(event); 12144 12145 //Find out if the clicked node (or one of its parents) is a actual item in this.items 12146 $(event.target).parents().each(function() { 12147 if($.data(this, that.widgetName + "-item") === that) { 12148 currentItem = $(this); 12149 return false; 12150 } 12151 }); 12152 if($.data(event.target, that.widgetName + "-item") === that) { 12153 currentItem = $(event.target); 12154 } 12155 12156 if(!currentItem) { 12157 return false; 12158 } 12159 if(this.options.handle && !overrideHandle) { 12160 $(this.options.handle, currentItem).find("*").addBack().each(function() { 12161 if(this === event.target) { 12162 validHandle = true; 12163 } 12164 }); 12165 if(!validHandle) { 12166 return false; 12167 } 12168 } 12169 12170 this.currentItem = currentItem; 12171 this._removeCurrentsFromItems(); 12172 return true; 12173 12174 }, 12175 12176 _mouseStart: function(event, overrideHandle, noActivation) { 12177 12178 var i, body, 12179 o = this.options; 12180 12181 this.currentContainer = this; 12182 12183 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 12184 this.refreshPositions(); 12185 12186 //Create and append the visible helper 12187 this.helper = this._createHelper(event); 12188 12189 //Cache the helper size 12190 this._cacheHelperProportions(); 12191 12192 /* 12193 * - Position generation - 12194 * This block generates everything position related - it's the core of draggables. 12195 */ 12196 12197 //Cache the margins of the original element 12198 this._cacheMargins(); 12199 12200 //Get the next scrolling parent 12201 this.scrollParent = this.helper.scrollParent(); 12202 12203 //The element's absolute position on the page minus margins 12204 this.offset = this.currentItem.offset(); 12205 this.offset = { 12206 top: this.offset.top - this.margins.top, 12207 left: this.offset.left - this.margins.left 12208 }; 12209 12210 $.extend(this.offset, { 12211 click: { //Where the click happened, relative to the element 12212 left: event.pageX - this.offset.left, 12213 top: event.pageY - this.offset.top 12214 }, 12215 parent: this._getParentOffset(), 12216 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 12217 }); 12218 12219 // Only after we got the offset, we can change the helper's position to absolute 12220 // TODO: Still need to figure out a way to make relative sorting possible 12221 this.helper.css("position", "absolute"); 12222 this.cssPosition = this.helper.css("position"); 12223 12224 //Generate the original position 12225 this.originalPosition = this._generatePosition(event); 12226 this.originalPageX = event.pageX; 12227 this.originalPageY = event.pageY; 12228 12229 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 12230 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 12231 12232 //Cache the former DOM position 12233 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 12234 12235 //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 12236 if(this.helper[0] !== this.currentItem[0]) { 12237 this.currentItem.hide(); 12238 } 12239 12240 //Create the placeholder 12241 this._createPlaceholder(); 12242 12243 //Set a containment if given in the options 12244 if(o.containment) { 12245 this._setContainment(); 12246 } 12247 12248 if( o.cursor && o.cursor !== "auto" ) { // cursor option 12249 body = this.document.find( "body" ); 12250 12251 // support: IE 12252 this.storedCursor = body.css( "cursor" ); 12253 body.css( "cursor", o.cursor ); 12254 12255 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 12256 } 12257 12258 if(o.opacity) { // opacity option 12259 if (this.helper.css("opacity")) { 12260 this._storedOpacity = this.helper.css("opacity"); 12261 } 12262 this.helper.css("opacity", o.opacity); 12263 } 12264 12265 if(o.zIndex) { // zIndex option 12266 if (this.helper.css("zIndex")) { 12267 this._storedZIndex = this.helper.css("zIndex"); 12268 } 12269 this.helper.css("zIndex", o.zIndex); 12270 } 12271 12272 //Prepare scrolling 12273 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 12274 this.overflowOffset = this.scrollParent.offset(); 12275 } 12276 12277 //Call callbacks 12278 this._trigger("start", event, this._uiHash()); 12279 12280 //Recache the helper size 12281 if(!this._preserveHelperProportions) { 12282 this._cacheHelperProportions(); 12283 } 12284 12285 12286 //Post "activate" events to possible containers 12287 if( !noActivation ) { 12288 for ( i = this.containers.length - 1; i >= 0; i-- ) { 12289 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 12290 } 12291 } 12292 12293 //Prepare possible droppables 12294 if($.ui.ddmanager) { 12295 $.ui.ddmanager.current = this; 12296 } 12297 12298 if ($.ui.ddmanager && !o.dropBehaviour) { 12299 $.ui.ddmanager.prepareOffsets(this, event); 12300 } 12301 12302 this.dragging = true; 12303 12304 this.helper.addClass("ui-sortable-helper"); 12305 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 12306 return true; 12307 12308 }, 12309 12310 _mouseDrag: function(event) { 12311 var i, item, itemElement, intersection, 12312 o = this.options, 12313 scrolled = false; 12314 12315 //Compute the helpers position 12316 this.position = this._generatePosition(event); 12317 this.positionAbs = this._convertPositionTo("absolute"); 12318 12319 if (!this.lastPositionAbs) { 12320 this.lastPositionAbs = this.positionAbs; 12321 } 12322 12323 //Do scrolling 12324 if(this.options.scroll) { 12325 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 12326 12327 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 12328 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 12329 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 12330 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 12331 } 12332 12333 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 12334 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 12335 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 12336 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 12337 } 12338 12339 } else { 12340 12341 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 12342 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 12343 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 12344 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 12345 } 12346 12347 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 12348 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 12349 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 12350 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 12351 } 12352 12353 } 12354 12355 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 12356 $.ui.ddmanager.prepareOffsets(this, event); 12357 } 12358 } 12359 12360 //Regenerate the absolute position used for position checks 12361 this.positionAbs = this._convertPositionTo("absolute"); 12362 12363 //Set the helper position 12364 if(!this.options.axis || this.options.axis !== "y") { 12365 this.helper[0].style.left = this.position.left+"px"; 12366 } 12367 if(!this.options.axis || this.options.axis !== "x") { 12368 this.helper[0].style.top = this.position.top+"px"; 12369 } 12370 12371 //Rearrange 12372 for (i = this.items.length - 1; i >= 0; i--) { 12373 12374 //Cache variables and intersection, continue if no intersection 12375 item = this.items[i]; 12376 itemElement = item.item[0]; 12377 intersection = this._intersectsWithPointer(item); 12378 if (!intersection) { 12379 continue; 12380 } 12381 12382 // Only put the placeholder inside the current Container, skip all 12383 // items from other containers. This works because when moving 12384 // an item from one container to another the 12385 // currentContainer is switched before the placeholder is moved. 12386 // 12387 // Without this, moving items in "sub-sortables" can cause 12388 // the placeholder to jitter beetween the outer and inner container. 12389 if (item.instance !== this.currentContainer) { 12390 continue; 12391 } 12392 12393 // cannot intersect with itself 12394 // no useless actions that have been done before 12395 // no action if the item moved is the parent of the item checked 12396 if (itemElement !== this.currentItem[0] && 12397 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 12398 !$.contains(this.placeholder[0], itemElement) && 12399 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 12400 ) { 12401 12402 this.direction = intersection === 1 ? "down" : "up"; 12403 12404 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 12405 this._rearrange(event, item); 12406 } else { 12407 break; 12408 } 12409 12410 this._trigger("change", event, this._uiHash()); 12411 break; 12412 } 12413 } 12414 12415 //Post events to containers 12416 this._contactContainers(event); 12417 12418 //Interconnect with droppables 12419 if($.ui.ddmanager) { 12420 $.ui.ddmanager.drag(this, event); 12421 } 12422 12423 //Call callbacks 12424 this._trigger("sort", event, this._uiHash()); 12425 12426 this.lastPositionAbs = this.positionAbs; 12427 return false; 12428 12429 }, 12430 12431 _mouseStop: function(event, noPropagation) { 12432 12433 if(!event) { 12434 return; 12435 } 12436 12437 //If we are using droppables, inform the manager about the drop 12438 if ($.ui.ddmanager && !this.options.dropBehaviour) { 12439 $.ui.ddmanager.drop(this, event); 12440 } 12441 12442 if(this.options.revert) { 12443 var that = this, 12444 cur = this.placeholder.offset(), 12445 axis = this.options.axis, 12446 animation = {}; 12447 12448 if ( !axis || axis === "x" ) { 12449 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 12450 } 12451 if ( !axis || axis === "y" ) { 12452 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 12453 } 12454 this.reverting = true; 12455 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 12456 that._clear(event); 12457 }); 12458 } else { 12459 this._clear(event, noPropagation); 12460 } 12461 12462 return false; 12463 12464 }, 12465 12466 cancel: function() { 12467 12468 if(this.dragging) { 12469 12470 this._mouseUp({ target: null }); 12471 12472 if(this.options.helper === "original") { 12473 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 12474 } else { 12475 this.currentItem.show(); 12476 } 12477 12478 //Post deactivating events to containers 12479 for (var i = this.containers.length - 1; i >= 0; i--){ 12480 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 12481 if(this.containers[i].containerCache.over) { 12482 this.containers[i]._trigger("out", null, this._uiHash(this)); 12483 this.containers[i].containerCache.over = 0; 12484 } 12485 } 12486 12487 } 12488 12489 if (this.placeholder) { 12490 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 12491 if(this.placeholder[0].parentNode) { 12492 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 12493 } 12494 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 12495 this.helper.remove(); 12496 } 12497 12498 $.extend(this, { 12499 helper: null, 12500 dragging: false, 12501 reverting: false, 12502 _noFinalSort: null 12503 }); 12504 12505 if(this.domPosition.prev) { 12506 $(this.domPosition.prev).after(this.currentItem); 12507 } else { 12508 $(this.domPosition.parent).prepend(this.currentItem); 12509 } 12510 } 12511 12512 return this; 12513 12514 }, 12515 12516 serialize: function(o) { 12517 12518 var items = this._getItemsAsjQuery(o && o.connected), 12519 str = []; 12520 o = o || {}; 12521 12522 $(items).each(function() { 12523 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 12524 if (res) { 12525 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 12526 } 12527 }); 12528 12529 if(!str.length && o.key) { 12530 str.push(o.key + "="); 12531 } 12532 12533 return str.join("&"); 12534 12535 }, 12536 12537 toArray: function(o) { 12538 12539 var items = this._getItemsAsjQuery(o && o.connected), 12540 ret = []; 12541 12542 o = o || {}; 12543 12544 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 12545 return ret; 12546 12547 }, 12548 12549 /* Be careful with the following core functions */ 12550 _intersectsWith: function(item) { 12551 12552 var x1 = this.positionAbs.left, 12553 x2 = x1 + this.helperProportions.width, 12554 y1 = this.positionAbs.top, 12555 y2 = y1 + this.helperProportions.height, 12556 l = item.left, 12557 r = l + item.width, 12558 t = item.top, 12559 b = t + item.height, 12560 dyClick = this.offset.click.top, 12561 dxClick = this.offset.click.left, 12562 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 12563 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 12564 isOverElement = isOverElementHeight && isOverElementWidth; 12565 12566 if ( this.options.tolerance === "pointer" || 12567 this.options.forcePointerForContainers || 12568 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 12569 ) { 12570 return isOverElement; 12571 } else { 12572 12573 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 12574 x2 - (this.helperProportions.width / 2) < r && // Left Half 12575 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 12576 y2 - (this.helperProportions.height / 2) < b ); // Top Half 12577 12578 } 12579 }, 12580 12581 _intersectsWithPointer: function(item) { 12582 12583 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 12584 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 12585 isOverElement = isOverElementHeight && isOverElementWidth, 12586 verticalDirection = this._getDragVerticalDirection(), 12587 horizontalDirection = this._getDragHorizontalDirection(); 12588 12589 if (!isOverElement) { 12590 return false; 12591 } 12592 12593 return this.floating ? 12594 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 12595 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 12596 12597 }, 12598 12599 _intersectsWithSides: function(item) { 12600 12601 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 12602 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 12603 verticalDirection = this._getDragVerticalDirection(), 12604 horizontalDirection = this._getDragHorizontalDirection(); 12605 12606 if (this.floating && horizontalDirection) { 12607 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 12608 } else { 12609 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 12610 } 12611 12612 }, 12613 12614 _getDragVerticalDirection: function() { 12615 var delta = this.positionAbs.top - this.lastPositionAbs.top; 12616 return delta !== 0 && (delta > 0 ? "down" : "up"); 12617 }, 12618 12619 _getDragHorizontalDirection: function() { 12620 var delta = this.positionAbs.left - this.lastPositionAbs.left; 12621 return delta !== 0 && (delta > 0 ? "right" : "left"); 12622 }, 12623 12624 refresh: function(event) { 12625 this._refreshItems(event); 12626 this.refreshPositions(); 12627 return this; 12628 }, 12629 12630 _connectWith: function() { 12631 var options = this.options; 12632 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 12633 }, 12634 12635 _getItemsAsjQuery: function(connected) { 12636 12637 var i, j, cur, inst, 12638 items = [], 12639 queries = [], 12640 connectWith = this._connectWith(); 12641 12642 if(connectWith && connected) { 12643 for (i = connectWith.length - 1; i >= 0; i--){ 12644 cur = $(connectWith[i]); 12645 for ( j = cur.length - 1; j >= 0; j--){ 12646 inst = $.data(cur[j], this.widgetFullName); 12647 if(inst && inst !== this && !inst.options.disabled) { 12648 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]); 12649 } 12650 } 12651 } 12652 } 12653 12654 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]); 12655 12656 function addItems() { 12657 items.push( this ); 12658 } 12659 for (i = queries.length - 1; i >= 0; i--){ 12660 queries[i][0].each( addItems ); 12661 } 12662 12663 return $(items); 12664 12665 }, 12666 12667 _removeCurrentsFromItems: function() { 12668 12669 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 12670 12671 this.items = $.grep(this.items, function (item) { 12672 for (var j=0; j < list.length; j++) { 12673 if(list[j] === item.item[0]) { 12674 return false; 12675 } 12676 } 12677 return true; 12678 }); 12679 12680 }, 12681 12682 _refreshItems: function(event) { 12683 12684 this.items = []; 12685 this.containers = [this]; 12686 12687 var i, j, cur, inst, targetData, _queries, item, queriesLength, 12688 items = this.items, 12689 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 12690 connectWith = this._connectWith(); 12691 12692 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 12693 for (i = connectWith.length - 1; i >= 0; i--){ 12694 cur = $(connectWith[i]); 12695 for (j = cur.length - 1; j >= 0; j--){ 12696 inst = $.data(cur[j], this.widgetFullName); 12697 if(inst && inst !== this && !inst.options.disabled) { 12698 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 12699 this.containers.push(inst); 12700 } 12701 } 12702 } 12703 } 12704 12705 for (i = queries.length - 1; i >= 0; i--) { 12706 targetData = queries[i][1]; 12707 _queries = queries[i][0]; 12708 12709 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 12710 item = $(_queries[j]); 12711 12712 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 12713 12714 items.push({ 12715 item: item, 12716 instance: targetData, 12717 width: 0, height: 0, 12718 left: 0, top: 0 12719 }); 12720 } 12721 } 12722 12723 }, 12724 12725 refreshPositions: function(fast) { 12726 12727 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 12728 if(this.offsetParent && this.helper) { 12729 this.offset.parent = this._getParentOffset(); 12730 } 12731 12732 var i, item, t, p; 12733 12734 for (i = this.items.length - 1; i >= 0; i--){ 12735 item = this.items[i]; 12736 12737 //We ignore calculating positions of all connected containers when we're not over them 12738 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 12739 continue; 12740 } 12741 12742 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 12743 12744 if (!fast) { 12745 item.width = t.outerWidth(); 12746 item.height = t.outerHeight(); 12747 } 12748 12749 p = t.offset(); 12750 item.left = p.left; 12751 item.top = p.top; 12752 } 12753 12754 if(this.options.custom && this.options.custom.refreshContainers) { 12755 this.options.custom.refreshContainers.call(this); 12756 } else { 12757 for (i = this.containers.length - 1; i >= 0; i--){ 12758 p = this.containers[i].element.offset(); 12759 this.containers[i].containerCache.left = p.left; 12760 this.containers[i].containerCache.top = p.top; 12761 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 12762 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 12763 } 12764 } 12765 12766 return this; 12767 }, 12768 12769 _createPlaceholder: function(that) { 12770 that = that || this; 12771 var className, 12772 o = that.options; 12773 12774 if(!o.placeholder || o.placeholder.constructor === String) { 12775 className = o.placeholder; 12776 o.placeholder = { 12777 element: function() { 12778 12779 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 12780 element = $( "<" + nodeName + ">", that.document[0] ) 12781 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 12782 .removeClass("ui-sortable-helper"); 12783 12784 if ( nodeName === "tr" ) { 12785 that.currentItem.children().each(function() { 12786 $( "<td> </td>", that.document[0] ) 12787 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 12788 .appendTo( element ); 12789 }); 12790 } else if ( nodeName === "img" ) { 12791 element.attr( "src", that.currentItem.attr( "src" ) ); 12792 } 12793 12794 if ( !className ) { 12795 element.css( "visibility", "hidden" ); 12796 } 12797 12798 return element; 12799 }, 12800 update: function(container, p) { 12801 12802 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 12803 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 12804 if(className && !o.forcePlaceholderSize) { 12805 return; 12806 } 12807 12808 //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 12809 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 12810 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 12811 } 12812 }; 12813 } 12814 12815 //Create the placeholder 12816 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 12817 12818 //Append it after the actual current item 12819 that.currentItem.after(that.placeholder); 12820 12821 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 12822 o.placeholder.update(that, that.placeholder); 12823 12824 }, 12825 12826 _contactContainers: function(event) { 12827 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, 12828 innermostContainer = null, 12829 innermostIndex = null; 12830 12831 // get innermost container that intersects with item 12832 for (i = this.containers.length - 1; i >= 0; i--) { 12833 12834 // never consider a container that's located within the item itself 12835 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 12836 continue; 12837 } 12838 12839 if(this._intersectsWith(this.containers[i].containerCache)) { 12840 12841 // if we've already found a container and it's more "inner" than this, then continue 12842 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 12843 continue; 12844 } 12845 12846 innermostContainer = this.containers[i]; 12847 innermostIndex = i; 12848 12849 } else { 12850 // container doesn't intersect. trigger "out" event if necessary 12851 if(this.containers[i].containerCache.over) { 12852 this.containers[i]._trigger("out", event, this._uiHash(this)); 12853 this.containers[i].containerCache.over = 0; 12854 } 12855 } 12856 12857 } 12858 12859 // if no intersecting containers found, return 12860 if(!innermostContainer) { 12861 return; 12862 } 12863 12864 // move the item into the container if it's not there already 12865 if(this.containers.length === 1) { 12866 if (!this.containers[innermostIndex].containerCache.over) { 12867 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 12868 this.containers[innermostIndex].containerCache.over = 1; 12869 } 12870 } else { 12871 12872 //When entering a new container, we will find the item with the least distance and append our item near it 12873 dist = 10000; 12874 itemWithLeastDistance = null; 12875 floating = innermostContainer.floating || isFloating(this.currentItem); 12876 posProperty = floating ? "left" : "top"; 12877 sizeProperty = floating ? "width" : "height"; 12878 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 12879 for (j = this.items.length - 1; j >= 0; j--) { 12880 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 12881 continue; 12882 } 12883 if(this.items[j].item[0] === this.currentItem[0]) { 12884 continue; 12885 } 12886 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { 12887 continue; 12888 } 12889 cur = this.items[j].item.offset()[posProperty]; 12890 nearBottom = false; 12891 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 12892 nearBottom = true; 12893 cur += this.items[j][sizeProperty]; 12894 } 12895 12896 if(Math.abs(cur - base) < dist) { 12897 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 12898 this.direction = nearBottom ? "up": "down"; 12899 } 12900 } 12901 12902 //Check if dropOnEmpty is enabled 12903 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 12904 return; 12905 } 12906 12907 if(this.currentContainer === this.containers[innermostIndex]) { 12908 return; 12909 } 12910 12911 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 12912 this._trigger("change", event, this._uiHash()); 12913 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 12914 this.currentContainer = this.containers[innermostIndex]; 12915 12916 //Update the placeholder 12917 this.options.placeholder.update(this.currentContainer, this.placeholder); 12918 12919 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 12920 this.containers[innermostIndex].containerCache.over = 1; 12921 } 12922 12923 12924 }, 12925 12926 _createHelper: function(event) { 12927 12928 var o = this.options, 12929 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 12930 12931 //Add the helper to the DOM if that didn't happen already 12932 if(!helper.parents("body").length) { 12933 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 12934 } 12935 12936 if(helper[0] === this.currentItem[0]) { 12937 this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left
vendor: 4,379 bytes, lines 12937-13054
12937: this.currentItem.css("left") }; 12938 } 12939 12940 if(!helper[0].style.width || o.forceHelperSize) { 12941 helper.width(this.currentItem.width()); 12942 } 12943 if(!helper[0].style.height || o.forceHelperSize) { 12944 helper.height(this.currentItem.height()); 12945 } 12946 12947 return helper; 12948 12949 }, 12950 12951 _adjustOffsetFromHelper: function(obj) { 12952 if (typeof obj === "string") { 12953 obj = obj.split(" "); 12954 } 12955 if ($.isArray(obj)) { 12956 obj = {left: +obj[0], top: +obj[1] || 0}; 12957 } 12958 if ("left" in obj) { 12959 this.offset.click.left = obj.left + this.margins.left; 12960 } 12961 if ("right" in obj) { 12962 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 12963 } 12964 if ("top" in obj) { 12965 this.offset.click.top = obj.top + this.margins.top; 12966 } 12967 if ("bottom" in obj) { 12968 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 12969 } 12970 }, 12971 12972 _getParentOffset: function() { 12973 12974 12975 //Get the offsetParent and cache its position 12976 this.offsetParent = this.helper.offsetParent(); 12977 var po = this.offsetParent.offset(); 12978 12979 // This is a special case where we need to modify a offset calculated on start, since the following happened: 12980 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 12981 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 12982 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 12983 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 12984 po.left += this.scrollParent.scrollLeft(); 12985 po.top += this.scrollParent.scrollTop(); 12986 } 12987 12988 // This needs to be actually done for all browsers, since pageX/pageY includes this information 12989 // with an ugly IE fix 12990 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 12991 po = { top: 0, left: 0 }; 12992 } 12993 12994 return { 12995 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 12996 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 12997 }; 12998 12999 }, 13000 13001 _getRelativeOffset: function() { 13002 13003 if(this.cssPosition === "relative") { 13004 var p = this.currentItem.position(); 13005 return { 13006 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 13007 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 13008 }; 13009 } else { 13010 return { top: 0, left: 0 }; 13011 } 13012 13013 }, 13014 13015 _cacheMargins: function() { 13016 this.margins = { 13017 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 13018 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 13019 }; 13020 }, 13021 13022 _cacheHelperProportions: function() { 13023 this.helperProportions = { 13024 width: this.helper.outerWidth(), 13025 height: this.helper.outerHeight() 13026 }; 13027 }, 13028 13029 _setContainment: function() { 13030 13031 var ce, co, over, 13032 o = this.options; 13033 if(o.containment === "parent") { 13034 o.containment = this.helper[0].parentNode; 13035 } 13036 if(o.containment === "document" || o.containment === "window") { 13037 this.containment = [ 13038 0 - this.offset.relative.left - this.offset.parent.left, 13039 0 - this.offset.relative.top - this.offset.parent.top, 13040 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 13041 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 13042 ]; 13043 } 13044 13045 if(!(/^(document|window|parent)$/).test(o.containment)) { 13046 ce = $(o.containment)[0]; 13047 co = $(o.containment).offset(); 13048 over = ($(ce).css("overflow") !== "hidden"); 13049 13050 this.containment = [ 13051 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 13052 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 13053 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, 13054 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
vendor: 5,508 bytes, lines 13054-13166
1305410) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 13055 ]; 13056 } 13057 13058 }, 13059 13060 _convertPositionTo: function(d, pos) { 13061 13062 if(!pos) { 13063 pos = this.position; 13064 } 13065 var mod = d === "absolute" ? 1 : -1, 13066 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 13067 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 13068 13069 return { 13070 top: ( 13071 pos.top + // The absolute mouse position 13072 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 13073 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 13074 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 13075 ), 13076 left: ( 13077 pos.left + // The absolute mouse position 13078 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 13079 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 13080 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 13081 ) 13082 }; 13083 13084 }, 13085 13086 _generatePosition: function(event) { 13087 13088 var top, left, 13089 o = this.options, 13090 pageX = event.pageX, 13091 pageY = event.pageY, 13092 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); 13093 13094 // This is another very weird special case that only happens for relative elements: 13095 // 1. If the css position is relative 13096 // 2. and the scroll parent is the document or similar to the offset parent 13097 // we have to refresh the relative offset during the scroll so there are no jumps 13098 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 13099 this.offset.relative = this._getRelativeOffset(); 13100 } 13101 13102 /* 13103 * - Position constraining - 13104 * Constrain the position to a mix of grid, containment. 13105 */ 13106 13107 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 13108 13109 if(this.containment) { 13110 if(event.pageX - this.offset.click.left < this.containment[0]) { 13111 pageX = this.containment[0] + this.offset.click.left; 13112 } 13113 if(event.pageY - this.offset.click.top < this.containment[1]) { 13114 pageY = this.containment[1] + this.offset.click.top; 13115 } 13116 if(event.pageX - this.offset.click.left > this.containment[2]) { 13117 pageX = this.containment[2] + this.offset.click.left; 13118 } 13119 if(event.pageY - this.offset.click.top > this.containment[3]) { 13120 pageY = this.containment[3] + this.offset.click.top; 13121 } 13122 } 13123 13124 if(o.grid) { 13125 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 13126 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; 13127 13128 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 13129 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; 13130 } 13131 13132 } 13133 13134 return { 13135 top: ( 13136 pageY - // The absolute mouse position 13137 this.offset.click.top - // Click offset (relative to the element) 13138 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 13139 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 13140 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 13141 ), 13142 left: ( 13143 pageX - // The absolute mouse position 13144 this.offset.click.left - // Click offset (relative to the element) 13145 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 13146 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 13147 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 13148 ) 13149 }; 13150 13151 }, 13152 13153 _rearrange: function(event, i, a, hardRefresh) { 13154 13155 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)); 13156 13157 //Various things done here to improve the performance: 13158 // 1. we create a setTimeout, that calls refreshPositions 13159 // 2. on the instance, we have a counter variable, that get's higher after every append 13160 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 13161 // 4. this lets only the last addition to the timeout stack through 13162 this.counter = this.counter ? ++this.counter : 1; 13163 var counter = this.counter; 13164 13165 this._delay(function() { 13166 if(counter === this.counter) {
vendor: 3,346 bytes, lines 13167-13255
13167 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 13168 } 13169 }); 13170 13171 }, 13172 13173 _clear: function(event, noPropagation) { 13174 13175 this.reverting = false; 13176 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 13177 // everything else normalized again 13178 var i, 13179 delayedTriggers = []; 13180 13181 // We first have to update the dom position of the actual currentItem 13182 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 13183 if(!this._noFinalSort && this.currentItem.parent().length) { 13184 this.placeholder.before(this.currentItem); 13185 } 13186 this._noFinalSort = null; 13187 13188 if(this.helper[0] === this.currentItem[0]) { 13189 for(i in this._storedCSS) { 13190 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 13191 this._storedCSS[i] = ""; 13192 } 13193 } 13194 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 13195 } else { 13196 this.currentItem.show(); 13197 } 13198 13199 if(this.fromOutside && !noPropagation) { 13200 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 13201 } 13202 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 13203 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 13204 } 13205 13206 // Check if the items Container has Changed and trigger appropriate 13207 // events. 13208 if (this !== this.currentContainer) { 13209 if(!noPropagation) { 13210 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 13211 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 13212 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 13213 } 13214 } 13215 13216 13217 //Post events to containers 13218 function delayEvent( type, instance, container ) { 13219 return function( event ) { 13220 container._trigger( type, event, instance._uiHash( instance ) ); 13221 }; 13222 } 13223 for (i = this.containers.length - 1; i >= 0; i--){ 13224 if (!noPropagation) { 13225 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 13226 } 13227 if(this.containers[i].containerCache.over) { 13228 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 13229 this.containers[i].containerCache.over = 0; 13230 } 13231 } 13232 13233 //Do what was originally in plugins 13234 if ( this.storedCursor ) { 13235 this.document.find( "body" ).css( "cursor", this.storedCursor ); 13236 this.storedStylesheet.remove(); 13237 } 13238 if(this._storedOpacity) { 13239 this.helper.css("opacity", this._storedOpacity); 13240 } 13241 if(this._storedZIndex) { 13242 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 13243 } 13244 13245 this.dragging = false; 13246 if(this.cancelHelperRemoval) { 13247 if(!noPropagation) { 13248 this._trigger("beforeStop", event, this._uiHash()); 13249 for (i=0; i < delayedTriggers.length; i++) { 13250 delayedTriggers[i].call(this, event); 13251 } //Trigger all delayed events 13252 this._trigger("stop", event, this._uiHash()); 13253 } 13254 13255 this.fromOutside = false;
vendor: 45,640 bytes, lines 13256-15008
13256 return false; 13257 } 13258 13259 if(!noPropagation) { 13260 this._trigger("beforeStop", event, this._uiHash()); 13261 } 13262 13263 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 13264 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 13265 13266 if(this.helper[0] !== this.currentItem[0]) { 13267 this.helper.remove(); 13268 } 13269 this.helper = null; 13270 13271 if(!noPropagation) { 13272 for (i=0; i < delayedTriggers.length; i++) { 13273 delayedTriggers[i].call(this, event); 13274 } //Trigger all delayed events 13275 this._trigger("stop", event, this._uiHash()); 13276 } 13277 13278 this.fromOutside = false; 13279 return true; 13280 13281 }, 13282 13283 _trigger: function() { 13284 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 13285 this.cancel(); 13286 } 13287 }, 13288 13289 _uiHash: function(_inst) { 13290 var inst = _inst || this; 13291 return { 13292 helper: inst.helper, 13293 placeholder: inst.placeholder || $([]), 13294 position: inst.position, 13295 originalPosition: inst.originalPosition, 13296 offset: inst.positionAbs, 13297 item: inst.currentItem, 13298 sender: _inst ? _inst.element : null 13299 }; 13300 } 13301 13302}); 13303 13304})(jQuery); 13305(function( $ ) { 13306 13307function modifier( fn ) { 13308 return function() { 13309 var previous = this.element.val(); 13310 fn.apply( this, arguments ); 13311 this._refresh(); 13312 if ( previous !== this.element.val() ) { 13313 this._trigger( "change" ); 13314 } 13315 }; 13316} 13317 13318$.widget( "ui.spinner", { 13319 version: "1.10.4", 13320 defaultElement: "<input>", 13321 widgetEventPrefix: "spin", 13322 options: { 13323 culture: null, 13324 icons: { 13325 down: "ui-icon-triangle-1-s", 13326 up: "ui-icon-triangle-1-n" 13327 }, 13328 incremental: true, 13329 max: null, 13330 min: null, 13331 numberFormat: null, 13332 page: 10, 13333 step: 1, 13334 13335 change: null, 13336 spin: null, 13337 start: null, 13338 stop: null 13339 }, 13340 13341 _create: function() { 13342 // handle string values that need to be parsed 13343 this._setOption( "max", this.options.max ); 13344 this._setOption( "min", this.options.min ); 13345 this._setOption( "step", this.options.step ); 13346 13347 // Only format if there is a value, prevents the field from being marked 13348 // as invalid in Firefox, see #9573. 13349 if ( this.value() !== "" ) { 13350 // Format the value, but don't constrain. 13351 this._value( this.element.val(), true ); 13352 } 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(function( $, undefined ) { 13788 13789var tabId = 0, 13790 rhash = /#.*$/; 13791 13792function getNextTabId() { 13793 return ++tabId; 13794} 13795 13796function isLocal( anchor ) { 13797 // support: IE7 13798 // IE7 doesn't normalize the href property when set via script (#9317) 13799 anchor = anchor.cloneNode( false ); 13800 13801 return anchor.hash.length > 1 && 13802 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 13803 decodeURIComponent( location.href.replace( rhash, "" ) ); 13804} 13805 13806$.widget( "ui.tabs", { 13807 version: "1.10.4", 13808 delay: 300, 13809 options: { 13810 active: null, 13811 collapsible: false, 13812 event: "click", 13813 heightStyle: "content", 13814 hide: null, 13815 show: null, 13816 13817 // callbacks 13818 activate: null, 13819 beforeActivate: null, 13820 beforeLoad: null, 13821 load: null 13822 }, 13823 13824 _create: function() { 13825 var that = this, 13826 options = this.options; 13827 13828 this.running = false; 13829 13830 this.element 13831 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 13832 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 13833 // Prevent users from focusing disabled tabs via click 13834 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 13835 if ( $( this ).is( ".ui-state-disabled" ) ) { 13836 event.preventDefault(); 13837 } 13838 }) 13839 // support: IE <9 13840 // Preventing the default action in mousedown doesn't prevent IE 13841 // from focusing the element, so if the anchor gets focused, blur. 13842 // We don't have to worry about focusing the previously focused 13843 // element since clicking on a non-focusable element should focus 13844 // the body anyway. 13845 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 13846 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 13847 this.blur(); 13848 } 13849 }); 13850 13851 this._processTabs(); 13852 options.active = this._initialActive(); 13853 13854 // Take disabling tabs via class attribute from HTML 13855 // into account and update option properly. 13856 if ( $.isArray( options.disabled ) ) { 13857 options.disabled = $.unique( options.disabled.concat( 13858 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 13859 return that.tabs.index( li ); 13860 }) 13861 ) ).sort(); 13862 } 13863 13864 // check for length avoids error when initializing empty list 13865 if ( this.options.active !== false && this.anchors.length ) { 13866 this.active = this._findActive( options.active ); 13867 } else { 13868 this.active = $(); 13869 } 13870 13871 this._refresh(); 13872 13873 if ( this.active.length ) { 13874 this.load( options.active ); 13875 } 13876 }, 13877 13878 _initialActive: function() { 13879 var active = this.options.active, 13880 collapsible = this.options.collapsible, 13881 locationHash = location.hash.substring( 1 ); 13882 13883 if ( active === null ) { 13884 // check the fragment identifier in the URL 13885 if ( locationHash ) { 13886 this.tabs.each(function( i, tab ) { 13887 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 13888 active = i; 13889 return false; 13890 } 13891 }); 13892 } 13893 13894 // check for a tab marked active via a class 13895 if ( active === null ) { 13896 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 13897 } 13898 13899 // no active tab, set to false 13900 if ( active === null || active === -1 ) { 13901 active = this.tabs.length ? 0 : false; 13902 } 13903 } 13904 13905 // handle numbers: negative, out of range 13906 if ( active !== false ) { 13907 active = this.tabs.index( this.tabs.eq( active ) ); 13908 if ( active === -1 ) { 13909 active = collapsible ? false : 0; 13910 } 13911 } 13912 13913 // don't allow collapsible: false and active: false 13914 if ( !collapsible && active === false && this.anchors.length ) { 13915 active = 0; 13916 } 13917 13918 return active; 13919 }, 13920 13921 _getCreateEventData: function() { 13922 return { 13923 tab: this.active, 13924 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 13925 }; 13926 }, 13927 13928 _tabKeydown: function( event ) { 13929 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 13930 selectedIndex = this.tabs.index( focusedTab ), 13931 goingForward = true; 13932 13933 if ( this._handlePageNav( event ) ) { 13934 return; 13935 } 13936 13937 switch ( event.keyCode ) { 13938 case $.ui.keyCode.RIGHT: 13939 case $.ui.keyCode.DOWN: 13940 selectedIndex++; 13941 break; 13942 case $.ui.keyCode.UP: 13943 case $.ui.keyCode.LEFT: 13944 goingForward = false; 13945 selectedIndex--; 13946 break; 13947 case $.ui.keyCode.END: 13948 selectedIndex = this.anchors.length - 1; 13949 break; 13950 case $.ui.keyCode.HOME: 13951 selectedIndex = 0; 13952 break; 13953 case $.ui.keyCode.SPACE: 13954 // Activate only, no collapsing 13955 event.preventDefault(); 13956 clearTimeout( this.activating ); 13957 this._activate( selectedIndex ); 13958 return; 13959 case $.ui.keyCode.ENTER: 13960 // Toggle (cancel delayed activation, allow collapsing) 13961 event.preventDefault(); 13962 clearTimeout( this.activating ); 13963 // Determine if we should collapse or activate 13964 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 13965 return; 13966 default: 13967 return; 13968 } 13969 13970 // Focus the appropriate tab, based on which key was pressed 13971 event.preventDefault(); 13972 clearTimeout( this.activating ); 13973 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 13974 13975 // Navigating with control key will prevent automatic activation 13976 if ( !event.ctrlKey ) { 13977 // Update aria-selected immediately so that AT think the tab is already selected. 13978 // Otherwise AT may confuse the user by stating that they need to activate the tab, 13979 // but the tab will already be activated by the time the announcement finishes. 13980 focusedTab.attr( "aria-selected", "false" ); 13981 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 13982 13983 this.activating = this._delay(function() { 13984 this.option( "active", selectedIndex ); 13985 }, this.delay ); 13986 } 13987 }, 13988 13989 _panelKeydown: function( event ) { 13990 if ( this._handlePageNav( event ) ) { 13991 return; 13992 } 13993 13994 // Ctrl+up moves focus to the current tab 13995 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 13996 event.preventDefault(); 13997 this.active.focus(); 13998 } 13999 }, 14000 14001 // Alt+page up/down moves focus to the previous/next tab (and activates) 14002 _handlePageNav: function( event ) { 14003 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 14004 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 14005 return true; 14006 } 14007 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 14008 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 14009 return true; 14010 } 14011 }, 14012 14013 _findNextTab: function( index, goingForward ) { 14014 var lastTabIndex = this.tabs.length - 1; 14015 14016 function constrain() { 14017 if ( index > lastTabIndex ) { 14018 index = 0; 14019 } 14020 if ( index < 0 ) { 14021 index = lastTabIndex; 14022 } 14023 return index; 14024 } 14025 14026 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 14027 index = goingForward ? index + 1 : index - 1; 14028 } 14029 14030 return index; 14031 }, 14032 14033 _focusNextTab: function( index, goingForward ) { 14034 index = this._findNextTab( index, goingForward ); 14035 this.tabs.eq( index ).focus(); 14036 return index; 14037 }, 14038 14039 _setOption: function( key, value ) { 14040 if ( key === "active" ) { 14041 // _activate() will handle invalid values and update this.options 14042 this._activate( value ); 14043 return; 14044 } 14045 14046 if ( key === "disabled" ) { 14047 // don't use the widget factory's disabled handling 14048 this._setupDisabled( value ); 14049 return; 14050 } 14051 14052 this._super( key, value); 14053 14054 if ( key === "collapsible" ) { 14055 this.element.toggleClass( "ui-tabs-collapsible", value ); 14056 // Setting collapsible: false while collapsed; open first panel 14057 if ( !value && this.options.active === false ) { 14058 this._activate( 0 ); 14059 } 14060 } 14061 14062 if ( key === "event" ) { 14063 this._setupEvents( value ); 14064 } 14065 14066 if ( key === "heightStyle" ) { 14067 this._setupHeightStyle( value ); 14068 } 14069 }, 14070 14071 _tabId: function( tab ) { 14072 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 14073 }, 14074 14075 _sanitizeSelector: function( hash ) { 14076 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 14077 }, 14078 14079 refresh: function() { 14080 var options = this.options, 14081 lis = this.tablist.children( ":has(a[href])" ); 14082 14083 // get disabled tabs from class attribute from HTML 14084 // this will get converted to a boolean if needed in _refresh() 14085 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 14086 return lis.index( tab ); 14087 }); 14088 14089 this._processTabs(); 14090 14091 // was collapsed or no tabs 14092 if ( options.active === false || !this.anchors.length ) { 14093 options.active = false; 14094 this.active = $(); 14095 // was active, but active tab is gone 14096 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 14097 // all remaining tabs are disabled 14098 if ( this.tabs.length === options.disabled.length ) { 14099 options.active = false; 14100 this.active = $(); 14101 // activate previous tab 14102 } else { 14103 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 14104 } 14105 // was active, active tab still exists 14106 } else { 14107 // make sure active index is correct 14108 options.active = this.tabs.index( this.active ); 14109 } 14110 14111 this._refresh(); 14112 }, 14113 14114 _refresh: function() { 14115 this._setupDisabled( this.options.disabled ); 14116 this._setupEvents( this.options.event ); 14117 this._setupHeightStyle( this.options.heightStyle ); 14118 14119 this.tabs.not( this.active ).attr({ 14120 "aria-selected": "false", 14121 tabIndex: -1 14122 }); 14123 this.panels.not( this._getPanelForTab( this.active ) ) 14124 .hide() 14125 .attr({ 14126 "aria-expanded": "false", 14127 "aria-hidden": "true" 14128 }); 14129 14130 // Make sure one tab is in the tab order 14131 if ( !this.active.length ) { 14132 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 14133 } else { 14134 this.active 14135 .addClass( "ui-tabs-active ui-state-active" ) 14136 .attr({ 14137 "aria-selected": "true", 14138 tabIndex: 0 14139 }); 14140 this._getPanelForTab( this.active ) 14141 .show() 14142 .attr({ 14143 "aria-expanded": "true", 14144 "aria-hidden": "false" 14145 }); 14146 } 14147 }, 14148 14149 _processTabs: function() { 14150 var that = this; 14151 14152 this.tablist = this._getList() 14153 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14154 .attr( "role", "tablist" ); 14155 14156 this.tabs = this.tablist.find( "> li:has(a[href])" ) 14157 .addClass( "ui-state-default ui-corner-top" ) 14158 .attr({ 14159 role: "tab", 14160 tabIndex: -1 14161 }); 14162 14163 this.anchors = this.tabs.map(function() { 14164 return $( "a", this )[ 0 ]; 14165 }) 14166 .addClass( "ui-tabs-anchor" ) 14167 .attr({ 14168 role: "presentation", 14169 tabIndex: -1 14170 }); 14171 14172 this.panels = $(); 14173 14174 this.anchors.each(function( i, anchor ) { 14175 var selector, panel, panelId, 14176 anchorId = $( anchor ).uniqueId().attr( "id" ), 14177 tab = $( anchor ).closest( "li" ), 14178 originalAriaControls = tab.attr( "aria-controls" ); 14179 14180 // inline tab 14181 if ( isLocal( anchor ) ) { 14182 selector = anchor.hash; 14183 panel = that.element.find( that._sanitizeSelector( selector ) ); 14184 // remote tab 14185 } else { 14186 panelId = that._tabId( tab ); 14187 selector = "#" + panelId; 14188 panel = that.element.find( selector ); 14189 if ( !panel.length ) { 14190 panel = that._createPanel( panelId ); 14191 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 14192 } 14193 panel.attr( "aria-live", "polite" ); 14194 } 14195 14196 if ( panel.length) { 14197 that.panels = that.panels.add( panel ); 14198 } 14199 if ( originalAriaControls ) { 14200 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 14201 } 14202 tab.attr({ 14203 "aria-controls": selector.substring( 1 ), 14204 "aria-labelledby": anchorId 14205 }); 14206 panel.attr( "aria-labelledby", anchorId ); 14207 }); 14208 14209 this.panels 14210 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14211 .attr( "role", "tabpanel" ); 14212 }, 14213 14214 // allow overriding how to find the list for rare usage scenarios (#7715) 14215 _getList: function() { 14216 return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); 14217 }, 14218 14219 _createPanel: function( id ) { 14220 return $( "<div>" ) 14221 .attr( "id", id ) 14222 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14223 .data( "ui-tabs-destroy", true ); 14224 }, 14225 14226 _setupDisabled: function( disabled ) { 14227 if ( $.isArray( disabled ) ) { 14228 if ( !disabled.length ) { 14229 disabled = false; 14230 } else if ( disabled.length === this.anchors.length ) { 14231 disabled = true; 14232 } 14233 } 14234 14235 // disable tabs 14236 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 14237 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 14238 $( li ) 14239 .addClass( "ui-state-disabled" ) 14240 .attr( "aria-disabled", "true" ); 14241 } else { 14242 $( li ) 14243 .removeClass( "ui-state-disabled" ) 14244 .removeAttr( "aria-disabled" ); 14245 } 14246 } 14247 14248 this.options.disabled = disabled; 14249 }, 14250 14251 _setupEvents: function( event ) { 14252 var events = { 14253 click: function( event ) { 14254 event.preventDefault(); 14255 } 14256 }; 14257 if ( event ) { 14258 $.each( event.split(" "), function( index, eventName ) { 14259 events[ eventName ] = "_eventHandler"; 14260 }); 14261 } 14262 14263 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 14264 this._on( this.anchors, events ); 14265 this._on( this.tabs, { keydown: "_tabKeydown" } ); 14266 this._on( this.panels, { keydown: "_panelKeydown" } ); 14267 14268 this._focusable( this.tabs ); 14269 this._hoverable( this.tabs ); 14270 }, 14271 14272 _setupHeightStyle: function( heightStyle ) { 14273 var maxHeight, 14274 parent = this.element.parent(); 14275 14276 if ( heightStyle === "fill" ) { 14277 maxHeight = parent.height(); 14278 maxHeight -= this.element.outerHeight() - this.element.height(); 14279 14280 this.element.siblings( ":visible" ).each(function() { 14281 var elem = $( this ), 14282 position = elem.css( "position" ); 14283 14284 if ( position === "absolute" || position === "fixed" ) { 14285 return; 14286 } 14287 maxHeight -= elem.outerHeight( true ); 14288 }); 14289 14290 this.element.children().not( this.panels ).each(function() { 14291 maxHeight -= $( this ).outerHeight( true ); 14292 }); 14293 14294 this.panels.each(function() { 14295 $( this ).height( Math.max( 0, maxHeight - 14296 $( this ).innerHeight() + $( this ).height() ) ); 14297 }) 14298 .css( "overflow", "auto" ); 14299 } else if ( heightStyle === "auto" ) { 14300 maxHeight = 0; 14301 this.panels.each(function() { 14302 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 14303 }).height( maxHeight ); 14304 } 14305 }, 14306 14307 _eventHandler: function( event ) { 14308 var options = this.options, 14309 active = this.active, 14310 anchor = $( event.currentTarget ), 14311 tab = anchor.closest( "li" ), 14312 clickedIsActive = tab[ 0 ] === active[ 0 ], 14313 collapsing = clickedIsActive && options.collapsible, 14314 toShow = collapsing ? $() : this._getPanelForTab( tab ), 14315 toHide = !active.length ? $() : this._getPanelForTab( active ), 14316 eventData = { 14317 oldTab: active, 14318 oldPanel: toHide, 14319 newTab: collapsing ? $() : tab, 14320 newPanel: toShow 14321 }; 14322 14323 event.preventDefault(); 14324 14325 if ( tab.hasClass( "ui-state-disabled" ) || 14326 // tab is already loading 14327 tab.hasClass( "ui-tabs-loading" ) || 14328 // can't switch durning an animation 14329 this.running || 14330 // click on active header, but not collapsible 14331 ( clickedIsActive && !options.collapsible ) || 14332 // allow canceling activation 14333 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 14334 return; 14335 } 14336 14337 options.active = collapsing ? false : this.tabs.index( tab ); 14338 14339 this.active = clickedIsActive ? $() : tab; 14340 if ( this.xhr ) { 14341 this.xhr.abort(); 14342 } 14343 14344 if ( !toHide.length && !toShow.length ) { 14345 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 14346 } 14347 14348 if ( toShow.length ) { 14349 this.load( this.tabs.index( tab ), event ); 14350 } 14351 this._toggle( event, eventData ); 14352 }, 14353 14354 // handles show/hide for selecting tabs 14355 _toggle: function( event, eventData ) { 14356 var that = this, 14357 toShow = eventData.newPanel, 14358 toHide = eventData.oldPanel; 14359 14360 this.running = true; 14361 14362 function complete() { 14363 that.running = false; 14364 that._trigger( "activate", event, eventData ); 14365 } 14366 14367 function show() { 14368 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 14369 14370 if ( toShow.length && that.options.show ) { 14371 that._show( toShow, that.options.show, complete ); 14372 } else { 14373 toShow.show(); 14374 complete(); 14375 } 14376 } 14377 14378 // start out by hiding, then showing, then completing 14379 if ( toHide.length && this.options.hide ) { 14380 this._hide( toHide, this.options.hide, function() { 14381 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14382 show(); 14383 }); 14384 } else { 14385 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14386 toHide.hide(); 14387 show(); 14388 } 14389 14390 toHide.attr({ 14391 "aria-expanded": "false", 14392 "aria-hidden": "true" 14393 }); 14394 eventData.oldTab.attr( "aria-selected", "false" ); 14395 // If we're switching tabs, remove the old tab from the tab order. 14396 // If we're opening from collapsed state, remove the previous tab from the tab order. 14397 // If we're collapsing, then keep the collapsing tab in the tab order. 14398 if ( toShow.length && toHide.length ) { 14399 eventData.oldTab.attr( "tabIndex", -1 ); 14400 } else if ( toShow.length ) { 14401 this.tabs.filter(function() { 14402 return $( this ).attr( "tabIndex" ) === 0; 14403 }) 14404 .attr( "tabIndex", -1 ); 14405 } 14406 14407 toShow.attr({ 14408 "aria-expanded": "true", 14409 "aria-hidden": "false" 14410 }); 14411 eventData.newTab.attr({ 14412 "aria-selected": "true", 14413 tabIndex: 0 14414 }); 14415 }, 14416 14417 _activate: function( index ) { 14418 var anchor, 14419 active = this._findActive( index ); 14420 14421 // trying to activate the already active panel 14422 if ( active[ 0 ] === this.active[ 0 ] ) { 14423 return; 14424 } 14425 14426 // trying to collapse, simulate a click on the current active header 14427 if ( !active.length ) { 14428 active = this.active; 14429 } 14430 14431 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 14432 this._eventHandler({ 14433 target: anchor, 14434 currentTarget: anchor, 14435 preventDefault: $.noop 14436 }); 14437 }, 14438 14439 _findActive: function( index ) { 14440 return index === false ? $() : this.tabs.eq( index ); 14441 }, 14442 14443 _getIndex: function( index ) { 14444 // meta-function to give users option to provide a href string instead of a numerical index. 14445 if ( typeof index === "string" ) { 14446 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 14447 } 14448 14449 return index; 14450 }, 14451 14452 _destroy: function() { 14453 if ( this.xhr ) { 14454 this.xhr.abort(); 14455 } 14456 14457 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 14458 14459 this.tablist 14460 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14461 .removeAttr( "role" ); 14462 14463 this.anchors 14464 .removeClass( "ui-tabs-anchor" ) 14465 .removeAttr( "role" ) 14466 .removeAttr( "tabIndex" ) 14467 .removeUniqueId(); 14468 14469 this.tabs.add( this.panels ).each(function() { 14470 if ( $.data( this, "ui-tabs-destroy" ) ) { 14471 $( this ).remove(); 14472 } else { 14473 $( this ) 14474 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 14475 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 14476 .removeAttr( "tabIndex" ) 14477 .removeAttr( "aria-live" ) 14478 .removeAttr( "aria-busy" ) 14479 .removeAttr( "aria-selected" ) 14480 .removeAttr( "aria-labelledby" ) 14481 .removeAttr( "aria-hidden" ) 14482 .removeAttr( "aria-expanded" ) 14483 .removeAttr( "role" ); 14484 } 14485 }); 14486 14487 this.tabs.each(function() { 14488 var li = $( this ), 14489 prev = li.data( "ui-tabs-aria-controls" ); 14490 if ( prev ) { 14491 li 14492 .attr( "aria-controls", prev ) 14493 .removeData( "ui-tabs-aria-controls" ); 14494 } else { 14495 li.removeAttr( "aria-controls" ); 14496 } 14497 }); 14498 14499 this.panels.show(); 14500 14501 if ( this.options.heightStyle !== "content" ) { 14502 this.panels.css( "height", "" ); 14503 } 14504 }, 14505 14506 enable: function( index ) { 14507 var disabled = this.options.disabled; 14508 if ( disabled === false ) { 14509 return; 14510 } 14511 14512 if ( index === undefined ) { 14513 disabled = false; 14514 } else { 14515 index = this._getIndex( index ); 14516 if ( $.isArray( disabled ) ) { 14517 disabled = $.map( disabled, function( num ) { 14518 return num !== index ? num : null; 14519 }); 14520 } else { 14521 disabled = $.map( this.tabs, function( li, num ) { 14522 return num !== index ? num : null; 14523 }); 14524 } 14525 } 14526 this._setupDisabled( disabled ); 14527 }, 14528 14529 disable: function( index ) { 14530 var disabled = this.options.disabled; 14531 if ( disabled === true ) { 14532 return; 14533 } 14534 14535 if ( index === undefined ) { 14536 disabled = true; 14537 } else { 14538 index = this._getIndex( index ); 14539 if ( $.inArray( index, disabled ) !== -1 ) { 14540 return; 14541 } 14542 if ( $.isArray( disabled ) ) { 14543 disabled = $.merge( [ index ], disabled ).sort(); 14544 } else { 14545 disabled = [ index ]; 14546 } 14547 } 14548 this._setupDisabled( disabled ); 14549 }, 14550 14551 load: function( index, event ) { 14552 index = this._getIndex( index ); 14553 var that = this, 14554 tab = this.tabs.eq( index ), 14555 anchor = tab.find( ".ui-tabs-anchor" ), 14556 panel = this._getPanelForTab( tab ), 14557 eventData = { 14558 tab: tab, 14559 panel: panel 14560 }; 14561 14562 // not remote 14563 if ( isLocal( anchor[ 0 ] ) ) { 14564 return; 14565 } 14566 14567 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 14568 14569 // support: jQuery <1.8 14570 // jQuery <1.8 returns false if the request is canceled in beforeSend, 14571 // but as of 1.8, $.ajax() always returns a jqXHR object. 14572 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 14573 tab.addClass( "ui-tabs-loading" ); 14574 panel.attr( "aria-busy", "true" ); 14575 14576 this.xhr 14577 .success(function( response ) { 14578 // support: jQuery <1.8 14579 // http://bugs.jquery.com/ticket/11778 14580 setTimeout(function() { 14581 panel.html( response ); 14582 that._trigger( "load", event, eventData ); 14583 }, 1 ); 14584 }) 14585 .complete(function( jqXHR, status ) { 14586 // support: jQuery <1.8 14587 // http://bugs.jquery.com/ticket/11778 14588 setTimeout(function() { 14589 if ( status === "abort" ) { 14590 that.panels.stop( false, true ); 14591 } 14592 14593 tab.removeClass( "ui-tabs-loading" ); 14594 panel.removeAttr( "aria-busy" ); 14595 14596 if ( jqXHR === that.xhr ) { 14597 delete that.xhr; 14598 } 14599 }, 1 ); 14600 }); 14601 } 14602 }, 14603 14604 _ajaxSettings: function( anchor, event, eventData ) { 14605 var that = this; 14606 return { 14607 url: anchor.attr( "href" ), 14608 beforeSend: function( jqXHR, settings ) { 14609 return that._trigger( "beforeLoad", event, 14610 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 14611 } 14612 }; 14613 }, 14614 14615 _getPanelForTab: function( tab ) { 14616 var id = $( tab ).attr( "aria-controls" ); 14617 return this.element.find( this._sanitizeSelector( "#" + id ) ); 14618 } 14619}); 14620 14621})( jQuery ); 14622(function( $ ) { 14623 14624var increments = 0; 14625 14626function addDescribedBy( elem, id ) { 14627 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 14628 describedby.push( id ); 14629 elem 14630 .data( "ui-tooltip-id", id ) 14631 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 14632} 14633 14634function removeDescribedBy( elem ) { 14635 var id = elem.data( "ui-tooltip-id" ), 14636 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 14637 index = $.inArray( id, describedby ); 14638 if ( index !== -1 ) { 14639 describedby.splice( index, 1 ); 14640 } 14641 14642 elem.removeData( "ui-tooltip-id" ); 14643 describedby = $.trim( describedby.join( " " ) ); 14644 if ( describedby ) { 14645 elem.attr( "aria-describedby", describedby ); 14646 } else { 14647 elem.removeAttr( "aria-describedby" ); 14648 } 14649} 14650 14651$.widget( "ui.tooltip", { 14652 version: "1.10.4", 14653 options: { 14654 content: function() { 14655 // support: IE<9, Opera in jQuery <1.7 14656 // .text() can't accept undefined, so coerce to a string 14657 var title = $( this ).attr( "title" ) || ""; 14658 // Escape title, since we're going from an attribute to raw HTML 14659 return $( "<a>" ).text( title ).html(); 14660 }, 14661 hide: true, 14662 // Disabled elements have inconsistent behavior across browsers (#8661) 14663 items: "[title]:not([disabled])", 14664 position: { 14665 my: "left top+15", 14666 at: "left bottom", 14667 collision: "flipfit flip" 14668 }, 14669 show: true, 14670 tooltipClass: null, 14671 track: false, 14672 14673 // callbacks 14674 close: null, 14675 open: null 14676 }, 14677 14678 _create: function() { 14679 this._on({ 14680 mouseover: "open", 14681 focusin: "open" 14682 }); 14683 14684 // IDs of generated tooltips, needed for destroy 14685 this.tooltips = {}; 14686 // IDs of parent tooltips where we removed the title attribute 14687 this.parents = {}; 14688 14689 if ( this.options.disabled ) { 14690 this._disable(); 14691 } 14692 }, 14693 14694 _setOption: function( key, value ) { 14695 var that = this; 14696 14697 if ( key === "disabled" ) { 14698 this[ value ? "_disable" : "_enable" ](); 14699 this.options[ key ] = value; 14700 // disable element style changes 14701 return; 14702 } 14703 14704 this._super( key, value ); 14705 14706 if ( key === "content" ) { 14707 $.each( this.tooltips, function( id, element ) { 14708 that._updateContent( element ); 14709 }); 14710 } 14711 }, 14712 14713 _disable: function() { 14714 var that = this; 14715 14716 // close open tooltips 14717 $.each( this.tooltips, function( id, element ) { 14718 var event = $.Event( "blur" ); 14719 event.target = event.currentTarget = element[0]; 14720 that.close( event, true ); 14721 }); 14722 14723 // remove title attributes to prevent native tooltips 14724 this.element.find( this.options.items ).addBack().each(function() { 14725 var element = $( this ); 14726 if ( element.is( "[title]" ) ) { 14727 element 14728 .data( "ui-tooltip-title", element.attr( "title" ) ) 14729 .attr( "title", "" ); 14730 } 14731 }); 14732 }, 14733 14734 _enable: function() { 14735 // restore title attributes 14736 this.element.find( this.options.items ).addBack().each(function() { 14737 var element = $( this ); 14738 if ( element.data( "ui-tooltip-title" ) ) { 14739 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14740 } 14741 }); 14742 }, 14743 14744 open: function( event ) { 14745 var that = this, 14746 target = $( event ? event.target : this.element ) 14747 // we need closest here due to mouseover bubbling, 14748 // but always pointing at the same event target 14749 .closest( this.options.items ); 14750 14751 // No element to show a tooltip for or the tooltip is already open 14752 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 14753 return; 14754 } 14755 14756 if ( target.attr( "title" ) ) { 14757 target.data( "ui-tooltip-title", target.attr( "title" ) ); 14758 } 14759 14760 target.data( "ui-tooltip-open", true ); 14761 14762 // kill parent tooltips, custom or native, for hover 14763 if ( event && event.type === "mouseover" ) { 14764 target.parents().each(function() { 14765 var parent = $( this ), 14766 blurEvent; 14767 if ( parent.data( "ui-tooltip-open" ) ) { 14768 blurEvent = $.Event( "blur" ); 14769 blurEvent.target = blurEvent.currentTarget = this; 14770 that.close( blurEvent, true ); 14771 } 14772 if ( parent.attr( "title" ) ) { 14773 parent.uniqueId(); 14774 that.parents[ this.id ] = { 14775 element: this, 14776 title: parent.attr( "title" ) 14777 }; 14778 parent.attr( "title", "" ); 14779 } 14780 }); 14781 } 14782 14783 this._updateContent( target, event ); 14784 }, 14785 14786 _updateContent: function( target, event ) { 14787 var content, 14788 contentOption = this.options.content, 14789 that = this, 14790 eventType = event ? event.type : null; 14791 14792 if ( typeof contentOption === "string" ) { 14793 return this._open( event, target, contentOption ); 14794 } 14795 14796 content = contentOption.call( target[0], function( response ) { 14797 // ignore async response if tooltip was closed already 14798 if ( !target.data( "ui-tooltip-open" ) ) { 14799 return; 14800 } 14801 // IE may instantly serve a cached response for ajax requests 14802 // delay this call to _open so the other call to _open runs first 14803 that._delay(function() { 14804 // jQuery creates a special event for focusin when it doesn't 14805 // exist natively. To improve performance, the native event 14806 // object is reused and the type is changed. Therefore, we can't 14807 // rely on the type being correct after the event finished 14808 // bubbling, so we set it back to the previous value. (#8740) 14809 if ( event ) { 14810 event.type = eventType; 14811 } 14812 this._open( event, target, response ); 14813 }); 14814 }); 14815 if ( content ) { 14816 this._open( event, target, content ); 14817 } 14818 }, 14819 14820 _open: function( event, target, content ) { 14821 var tooltip, events, delayedShow, 14822 positionOption = $.extend( {}, this.options.position ); 14823 14824 if ( !content ) { 14825 return; 14826 } 14827 14828 // Content can be updated multiple times. If the tooltip already 14829 // exists, then just update the content and bail. 14830 tooltip = this._find( target ); 14831 if ( tooltip.length ) { 14832 tooltip.find( ".ui-tooltip-content" ).html( content ); 14833 return; 14834 } 14835 14836 // if we have a title, clear it to prevent the native tooltip 14837 // we have to check first to avoid defining a title if none exists 14838 // (we don't want to cause an element to start matching [title]) 14839 // 14840 // We use removeAttr only for key events, to allow IE to export the correct 14841 // accessible attributes. For mouse events, set to empty string to avoid 14842 // native tooltip showing up (happens only when removing inside mouseover). 14843 if ( target.is( "[title]" ) ) { 14844 if ( event && event.type === "mouseover" ) { 14845 target.attr( "title", "" ); 14846 } else { 14847 target.removeAttr( "title" ); 14848 } 14849 } 14850 14851 tooltip = this._tooltip( target ); 14852 addDescribedBy( target, tooltip.attr( "id" ) ); 14853 tooltip.find( ".ui-tooltip-content" ).html( content ); 14854 14855 function position( event ) { 14856 positionOption.of = event; 14857 if ( tooltip.is( ":hidden" ) ) { 14858 return; 14859 } 14860 tooltip.position( positionOption ); 14861 } 14862 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 14863 this._on( this.document, { 14864 mousemove: position 14865 }); 14866 // trigger once to override element-relative positioning 14867 position( event ); 14868 } else { 14869 tooltip.position( $.extend({ 14870 of: target 14871 }, this.options.position ) ); 14872 } 14873 14874 tooltip.hide(); 14875 14876 this._show( tooltip, this.options.show ); 14877 // Handle tracking tooltips that are shown with a delay (#8644). As soon 14878 // as the tooltip is visible, position the tooltip using the most recent 14879 // event. 14880 if ( this.options.show && this.options.show.delay ) { 14881 delayedShow = this.delayedShow = setInterval(function() { 14882 if ( tooltip.is( ":visible" ) ) { 14883 position( positionOption.of ); 14884 clearInterval( delayedShow ); 14885 } 14886 }, $.fx.interval ); 14887 } 14888 14889 this._trigger( "open", event, { tooltip: tooltip } ); 14890 14891 events = { 14892 keyup: function( event ) { 14893 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 14894 var fakeEvent = $.Event(event); 14895 fakeEvent.currentTarget = target[0]; 14896 this.close( fakeEvent, true ); 14897 } 14898 }, 14899 remove: function() { 14900 this._removeTooltip( tooltip ); 14901 } 14902 }; 14903 if ( !event || event.type === "mouseover" ) { 14904 events.mouseleave = "close"; 14905 } 14906 if ( !event || event.type === "focusin" ) { 14907 events.focusout = "close"; 14908 } 14909 this._on( true, target, events ); 14910 }, 14911 14912 close: function( event ) { 14913 var that = this, 14914 target = $( event ? event.currentTarget : this.element ), 14915 tooltip = this._find( target ); 14916 14917 // disabling closes the tooltip, so we need to track when we're closing 14918 // to avoid an infinite loop in case the tooltip becomes disabled on close 14919 if ( this.closing ) { 14920 return; 14921 } 14922 14923 // Clear the interval for delayed tracking tooltips 14924 clearInterval( this.delayedShow ); 14925 14926 // only set title if we had one before (see comment in _open()) 14927 if ( target.data( "ui-tooltip-title" ) ) { 14928 target.attr( "title", target.data( "ui-tooltip-title" ) ); 14929 } 14930 14931 removeDescribedBy( target ); 14932 14933 tooltip.stop( true ); 14934 this._hide( tooltip, this.options.hide, function() { 14935 that._removeTooltip( $( this ) ); 14936 }); 14937 14938 target.removeData( "ui-tooltip-open" ); 14939 this._off( target, "mouseleave focusout keyup" ); 14940 // Remove 'remove' binding only on delegated targets 14941 if ( target[0] !== this.element[0] ) { 14942 this._off( target, "remove" ); 14943 } 14944 this._off( this.document, "mousemove" ); 14945 14946 if ( event && event.type === "mouseleave" ) { 14947 $.each( this.parents, function( id, parent ) { 14948 $( parent.element ).attr( "title", parent.title ); 14949 delete that.parents[ id ]; 14950 }); 14951 } 14952 14953 this.closing = true; 14954 this._trigger( "close", event, { tooltip: tooltip } ); 14955 this.closing = false; 14956 }, 14957 14958 _tooltip: function( element ) { 14959 var id = "ui-tooltip-" + increments++, 14960 tooltip = $( "<div>" ) 14961 .attr({ 14962 id: id, 14963 role: "tooltip" 14964 }) 14965 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 14966 ( this.options.tooltipClass || "" ) ); 14967 $( "<div>" ) 14968 .addClass( "ui-tooltip-content" ) 14969 .appendTo( tooltip ); 14970 tooltip.appendTo( this.document[0].body ); 14971 this.tooltips[ id ] = element; 14972 return tooltip; 14973 }, 14974 14975 _find: function( target ) { 14976 var id = target.data( "ui-tooltip-id" ); 14977 return id ? $( "#" + id ) : $(); 14978 }, 14979 14980 _removeTooltip: function( tooltip ) { 14981 tooltip.remove(); 14982 delete this.tooltips[ tooltip.attr( "id" ) ]; 14983 }, 14984 14985 _destroy: function() { 14986 var that = this; 14987 14988 // close open tooltips 14989 $.each( this.tooltips, function( id, element ) { 14990 // Delegate to close method to handle common cleanup 14991 var event = $.Event( "blur" ); 14992 event.target = event.currentTarget = element[0]; 14993 that.close( event, true ); 14994 14995 // Remove immediately; destroying an open tooltip doesn't use the 14996 // hide animation 14997 $( "#" + id ).remove(); 14998 14999 // Restore the title 15000 if ( element.data( "ui-tooltip-title" ) ) { 15001 element.attr( "title", element.data( "ui-tooltip-title" ) ); 15002 element.removeData( "ui-tooltip-title" ); 15003 } 15004 }); 15005 } 15006}); 15007 15008}( 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.