vendor: 6,214 bytes, lines 1-227
1/*! jQuery UI - v1.9.2 - 2013-11-19 2* http://jqueryui.com 3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.datepicker.js 4* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ 5 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11// prevent duplicate loading 12// this is only a problem because we proxy existing functions 13// and we don't want to double proxy them 14$.ui = $.ui || {}; 15if ( $.ui.version ) { 16 return; 17} 18 19$.extend( $.ui, { 20 version: "1.9.2", 21 22 keyCode: { 23 BACKSPACE: 8, 24 COMMA: 188, 25 DELETE: 46, 26 DOWN: 40, 27 END: 35, 28 ENTER: 13, 29 ESCAPE: 27, 30 HOME: 36, 31 LEFT: 37, 32 NUMPAD_ADD: 107, 33 NUMPAD_DECIMAL: 110, 34 NUMPAD_DIVIDE: 111, 35 NUMPAD_ENTER: 108, 36 NUMPAD_MULTIPLY: 106, 37 NUMPAD_SUBTRACT: 109, 38 PAGE_DOWN: 34, 39 PAGE_UP: 33, 40 PERIOD: 190, 41 RIGHT: 39, 42 SPACE: 32, 43 TAB: 9, 44 UP: 38 45 } 46}); 47 48// plugins 49$.fn.extend({ 50 _focus: $.fn.focus, 51 focus: function( delay, fn ) { 52 return typeof delay === "number" ? 53 this.each(function() { 54 var elem = this; 55 setTimeout(function() { 56 $( elem ).focus(); 57 if ( fn ) { 58 fn.call( elem ); 59 } 60 }, delay ); 61 }) : 62 this._focus.apply( this, arguments ); 63 }, 64 65 scrollParent: function() { 66 var scrollParent; 67 if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { 68 scrollParent = this.parents().filter(function() { 69 return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); 70 }).eq(0); 71 } else { 72 scrollParent = this.parents().filter(function() { 73 return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); 74 }).eq(0); 75 } 76 77 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; 78 }, 79 80 zIndex: function( zIndex ) { 81 if ( zIndex !== undefined ) { 82 return this.css( "zIndex", zIndex ); 83 } 84 85 if ( this.length ) { 86 var elem = $( this[ 0 ] ), position, value; 87 while ( elem.length && elem[ 0 ] !== document ) { 88 // Ignore z-index if position is set to a value where z-index is ignored by the browser 89 // This makes behavior of this function consistent across browsers 90 // WebKit always returns auto if the element is positioned 91 position = elem.css( "position" ); 92 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 93 // IE returns 0 when zIndex is not specified 94 // other browsers return a string 95 // we ignore the case of nested elements with an explicit value of 0 96 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 97 value = parseInt( elem.css( "zIndex" ), 10 ); 98 if ( !isNaN( value ) && value !== 0 ) { 99 return value; 100 } 101 } 102 elem = elem.parent(); 103 } 104 } 105 106 return 0; 107 }, 108 109 uniqueId: function() { 110 return this.each(function() { 111 if ( !this.id ) { 112 this.id = "ui-id-" + (++uuid); 113 } 114 }); 115 }, 116 117 removeUniqueId: function() { 118 return this.each(function() { 119 if ( runiqueId.test( this.id ) ) { 120 $( this ).removeAttr( "id" ); 121 } 122 }); 123 } 124}); 125 126// selectors 127function focusable( element, isTabIndexNotNaN ) { 128 var map, mapName, img, 129 nodeName = element.nodeName.toLowerCase(); 130 if ( "area" === nodeName ) { 131 map = element.parentNode; 132 mapName = map.name; 133 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 134 return false; 135 } 136 img = $( "img[usemap=#" + mapName + "]" )[0]; 137 return !!img && visible( img ); 138 } 139 return ( /input|select|textarea|button|object/.test( nodeName ) ? 140 !element.disabled : 141 "a" === nodeName ? 142 element.href || isTabIndexNotNaN : 143 isTabIndexNotNaN) && 144 // the element and all of its ancestors must be visible 145 visible( element ); 146} 147 148function visible( element ) { 149 return $.expr.filters.visible( element ) && 150 !$( element ).parents().andSelf().filter(function() { 151 return $.css( this, "visibility" ) === "hidden"; 152 }).length; 153} 154 155$.extend( $.expr[ ":" ], { 156 data: $.expr.createPseudo ? 157 $.expr.createPseudo(function( dataName ) { 158 return function( elem ) { 159 return !!$.data( elem, dataName ); 160 }; 161 }) : 162 // support: jQuery <1.8 163 function( elem, i, match ) { 164 return !!$.data( elem, match[ 3 ] ); 165 }, 166 167 focusable: function( element ) { 168 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 169 }, 170 171 tabbable: function( element ) { 172 var tabIndex = $.attr( element, "tabindex" ), 173 isTabIndexNaN = isNaN( tabIndex ); 174 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 175 } 176}); 177 178// support 179$(function() { 180 var body = document.body, 181 div = body.appendChild( div = document.createElement( "div" ) ); 182 183 // access offsetHeight before setting the style to prevent a layout bug 184 // in IE 9 which causes the element to continue to take up space even 185 // after it is removed from the DOM (#8026) 186 div.offsetHeight; 187 188 $.extend( div.style, { 189 minHeight: "100px", 190 height: "auto", 191 padding: 0, 192 borderWidth: 0 193 }); 194 195 $.support.minHeight = div.offsetHeight === 100; 196 $.support.selectstart = "onselectstart" in div; 197 198 // set display to none to avoid a layout bug in IE 199 // http://dev.jquery.com/ticket/4014 200 body.removeChild( div ).style.display = "none"; 201}); 202 203// support: jQuery <1.8 204if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 205 $.each( [ "Width", "Height" ], function( i, name ) { 206 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 207 type = name.toLowerCase(), 208 orig = { 209 innerWidth: $.fn.innerWidth, 210 innerHeight: $.fn.innerHeight, 211 outerWidth: $.fn.outerWidth, 212 outerHeight: $.fn.outerHeight 213 }; 214 215 function reduce( elem, size, border, margin ) { 216 $.each( side, function() { 217 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 218 if ( border ) { 219 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 220 } 221 if ( margin ) { 222 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 223 } 224 }); 225 return size; 226 } 227
228 $.fn[ "inner" + name ] = function( size ) { 229 if ( size === undefined ) { 230 return orig[ "inner" + name ].call( this ); 231 } 232 233 return this.each(function() { 234 $( this ).css( type, reduce( this, size ) + "px" ); 235 }); 236 }; 237 238 $.fn[ "outer" + name] = function( size, margin ) { 239 if ( typeof size !== "number" ) { 240 return orig[ "outer" + name ].call( this, size ); 241 } 242 243 return this.each(function() { 244 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 245 }); 246 }; 247 }); 248} 249 250// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 251if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 252 $.fn.removeData = (function( removeData ) { 253 return function( key ) { 254 if ( arguments.length ) { 255 return removeData.call( this, $.camelCase( key ) ); 256 } else { 257 return removeData.call( this ); 258 } 259 }; 260 })( $.fn.removeData ); 261} 262 263 264 265 266 267// deprecated 268 269(function() { 270 var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || []; 271 $.ui.ie = uaMatch.length ? true : false; 272 $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6; 273})(); 274 275$.fn.extend({ 276 disableSelection: function() { 277 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 278 ".ui-disableSelection", function( event ) { 279 event.preventDefault(); 280 }); 281 }, 282 283 enableSelection: function() { 284 return this.unbind( ".ui-disableSelection" ); 285 } 286}); 287 288$.extend( $.ui, { 289 // $.ui.plugin is deprecated. Use the proxy pattern instead. 290 plugin: { 291 add: function( module, option, set ) { 292 var i, 293 proto = $.ui[ module ].prototype; 294 for ( i in set ) { 295 proto.plugins[ i ] = proto.plugins[ i ] || []; 296 proto.plugins[ i ].push( [ option, set[ i ] ] ); 297 } 298 }, 299 call: function( instance, name, args ) { 300 var i, 301 set = instance.plugins[ name ]; 302 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 303 return; 304 } 305 306 for ( i = 0; i < set.length; i++ ) { 307 if ( instance.options[ set[ i ][ 0 ] ] ) { 308 set[ i ][ 1 ].apply( instance.element, args ); 309 } 310 } 311 } 312 }, 313 314 contains: $.contains, 315 316 // only used by resizable 317 hasScroll: function( el, a ) { 318 319 //If overflow is hidden, the element might have extra content, but the user wants to hide it 320 if ( $( el ).css( "overflow" ) === "hidden") { 321 return false; 322 } 323 324 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 325 has = false; 326 327 if ( el[ scroll ] > 0 ) { 328 return true; 329 } 330 331 // TODO: determine which cases actually cause this to happen 332 // if the element doesn't have the scroll set, see if it's possible to 333 // set the scroll 334 el[ scroll ] = 1; 335 has = ( el[ scroll ] > 0 ); 336 el[ scroll ] = 0; 337 return has; 338 }, 339 340 // these are odd functions, fix the API or move into individual plugins 341 isOverAxis: function( x, reference, size ) { 342 //Determines when x coordinate is over "b" element axis 343 return ( x > reference ) && ( x < ( reference + size ) ); 344 }, 345 isOver: function( y, x, top, left, height, width ) { 346 //Determines when x, y coordinates is over "b" element 347 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width ); 348 } 349}); 350 351})( jQuery ); 352(function( $, undefined ) { 353 354var uuid = 0, 355 slice = Array.prototype.slice, 356 _cleanData = $.cleanData; 357$.cleanData = function( elems ) { 358 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 359 try { 360 $( elem ).triggerHandler( "remove" ); 361 // http://bugs.jquery.com/ticket/8235 362 } catch( e ) {} 363 } 364 _cleanData( elems ); 365}; 366 367$.widget = function( name, base, prototype ) { 368 var fullName, existingConstructor, constructor, basePrototype, 369 namespace = name.split( "." )[ 0 ]; 370 371 name = name.split( "." )[ 1 ]; 372 fullName = namespace + "-" + name; 373 374 if ( !prototype ) { 375 prototype = base; 376 base = $.Widget; 377 } 378 379 // create selector for plugin 380 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 381 return !!$.data( elem, fullName ); 382 }; 383 384 $[ namespace ] = $[ namespace ] || {}; 385 existingConstructor = $[ namespace ][ name ]; 386 constructor = $[ namespace ][ name ] = function( options, element ) { 387 // allow instantiation without "new" keyword 388 if ( !this._createWidget ) { 389 return new constructor( options, element ); 390 } 391 392 // allow instantiation without initializing for simple inheritance 393 // must use "new" keyword (the code above always passes args) 394 if ( arguments.length ) { 395 this._createWidget( options, element ); 396 } 397 }; 398 // extend with the existing constructor to carry over any static properties 399 $.extend( constructor, existingConstructor, { 400 version: prototype.version, 401 // copy the object used to create the prototype in case we need to 402 // redefine the widget later 403 _proto: $.extend( {}, prototype ), 404 // track widgets that inherit from this widget in case this widget is 405 // redefined after a widget inherits from it 406 _childConstructors: [] 407 }); 408 409 basePrototype = new base(); 410 // we need to make the options hash a property directly on the new instance 411 // otherwise we'll modify the options hash on the prototype that we're 412 // inheriting from 413 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 414 $.each( prototype, function( prop, value ) { 415 if ( $.isFunction( value ) ) { 416 prototype[ prop ] = (function() { 417 var _super = function() { 418 return base.prototype[ prop ].apply( this, arguments ); 419 }, 420 _superApply = function( args ) { 421 return base.prototype[ prop ].apply( this, args ); 422 }; 423 return function() { 424 var __super = this._super, 425 __superApply = this._superApply, 426 returnValue; 427 428 this._super = _super; 429 this._superApply = _superApply; 430
vendor: 12,147 bytes, lines 431-848
431 returnValue = value.apply( this, arguments ); 432 433 this._super = __super; 434 this._superApply = __superApply; 435 436 return returnValue; 437 }; 438 })(); 439 } 440 }); 441 constructor.prototype = $.widget.extend( basePrototype, { 442 // TODO: remove support for widgetEventPrefix 443 // always use the name + a colon as the prefix, e.g., draggable:start 444 // don't prefix for widgets that aren't DOM-based 445 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 446 }, prototype, { 447 constructor: constructor, 448 namespace: namespace, 449 widgetName: name, 450 // TODO remove widgetBaseClass, see #8155 451 widgetBaseClass: fullName, 452 widgetFullName: fullName 453 }); 454 455 // If this widget is being redefined then we need to find all widgets that 456 // are inheriting from it and redefine all of them so that they inherit from 457 // the new version of this widget. We're essentially trying to replace one 458 // level in the prototype chain. 459 if ( existingConstructor ) { 460 $.each( existingConstructor._childConstructors, function( i, child ) { 461 var childPrototype = child.prototype; 462 463 // redefine the child widget using the same prototype that was 464 // originally used, but inherit from the new version of the base 465 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 466 }); 467 // remove the list of existing child constructors from the old constructor 468 // so the old child constructors can be garbage collected 469 delete existingConstructor._childConstructors; 470 } else { 471 base._childConstructors.push( constructor ); 472 } 473 474 $.widget.bridge( name, constructor ); 475}; 476 477$.widget.extend = function( target ) { 478 var input = slice.call( arguments, 1 ), 479 inputIndex = 0, 480 inputLength = input.length, 481 key, 482 value; 483 for ( ; inputIndex < inputLength; inputIndex++ ) { 484 for ( key in input[ inputIndex ] ) { 485 value = input[ inputIndex ][ key ]; 486 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 487 // Clone objects 488 if ( $.isPlainObject( value ) ) { 489 target[ key ] = $.isPlainObject( target[ key ] ) ? 490 $.widget.extend( {}, target[ key ], value ) : 491 // Don't extend strings, arrays, etc. with objects 492 $.widget.extend( {}, value ); 493 // Copy everything else by reference 494 } else { 495 target[ key ] = value; 496 } 497 } 498 } 499 } 500 return target; 501}; 502 503$.widget.bridge = function( name, object ) { 504 var fullName = object.prototype.widgetFullName || name; 505 $.fn[ name ] = function( options ) { 506 var isMethodCall = typeof options === "string", 507 args = slice.call( arguments, 1 ), 508 returnValue = this; 509 510 // allow multiple hashes to be passed on init 511 options = !isMethodCall && args.length ? 512 $.widget.extend.apply( null, [ options ].concat(args) ) : 513 options; 514 515 if ( isMethodCall ) { 516 this.each(function() { 517 var methodValue, 518 instance = $.data( this, fullName ); 519 if ( !instance ) { 520 return $.error( "cannot call methods on " + name + " prior to initialization; " + 521 "attempted to call method '" + options + "'" ); 522 } 523 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 524 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 525 } 526 methodValue = instance[ options ].apply( instance, args ); 527 if ( methodValue !== instance && methodValue !== undefined ) { 528 returnValue = methodValue && methodValue.jquery ? 529 returnValue.pushStack( methodValue.get() ) : 530 methodValue; 531 return false; 532 } 533 }); 534 } else { 535 this.each(function() { 536 var instance = $.data( this, fullName ); 537 if ( instance ) { 538 instance.option( options || {} )._init(); 539 } else { 540 $.data( this, fullName, new object( options, this ) ); 541 } 542 }); 543 } 544 545 return returnValue; 546 }; 547}; 548 549$.Widget = function( /* options, element */ ) {}; 550$.Widget._childConstructors = []; 551 552$.Widget.prototype = { 553 widgetName: "widget", 554 widgetEventPrefix: "", 555 defaultElement: "<div>", 556 options: { 557 disabled: false, 558 559 // callbacks 560 create: null 561 }, 562 _createWidget: function( options, element ) { 563 element = $( element || this.defaultElement || this )[ 0 ]; 564 this.element = $( element ); 565 this.uuid = uuid++; 566 this.eventNamespace = "." + this.widgetName + this.uuid; 567 this.options = $.widget.extend( {}, 568 this.options, 569 this._getCreateOptions(), 570 options ); 571 572 this.bindings = $(); 573 this.hoverable = $(); 574 this.focusable = $(); 575 576 if ( element !== this ) { 577 // 1.9 BC for #7810 578 // TODO remove dual storage 579 $.data( element, this.widgetName, this ); 580 $.data( element, this.widgetFullName, this ); 581 this._on( true, this.element, { 582 remove: function( event ) { 583 if ( event.target === element ) { 584 this.destroy(); 585 } 586 } 587 }); 588 this.document = $( element.style ? 589 // element within the document 590 element.ownerDocument : 591 // element is window or document 592 element.document || element ); 593 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 594 } 595 596 this._create(); 597 this._trigger( "create", null, this._getCreateEventData() ); 598 this._init(); 599 }, 600 _getCreateOptions: $.noop, 601 _getCreateEventData: $.noop, 602 _create: $.noop, 603 _init: $.noop, 604 605 destroy: function() { 606 this._destroy(); 607 // we can probably remove the unbind calls in 2.0 608 // all event bindings should go through this._on() 609 this.element 610 .unbind( this.eventNamespace ) 611 // 1.9 BC for #7810 612 // TODO remove dual storage 613 .removeData( this.widgetName ) 614 .removeData( this.widgetFullName ) 615 // support: jquery <1.6.3 616 // http://bugs.jquery.com/ticket/9413 617 .removeData( $.camelCase( this.widgetFullName ) ); 618 this.widget() 619 .unbind( this.eventNamespace ) 620 .removeAttr( "aria-disabled" ) 621 .removeClass( 622 this.widgetFullName + "-disabled " + 623 "ui-state-disabled" ); 624 625 // clean up events and states 626 this.bindings.unbind( this.eventNamespace ); 627 this.hoverable.removeClass( "ui-state-hover" ); 628 this.focusable.removeClass( "ui-state-focus" ); 629 }, 630 _destroy: $.noop, 631 632 widget: function() { 633 return this.element; 634 }, 635 636 option: function( key, value ) { 637 var options = key, 638 parts, 639 curOption, 640 i; 641 642 if ( arguments.length === 0 ) { 643 // don't return a reference to the internal hash 644 return $.widget.extend( {}, this.options ); 645 } 646 647 if ( typeof key === "string" ) { 648 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 649 options = {}; 650 parts = key.split( "." ); 651 key = parts.shift(); 652 if ( parts.length ) { 653 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 654 for ( i = 0; i < parts.length - 1; i++ ) { 655 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 656 curOption = curOption[ parts[ i ] ]; 657 } 658 key = parts.pop(); 659 if ( value === undefined ) { 660 return curOption[ key ] === undefined ? null : curOption[ key ]; 661 } 662 curOption[ key ] = value; 663 } else { 664 if ( value === undefined ) { 665 return this.options[ key ] === undefined ? null : this.options[ key ]; 666 } 667 options[ key ] = value; 668 } 669 } 670 671 this._setOptions( options ); 672 673 return this; 674 }, 675 _setOptions: function( options ) { 676 var key; 677 678 for ( key in options ) { 679 this._setOption( key, options[ key ] ); 680 } 681 682 return this; 683 }, 684 _setOption: function( key, value ) { 685 this.options[ key ] = value; 686 687 if ( key === "disabled" ) { 688 this.widget() 689 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 690 .attr( "aria-disabled", value ); 691 this.hoverable.removeClass( "ui-state-hover" ); 692 this.focusable.removeClass( "ui-state-focus" ); 693 } 694 695 return this; 696 }, 697 698 enable: function() { 699 return this._setOption( "disabled", false ); 700 }, 701 disable: function() { 702 return this._setOption( "disabled", true ); 703 }, 704 705 _on: function( suppressDisabledCheck, element, handlers ) { 706 var delegateElement, 707 instance = this; 708 709 // no suppressDisabledCheck flag, shuffle arguments 710 if ( typeof suppressDisabledCheck !== "boolean" ) { 711 handlers = element; 712 element = suppressDisabledCheck; 713 suppressDisabledCheck = false; 714 } 715 716 // no element argument, shuffle and use this.element 717 if ( !handlers ) { 718 handlers = element; 719 element = this.element; 720 delegateElement = this.widget(); 721 } else { 722 // accept selectors, DOM elements 723 element = delegateElement = $( element ); 724 this.bindings = this.bindings.add( element ); 725 } 726 727 $.each( handlers, function( event, handler ) { 728 function handlerProxy() { 729 // allow widgets to customize the disabled handling 730 // - disabled as an array instead of boolean 731 // - disabled class as method for disabling individual parts 732 if ( !suppressDisabledCheck && 733 ( instance.options.disabled === true || 734 $( this ).hasClass( "ui-state-disabled" ) ) ) { 735 return; 736 } 737 return ( typeof handler === "string" ? instance[ handler ] : handler ) 738 .apply( instance, arguments ); 739 } 740 741 // copy the guid so direct unbinding works 742 if ( typeof handler !== "string" ) { 743 handlerProxy.guid = handler.guid = 744 handler.guid || handlerProxy.guid || $.guid++; 745 } 746 747 var match = event.match( /^(\w+)\s*(.*)$/ ), 748 eventName = match[1] + instance.eventNamespace, 749 selector = match[2]; 750 if ( selector ) { 751 delegateElement.delegate( selector, eventName, handlerProxy ); 752 } else { 753 element.bind( eventName, handlerProxy ); 754 } 755 }); 756 }, 757 758 _off: function( element, eventName ) { 759 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 760 element.unbind( eventName ).undelegate( eventName ); 761 }, 762 763 _delay: function( handler, delay ) { 764 function handlerProxy() { 765 return ( typeof handler === "string" ? instance[ handler ] : handler ) 766 .apply( instance, arguments ); 767 } 768 var instance = this; 769 return setTimeout( handlerProxy, delay || 0 ); 770 }, 771 772 _hoverable: function( element ) { 773 this.hoverable = this.hoverable.add( element ); 774 this._on( element, { 775 mouseenter: function( event ) { 776 $( event.currentTarget ).addClass( "ui-state-hover" ); 777 }, 778 mouseleave: function( event ) { 779 $( event.currentTarget ).removeClass( "ui-state-hover" ); 780 } 781 }); 782 }, 783 784 _focusable: function( element ) { 785 this.focusable = this.focusable.add( element ); 786 this._on( element, { 787 focusin: function( event ) { 788 $( event.currentTarget ).addClass( "ui-state-focus" ); 789 }, 790 focusout: function( event ) { 791 $( event.currentTarget ).removeClass( "ui-state-focus" ); 792 } 793 }); 794 }, 795 796 _trigger: function( type, event, data ) { 797 var prop, orig, 798 callback = this.options[ type ]; 799 800 data = data || {}; 801 event = $.Event( event ); 802 event.type = ( type === this.widgetEventPrefix ? 803 type : 804 this.widgetEventPrefix + type ).toLowerCase(); 805 // the original event may come from any element 806 // so we need to reset the target on the new event 807 event.target = this.element[ 0 ]; 808 809 // copy original event properties over to the new event 810 orig = event.originalEvent; 811 if ( orig ) { 812 for ( prop in orig ) { 813 if ( !( prop in event ) ) { 814 event[ prop ] = orig[ prop ]; 815 } 816 } 817 } 818 819 this.element.trigger( event, data ); 820 return !( $.isFunction( callback ) && 821 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 822 event.isDefaultPrevented() ); 823 } 824}; 825 826$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 827 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 828 if ( typeof options === "string" ) { 829 options = { effect: options }; 830 } 831 var hasOptions, 832 effectName = !options ? 833 method : 834 options === true || typeof options === "number" ? 835 defaultEffect : 836 options.effect || defaultEffect; 837 options = options || {}; 838 if ( typeof options === "number" ) { 839 options = { duration: options }; 840 } 841 hasOptions = !$.isEmptyObject( options ); 842 options.complete = callback; 843 if ( options.delay ) { 844 element.delay( options.delay ); 845 } 846 if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { 847 element[ method ]( options ); 848 } else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,170 bytes, lines 849-1003
849 element[ effectName ]( options.duration, options.easing, callback ); 850 } else { 851 element.queue(function( next ) { 852 $( this )[ method ](); 853 if ( callback ) { 854 callback.call( element[ 0 ] ); 855 } 856 next(); 857 }); 858 } 859 }; 860}); 861 862// DEPRECATED 863if ( $.uiBackCompat !== false ) { 864 $.Widget.prototype._getCreateOptions = function() { 865 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; 866 }; 867} 868 869})( jQuery ); 870(function( $, undefined ) { 871 872var mouseHandled = false; 873$( document ).mouseup( function( e ) { 874 mouseHandled = false; 875}); 876 877$.widget("ui.mouse", { 878 version: "1.9.2", 879 options: { 880 cancel: 'input,textarea,button,select,option', 881 distance: 1, 882 delay: 0 883 }, 884 _mouseInit: function() { 885 var that = this; 886 887 this.element 888 .bind('mousedown.'+this.widgetName, function(event) { 889 return that._mouseDown(event); 890 }) 891 .bind('click.'+this.widgetName, function(event) { 892 if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) { 893 $.removeData(event.target, that.widgetName + '.preventClickEvent'); 894 event.stopImmediatePropagation(); 895 return false; 896 } 897 }); 898 899 this.started = false; 900 }, 901 902 // TODO: make sure destroying one instance of mouse doesn't mess with 903 // other instances of mouse 904 _mouseDestroy: function() { 905 this.element.unbind('.'+this.widgetName); 906 if ( this._mouseMoveDelegate ) { 907 $(document) 908 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 909 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); 910 } 911 }, 912 913 _mouseDown: function(event) { 914 // don't let more than one widget handle mouseStart 915 if( mouseHandled ) { return; } 916 917 // we may have missed mouseup (out of window) 918 (this._mouseStarted && this._mouseUp(event)); 919 920 this._mouseDownEvent = event; 921 922 var that = this, 923 btnIsLeft = (event.which === 1), 924 // event.target.nodeName works around a bug in IE 8 with 925 // disabled inputs (#7620) 926 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 927 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 928 return true; 929 } 930 931 this.mouseDelayMet = !this.options.delay; 932 if (!this.mouseDelayMet) { 933 this._mouseDelayTimer = setTimeout(function() { 934 that.mouseDelayMet = true; 935 }, this.options.delay); 936 } 937 938 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 939 this._mouseStarted = (this._mouseStart(event) !== false); 940 if (!this._mouseStarted) { 941 event.preventDefault(); 942 return true; 943 } 944 } 945 946 // Click event may never have fired (Gecko & Opera) 947 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) { 948 $.removeData(event.target, this.widgetName + '.preventClickEvent'); 949 } 950 951 // these delegates are required to keep context 952 this._mouseMoveDelegate = function(event) { 953 return that._mouseMove(event); 954 }; 955 this._mouseUpDelegate = function(event) { 956 return that._mouseUp(event); 957 }; 958 $(document) 959 .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 960 .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); 961 962 event.preventDefault(); 963 964 mouseHandled = true; 965 return true; 966 }, 967 968 _mouseMove: function(event) { 969 // IE mouseup check - mouseup happened when mouse was out of window 970 if ($.ui.ie && !(document.documentMode >= 9) && !event.button) { 971 return this._mouseUp(event); 972 } 973 974 if (this._mouseStarted) { 975 this._mouseDrag(event); 976 return event.preventDefault(); 977 } 978 979 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 980 this._mouseStarted = 981 (this._mouseStart(this._mouseDownEvent, event) !== false); 982 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 983 } 984 985 return !this._mouseStarted; 986 }, 987 988 _mouseUp: function(event) { 989 $(document) 990 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 991 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); 992 993 if (this._mouseStarted) { 994 this._mouseStarted = false; 995 996 if (event.target === this._mouseDownEvent.target) { 997 $.data(event.target, this.widgetName + '.preventClickEvent', true); 998 } 999 1000 this._mouseStop(event); 1001 } 1002 1003 return false;
1004 }, 1005 1006 _mouseDistanceMet: function(event) { 1007 return (Math.max( 1008 Math.abs(this._mouseDownEvent.pageX - event.pageX), 1009 Math.abs(this._mouseDownEvent.pageY - event.pageY) 1010 ) >= this.options.distance 1011 ); 1012 }, 1013 1014 _mouseDelayMet: function(event) { 1015 return this.mouseDelayMet; 1016 }, 1017 1018 // These are placeholder methods, to be overriden by extending plugin 1019 _mouseStart: function(event) {}, 1020 _mouseDrag: function(event) {}, 1021 _mouseStop: function(event) {}, 1022 _mouseCapture: function(event) { return true; } 1023}); 1024 1025})(jQuery); 1026(function( $, undefined ) { 1027 1028$.ui = $.ui || {}; 1029 1030var cachedScrollbarWidth, 1031 max = Math.max, 1032 abs = Math.abs, 1033 round = Math.round, 1034 rhorizontal = /left|center|right/, 1035 rvertical = /top|center|bottom/, 1036 roffset = /[\+\-]\d+%?/, 1037 rposition = /^\w+/, 1038 rpercent = /%$/, 1039 _position = $.fn.position; 1040 1041function getOffsets( offsets, width, height ) { 1042 return [ 1043 parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1044 parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1045 ]; 1046} 1047function parseCss( element, property ) { 1048 return parseInt( $.css( element, property ), 10 ) || 0; 1049} 1050 1051$.position = { 1052 scrollbarWidth: function() { 1053 if ( cachedScrollbarWidth !== undefined ) { 1054 return cachedScrollbarWidth; 1055 } 1056 var w1, w2, 1057 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1058 innerDiv = div.children()[0]; 1059 1060 $( "body" ).append( div ); 1061 w1 = innerDiv.offsetWidth; 1062 div.css( "overflow", "scroll" ); 1063 1064 w2 = innerDiv.offsetWidth; 1065 1066 if ( w1 === w2 ) { 1067 w2 = div[0].clientWidth; 1068 } 1069 1070 div.remove(); 1071 1072 return (cachedScrollbarWidth = w1 - w2); 1073 }, 1074 getScrollInfo: function( within ) { 1075 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 1076 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 1077 hasOverflowX = overflowX === "scroll" || 1078 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1079 hasOverflowY = overflowY === "scroll" || 1080 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1081 return { 1082 width: hasOverflowX ? $.position.scrollbarWidth() : 0, 1083 height: hasOverflowY ? $.position.scrollbarWidth() : 0 1084 }; 1085 }, 1086 getWithinInfo: function( element ) { 1087 var withinElement = $( element || window ), 1088 isWindow = $.isWindow( withinElement[0] ); 1089 return { 1090 element: withinElement, 1091 isWindow: isWindow, 1092 offset: withinElement.offset() || { left: 0, top: 0 }, 1093 scrollLeft: withinElement.scrollLeft(), 1094 scrollTop: withinElement.scrollTop(), 1095 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 1096 height: isWindow ? withinElement.height() : withinElement.outerHeight() 1097 }; 1098 } 1099}; 1100 1101$.fn.position = function( options ) { 1102 if ( !options || !options.of ) { 1103 return _position.apply( this, arguments ); 1104 } 1105 1106 // make a copy, we don't want to modify arguments 1107 options = $.extend( {}, options ); 1108 1109 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, 1110 target = $( options.of ), 1111 within = $.position.getWithinInfo( options.within ), 1112 scrollInfo = $.position.getScrollInfo( within ), 1113 targetElem = target[0], 1114 collision = ( options.collision || "flip" ).split( " " ), 1115 offsets = {}; 1116 1117 if ( targetElem.nodeType === 9 ) { 1118 targetWidth = target.width(); 1119 targetHeight = target.height(); 1120 targetOffset = { top: 0, left: 0 }; 1121 } else if ( $.isWindow( targetElem ) ) { 1122 targetWidth = target.width(); 1123 targetHeight = target.height(); 1124 targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; 1125 } else if ( targetElem.preventDefault ) { 1126 // force left top to allow flipping 1127 options.at = "left top"; 1128 targetWidth = targetHeight = 0; 1129 targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; 1130 } else { 1131 targetWidth = target.outerWidth(); 1132 targetHeight = target.outerHeight(); 1133 targetOffset = target.offset(); 1134 } 1135 // clone to reuse original targetOffset later 1136 basePosition = $.extend( {}, targetOffset ); 1137 1138 // force my and at to have valid horizontal and vertical positions 1139 // if a value is missing or invalid, it will be converted to center 1140 $.each( [ "my", "at" ], function() { 1141 var pos = ( options[ this ] || "" ).split( " " ), 1142 horizontalOffset, 1143 verticalOffset; 1144 1145 if ( pos.length === 1) { 1146 pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 12,659 bytes, lines 1147-1544
1147 pos.concat( [ "center" ] ) : 1148 rvertical.test( pos[ 0 ] ) ? 1149 [ "center" ].concat( pos ) : 1150 [ "center", "center" ]; 1151 } 1152 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1153 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1154 1155 // calculate offsets 1156 horizontalOffset = roffset.exec( pos[ 0 ] ); 1157 verticalOffset = roffset.exec( pos[ 1 ] ); 1158 offsets[ this ] = [ 1159 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1160 verticalOffset ? verticalOffset[ 0 ] : 0 1161 ]; 1162 1163 // reduce to just the positions without the offsets 1164 options[ this ] = [ 1165 rposition.exec( pos[ 0 ] )[ 0 ], 1166 rposition.exec( pos[ 1 ] )[ 0 ] 1167 ]; 1168 }); 1169 1170 // normalize collision option 1171 if ( collision.length === 1 ) { 1172 collision[ 1 ] = collision[ 0 ]; 1173 } 1174 1175 if ( options.at[ 0 ] === "right" ) { 1176 basePosition.left += targetWidth; 1177 } else if ( options.at[ 0 ] === "center" ) { 1178 basePosition.left += targetWidth / 2; 1179 } 1180 1181 if ( options.at[ 1 ] === "bottom" ) { 1182 basePosition.top += targetHeight; 1183 } else if ( options.at[ 1 ] === "center" ) { 1184 basePosition.top += targetHeight / 2; 1185 } 1186 1187 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1188 basePosition.left += atOffset[ 0 ]; 1189 basePosition.top += atOffset[ 1 ]; 1190 1191 return this.each(function() { 1192 var collisionPosition, using, 1193 elem = $( this ), 1194 elemWidth = elem.outerWidth(), 1195 elemHeight = elem.outerHeight(), 1196 marginLeft = parseCss( this, "marginLeft" ), 1197 marginTop = parseCss( this, "marginTop" ), 1198 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1199 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1200 position = $.extend( {}, basePosition ), 1201 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1202 1203 if ( options.my[ 0 ] === "right" ) { 1204 position.left -= elemWidth; 1205 } else if ( options.my[ 0 ] === "center" ) { 1206 position.left -= elemWidth / 2; 1207 } 1208 1209 if ( options.my[ 1 ] === "bottom" ) { 1210 position.top -= elemHeight; 1211 } else if ( options.my[ 1 ] === "center" ) { 1212 position.top -= elemHeight / 2; 1213 } 1214 1215 position.left += myOffset[ 0 ]; 1216 position.top += myOffset[ 1 ]; 1217 1218 // if the browser doesn't support fractions, then round for consistent results 1219 if ( !$.support.offsetFractions ) { 1220 position.left = round( position.left ); 1221 position.top = round( position.top ); 1222 } 1223 1224 collisionPosition = { 1225 marginLeft: marginLeft, 1226 marginTop: marginTop 1227 }; 1228 1229 $.each( [ "left", "top" ], function( i, dir ) { 1230 if ( $.ui.position[ collision[ i ] ] ) { 1231 $.ui.position[ collision[ i ] ][ dir ]( position, { 1232 targetWidth: targetWidth, 1233 targetHeight: targetHeight, 1234 elemWidth: elemWidth, 1235 elemHeight: elemHeight, 1236 collisionPosition: collisionPosition, 1237 collisionWidth: collisionWidth, 1238 collisionHeight: collisionHeight, 1239 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1240 my: options.my, 1241 at: options.at, 1242 within: within, 1243 elem : elem 1244 }); 1245 } 1246 }); 1247 1248 if ( $.fn.bgiframe ) { 1249 elem.bgiframe(); 1250 } 1251 1252 if ( options.using ) { 1253 // adds feedback as second argument to using callback, if present 1254 using = function( props ) { 1255 var left = targetOffset.left - position.left, 1256 right = left + targetWidth - elemWidth, 1257 top = targetOffset.top - position.top, 1258 bottom = top + targetHeight - elemHeight, 1259 feedback = { 1260 target: { 1261 element: target, 1262 left: targetOffset.left, 1263 top: targetOffset.top, 1264 width: targetWidth, 1265 height: targetHeight 1266 }, 1267 element: { 1268 element: elem, 1269 left: position.left, 1270 top: position.top, 1271 width: elemWidth, 1272 height: elemHeight 1273 }, 1274 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1275 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1276 }; 1277 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1278 feedback.horizontal = "center"; 1279 } 1280 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1281 feedback.vertical = "middle"; 1282 } 1283 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1284 feedback.important = "horizontal"; 1285 } else { 1286 feedback.important = "vertical"; 1287 } 1288 options.using.call( this, props, feedback ); 1289 }; 1290 } 1291 1292 elem.offset( $.extend( position, { using: using } ) ); 1293 }); 1294}; 1295 1296$.ui.position = { 1297 fit: { 1298 left: function( position, data ) { 1299 var within = data.within, 1300 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1301 outerWidth = within.width, 1302 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1303 overLeft = withinOffset - collisionPosLeft, 1304 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1305 newOverRight; 1306 1307 // element is wider than within 1308 if ( data.collisionWidth > outerWidth ) { 1309 // element is initially over the left side of within 1310 if ( overLeft > 0 && overRight <= 0 ) { 1311 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1312 position.left += overLeft - newOverRight; 1313 // element is initially over right side of within 1314 } else if ( overRight > 0 && overLeft <= 0 ) { 1315 position.left = withinOffset; 1316 // element is initially over both left and right sides of within 1317 } else { 1318 if ( overLeft > overRight ) { 1319 position.left = withinOffset + outerWidth - data.collisionWidth; 1320 } else { 1321 position.left = withinOffset; 1322 } 1323 } 1324 // too far left -> align with left edge 1325 } else if ( overLeft > 0 ) { 1326 position.left += overLeft; 1327 // too far right -> align with right edge 1328 } else if ( overRight > 0 ) { 1329 position.left -= overRight; 1330 // adjust based on position and margin 1331 } else { 1332 position.left = max( position.left - collisionPosLeft, position.left ); 1333 } 1334 }, 1335 top: function( position, data ) { 1336 var within = data.within, 1337 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1338 outerHeight = data.within.height, 1339 collisionPosTop = position.top - data.collisionPosition.marginTop, 1340 overTop = withinOffset - collisionPosTop, 1341 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1342 newOverBottom; 1343 1344 // element is taller than within 1345 if ( data.collisionHeight > outerHeight ) { 1346 // element is initially over the top of within 1347 if ( overTop > 0 && overBottom <= 0 ) { 1348 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1349 position.top += overTop - newOverBottom; 1350 // element is initially over bottom of within 1351 } else if ( overBottom > 0 && overTop <= 0 ) { 1352 position.top = withinOffset; 1353 // element is initially over both top and bottom of within 1354 } else { 1355 if ( overTop > overBottom ) { 1356 position.top = withinOffset + outerHeight - data.collisionHeight; 1357 } else { 1358 position.top = withinOffset; 1359 } 1360 } 1361 // too far up -> align with top 1362 } else if ( overTop > 0 ) { 1363 position.top += overTop; 1364 // too far down -> align with bottom edge 1365 } else if ( overBottom > 0 ) { 1366 position.top -= overBottom; 1367 // adjust based on position and margin 1368 } else { 1369 position.top = max( position.top - collisionPosTop, position.top ); 1370 } 1371 } 1372 }, 1373 flip: { 1374 left: function( position, data ) { 1375 var within = data.within, 1376 withinOffset = within.offset.left + within.scrollLeft, 1377 outerWidth = within.width, 1378 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1379 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1380 overLeft = collisionPosLeft - offsetLeft, 1381 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1382 myOffset = data.my[ 0 ] === "left" ? 1383 -data.elemWidth : 1384 data.my[ 0 ] === "right" ? 1385 data.elemWidth : 1386 0, 1387 atOffset = data.at[ 0 ] === "left" ? 1388 data.targetWidth : 1389 data.at[ 0 ] === "right" ? 1390 -data.targetWidth : 1391 0, 1392 offset = -2 * data.offset[ 0 ], 1393 newOverRight, 1394 newOverLeft; 1395 1396 if ( overLeft < 0 ) { 1397 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1398 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1399 position.left += myOffset + atOffset + offset; 1400 } 1401 } 1402 else if ( overRight > 0 ) { 1403 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1404 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1405 position.left += myOffset + atOffset + offset; 1406 } 1407 } 1408 }, 1409 top: function( position, data ) { 1410 var within = data.within, 1411 withinOffset = within.offset.top + within.scrollTop, 1412 outerHeight = within.height, 1413 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1414 collisionPosTop = position.top - data.collisionPosition.marginTop, 1415 overTop = collisionPosTop - offsetTop, 1416 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1417 top = data.my[ 1 ] === "top", 1418 myOffset = top ? 1419 -data.elemHeight : 1420 data.my[ 1 ] === "bottom" ? 1421 data.elemHeight : 1422 0, 1423 atOffset = data.at[ 1 ] === "top" ? 1424 data.targetHeight : 1425 data.at[ 1 ] === "bottom" ? 1426 -data.targetHeight : 1427 0, 1428 offset = -2 * data.offset[ 1 ], 1429 newOverTop, 1430 newOverBottom; 1431 if ( overTop < 0 ) { 1432 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1433 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1434 position.top += myOffset + atOffset + offset; 1435 } 1436 } 1437 else if ( overBottom > 0 ) { 1438 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1439 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1440 position.top += myOffset + atOffset + offset; 1441 } 1442 } 1443 } 1444 }, 1445 flipfit: { 1446 left: function() { 1447 $.ui.position.flip.left.apply( this, arguments ); 1448 $.ui.position.fit.left.apply( this, arguments ); 1449 }, 1450 top: function() { 1451 $.ui.position.flip.top.apply( this, arguments ); 1452 $.ui.position.fit.top.apply( this, arguments ); 1453 } 1454 } 1455}; 1456 1457// fraction support test 1458(function () { 1459 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1460 body = document.getElementsByTagName( "body" )[ 0 ], 1461 div = document.createElement( "div" ); 1462 1463 //Create a "fake body" for testing based on method used in jQuery.support 1464 testElement = document.createElement( body ? "div" : "body" ); 1465 testElementStyle = { 1466 visibility: "hidden", 1467 width: 0, 1468 height: 0, 1469 border: 0, 1470 margin: 0, 1471 background: "none" 1472 }; 1473 if ( body ) { 1474 $.extend( testElementStyle, { 1475 position: "absolute", 1476 left: "-1000px", 1477 top: "-1000px" 1478 }); 1479 } 1480 for ( i in testElementStyle ) { 1481 testElement.style[ i ] = testElementStyle[ i ]; 1482 } 1483 testElement.appendChild( div ); 1484 testElementParent = body || document.documentElement; 1485 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1486 1487 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1488 1489 offsetLeft = $( div ).offset().left; 1490 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 1491 1492 testElement.innerHTML = ""; 1493 testElementParent.removeChild( testElement ); 1494})(); 1495 1496// DEPRECATED 1497if ( $.uiBackCompat !== false ) { 1498 // offset option 1499 (function( $ ) { 1500 var _position = $.fn.position; 1501 $.fn.position = function( options ) { 1502 if ( !options || !options.offset ) { 1503 return _position.call( this, options ); 1504 } 1505 var offset = options.offset.split( " " ), 1506 at = options.at.split( " " ); 1507 if ( offset.length === 1 ) { 1508 offset[ 1 ] = offset[ 0 ]; 1509 } 1510 if ( /^\d/.test( offset[ 0 ] ) ) { 1511 offset[ 0 ] = "+" + offset[ 0 ]; 1512 } 1513 if ( /^\d/.test( offset[ 1 ] ) ) { 1514 offset[ 1 ] = "+" + offset[ 1 ]; 1515 } 1516 if ( at.length === 1 ) { 1517 if ( /left|center|right/.test( at[ 0 ] ) ) { 1518 at[ 1 ] = "center"; 1519 } else { 1520 at[ 1 ] = at[ 0 ]; 1521 at[ 0 ] = "center"; 1522 } 1523 } 1524 return _position.call( this, $.extend( options, { 1525 at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ], 1526 offset: undefined 1527 } ) ); 1528 }; 1529 }( jQuery ) ); 1530} 1531 1532}( jQuery ) ); 1533(function( $, undefined ) { 1534 1535$.widget("ui.draggable", $.ui.mouse, { 1536 version: "1.9.2", 1537 widgetEventPrefix: "drag", 1538 options: { 1539 addClasses: true, 1540 appendTo: "parent", 1541 axis: false, 1542 connectToSortable: false, 1543 containment: false, 1544 cursor: "auto",
1545 cursorAt: false, 1546 grid: false, 1547 handle: false, 1548 helper: "original", 1549 iframeFix: false, 1550 opacity: false, 1551 refreshPositions: false, 1552 revert: false, 1553 revertDuration: 500, 1554 scope: "default", 1555 scroll: true, 1556 scrollSensitivity: 20, 1557 scrollSpeed: 20, 1558 snap: false, 1559 snapMode: "both", 1560 snapTolerance: 20, 1561 stack: false, 1562 zIndex: false 1563 }, 1564 _create: function() { 1565 1566 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) 1567 this.element[0].style.position = 'relative'; 1568 1569 (this.options.addClasses && this.element.addClass("ui-draggable")); 1570 (this.options.disabled && this.element.addClass("ui-draggable-disabled")); 1571 1572 this._mouseInit(); 1573 1574 }, 1575 1576 _destroy: function() { 1577 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1578 this._mouseDestroy(); 1579 }, 1580 1581 _mouseCapture: function(event) { 1582 1583 var o = this.options; 1584 1585 // among others, prevent a drag on a resizable-handle 1586 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) 1587 return false; 1588 1589 //Quit if we're not on a valid handle 1590 this.handle = this._getHandle(event); 1591 if (!this.handle) 1592 return false; 1593 1594 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1595 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>') 1596 .css({ 1597 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1598 position: "absolute", opacity: "0.001", zIndex: 1000 1599 }) 1600 .css($(this).offset()) 1601 .appendTo("body"); 1602 }); 1603 1604 return true; 1605 1606 }, 1607 1608 _mouseStart: function(event) { 1609 1610 var o = this.options; 1611 1612 //Create and append the visible helper 1613 this.helper = this._createHelper(event); 1614 1615 this.helper.addClass("ui-draggable-dragging"); 1616 1617 //Cache the helper size 1618 this._cacheHelperProportions(); 1619 1620 //If ddmanager is used for droppables, set the global draggable 1621 if($.ui.ddmanager) 1622 $.ui.ddmanager.current = this; 1623 1624 /* 1625 * - Position generation - 1626 * This block generates everything position related - it's the core of draggables. 1627 */ 1628 1629 //Cache the margins of the original element 1630 this._cacheMargins(); 1631 1632 //Store the helper's css position 1633 this.cssPosition = this.helper.css("position"); 1634 this.scrollParent = this.helper.scrollParent(); 1635 1636 //The element's absolute position on the page minus margins 1637 this.offset = this.positionAbs = this.element.offset(); 1638 this.offset = { 1639 top: this.offset.top - this.margins.top, 1640 left: this.offset.left - this.margins.left 1641 }; 1642 1643 $.extend(this.offset, { 1644 click: { //Where the click happened, relative to the element 1645 left: event.pageX - this.offset.left, 1646 top: event.pageY - this.offset.top 1647 }, 1648 parent: this._getParentOffset(), 1649 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1650 }); 1651 1652 //Generate the original position 1653 this.originalPosition = this.position = this._generatePosition(event); 1654 this.originalPageX = event.pageX; 1655 this.originalPageY = event.pageY; 1656 1657 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 1658 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1659 1660 //Set a containment if given in the options 1661 if(o.containment) 1662 this._setContainment(); 1663 1664 //Trigger event + callbacks 1665 if(this._trigger("start", event) === false) { 1666 this._clear(); 1667 return false; 1668 } 1669 1670 //Recache the helper size 1671 this._cacheHelperProportions(); 1672 1673 //Prepare the droppable offsets 1674 if ($.ui.ddmanager && !o.dropBehaviour) 1675 $.ui.ddmanager.prepareOffsets(this, event); 1676 1677 1678 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1679 1680 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1681 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); 1682 1683 return true; 1684 }, 1685 1686 _mouseDrag: function(event, noPropagation) { 1687 1688 //Compute the helpers position 1689 this.position = this._generatePosition(event); 1690 this.positionAbs = this._convertPositionTo("absolute"); 1691 1692 //Call plugins and callbacks and use the resulting position if something is returned 1693 if (!noPropagation) { 1694 var ui = this._uiHash(); 1695 if(this._trigger('drag', event, ui) === false) { 1696 this._mouseUp({}); 1697 return false;
1698 } 1699 this.position = ui.position; 1700 } 1701 1702 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 1703 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 1704 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 1705 1706 return false; 1707 }, 1708 1709 _mouseStop: function(event) { 1710 1711 //If we are using droppables, inform the manager about the drop 1712 var dropped = false; 1713 if ($.ui.ddmanager && !this.options.dropBehaviour) 1714 dropped = $.ui.ddmanager.drop(this, event); 1715 1716 //if a drop comes from outside (a sortable) 1717 if(this.dropped) { 1718 dropped = this.dropped; 1719 this.dropped = false; 1720 } 1721 1722 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1723 var element = this.element[0], elementInDom = false; 1724 while ( element && (element = element.parentNode) ) { 1725 if (element == document ) { 1726 elementInDom = true; 1727 } 1728 } 1729 if ( !elementInDom && this.options.helper === "original" ) 1730 return false; 1731 1732 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))) { 1733 var that = this; 1734 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1735 if(that._trigger("stop", event) !== false) { 1736 that._clear(); 1737 } 1738 }); 1739 } else { 1740 if(this._trigger("stop", event) !== false) { 1741 this._clear(); 1742 } 1743 } 1744 1745 return false; 1746 }, 1747 1748 _mouseUp: function(event) { 1749 //Remove frame helpers 1750 $("div.ui-draggable-iframeFix").each(function() { 1751 this.parentNode.removeChild(this); 1752 }); 1753 1754 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1755 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); 1756 1757 return $.ui.mouse.prototype._mouseUp.call(this, event); 1758 }, 1759 1760 cancel: function() { 1761 1762 if(this.helper.is(".ui-draggable-dragging")) { 1763 this._mouseUp({}); 1764 } else { 1765 this._clear(); 1766 } 1767 1768 return this; 1769 1770 }, 1771 1772 _getHandle: function(event) { 1773 1774 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; 1775 $(this.options.handle, this.element) 1776 .find("*") 1777 .andSelf() 1778 .each(function() { 1779 if(this == event.target) handle = true; 1780 }); 1781 1782 return handle; 1783 1784 }, 1785 1786 _createHelper: function(event) { 1787 1788 var o = this.options; 1789 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); 1790 1791 if(!helper.parents('body').length) 1792 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); 1793 1794 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) 1795 helper.css("position", "absolute"); 1796 1797 return helper; 1798 1799 }, 1800 1801 _adjustOffsetFromHelper: function(obj) { 1802 if (typeof obj == 'string') { 1803 obj = obj.split(' '); 1804 } 1805 if ($.isArray(obj)) { 1806 obj = {left: +obj[0], top: +obj[1] || 0}; 1807 } 1808 if ('left' in obj) { 1809 this.offset.click.left = obj.left + this.margins.left; 1810 } 1811 if ('right' in obj) { 1812 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1813 } 1814 if ('top' in obj) { 1815 this.offset.click.top = obj.top + this.margins.top; 1816 } 1817 if ('bottom' in obj) { 1818 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1819 } 1820 }, 1821 1822 _getParentOffset: function() { 1823 1824 //Get the offsetParent and cache its position 1825 this.offsetParent = this.helper.offsetParent(); 1826 var po = this.offsetParent.offset(); 1827 1828 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1829 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1830 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1831 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1832 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1833 po.left += this.scrollParent.scrollLeft(); 1834 po.top += this.scrollParent.scrollTop(); 1835 } 1836 1837 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 1838 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 1839 po = { top: 0, left: 0 }; 1840 1841 return { 1842 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
184210) || 0), 1843 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1844 }; 1845 1846 }, 1847 1848 _getRelativeOffset: function() { 1849 1850 if(this.cssPosition == "relative") { 1851 var p = this.element.position(); 1852 return { 1853 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1854 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1855 }; 1856 } else { 1857 return { top: 0, left: 0 }; 1858 } 1859 1860 }, 1861 1862 _cacheMargins: function() { 1863 this.margins = { 1864 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1865 top: (parseInt(this.element.css("marginTop"),10) || 0), 1866 right: (parseInt(this.element.css("marginRight"),10) || 0), 1867 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1868 }; 1869 }, 1870 1871 _cacheHelperProportions: function() { 1872 this.helperProportions = { 1873 width: this.helper.outerWidth(), 1874 height: this.helper.outerHeight() 1875 }; 1876 }, 1877 1878 _setContainment: function() { 1879 1880 var o = this.options; 1881 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 1882 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 1883 o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1884 o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1885 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 1886 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 1887 ]; 1888 1889 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { 1890 var c = $(o.containment); 1891 var ce = c[0]; if(!ce) return; 1892 var co = c.offset(); 1893 var over = ($(ce).css("overflow") != 'hidden'); 1894 1895 this.containment = [ 1896 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), 1897 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1898 (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 - this.margins.right, 1899 (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom 1900 ]; 1901 this.relative_container = c; 1902 1903 } else if(o.containment.constructor == Array) { 1904 this.containment = o.containment; 1905 } 1906 1907 }, 1908 1909 _convertPositionTo: function(d, pos) { 1910 1911 if(!pos) pos = this.position; 1912 var mod = d == "absolute" ? 1 : -1; 1913 var o = this.options, 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); 1914 1915 return { 1916 top: ( 1917 pos.top // The absolute mouse position 1918 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 1919 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 1920 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 1921 ), 1922 left: ( 1923 pos.left // The absolute mouse position 1924 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 1925 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 1926 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 1927 ) 1928 }; 1929 1930 }, 1931 1932 _generatePosition: function(event) { 1933 1934 var o = this.options, 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); 1935 var pageX = event.pageX; 1936 var pageY = event.pageY; 1937 1938 /* 1939 * - Position constraining - 1940 * Constrain the position to a mix of grid, containment. 1941 */ 1942 1943 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 1944 var containment; 1945 if(this.containment) { 1946 if (this.relative_container){ 1947 var co = this.relative_container.offset(); 1948 containment = [ this.containment[0] + co.left, 1949 this.containment[1] + co.top, 1950 this.containment[2] + co.left, 1951 this.containment[3] + co.top ]; 1952 } 1953 else { 1954 containment = this.containment; 1955 } 1956 1957 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; 1958 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; 1959 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; 1960 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; 1961 } 1962 1963 if(o.grid) { 1964 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1965 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1966 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; 1967 1968 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1969 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; 1970 } 1971 1972 } 1973 1974 return { 1975 top: ( 1976 pageY // The absolute mouse position 1977 - this.offset.click.top // Click offset (relative to the element) 1978 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 1979 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 1980 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 1981 ), 1982 left: ( 1983 pageX // The absolute mouse position 1984 - this.offset.click.left // Click offset (relative to the element) 1985 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 1986 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 1987 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 1988 ) 1989 }; 1990 1991 }, 1992 1993 _clear: function() { 1994 this.helper.removeClass("ui-draggable-dragging"); 1995 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); 1996 //if($.ui.ddmanager) $.ui.ddmanager.current = null; 1997 this.helper = null; 1998 this.cancelHelperRemoval = false;
1999 }, 2000 2001 // From now on bulk stuff - mainly helpers 2002 2003 _trigger: function(type, event, ui) { 2004 ui = ui || this._uiHash(); 2005 $.ui.plugin.call(this, type, [event, ui]); 2006 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins 2007 return $.Widget.prototype._trigger.call(this, type, event, ui); 2008 }, 2009 2010 plugins: {}, 2011 2012 _uiHash: function(event) { 2013 return { 2014 helper: this.helper, 2015 position: this.position, 2016 originalPosition: this.originalPosition, 2017 offset: this.positionAbs 2018 }; 2019 } 2020 2021}); 2022 2023$.ui.plugin.add("draggable", "connectToSortable", { 2024 start: function(event, ui) { 2025 2026 var inst = $(this).data("draggable"), o = inst.options, 2027 uiSortable = $.extend({}, ui, { item: inst.element }); 2028 inst.sortables = []; 2029 $(o.connectToSortable).each(function() { 2030 var sortable = $.data(this, 'sortable'); 2031 if (sortable && !sortable.options.disabled) { 2032 inst.sortables.push({ 2033 instance: sortable, 2034 shouldRevert: sortable.options.revert 2035 }); 2036 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). 2037 sortable._trigger("activate", event, uiSortable); 2038 } 2039 }); 2040 2041 }, 2042 stop: function(event, ui) { 2043 2044 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 2045 var inst = $(this).data("draggable"), 2046 uiSortable = $.extend({}, ui, { item: inst.element }); 2047 2048 $.each(inst.sortables, function() { 2049 if(this.instance.isOver) { 2050 2051 this.instance.isOver = 0; 2052 2053 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 2054 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 2055 2056 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' 2057 if(this.shouldRevert) this.instance.options.revert = true; 2058 2059 //Trigger the stop of the sortable 2060 this.instance._mouseStop(event); 2061 2062 this.instance.options.helper = this.instance.options._helper; 2063 2064 //If the helper has been the original item, restore properties in the sortable 2065 if(inst.options.helper == 'original') 2066 this.instance.currentItem.css({ top: 'auto', left: 'auto' }); 2067 2068 } else { 2069 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 2070 this.instance._trigger("deactivate", event, uiSortable); 2071 } 2072 2073 }); 2074 2075 }, 2076 drag: function(event, ui) { 2077 2078 var inst = $(this).data("draggable"), that = this; 2079 2080 var checkPos = function(o) { 2081 var dyClick = this.offset.click.top, dxClick = this.offset.click.left; 2082 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; 2083 var itemHeight = o.height, itemWidth = o.width; 2084 var itemTop = o.top, itemLeft = o.left; 2085 2086 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); 2087 }; 2088 2089 $.each(inst.sortables, function(i) { 2090 2091 var innermostIntersecting = false; 2092 var thisSortable = this; 2093 //Copy over some variables to allow calling the sortable's native _intersectsWith 2094 this.instance.positionAbs = inst.positionAbs; 2095 this.instance.helperProportions = inst.helperProportions; 2096 this.instance.offset.click = inst.offset.click; 2097 2098 if(this.instance._intersectsWith(this.instance.containerCache)) { 2099 innermostIntersecting = true; 2100 $.each(inst.sortables, function () { 2101 this.instance.positionAbs = inst.positionAbs; 2102 this.instance.helperProportions = inst.helperProportions; 2103 this.instance.offset.click = inst.offset.click; 2104 if (this != thisSortable 2105 && this.instance._intersectsWith(this.instance.containerCache) 2106 && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0])) 2107 innermostIntersecting = false; 2108 return innermostIntersecting; 2109 }); 2110 } 2111 2112 2113 if(innermostIntersecting) { 2114 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 2115 if(!this.instance.isOver) { 2116 2117 this.instance.isOver = 1; 2118 //Now we fake the start of dragging for the sortable instance, 2119 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 2120 //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) 2121 this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); 2122 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 2123 this.instance.options.helper = function() { return ui.helper[0]; }; 2124 2125 event.target = this.instance.currentItem[0]; 2126 this.instance._mouseCapture(event, true); 2127 this.instance._mouseStart(event, true, true); 2128
2129 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 2130 this.instance.offset.click.top = inst.offset.click.top; 2131 this.instance.offset.click.left = inst.offset.click.left; 2132 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 2133 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 2134 2135 inst._trigger("toSortable", event); 2136 inst.dropped = this.instance.element; //draggable revert needs that 2137 //hack so receive/update callbacks work (mostly) 2138 inst.currentItem = inst.element; 2139 this.instance.fromOutside = inst; 2140 2141 } 2142 2143 //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 2144 if(this.instance.currentItem) this.instance._mouseDrag(event); 2145 2146 } else { 2147 2148 //If it doesn't intersect with the sortable, and it intersected before, 2149 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 2150 if(this.instance.isOver) { 2151 2152 this.instance.isOver = 0; 2153 this.instance.cancelHelperRemoval = true; 2154 2155 //Prevent reverting on this forced stop 2156 this.instance.options.revert = false; 2157 2158 // The out event needs to be triggered independently 2159 this.instance._trigger('out', event, this.instance._uiHash(this.instance)); 2160 2161 this.instance._mouseStop(event, true); 2162 this.instance.options.helper = this.instance.options._helper; 2163 2164 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 2165 this.instance.currentItem.remove(); 2166 if(this.instance.placeholder) this.instance.placeholder.remove(); 2167 2168 inst._trigger("fromSortable", event); 2169 inst.dropped = false; //draggable revert needs that 2170 } 2171 2172 }; 2173 2174 }); 2175 2176 } 2177}); 2178 2179$.ui.plugin.add("draggable", "cursor", { 2180 start: function(event, ui) { 2181 var t = $('body'), o = $(this).data('draggable').options; 2182 if (t.css("cursor")) o._cursor = t.css("cursor"); 2183 t.css("cursor", o.cursor); 2184 }, 2185 stop: function(event, ui) { 2186 var o = $(this).data('draggable').options; 2187 if (o._cursor) $('body').css("cursor", o._cursor); 2188 } 2189}); 2190 2191$.ui.plugin.add("draggable", "opacity", { 2192 start: function(event, ui) { 2193 var t = $(ui.helper), o = $(this).data('draggable').options; 2194 if(t.css("opacity")) o._opacity = t.css("opacity"); 2195 t.css('opacity', o.opacity); 2196 }, 2197 stop: function(event, ui) { 2198 var o = $(this).data('draggable').options; 2199 if(o._opacity) $(ui.helper).css('opacity', o._opacity); 2200 } 2201}); 2202 2203$.ui.plugin.add("draggable", "scroll", { 2204 start: function(event, ui) { 2205 var i = $(this).data("draggable"); 2206 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); 2207 }, 2208 drag: function(event, ui) { 2209 2210 var i = $(this).data("draggable"), o = i.options, scrolled = false; 2211 2212 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { 2213 2214 if(!o.axis || o.axis != 'x') { 2215 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 2216 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 2217 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) 2218 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 2219 } 2220 2221 if(!o.axis || o.axis != 'y') { 2222 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 2223 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 2224 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) 2225 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 2226 } 2227 2228 } else { 2229 2230 if(!o.axis || o.axis != 'x') { 2231 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 2232 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 2233 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 2234 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 2235 } 2236 2237 if(!o.axis || o.axis != 'y') { 2238 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 2239 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 2240 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 2241 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 2242 } 2243 2244 } 2245 2246 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 2247 $.ui.ddmanager.prepareOffsets(i, event); 2248 2249 } 2250}); 2251 2252$.ui.plugin.add("draggable", "snap", { 2253 start: function(event, ui) { 2254 2255 var i = $(this).data("draggable"), o = i.options; 2256 i.snapElements = []; 2257 2258 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { 2259 var $t = $(this); var $o = $t.offset(); 2260 if(this != i.element[0]) i.snapElements.push({ 2261 item: this, 2262 width: $t.outerWidth(), height: $t.outerHeight(), 2263 top: $o.top, left: $o.left 2264 }); 2265 }); 2266 2267 }, 2268 drag: function(event, ui) { 2269 2270 var inst = $(this).data("draggable"), o = inst.options; 2271 var d = o.snapTolerance; 2272 2273 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 2274 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 2275 2276 for (var i = inst.snapElements.length - 1; i >= 0; i--){ 2277 2278 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, 2279 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; 2280 2281 //Yes, I know, this is insane ;) 2282 if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { 2283 if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2284 inst.snapElements[i].snapping = false;
2285 continue; 2286 } 2287 2288 if(o.snapMode != 'inner') { 2289 var ts = Math.abs(t - y2) <= d; 2290 var bs = Math.abs(b - y1) <= d; 2291 var ls = Math.abs(l - x2) <= d; 2292 var rs = Math.abs(r - x1) <= d; 2293 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2294 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 2295 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 2296 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 2297 } 2298 2299 var first = (ts || bs || ls || rs); 2300 2301 if(o.snapMode != 'outer') { 2302 var ts = Math.abs(t - y1) <= d; 2303 var bs = Math.abs(b - y2) <= d; 2304 var ls = Math.abs(l - x1) <= d; 2305 var rs = Math.abs(r - x2) <= d; 2306 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 2307 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2308 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 2309 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 2310 } 2311 2312 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) 2313 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2314 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 2315 2316 }; 2317 2318 } 2319}); 2320 2321$.ui.plugin.add("draggable", "stack", { 2322 start: function(event, ui) { 2323 2324 var o = $(this).data("draggable").options; 2325 2326 var group = $.makeArray($(o.stack)).sort(function(a,b) { 2327 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 2328 }); 2329 if (!group.length) { return; } 2330 2331 var min = parseInt(group[0].style.zIndex) || 0; 2332 $(group).each(function(i) { 2333 this.style.zIndex = min + i; 2334 }); 2335 2336 this[0].style.zIndex = min + group.length; 2337 2338 } 2339}); 2340 2341$.ui.plugin.add("draggable", "zIndex", { 2342 start: function(event, ui) { 2343 var t = $(ui.helper), o = $(this).data("draggable").options; 2344 if(t.css("zIndex")) o._zIndex = t.css("zIndex"); 2345 t.css('zIndex', o.zIndex); 2346 }, 2347 stop: function(event, ui) { 2348 var o = $(this).data("draggable").options; 2349 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); 2350 } 2351}); 2352 2353})(jQuery); 2354(function( $, undefined ) { 2355 2356$.widget("ui.droppable", { 2357 version: "1.9.2", 2358 widgetEventPrefix: "drop", 2359 options: { 2360 accept: '*', 2361 activeClass: false, 2362 addClasses: true, 2363 greedy: false, 2364 hoverClass: false, 2365 scope: 'default', 2366 tolerance: 'intersect' 2367 }, 2368 _create: function() { 2369 2370 var o = this.options, accept = o.accept; 2371 this.isover = 0; this.isout = 1; 2372 2373 this.accept = $.isFunction(accept) ? accept : function(d) { 2374 return d.is(accept); 2375 }; 2376 2377 //Store the droppable's proportions 2378 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 2379 2380 // Add the reference and positions to the manager 2381 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 2382 $.ui.ddmanager.droppables[o.scope].push(this); 2383 2384 (o.addClasses && this.element.addClass("ui-droppable")); 2385 2386 }, 2387 2388 _destroy: function() { 2389 var drop = $.ui.ddmanager.droppables[this.options.scope]; 2390 for ( var i = 0; i < drop.length; i++ ) 2391 if ( drop[i] == this ) 2392 drop.splice(i, 1); 2393 2394 this.element.removeClass("ui-droppable ui-droppable-disabled"); 2395 }, 2396 2397 _setOption: function(key, value) { 2398 2399 if(key == 'accept') { 2400 this.accept = $.isFunction(value) ? value : function(d) { 2401 return d.is(value); 2402 }; 2403 } 2404 $.Widget.prototype._setOption.apply(this, arguments); 2405 }, 2406 2407 _activate: function(event) { 2408 var draggable = $.ui.ddmanager.current; 2409 if(this.options.activeClass) this.element.addClass(this.options.activeClass); 2410 (draggable && this._trigger('activate', event, this.ui(draggable))); 2411 }, 2412 2413 _deactivate: function(event) { 2414 var draggable = $.ui.ddmanager.current; 2415 if(this.options.activeClass) this.element.removeClass(this.options.activeClass); 2416 (draggable && this._trigger('deactivate', event, this.ui(draggable))); 2417 }, 2418 2419 _over: function(event) { 2420 2421 var draggable = $.ui.ddmanager.current; 2422 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 2423 2424 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2425 if(this.options.hoverClass) this.element.addClass(this.options.hoverClass); 2426 this._trigger('over', event, this.ui(draggable)); 2427 } 2428 2429 }, 2430 2431 _out: function(event) { 2432 2433 var draggable = $.ui.ddmanager.current; 2434 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 2435 2436 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2437 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 2438 this._trigger('out', event, this.ui(draggable)); 2439 } 2440 2441 }, 2442 2443 _drop: function(event,custom) { 2444 2445 var draggable = custom || $.ui.ddmanager.current; 2446 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element 2447 2448 var childrenIntersection = false;
2449 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { 2450 var inst = $.data(this, 'droppable'); 2451 if( 2452 inst.options.greedy 2453 && !inst.options.disabled 2454 && inst.options.scope == draggable.options.scope 2455 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) 2456 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2457 ) { childrenIntersection = true; return false; } 2458 }); 2459 if(childrenIntersection) return false; 2460 2461 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2462 if(this.options.activeClass) this.element.removeClass(this.options.activeClass); 2463 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 2464 this._trigger('drop', event, this.ui(draggable)); 2465 return this.element; 2466 } 2467 2468 return false; 2469 2470 }, 2471 2472 ui: function(c) { 2473 return { 2474 draggable: (c.currentItem || c.element), 2475 helper: c.helper, 2476 position: c.position, 2477 offset: c.positionAbs 2478 }; 2479 } 2480 2481}); 2482 2483$.ui.intersect = function(draggable, droppable, toleranceMode) { 2484 2485 if (!droppable.offset) return false; 2486 2487 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 2488 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; 2489 var l = droppable.offset.left, r = l + droppable.proportions.width, 2490 t = droppable.offset.top, b = t + droppable.proportions.height; 2491 2492 switch (toleranceMode) { 2493 case 'fit': 2494 return (l <= x1 && x2 <= r 2495 && t <= y1 && y2 <= b); 2496 break; 2497 case 'intersect': 2498 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half 2499 && x2 - (draggable.helperProportions.width / 2) < r // Left Half 2500 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half 2501 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 2502 break; 2503 case 'pointer': 2504 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), 2505 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), 2506 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); 2507 return isOver; 2508 break; 2509 case 'touch': 2510 return ( 2511 (y1 >= t && y1 <= b) || // Top edge touching 2512 (y2 >= t && y2 <= b) || // Bottom edge touching 2513 (y1 < t && y2 > b) // Surrounded vertically 2514 ) && ( 2515 (x1 >= l && x1 <= r) || // Left edge touching 2516 (x2 >= l && x2 <= r) || // Right edge touching 2517 (x1 < l && x2 > r) // Surrounded horizontally 2518 ); 2519 break; 2520 default: 2521 return false; 2522 break; 2523 } 2524 2525}; 2526 2527/* 2528 This manager tracks offsets of draggables and droppables 2529*/ 2530$.ui.ddmanager = { 2531 current: null, 2532 droppables: { 'default': [] }, 2533 prepareOffsets: function(t, event) { 2534 2535 var m = $.ui.ddmanager.droppables[t.options.scope] || []; 2536 var type = event ? event.type : null; // workaround for #2317 2537 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); 2538 2539 droppablesLoop: for (var i = 0; i < m.length; i++) { 2540 2541 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted 2542 for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item 2543 m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue 2544 2545 if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables 2546 2547 m[i].offset = m[i].element.offset(); 2548 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2549 2550 } 2551 2552 }, 2553 drop: function(draggable, event) { 2554 2555 var dropped = false; 2556 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2557 2558 if(!this.options) return; 2559 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) 2560 dropped = this._drop.call(this, event) || dropped; 2561 2562 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2563 this.isout = 1; this.isover = 0; 2564 this._deactivate.call(this, event); 2565 } 2566 2567 }); 2568 return dropped; 2569 2570 }, 2571 dragStart: function( draggable, event ) { 2572 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2573 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2574 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); 2575 }); 2576 }, 2577 drag: function(draggable, event) { 2578 2579 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2580 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); 2581 2582 //Run through all droppables and check their positions based on specific tolerance options 2583 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2584 2585 if(this.options.disabled || this.greedyChild || !this.visible) return; 2586 var intersects = $.ui.intersect(draggable, this, this.options.tolerance); 2587 2588 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); 2589 if(!c) return; 2590 2591 var parentInstance; 2592 if (this.options.greedy) { 2593 // find droppable parents with same scope 2594 var scope = this.options.scope; 2595 var parent = this.element.parents(':data(droppable)').filter(function () { 2596 return $.data(this, 'droppable').options.scope === scope; 2597 }); 2598 2599 if (parent.length) { 2600 parentInstance = $.data(parent[0], 'droppable'); 2601 parentInstance.greedyChild = (c == 'isover' ? 1 : 0); 2602 } 2603 } 2604 2605 // we just moved into a greedy child 2606 if (parentInstance && c == 'isover') { 2607 parentInstance['isover'] = 0; 2608 parentInstance['isout'] = 1; 2609 parentInstance._out.call(parentInstance, event); 2610 } 2611 2612 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; 2613 this[c == "isover" ? "_over" : "_out"].call(this, event); 2614 2615 // we just moved out of a greedy child 2616 if (parentInstance && c == 'isout') { 2617 parentInstance['isout'] = 0; 2618 parentInstance['isover'] = 1; 2619 parentInstance._over.call(parentInstance, event); 2620 } 2621 }); 2622 2623 }, 2624 dragStop: function( draggable, event ) { 2625 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2626 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2627 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); 2628 } 2629}; 2630 2631})(jQuery); 2632(function( $, undefined ) { 2633 2634$.widget("ui.resizable", $.ui.mouse, { 2635 version: "1.9.2", 2636 widgetEventPrefix: "resize", 2637 options: { 2638 alsoResize: false, 2639 animate: false, 2640 animateDuration: "slow", 2641 animateEasing: "swing", 2642 aspectRatio: false, 2643 autoHide: false, 2644 containment: false, 2645 ghost: false, 2646 grid: false, 2647 handles: "e,s,se", 2648 helper: false, 2649 maxHeight: null, 2650 maxWidth: null, 2651 minHeight: 10, 2652 minWidth: 10, 2653 zIndex: 1000 2654 }, 2655 _create: function() { 2656 2657 var that = this, o = this.options; 2658 this.element.addClass("ui-resizable"); 2659 2660 $.extend(this, { 2661 _aspectRatio: !!(o.aspectRatio), 2662 aspectRatio: o.aspectRatio, 2663 originalElement: this.element, 2664 _proportionallyResizeElements: [], 2665 _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null 2666 }); 2667 2668 //Wrap the element if it cannot hold child nodes 2669 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2670 2671 //Create a wrapper element and set the wrapper to the new current internal element 2672 this.element.wrap( 2673 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({ 2674 position: this.element.css('position'), 2675 width: this.element.outerWidth(), 2676 height: this.element.outerHeight(), 2677 top: this.element.css('top'), 2678 left: this.element.css('left') 2679 }) 2680 ); 2681 2682 //Overwrite the original this.element 2683 this.element = this.element.parent().data( 2684 "resizable", this.element.data('resizable') 2685 ); 2686 2687 this.elementIsWrapper = true; 2688 2689 //Move margins to the wrapper 2690 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2691 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2692 2693 //Prevent Safari textarea resize 2694 this.originalResizeStyle = this.originalElement.css('resize'); 2695 this.originalElement.css('resize', 'none'); 2696 2697 //Push the actual element to our proportionallyResize internal array 2698 this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); 2699 2700 // avoid IE jump (hard set the margin) 2701 this.originalElement.css({ margin: this.originalElement.css('margin') }); 2702 2703 // fix handlers offset 2704 this._proportionallyResize(); 2705 2706 } 2707 2708 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' }); 2709 if(this.handles.constructor == String) { 2710 2711 if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; 2712 var n = this.handles.split(","); this.handles = {}; 2713 2714 for(var i = 0; i < n.length; i++) { 2715 2716 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; 2717 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); 2718 2719 // Apply zIndex to all handles - see #7960 2720 axis.css({ zIndex: o.zIndex }); 2721 2722 //TODO : What's going on here? 2723 if ('se' == handle) { 2724 axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); 2725 }; 2726 2727 //Insert into internal handles object and append to element 2728 this.handles[handle] = '.ui-resizable-'+handle; 2729 this.element.append(axis); 2730 } 2731 2732 } 2733 2734 this._renderAxis = function(target) { 2735 2736 target = target || this.element; 2737 2738 for(var i in this.handles) { 2739 2740 if(this.handles[i].constructor == String) 2741 this.handles[i] = $(this.handles[i], this.element).show(); 2742 2743 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2744 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2745 2746 var axis = $(this.handles[i], this.element), padWrapper = 0; 2747 2748 //Checking the correct pad and border 2749 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2750 2751 //The padding type i have to apply... 2752 var padPos = [ 'padding',
2753 /ne|nw|n/.test(i) ? 'Top' : 2754 /se|sw|s/.test(i) ? 'Bottom' : 2755 /^e$/.test(i) ? 'Right' : 'Left' ].join(""); 2756 2757 target.css(padPos, padWrapper); 2758 2759 this._proportionallyResize(); 2760 2761 } 2762 2763 //TODO: What's that good for? There's not anything to be executed left 2764 if(!$(this.handles[i]).length) 2765 continue; 2766 2767 } 2768 }; 2769 2770 //TODO: make renderAxis a prototype function 2771 this._renderAxis(this.element); 2772 2773 this._handles = $('.ui-resizable-handle', this.element) 2774 .disableSelection(); 2775 2776 //Matching axis name 2777 this._handles.mouseover(function() { 2778 if (!that.resizing) { 2779 if (this.className) 2780 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2781 //Axis, default = se 2782 that.axis = axis && axis[1] ? axis[1] : 'se'; 2783 } 2784 }); 2785 2786 //If we want to auto hide the elements 2787 if (o.autoHide) { 2788 this._handles.hide(); 2789 $(this.element) 2790 .addClass("ui-resizable-autohide") 2791 .mouseenter(function() { 2792 if (o.disabled) return; 2793 $(this).removeClass("ui-resizable-autohide"); 2794 that._handles.show(); 2795 }) 2796 .mouseleave(function(){ 2797 if (o.disabled) return; 2798 if (!that.resizing) { 2799 $(this).addClass("ui-resizable-autohide"); 2800 that._handles.hide(); 2801 } 2802 }); 2803 } 2804 2805 //Initialize the mouse interaction 2806 this._mouseInit(); 2807 2808 }, 2809 2810 _destroy: function() { 2811 2812 this._mouseDestroy(); 2813 2814 var _destroy = function(exp) { 2815 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2816 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); 2817 }; 2818 2819 //TODO: Unwrap at same DOM position 2820 if (this.elementIsWrapper) { 2821 _destroy(this.element); 2822 var wrapper = this.element; 2823 this.originalElement.css({ 2824 position: wrapper.css('position'), 2825 width: wrapper.outerWidth(), 2826 height: wrapper.outerHeight(), 2827 top: wrapper.css('top'), 2828 left: wrapper.css('left') 2829 }).insertAfter( wrapper ); 2830 wrapper.remove(); 2831 } 2832 2833 this.originalElement.css('resize', this.originalResizeStyle); 2834 _destroy(this.originalElement); 2835 2836 return this; 2837 }, 2838 2839 _mouseCapture: function(event) { 2840 var handle = false; 2841 for (var i in this.handles) { 2842 if ($(this.handles[i])[0] == event.target) { 2843 handle = true; 2844 } 2845 } 2846 2847 return !this.options.disabled && handle; 2848 }, 2849 2850 _mouseStart: function(event) { 2851 2852 var o = this.options, iniPos = this.element.position(), el = this.element; 2853 2854 this.resizing = true; 2855 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; 2856 2857 // bugfix for http://dev.jquery.com/ticket/1749 2858 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { 2859 el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); 2860 } 2861 2862 this._renderProxy(); 2863 2864 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); 2865 2866 if (o.containment) { 2867 curleft += $(o.containment).scrollLeft() || 0; 2868 curtop += $(o.containment).scrollTop() || 0; 2869 } 2870 2871 //Store needed variables 2872 this.offset = this.helper.offset(); 2873 this.position = { left: curleft, top: curtop }; 2874 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2875 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2876 this.originalPosition = { left: curleft, top: curtop }; 2877 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 2878 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2879 2880 //Aspect Ratio 2881 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 2882 2883 var cursor = $('.ui-resizable-' + this.axis).css('cursor'); 2884 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); 2885 2886 el.addClass("ui-resizable-resizing"); 2887 this._propagate("start", event); 2888 return true; 2889 }, 2890 2891 _mouseDrag: function(event) { 2892 2893 //Increase performance, avoid regex 2894 var el = this.helper, o = this.options, props = {}, 2895 that = this, smp = this.originalMousePosition, a = this.axis; 2896 2897 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; 2898 var trigger = this._change[a]; 2899 if (!trigger) return false;
2900 2901 // Calculate the attrs that will be change 2902 var data = trigger.apply(this, [event, dx, dy]); 2903 2904 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 2905 this._updateVirtualBoundaries(event.shiftKey); 2906 if (this._aspectRatio || event.shiftKey) 2907 data = this._updateRatio(data, event); 2908 2909 data = this._respectSize(data, event); 2910 2911 // plugins callbacks need to be called first 2912 this._propagate("resize", event); 2913 2914 el.css({ 2915 top: this.position.top + "px", left: this.position.left + "px", 2916 width: this.size.width + "px", height: this.size.height + "px" 2917 }); 2918 2919 if (!this._helper && this._proportionallyResizeElements.length) 2920 this._proportionallyResize(); 2921 2922 this._updateCache(data); 2923 2924 // calling the user callback at the end 2925 this._trigger('resize', event, this.ui()); 2926 2927 return false; 2928 }, 2929 2930 _mouseStop: function(event) { 2931 2932 this.resizing = false; 2933 var o = this.options, that = this; 2934 2935 if(this._helper) { 2936 var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2937 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2938 soffsetw = ista ? 0 : that.sizeDiff.width; 2939 2940 var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }, 2941 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 2942 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 2943 2944 if (!o.animate) 2945 this.element.css($.extend(s, { top: top, left: left })); 2946 2947 that.helper.height(that.size.height); 2948 that.helper.width(that.size.width); 2949 2950 if (this._helper && !o.animate) this._proportionallyResize(); 2951 } 2952 2953 $('body').css('cursor', 'auto'); 2954 2955 this.element.removeClass("ui-resizable-resizing"); 2956 2957 this._propagate("stop", event); 2958 2959 if (this._helper) this.helper.remove(); 2960 return false; 2961 2962 }, 2963 2964 _updateVirtualBoundaries: function(forceAspectRatio) { 2965 var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; 2966 2967 b = { 2968 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 2969 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 2970 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 2971 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 2972 }; 2973 2974 if(this._aspectRatio || forceAspectRatio) { 2975 // We want to create an enclosing box whose aspect ration is the requested one 2976 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 2977 pMinWidth = b.minHeight * this.aspectRatio; 2978 pMinHeight = b.minWidth / this.aspectRatio; 2979 pMaxWidth = b.maxHeight * this.aspectRatio; 2980 pMaxHeight = b.maxWidth / this.aspectRatio; 2981 2982 if(pMinWidth > b.minWidth) b.minWidth = pMinWidth; 2983 if(pMinHeight > b.minHeight) b.minHeight = pMinHeight; 2984 if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; 2985 if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; 2986 } 2987 this._vBoundaries = b; 2988 }, 2989 2990 _updateCache: function(data) { 2991 var o = this.options; 2992 this.offset = this.helper.offset(); 2993 if (isNumber(data.left)) this.position.left = data.left; 2994 if (isNumber(data.top)) this.position.top = data.top; 2995 if (isNumber(data.height)) this.size.height = data.height; 2996 if (isNumber(data.width)) this.size.width = data.width; 2997 }, 2998 2999 _updateRatio: function(data, event) { 3000 3001 var o = this.options, cpos = this.position, csize = this.size, a = this.axis; 3002 3003 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); 3004 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); 3005 3006 if (a == 'sw') { 3007 data.left = cpos.left + (csize.width - data.width); 3008 data.top = null; 3009 } 3010 if (a == 'nw') { 3011 data.top = cpos.top + (csize.height - data.height); 3012 data.left = cpos.left + (csize.width - data.width); 3013 } 3014 3015 return data; 3016 }, 3017 3018 _respectSize: function(data, event) { 3019 3020 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, 3021 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 3022 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); 3023 3024 if (isminw) data.width = o.minWidth; 3025 if (isminh) data.height = o.minHeight; 3026 if (ismaxw) data.width = o.maxWidth; 3027 if (ismaxh) data.height = o.maxHeight; 3028 3029 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; 3030 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 3031 3032 if (isminw && cw) data.left = dw - o.minWidth; 3033 if (ismaxw && cw) data.left = dw - o.maxWidth; 3034 if (isminh && ch) data.top = dh - o.minHeight; 3035 if (ismaxh && ch) data.top = dh - o.maxHeight; 3036 3037 // fixing jump error on top/left - bug #2330 3038 var isNotwh = !data.width && !data.height; 3039 if (isNotwh && !data.left && data.top) data.top = null; 3040 else if (isNotwh && !data.top && data.left) data.left = null; 3041 3042 return data; 3043 }, 3044 3045 _proportionallyResize: function() { 3046 3047 var o = this.options; 3048 if (!this._proportionallyResizeElements.length) return; 3049 var element = this.helper || this.element; 3050 3051 for (var i=0; i < this._proportionallyResizeElements.length; i++) { 3052 3053 var prel = this._proportionallyResizeElements[i]; 3054 3055 if (!this.borderDif) { 3056 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], 3057 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; 3058 3059 this.borderDif = $.map(b, function(v, i) { 3060 var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; 3061 return border + padding; 3062 }); 3063 } 3064 3065 prel.css({ 3066 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 3067 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 3068 }); 3069 3070 }; 3071 3072 }, 3073 3074 _renderProxy: function() { 3075 3076 var el = this.element, o = this.options; 3077 this.elementOffset = el.offset(); 3078 3079 if(this._helper) { 3080 3081 this.helper = this.helper || $('<div style="overflow:hidden;"></div>'); 3082 3083 // fix ie6 offset TODO: This seems broken 3084 var ie6offset = ($.ui.ie6 ? 1 : 0), 3085 pxyoffset = ( $.ui.ie6 ? 2 : -1 ); 3086 3087 this.helper.addClass(this._helper).css({ 3088 width: this.element.outerWidth() + pxyoffset, 3089 height: this.element.outerHeight() + pxyoffset, 3090 position: 'absolute', 3091 left: this.elementOffset.left - ie6offset +'px', 3092 top: this.elementOffset.top - ie6offset +'px', 3093 zIndex: ++o.zIndex //TODO: Don't modify option 3094 }); 3095 3096 this.helper 3097 .appendTo("body") 3098 .disableSelection(); 3099 3100 } else { 3101 this.helper = this.element; 3102 } 3103 3104 }, 3105 3106 _change: { 3107 e: function(event, dx, dy) { 3108 return { width: this.originalSize.width + dx }; 3109 }, 3110 w: function(event, dx, dy) { 3111 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 3112 return { left: sp.left + dx, width: cs.width - dx }; 3113 }, 3114 n: function(event, dx, dy) { 3115 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 3116 return { top: sp.top + dy, height: cs.height - dy }; 3117 }, 3118 s: function(event, dx, dy) { 3119 return { height: this.originalSize.height + dy }; 3120 }, 3121 se: function(event, dx, dy) { 3122 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3123 }, 3124 sw: function(event, dx, dy) { 3125 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3126 }, 3127 ne: function(event, dx, dy) { 3128 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3129 }, 3130 nw: function(event, dx, dy) { 3131 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3132 } 3133 }, 3134 3135 _propagate: function(n, event) { 3136 $.ui.plugin.call(this, n, [event, this.ui()]); 3137 (n != "resize" && this._trigger(n, event, this.ui())); 3138 }, 3139 3140 plugins: {}, 3141 3142 ui: function() { 3143 return { 3144 originalElement: this.originalElement, 3145 element: this.element, 3146 helper: this.helper, 3147 position: this.position, 3148 size: this.size, 3149 originalSize: this.originalSize, 3150 originalPosition: this.originalPosition 3151 }; 3152 } 3153 3154}); 3155 3156/* 3157 * Resizable Extensions 3158 */ 3159 3160$.ui.plugin.add("resizable", "alsoResize", { 3161 3162 start: function (event, ui) { 3163 var that = $(this).data("resizable"), o = that.options; 3164 3165 var _store = function (exp) { 3166 $(exp).each(function() { 3167 var el = $(this); 3168 el.data("resizable-alsoresize", { 3169 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3170 left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10) 3171 }); 3172 }); 3173 }; 3174 3175 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { 3176 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3177 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3178 }else{ 3179 _store(o.alsoResize); 3180 } 3181 }, 3182 3183 resize: function (event, ui) { 3184 var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition; 3185 3186 var delta = { 3187 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3188 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3189 }, 3190 3191 _alsoResize = function (exp, c) { 3192 $(exp).each(function() { 3193 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 3194 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; 3195
3196 $.each(css, function (i, prop) { 3197 var sum = (start[prop]||0) + (delta[prop]||0); 3198 if (sum && sum >= 0) 3199 style[prop] = sum || null; 3200 }); 3201 3202 el.css(style); 3203 }); 3204 }; 3205 3206 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { 3207 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3208 }else{ 3209 _alsoResize(o.alsoResize); 3210 } 3211 }, 3212 3213 stop: function (event, ui) { 3214 $(this).removeData("resizable-alsoresize"); 3215 } 3216}); 3217 3218$.ui.plugin.add("resizable", "animate", { 3219 3220 stop: function(event, ui) { 3221 var that = $(this).data("resizable"), o = that.options; 3222 3223 var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 3224 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 3225 soffsetw = ista ? 0 : that.sizeDiff.width; 3226 3227 var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 3228 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 3229 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 3230 3231 that.element.animate( 3232 $.extend(style, top && left ? { top: top, left: left } : {}), { 3233 duration: o.animateDuration, 3234 easing: o.animateEasing, 3235 step: function() { 3236 3237 var data = { 3238 width: parseInt(that.element.css('width'), 10), 3239 height: parseInt(that.element.css('height'), 10), 3240 top: parseInt(that.element.css('top'), 10), 3241 left: parseInt(that.element.css('left'), 10) 3242 }; 3243 3244 if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); 3245 3246 // propagating resize, and updating values for each animation step 3247 that._updateCache(data); 3248 that._propagate("resize", event); 3249 3250 } 3251 } 3252 ); 3253 } 3254 3255}); 3256 3257$.ui.plugin.add("resizable", "containment", { 3258 3259 start: function(event, ui) { 3260 var that = $(this).data("resizable"), o = that.options, el = that.element; 3261 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 3262 if (!ce) return; 3263 3264 that.containerElement = $(ce); 3265 3266 if (/document/.test(oc) || oc == document) { 3267 that.containerOffset = { left: 0, top: 0 }; 3268 that.containerPosition = { left: 0, top: 0 }; 3269 3270 that.parentData = { 3271 element: $(document), left: 0, top: 0, 3272 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 3273 }; 3274 } 3275 3276 // i'm a node, so compute top, left, right, bottom 3277 else { 3278 var element = $(ce), p = []; 3279 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 3280 3281 that.containerOffset = element.offset(); 3282 that.containerPosition = element.position(); 3283 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 3284 3285 var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width, 3286 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 3287 3288 that.parentData = { 3289 element: ce, left: co.left, top: co.top, width: width, height: height 3290 }; 3291 } 3292 }, 3293 3294 resize: function(event, ui) { 3295 var that = $(this).data("resizable"), o = that.options, 3296 ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position, 3297 pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement; 3298 3299 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; 3300 3301 if (cp.left < (that._helper ? co.left : 0)) { 3302 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 3303 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 3304 that.position.left = o.helper ? co.left : 0; 3305 } 3306 3307 if (cp.top < (that._helper ? co.top : 0)) { 3308 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3309 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 3310 that.position.top = that._helper ? co.top : 0; 3311 } 3312 3313 that.offset.left = that.parentData.left+that.position.left; 3314 that.offset.top = that.parentData.top+that.position.top; 3315 3316 var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ), 3317 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3318 3319 var isParent = that.containerElement.get(0) == that.element.parent().get(0), 3320 isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position')); 3321 3322 if(isParent && isOffsetRelative) woset -= that.parentData.left; 3323 3324 if (woset + that.size.width >= that.parentData.width) { 3325 that.size.width = that.parentData.width - woset; 3326 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 3327 } 3328 3329 if (hoset + that.size.height >= that.parentData.height) { 3330 that.size.height = that.parentData.height - hoset; 3331 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 3332 } 3333 }, 3334 3335 stop: function(event, ui){ 3336 var that = $(this).data("resizable"), o = that.options, cp = that.position, 3337 co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement; 3338 3339 var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height; 3340
3341 if (that._helper && !o.animate && (/relative/).test(ce.css('position'))) 3342 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3343 3344 if (that._helper && !o.animate && (/static/).test(ce.css('position'))) 3345 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3346 3347 } 3348}); 3349 3350$.ui.plugin.add("resizable", "ghost", { 3351 3352 start: function(event, ui) { 3353 3354 var that = $(this).data("resizable"), o = that.options, cs = that.size; 3355 3356 that.ghost = that.originalElement.clone(); 3357 that.ghost 3358 .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3359 .addClass('ui-resizable-ghost') 3360 .addClass(typeof o.ghost == 'string' ? o.ghost : ''); 3361 3362 that.ghost.appendTo(that.helper); 3363 3364 }, 3365 3366 resize: function(event, ui){ 3367 var that = $(this).data("resizable"), o = that.options; 3368 if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width }); 3369 }, 3370 3371 stop: function(event, ui){ 3372 var that = $(this).data("resizable"), o = that.options; 3373 if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0)); 3374 } 3375 3376}); 3377 3378$.ui.plugin.add("resizable", "grid", { 3379 3380 resize: function(event, ui) { 3381 var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey; 3382 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; 3383 var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); 3384 3385 if (/^(se|s|e)$/.test(a)) { 3386 that.size.width = os.width + ox; 3387 that.size.height = os.height + oy; 3388 } 3389 else if (/^(ne)$/.test(a)) { 3390 that.size.width = os.width + ox; 3391 that.size.height = os.height + oy; 3392 that.position.top = op.top - oy; 3393 } 3394 else if (/^(sw)$/.test(a)) { 3395 that.size.width = os.width + ox; 3396 that.size.height = os.height + oy; 3397 that.position.left = op.left - ox; 3398 } 3399 else { 3400 that.size.width = os.width + ox; 3401 that.size.height = os.height + oy; 3402 that.position.top = op.top - oy; 3403 that.position.left = op.left - ox; 3404 } 3405 } 3406 3407}); 3408 3409var num = function(v) { 3410 return parseInt(v, 10) || 0; 3411}; 3412 3413var isNumber = function(value) { 3414 return !isNaN(parseInt(value, 10)); 3415}; 3416 3417})(jQuery); 3418(function( $, undefined ) { 3419 3420$.widget("ui.selectable", $.ui.mouse, { 3421 version: "1.9.2", 3422 options: { 3423 appendTo: 'body', 3424 autoRefresh: true, 3425 distance: 0, 3426 filter: '*', 3427 tolerance: 'touch' 3428 }, 3429 _create: function() { 3430 var that = this; 3431 3432 this.element.addClass("ui-selectable"); 3433 3434 this.dragged = false; 3435 3436 // cache selectee children based on filter 3437 var selectees; 3438 this.refresh = function() { 3439 selectees = $(that.options.filter, that.element[0]); 3440 selectees.addClass("ui-selectee"); 3441 selectees.each(function() { 3442 var $this = $(this); 3443 var pos = $this.offset(); 3444 $.data(this, "selectable-item", { 3445 element: this, 3446 $element: $this, 3447 left: pos.left, 3448 top: pos.top, 3449 right: pos.left + $this.outerWidth(), 3450 bottom: pos.top + $this.outerHeight(), 3451 startselected: false, 3452 selected: $this.hasClass('ui-selected'), 3453 selecting: $this.hasClass('ui-selecting'), 3454 unselecting: $this.hasClass('ui-unselecting') 3455 }); 3456 }); 3457 }; 3458 this.refresh(); 3459 3460 this.selectees = selectees.addClass("ui-selectee"); 3461 3462 this._mouseInit(); 3463 3464 this.helper = $("<div class='ui-selectable-helper'></div>"); 3465 }, 3466 3467 _destroy: function() { 3468 this.selectees 3469 .removeClass("ui-selectee") 3470 .removeData("selectable-item"); 3471 this.element 3472 .removeClass("ui-selectable ui-selectable-disabled"); 3473 this._mouseDestroy(); 3474 }, 3475 3476 _mouseStart: function(event) { 3477 var that = this; 3478 3479 this.opos = [event.pageX, event.pageY]; 3480 3481 if (this.options.disabled) 3482 return; 3483 3484 var options = this.options; 3485 3486 this.selectees = $(options.filter, this.element[0]); 3487 3488 this._trigger("start", event); 3489 3490 $(options.appendTo).append(this.helper); 3491 // position helper (lasso) 3492 this.helper.css({ 3493 "left": event.clientX, 3494 "top": event.clientY, 3495 "width": 0, 3496 "height": 0 3497 }); 3498 3499 if (options.autoRefresh) { 3500 this.refresh(); 3501 } 3502 3503 this.selectees.filter('.ui-selected').each(function() { 3504 var selectee = $.data(this, "selectable-item"); 3505 selectee.startselected = true; 3506 if (!event.metaKey && !event.ctrlKey) { 3507 selectee.$element.removeClass('ui-selected'); 3508 selectee.selected = false;
vendor: 4,195 bytes, lines 3509-3647
3509 selectee.$element.addClass('ui-unselecting'); 3510 selectee.unselecting = true; 3511 // selectable UNSELECTING callback 3512 that._trigger("unselecting", event, { 3513 unselecting: selectee.element 3514 }); 3515 } 3516 }); 3517 3518 $(event.target).parents().andSelf().each(function() { 3519 var selectee = $.data(this, "selectable-item"); 3520 if (selectee) { 3521 var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected'); 3522 selectee.$element 3523 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3524 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3525 selectee.unselecting = !doSelect; 3526 selectee.selecting = doSelect; 3527 selectee.selected = doSelect; 3528 // selectable (UN)SELECTING callback 3529 if (doSelect) { 3530 that._trigger("selecting", event, { 3531 selecting: selectee.element 3532 }); 3533 } else { 3534 that._trigger("unselecting", event, { 3535 unselecting: selectee.element 3536 }); 3537 } 3538 return false; 3539 } 3540 }); 3541 3542 }, 3543 3544 _mouseDrag: function(event) { 3545 var that = this; 3546 this.dragged = true; 3547 3548 if (this.options.disabled) 3549 return; 3550 3551 var options = this.options; 3552 3553 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; 3554 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } 3555 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } 3556 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3557 3558 this.selectees.each(function() { 3559 var selectee = $.data(this, "selectable-item"); 3560 //prevent helper from being selected if appendTo: selectable 3561 if (!selectee || selectee.element == that.element[0]) 3562 return; 3563 var hit = false; 3564 if (options.tolerance == 'touch') { 3565 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3566 } else if (options.tolerance == 'fit') { 3567 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3568 } 3569 3570 if (hit) { 3571 // SELECT 3572 if (selectee.selected) { 3573 selectee.$element.removeClass('ui-selected'); 3574 selectee.selected = false; 3575 } 3576 if (selectee.unselecting) { 3577 selectee.$element.removeClass('ui-unselecting'); 3578 selectee.unselecting = false; 3579 } 3580 if (!selectee.selecting) { 3581 selectee.$element.addClass('ui-selecting'); 3582 selectee.selecting = true; 3583 // selectable SELECTING callback 3584 that._trigger("selecting", event, { 3585 selecting: selectee.element 3586 }); 3587 } 3588 } else { 3589 // UNSELECT 3590 if (selectee.selecting) { 3591 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3592 selectee.$element.removeClass('ui-selecting'); 3593 selectee.selecting = false; 3594 selectee.$element.addClass('ui-selected'); 3595 selectee.selected = true; 3596 } else { 3597 selectee.$element.removeClass('ui-selecting'); 3598 selectee.selecting = false; 3599 if (selectee.startselected) { 3600 selectee.$element.addClass('ui-unselecting'); 3601 selectee.unselecting = true; 3602 } 3603 // selectable UNSELECTING callback 3604 that._trigger("unselecting", event, { 3605 unselecting: selectee.element 3606 }); 3607 } 3608 } 3609 if (selectee.selected) { 3610 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3611 selectee.$element.removeClass('ui-selected'); 3612 selectee.selected = false; 3613 3614 selectee.$element.addClass('ui-unselecting'); 3615 selectee.unselecting = true; 3616 // selectable UNSELECTING callback 3617 that._trigger("unselecting", event, { 3618 unselecting: selectee.element 3619 }); 3620 } 3621 } 3622 } 3623 }); 3624 3625 return false; 3626 }, 3627 3628 _mouseStop: function(event) { 3629 var that = this; 3630 3631 this.dragged = false; 3632 3633 var options = this.options; 3634 3635 $('.ui-unselecting', this.element[0]).each(function() { 3636 var selectee = $.data(this, "selectable-item"); 3637 selectee.$element.removeClass('ui-unselecting'); 3638 selectee.unselecting = false; 3639 selectee.startselected = false; 3640 that._trigger("unselected", event, { 3641 unselected: selectee.element 3642 }); 3643 }); 3644 $('.ui-selecting', this.element[0]).each(function() { 3645 var selectee = $.data(this, "selectable-item"); 3646 selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); 3647 selectee.selecting = false;
3648 selectee.selected = true; 3649 selectee.startselected = true; 3650 that._trigger("selected", event, { 3651 selected: selectee.element 3652 }); 3653 }); 3654 this._trigger("stop", event); 3655 3656 this.helper.remove(); 3657 3658 return false; 3659 } 3660 3661}); 3662 3663})(jQuery); 3664(function( $, undefined ) { 3665 3666$.widget("ui.sortable", $.ui.mouse, { 3667 version: "1.9.2", 3668 widgetEventPrefix: "sort", 3669 ready: false, 3670 options: { 3671 appendTo: "parent", 3672 axis: false, 3673 connectWith: false, 3674 containment: false, 3675 cursor: 'auto', 3676 cursorAt: false, 3677 dropOnEmpty: true, 3678 forcePlaceholderSize: false, 3679 forceHelperSize: false, 3680 grid: false, 3681 handle: false, 3682 helper: "original", 3683 items: '> *', 3684 opacity: false, 3685 placeholder: false, 3686 revert: false, 3687 scroll: true, 3688 scrollSensitivity: 20, 3689 scrollSpeed: 20, 3690 scope: "default", 3691 tolerance: "intersect", 3692 zIndex: 1000 3693 }, 3694 _create: function() { 3695 3696 var o = this.options; 3697 this.containerCache = {}; 3698 this.element.addClass("ui-sortable"); 3699 3700 //Get the items 3701 this.refresh(); 3702 3703 //Let's determine if the items are being displayed horizontally 3704 this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false; 3705 3706 //Let's determine the parent's offset 3707 this.offset = this.element.offset(); 3708 3709 //Initialize mouse events for interaction 3710 this._mouseInit(); 3711 3712 //We're ready to go 3713 this.ready = true 3714 3715 }, 3716 3717 _destroy: function() { 3718 this.element 3719 .removeClass("ui-sortable ui-sortable-disabled"); 3720 this._mouseDestroy(); 3721 3722 for ( var i = this.items.length - 1; i >= 0; i-- ) 3723 this.items[i].item.removeData(this.widgetName + "-item"); 3724 3725 return this; 3726 }, 3727 3728 _setOption: function(key, value){ 3729 if ( key === "disabled" ) { 3730 this.options[ key ] = value; 3731 3732 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 3733 } else { 3734 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 3735 $.Widget.prototype._setOption.apply(this, arguments); 3736 } 3737 }, 3738 3739 _mouseCapture: function(event, overrideHandle) { 3740 var that = this; 3741 3742 if (this.reverting) { 3743 return false; 3744 } 3745 3746 if(this.options.disabled || this.options.type == 'static') return false; 3747 3748 //We have to refresh the items data once first 3749 this._refreshItems(event); 3750 3751 //Find out if the clicked node (or one of its parents) is a actual item in this.items 3752 var currentItem = null, nodes = $(event.target).parents().each(function() { 3753 if($.data(this, that.widgetName + '-item') == that) { 3754 currentItem = $(this); 3755 return false; 3756 } 3757 }); 3758 if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target); 3759 3760 if(!currentItem) return false; 3761 if(this.options.handle && !overrideHandle) { 3762 var validHandle = false; 3763 3764 $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); 3765 if(!validHandle) return false; 3766 } 3767 3768 this.currentItem = currentItem; 3769 this._removeCurrentsFromItems(); 3770 return true; 3771 3772 }, 3773 3774 _mouseStart: function(event, overrideHandle, noActivation) { 3775 3776 var o = this.options; 3777 this.currentContainer = this; 3778 3779 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 3780 this.refreshPositions(); 3781 3782 //Create and append the visible helper 3783 this.helper = this._createHelper(event); 3784 3785 //Cache the helper size 3786 this._cacheHelperProportions(); 3787 3788 /* 3789 * - Position generation - 3790 * This block generates everything position related - it's the core of draggables. 3791 */ 3792 3793 //Cache the margins of the original element 3794 this._cacheMargins(); 3795 3796 //Get the next scrolling parent 3797 this.scrollParent = this.helper.scrollParent(); 3798 3799 //The element's absolute position on the page minus margins 3800 this.offset = this.currentItem.offset(); 3801 this.offset = { 3802 top: this.offset.top - this.margins.top, 3803 left: this.offset.left - this.margins.left 3804 }; 3805 3806 $.extend(this.offset, { 3807 click: { //Where the click happened, relative to the element 3808 left: event.pageX - this.offset.left, 3809 top: event.pageY - this.offset.top 3810 }, 3811 parent: this._getParentOffset(), 3812 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3813 }); 3814 3815 // Only after we got the offset, we can change the helper's position to absolute 3816 // TODO: Still need to figure out a way to make relative sorting possible 3817 this.helper.css("position", "absolute"); 3818 this.cssPosition = this.helper.css("position"); 3819 3820 //Generate the original position 3821 this.originalPosition = this._generatePosition(event); 3822 this.originalPageX = event.pageX; 3823 this.originalPageY = event.pageY; 3824 3825 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 3826 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 3827 3828 //Cache the former DOM position 3829 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 3830 3831 //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 3832 if(this.helper[0] != this.currentItem[0]) { 3833 this.currentItem.hide(); 3834 } 3835 3836 //Create the placeholder 3837 this._createPlaceholder(); 3838 3839 //Set a containment if given in the options 3840 if(o.containment) 3841 this._setContainment(); 3842 3843 if(o.cursor) { // cursor option 3844 if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor"); 3845 $('body').css("cursor", o.cursor); 3846 } 3847 3848 if(o.opacity) { // opacity option 3849 if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity"); 3850 this.helper.css("opacity", o.opacity); 3851 } 3852 3853 if(o.zIndex) { // zIndex option 3854 if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex"); 3855 this.helper.css("zIndex", o.zIndex); 3856 } 3857 3858 //Prepare scrolling 3859 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') 3860 this.overflowOffset = this.scrollParent.offset(); 3861 3862 //Call callbacks 3863 this._trigger("start", event, this._uiHash()); 3864 3865 //Recache the helper size 3866 if(!this._preserveHelperProportions) 3867 this._cacheHelperProportions(); 3868 3869 3870 //Post 'activate' events to possible containers 3871 if(!noActivation) { 3872 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); } 3873 } 3874 3875 //Prepare possible droppables 3876 if($.ui.ddmanager) 3877 $.ui.ddmanager.current = this; 3878 3879 if ($.ui.ddmanager && !o.dropBehaviour) 3880 $.ui.ddmanager.prepareOffsets(this, event); 3881 3882 this.dragging = true; 3883 3884 this.helper.addClass("ui-sortable-helper"); 3885 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3886 return true; 3887 3888 }, 3889 3890 _mouseDrag: function(event) { 3891 3892 //Compute the helpers position 3893 this.position = this._generatePosition(event); 3894 this.positionAbs = this._convertPositionTo("absolute"); 3895 3896 if (!this.lastPositionAbs) { 3897 this.lastPositionAbs = this.positionAbs; 3898 } 3899 3900 //Do scrolling 3901 if(this.options.scroll) { 3902 var o = this.options, scrolled = false;
3903 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { 3904 3905 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 3906 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 3907 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) 3908 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 3909 3910 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 3911 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 3912 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) 3913 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 3914 3915 } else { 3916 3917 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 3918 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3919 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 3920 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3921 3922 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 3923 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3924 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 3925 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3926 3927 } 3928 3929 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 3930 $.ui.ddmanager.prepareOffsets(this, event); 3931 } 3932 3933 //Regenerate the absolute position used for position checks 3934 this.positionAbs = this._convertPositionTo("absolute"); 3935 3936 //Set the helper position 3937 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 3938 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 3939 3940 //Rearrange 3941 for (var i = this.items.length - 1; i >= 0; i--) { 3942 3943 //Cache variables and intersection, continue if no intersection 3944 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); 3945 if (!intersection) continue; 3946 3947 // Only put the placeholder inside the current Container, skip all 3948 // items form other containers. This works because when moving 3949 // an item from one container to another the 3950 // currentContainer is switched before the placeholder is moved. 3951 // 3952 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 3953 // beetween the outer and inner container. 3954 if (item.instance !== this.currentContainer) continue; 3955 3956 if (itemElement != this.currentItem[0] //cannot intersect with itself 3957 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before 3958 && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked 3959 && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true) 3960 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container 3961 ) { 3962 3963 this.direction = intersection == 1 ? "down" : "up"; 3964 3965 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { 3966 this._rearrange(event, item); 3967 } else { 3968 break; 3969 } 3970 3971 this._trigger("change", event, this._uiHash()); 3972 break; 3973 } 3974 } 3975 3976 //Post events to containers 3977 this._contactContainers(event); 3978 3979 //Interconnect with droppables 3980 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 3981 3982 //Call callbacks 3983 this._trigger('sort', event, this._uiHash()); 3984 3985 this.lastPositionAbs = this.positionAbs; 3986 return false; 3987 3988 }, 3989 3990 _mouseStop: function(event, noPropagation) { 3991 3992 if(!event) return; 3993 3994 //If we are using droppables, inform the manager about the drop 3995 if ($.ui.ddmanager && !this.options.dropBehaviour) 3996 $.ui.ddmanager.drop(this, event); 3997 3998 if(this.options.revert) { 3999 var that = this; 4000 var cur = this.placeholder.offset(); 4001 4002 this.reverting = true; 4003 4004 $(this.helper).animate({ 4005 left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), 4006 top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) 4007 }, parseInt(this.options.revert, 10) || 500, function() { 4008 that._clear(event); 4009 }); 4010 } else { 4011 this._clear(event, noPropagation); 4012 } 4013 4014 return false;
4015 4016 }, 4017 4018 cancel: function() { 4019 4020 if(this.dragging) { 4021 4022 this._mouseUp({ target: null }); 4023 4024 if(this.options.helper == "original") 4025 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4026 else 4027 this.currentItem.show(); 4028 4029 //Post deactivating events to containers 4030 for (var i = this.containers.length - 1; i >= 0; i--){ 4031 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 4032 if(this.containers[i].containerCache.over) { 4033 this.containers[i]._trigger("out", null, this._uiHash(this)); 4034 this.containers[i].containerCache.over = 0; 4035 } 4036 } 4037 4038 } 4039 4040 if (this.placeholder) { 4041 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4042 if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4043 if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); 4044 4045 $.extend(this, { 4046 helper: null, 4047 dragging: false, 4048 reverting: false, 4049 _noFinalSort: null 4050 }); 4051 4052 if(this.domPosition.prev) { 4053 $(this.domPosition.prev).after(this.currentItem); 4054 } else { 4055 $(this.domPosition.parent).prepend(this.currentItem); 4056 } 4057 } 4058 4059 return this; 4060 4061 }, 4062 4063 serialize: function(o) { 4064 4065 var items = this._getItemsAsjQuery(o && o.connected); 4066 var str = []; o = o || {}; 4067 4068 $(items).each(function() { 4069 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); 4070 if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); 4071 }); 4072 4073 if(!str.length && o.key) { 4074 str.push(o.key + '='); 4075 } 4076 4077 return str.join('&'); 4078 4079 }, 4080 4081 toArray: function(o) { 4082 4083 var items = this._getItemsAsjQuery(o && o.connected); 4084 var ret = []; o = o || {}; 4085 4086 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); 4087 return ret; 4088 4089 }, 4090 4091 /* Be careful with the following core functions */ 4092 _intersectsWith: function(item) { 4093 4094 var x1 = this.positionAbs.left, 4095 x2 = x1 + this.helperProportions.width, 4096 y1 = this.positionAbs.top, 4097 y2 = y1 + this.helperProportions.height; 4098 4099 var l = item.left, 4100 r = l + item.width, 4101 t = item.top, 4102 b = t + item.height; 4103 4104 var dyClick = this.offset.click.top, 4105 dxClick = this.offset.click.left; 4106 4107 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 4108 4109 if( this.options.tolerance == "pointer" 4110 || this.options.forcePointerForContainers 4111 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) 4112 ) { 4113 return isOverElement; 4114 } else { 4115 4116 return (l < x1 + (this.helperProportions.width / 2) // Right Half 4117 && x2 - (this.helperProportions.width / 2) < r // Left Half 4118 && t < y1 + (this.helperProportions.height / 2) // Bottom Half 4119 && y2 - (this.helperProportions.height / 2) < b ); // Top Half 4120 4121 } 4122 }, 4123 4124 _intersectsWithPointer: function(item) { 4125 4126 var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4127 isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4128 isOverElement = isOverElementHeight && isOverElementWidth, 4129 verticalDirection = this._getDragVerticalDirection(), 4130 horizontalDirection = this._getDragHorizontalDirection(); 4131 4132 if (!isOverElement) 4133 return false; 4134 4135 return this.floating ? 4136 ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) 4137 : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); 4138 4139 }, 4140 4141 _intersectsWithSides: function(item) { 4142 4143 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4144 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4145 verticalDirection = this._getDragVerticalDirection(), 4146 horizontalDirection = this._getDragHorizontalDirection(); 4147 4148 if (this.floating && horizontalDirection) { 4149 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); 4150 } else { 4151 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); 4152 } 4153 4154 }, 4155 4156 _getDragVerticalDirection: function() { 4157 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4158 return delta != 0 && (delta > 0 ? "down" : "up"); 4159 }, 4160 4161 _getDragHorizontalDirection: function() { 4162 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4163 return delta != 0 && (delta > 0 ? "right" : "left"); 4164 }, 4165 4166 refresh: function(event) { 4167 this._refreshItems(event); 4168 this.refreshPositions(); 4169 return this; 4170 }, 4171 4172 _connectWith: function() { 4173 var options = this.options; 4174 return options.connectWith.constructor == String
4175 ? [options.connectWith] 4176 : options.connectWith; 4177 }, 4178 4179 _getItemsAsjQuery: function(connected) { 4180 4181 var items = []; 4182 var queries = []; 4183 var connectWith = this._connectWith(); 4184 4185 if(connectWith && connected) { 4186 for (var i = connectWith.length - 1; i >= 0; i--){ 4187 var cur = $(connectWith[i]); 4188 for (var j = cur.length - 1; j >= 0; j--){ 4189 var inst = $.data(cur[j], this.widgetName); 4190 if(inst && inst != this && !inst.options.disabled) { 4191 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]); 4192 } 4193 }; 4194 }; 4195 } 4196 4197 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]); 4198 4199 for (var i = queries.length - 1; i >= 0; i--){ 4200 queries[i][0].each(function() { 4201 items.push(this); 4202 }); 4203 }; 4204 4205 return $(items); 4206 4207 }, 4208 4209 _removeCurrentsFromItems: function() { 4210 4211 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4212 4213 this.items = $.grep(this.items, function (item) { 4214 for (var j=0; j < list.length; j++) { 4215 if(list[j] == item.item[0]) 4216 return false; 4217 }; 4218 return true; 4219 }); 4220 4221 }, 4222 4223 _refreshItems: function(event) { 4224 4225 this.items = []; 4226 this.containers = [this]; 4227 var items = this.items; 4228 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; 4229 var connectWith = this._connectWith(); 4230 4231 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4232 for (var i = connectWith.length - 1; i >= 0; i--){ 4233 var cur = $(connectWith[i]); 4234 for (var j = cur.length - 1; j >= 0; j--){ 4235 var inst = $.data(cur[j], this.widgetName); 4236 if(inst && inst != this && !inst.options.disabled) { 4237 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4238 this.containers.push(inst); 4239 } 4240 }; 4241 }; 4242 } 4243 4244 for (var i = queries.length - 1; i >= 0; i--) { 4245 var targetData = queries[i][1]; 4246 var _queries = queries[i][0]; 4247 4248 for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4249 var item = $(_queries[j]); 4250 4251 item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager) 4252 4253 items.push({ 4254 item: item, 4255 instance: targetData, 4256 width: 0, height: 0, 4257 left: 0, top: 0 4258 }); 4259 }; 4260 }; 4261 4262 }, 4263 4264 refreshPositions: function(fast) { 4265 4266 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4267 if(this.offsetParent && this.helper) { 4268 this.offset.parent = this._getParentOffset(); 4269 } 4270 4271 for (var i = this.items.length - 1; i >= 0; i--){ 4272 var item = this.items[i]; 4273 4274 //We ignore calculating positions of all connected containers when we're not over them 4275 if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) 4276 continue; 4277 4278 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4279 4280 if (!fast) { 4281 item.width = t.outerWidth(); 4282 item.height = t.outerHeight(); 4283 } 4284 4285 var p = t.offset(); 4286 item.left = p.left; 4287 item.top = p.top; 4288 }; 4289 4290 if(this.options.custom && this.options.custom.refreshContainers
4290) { 4291 this.options.custom.refreshContainers.call(this); 4292 } else { 4293 for (var i = this.containers.length - 1; i >= 0; i--){ 4294 var p = this.containers[i].element.offset(); 4295 this.containers[i].containerCache.left = p.left; 4296 this.containers[i].containerCache.top = p.top; 4297 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 4298 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4299 }; 4300 } 4301 4302 return this; 4303 }, 4304 4305 _createPlaceholder: function(that) { 4306 that = that || this; 4307 var o = that.options; 4308 4309 if(!o.placeholder || o.placeholder.constructor == String) { 4310 var className = o.placeholder; 4311 o.placeholder = { 4312 element: function() { 4313 4314 var el = $(document.createElement(that.currentItem[0].nodeName)) 4315 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4316 .removeClass("ui-sortable-helper")[0]; 4317 4318 if(!className) 4319 el.style.visibility = "hidden"; 4320 4321 return el; 4322 }, 4323 update: function(container, p) { 4324 4325 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4326 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4327 if(className && !o.forcePlaceholderSize) return; 4328 4329 //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
4330 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); }; 4331 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); }; 4332 } 4333 }; 4334 } 4335 4336 //Create the placeholder 4337 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4338 4339 //Append it after the actual current item 4340 that.currentItem.after(that.placeholder); 4341 4342 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4343 o.placeholder.update(that, that.placeholder); 4344 4345 }, 4346 4347 _contactContainers: function(event) { 4348 4349 // get innermost container that intersects with item 4350 var innermostContainer = null, innermostIndex = null; 4351 4352 4353 for (var i = this.containers.length - 1; i >= 0; i--){ 4354 4355 // never consider a container that's located within the item itself 4356 if($.contains(this.currentItem[0], this.containers[i].element[0])) 4357 continue; 4358 4359 if(this._intersectsWith(this.containers[i].containerCache)) { 4360 4361 // if we've already found a container and it's more "inner" than this, then continue 4362 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) 4363 continue; 4364 4365 innermostContainer = this.containers[i]; 4366 innermostIndex = i; 4367 4368 } else { 4369 // container doesn't intersect. trigger "out" event if necessary 4370 if(this.containers[i].containerCache.over) { 4371 this.containers[i]._trigger("out", event, this._uiHash(this)); 4372 this.containers[i].containerCache.over = 0; 4373 } 4374 } 4375 4376 } 4377 4378 // if no intersecting containers found, return 4379 if(!innermostContainer) return; 4380 4381 // move the item into the container if it's not there already 4382 if(this.containers.length === 1) { 4383 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4384 this.containers[innermostIndex].containerCache.over = 1; 4385 } else { 4386 4387 //When entering a new container, we will find the item with the least distance and append our item near it 4388 var dist = 10000; var itemWithLeastDistance = null; 4389 var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top'; 4390 var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height'; 4391 var base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 4392 for (var j = this.items.length - 1; j >= 0; j--) { 4393 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 4394 if(this.items[j].item[0] == this.currentItem[0]) continue; 4395 var cur = this.items[j].item.offset()[posProperty]; 4396 var nearBottom = false; 4397 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 4398 nearBottom = true; 4399 cur += this.items[j][sizeProperty]; 4400 } 4401 4402 if(Math.abs(cur - base) < dist) { 4403 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 4404 this.direction = nearBottom ? "up": "down"; 4405 } 4406 } 4407 4408 if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 4409 return; 4410 4411 this.currentContainer = this.containers[innermostIndex]; 4412 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 4413 this._trigger("change", event, this._uiHash()); 4414 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 4415 4416 //Update the placeholder 4417 this.options.placeholder.update(this.currentContainer, this.placeholder); 4418 4419 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4420 this.containers[innermostIndex].containerCache.over = 1; 4421 } 4422 4423 4424 }, 4425 4426 _createHelper: function(event) { 4427 4428 var o = this.options; 4429 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); 4430 4431 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already 4432 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 4433 4434 if(helper[0] == this.currentItem[0]) 4435 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
4435: this.currentItem.css("left") }; 4436 4437 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); 4438 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); 4439 4440 return helper; 4441 4442 }, 4443 4444 _adjustOffsetFromHelper: function(obj) { 4445 if (typeof obj == 'string') { 4446 obj = obj.split(' '); 4447 } 4448 if ($.isArray(obj)) { 4449 obj = {left: +obj[0], top: +obj[1] || 0}; 4450 } 4451 if ('left' in obj) { 4452 this.offset.click.left = obj.left + this.margins.left; 4453 } 4454 if ('right' in obj) { 4455 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4456 } 4457 if ('top' in obj) { 4458 this.offset.click.top = obj.top + this.margins.top; 4459 } 4460 if ('bottom' in obj) { 4461 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4462 } 4463 }, 4464 4465 _getParentOffset: function() { 4466 4467 4468 //Get the offsetParent and cache its position 4469 this.offsetParent = this.helper.offsetParent(); 4470 var po = this.offsetParent.offset(); 4471 4472 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4473 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4474 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4475 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4476 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4477 po.left += this.scrollParent.scrollLeft(); 4478 po.top += this.scrollParent.scrollTop(); 4479 } 4480 4481 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 4482 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 4483 po = { top: 0, left: 0 }; 4484 4485 return { 4486 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4487 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4488 }; 4489 4490 }, 4491 4492 _getRelativeOffset: function() { 4493 4494 if(this.cssPosition == "relative") { 4495 var p = this.currentItem.position(); 4496 return { 4497 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4498 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4499 }; 4500 } else { 4501 return { top: 0, left: 0 }; 4502 } 4503 4504 }, 4505 4506 _cacheMargins: function() { 4507 this.margins = { 4508 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 4509 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 4510 }; 4511 }, 4512 4513 _cacheHelperProportions: function() { 4514 this.helperProportions = { 4515 width: this.helper.outerWidth(), 4516 height: this.helper.outerHeight() 4517 }; 4518 }, 4519 4520 _setContainment: function() { 4521 4522 var o = this.options; 4523 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 4524 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 4525 0 - this.offset.relative.left - this.offset.parent.left, 4526 0 - this.offset.relative.top - this.offset.parent.top, 4527 $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 4528 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4529 ]; 4530 4531 if(!(/^(document|window|parent)$/).test(o.containment)) { 4532 var ce = $(o.containment)[0]; 4533 var co = $(o.containment).offset(); 4534 var over = ($(ce).css("overflow") != 'hidden'); 4535 4536 this.containment = [ 4537 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 4538 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 4539 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, 4540 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
454010) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 4541 ]; 4542 } 4543 4544 }, 4545 4546 _convertPositionTo: function(d, pos) { 4547 4548 if(!pos) pos = this.position; 4549 var mod = d == "absolute" ? 1 : -1; 4550 var o = this.options, 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); 4551 4552 return { 4553 top: ( 4554 pos.top // The absolute mouse position 4555 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4556 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 4557 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4558 ), 4559 left: ( 4560 pos.left // The absolute mouse position 4561 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4562 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 4563 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4564 ) 4565 }; 4566 4567 }, 4568 4569 _generatePosition: function(event) { 4570 4571 var o = this.options, 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); 4572 4573 // This is another very weird special case that only happens for relative elements: 4574 // 1. If the css position is relative 4575 // 2. and the scroll parent is the document or similar to the offset parent 4576 // we have to refresh the relative offset during the scroll so there are no jumps 4577 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { 4578 this.offset.relative = this._getRelativeOffset(); 4579 } 4580 4581 var pageX = event.pageX; 4582 var pageY = event.pageY; 4583 4584 /* 4585 * - Position constraining - 4586 * Constrain the position to a mix of grid, containment. 4587 */ 4588 4589 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 4590 4591 if(this.containment) { 4592 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; 4593 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; 4594 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; 4595 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; 4596 } 4597 4598 if(o.grid) { 4599 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 4600 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; 4601 4602 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 4603 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; 4604 } 4605 4606 } 4607 4608 return { 4609 top: ( 4610 pageY // The absolute mouse position 4611 - this.offset.click.top // Click offset (relative to the element) 4612 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 4613 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 4614 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 4615 ), 4616 left: ( 4617 pageX // The absolute mouse position 4618 - this.offset.click.left // Click offset (relative to the element) 4619 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 4620 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 4621 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 4622 ) 4623 }; 4624 4625 }, 4626 4627 _rearrange: function(event, i, a, hardRefresh) { 4628 4629 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)); 4630 4631 //Various things done here to improve the performance: 4632 // 1. we create a setTimeout, that calls refreshPositions 4633 // 2. on the instance, we have a counter variable, that get's higher after every append 4634 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 4635 // 4. this lets only the last addition to the timeout stack through 4636 this.counter = this.counter ? ++this.counter : 1; 4637 var counter = this.counter; 4638 4639 this._delay(function() {
4640 if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 4641 }); 4642 4643 }, 4644 4645 _clear: function(event, noPropagation) { 4646 4647 this.reverting = false; 4648 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 4649 // everything else normalized again 4650 var delayedTriggers = []; 4651 4652 // We first have to update the dom position of the actual currentItem 4653 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 4654 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); 4655 this._noFinalSort = null; 4656 4657 if(this.helper[0] == this.currentItem[0]) { 4658 for(var i in this._storedCSS) { 4659 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; 4660 } 4661 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4662 } else { 4663 this.currentItem.show(); 4664 } 4665 4666 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 4667 if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 4668 4669 // Check if the items Container has Changed and trigger appropriate 4670 // events. 4671 if (this !== this.currentContainer) { 4672 if(!noPropagation) { 4673 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 4674 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4675 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4676 } 4677 } 4678 4679 4680 //Post events to containers 4681 for (var i = this.containers.length - 1; i >= 0; i--){ 4682 if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4683 if(this.containers[i].containerCache.over) { 4684 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4685 this.containers[i].containerCache.over = 0; 4686 } 4687 } 4688 4689 //Do what was originally in plugins 4690 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor 4691 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity 4692 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index 4693 4694 this.dragging = false; 4695 if(this.cancelHelperRemoval) { 4696 if(!noPropagation) { 4697 this._trigger("beforeStop", event, this._uiHash()); 4698 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 4699 this._trigger("stop", event, this._uiHash()); 4700 } 4701 4702 this.fromOutside = false;
4703 return false; 4704 } 4705 4706 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash()); 4707 4708 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4709 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4710 4711 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; 4712 4713 if(!noPropagation) { 4714 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 4715 this._trigger("stop", event, this._uiHash()); 4716 } 4717 4718 this.fromOutside = false; 4719 return true; 4720 4721 }, 4722 4723 _trigger: function() { 4724 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 4725 this.cancel(); 4726 } 4727 }, 4728 4729 _uiHash: function(_inst) { 4730 var inst = _inst || this; 4731 return { 4732 helper: inst.helper, 4733 placeholder: inst.placeholder || $([]), 4734 position: inst.position, 4735 originalPosition: inst.originalPosition, 4736 offset: inst.positionAbs, 4737 item: inst.currentItem, 4738 sender: _inst ? _inst.element : null 4739 }; 4740 } 4741 4742}); 4743 4744})(jQuery); 4745(function( $, undefined ) { 4746 4747$.extend($.ui, { datepicker: { version: "1.9.2" } }); 4748 4749var PROP_NAME = 'datepicker'; 4750var dpuuid = new Date().getTime(); 4751var instActive; 4752 4753/* Date picker manager. 4754 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 4755 Settings for (groups of) date pickers are maintained in an instance object, 4756 allowing multiple different settings on the same page. */ 4757 4758function Datepicker() { 4759 this.debug = false; // Change this to true to start debugging 4760 this._curInst = null; // The current instance in use 4761 this._keyEvent = false; // If the last event was a key event 4762 this._disabledInputs = []; // List of date picker inputs that have been disabled 4763 this._datepickerShowing = false; // True if the popup picker is showing , false if not 4764 this._inDialog = false; // True if showing within a "dialog", false if not 4765 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division 4766 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class 4767 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class 4768 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class 4769 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class 4770 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class 4771 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class 4772 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class 4773 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class 4774 this.regional = []; // Available regional settings, indexed by language code 4775 this.regional[''] = { // Default regional settings 4776 closeText: 'Done', // Display text for close link 4777 prevText: 'Prev', // Display text for previous month link 4778 nextText: 'Next', // Display text for next month link 4779 currentText: 'Today', // Display text for current month link 4780 monthNames: ['January','February','March','April','May','June', 4781 'July','August','September','October','November','December'], // Names of months for drop-down and formatting 4782 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting 4783 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting 4784 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting 4785 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday 4786 weekHeader: 'Wk', // Column header for week of the year 4787 dateFormat: 'mm/dd/yy', // See format options on parseDate 4788 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 4789 isRTL: false, // True if right-to-left language, false if left-to-right 4790 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 4791 yearSuffix: '' // Additional text to append to the year in the month headers 4792 }; 4793 this._defaults = { // Global defaults for all the date picker instances 4794 showOn: 'focus', // 'focus' for popup on focus, 4795 // 'button' for trigger button, or 'both' for either
vendor: 4,836 bytes, lines 4796-4882
4796 showAnim: 'fadeIn', // Name of jQuery animation for popup 4797 showOptions: {}, // Options for enhanced animations 4798 defaultDate: null, // Used when field is blank: actual date, 4799 // +/-number for offset from today, null for today 4800 appendText: '', // Display text following the input box, e.g. showing the format 4801 buttonText: '...', // Text for trigger button 4802 buttonImage: '', // URL for trigger button image 4803 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 4804 hideIfNoPrevNext: false, // True to hide next/previous month links 4805 // if not applicable, false to just disable them 4806 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 4807 gotoCurrent: false, // True if today link goes back to current selection instead 4808 changeMonth: false, // True if month can be selected directly, false if only prev/next 4809 changeYear: false, // True if year can be selected directly, false if only prev/next 4810 yearRange: 'c-10:c+10', // Range of years to display in drop-down, 4811 // either relative to today's year (-nn:+nn), relative to currently displayed year 4812 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 4813 showOtherMonths: false, // True to show dates in other months, false to leave blank 4814 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 4815 showWeek: false, // True to show week of the year, false to not show it 4816 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 4817 // takes a Date and returns the number of the week for it 4818 shortYearCutoff: '+10', // Short year values < this are in the current century, 4819 // > this are in the previous century, 4820 // string value starting with '+' for current year + value 4821 minDate: null, // The earliest selectable date, or null for no limit 4822 maxDate: null, // The latest selectable date, or null for no limit 4823 duration: 'fast', // Duration of display/closure 4824 beforeShowDay: null, // Function that takes a date and returns an array with 4825 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', 4826 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 4827 beforeShow: null, // Function that takes an input field and 4828 // returns a set of custom settings for the date picker 4829 onSelect: null, // Define a callback function when a date is selected 4830 onChangeMonthYear: null, // Define a callback function when the month or year is changed 4831 onClose: null, // Define a callback function when the datepicker is closed 4832 numberOfMonths: 1, // Number of months to show at a time 4833 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 4834 stepMonths: 1, // Number of months to step back/forward 4835 stepBigMonths: 12, // Number of months to step back/forward for the big links 4836 altField: '', // Selector for an alternate field to store selected dates into 4837 altFormat: '', // The date format to use for the alternate field 4838 constrainInput: true, // The input is constrained by the current date format 4839 showButtonPanel: false, // True to show button panel, false to not show it 4840 autoSize: false, // True to size the input for the date format, false to leave as is 4841 disabled: false // The initial disabled state 4842 }; 4843 $.extend(this._defaults, this.regional['']); 4844 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')); 4845} 4846 4847$.extend(Datepicker.prototype, { 4848 /* Class name added to elements to indicate already configured with a date picker. */ 4849 markerClassName: 'hasDatepicker', 4850 4851 //Keep track of the maximum number of rows displayed (see #7043) 4852 maxRows: 4, 4853 4854 /* Debug logging (if enabled). */ 4855 log: function () { 4856 if (this.debug) 4857 console.log.apply('', arguments); 4858 }, 4859 4860 // TODO rename to "widget" when switching to widget factory 4861 _widgetDatepicker: function() { 4862 return this.dpDiv; 4863 }, 4864 4865 /* Override the default settings for all instances of the date picker. 4866 @param settings object - the new settings to use as defaults (anonymous object) 4867 @return the manager object */ 4868 setDefaults: function(settings) { 4869 extendRemove(this._defaults, settings || {}); 4870 return this; 4871 }, 4872 4873 /* Attach the date picker to a jQuery selection. 4874 @param target element - the target input field or division or span 4875 @param settings object - the new settings to use for this date picker instance (anonymous) */ 4876 _attachDatepicker: function(target, settings) { 4877 // check for settings on the control itself - in namespace 'date:' 4878 var inlineSettings = null; 4879 for (var attrName in this._defaults) { 4880 var attrValue = target.getAttribute('date:' + attrName); 4881 if (attrValue) { 4882 inlineSettings = inlineSettings || {};
4883 try { 4884 inlineSettings[attrName] = eval(attrValue); 4885 } catch (err) { 4886 inlineSettings[attrName] = attrValue; 4887 } 4888 } 4889 } 4890 var nodeName = target.nodeName.toLowerCase(); 4891 var inline = (nodeName == 'div' || nodeName == 'span'); 4892 if (!target.id) { 4893 this.uuid += 1; 4894 target.id = 'dp' + this.uuid; 4895 } 4896 var inst = this._newInst($(target), inline); 4897 inst.settings = $.extend({}, settings || {}, inlineSettings || {}); 4898 if (nodeName == 'input') { 4899 this._connectDatepicker(target, inst); 4900 } else if (inline) { 4901 this._inlineDatepicker(target, inst); 4902 } 4903 }, 4904 4905 /* Create a new instance object. */ 4906 _newInst: function(target, inline) { 4907 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars 4908 return {id: id, input: target, // associated target 4909 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 4910 drawMonth: 0, drawYear: 0, // month being drawn 4911 inline: inline, // is datepicker inline or not 4912 dpDiv: (!inline ? this.dpDiv : // presentation div 4913 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))}; 4914 }, 4915 4916 /* Attach the date picker to an input field. */ 4917 _connectDatepicker: function(target, inst) { 4918 var input = $(target); 4919 inst.append = $([]); 4920 inst.trigger = $([]); 4921 if (input.hasClass(this.markerClassName)) 4922 return; 4923 this._attachments(input, inst); 4924 input.addClass(this.markerClassName).keydown(this._doKeyDown). 4925 keypress(this._doKeyPress).keyup(this._doKeyUp). 4926 bind("setData.datepicker", function(event, key, value) { 4927 inst.settings[key] = value; 4928 }).bind("getData.datepicker", function(event, key) { 4929 return this._get(inst, key); 4930 }); 4931 this._autoSize(inst); 4932 $.data(target, PROP_NAME, inst); 4933 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 4934 if( inst.settings.disabled ) { 4935 this._disableDatepicker( target ); 4936 } 4937 }, 4938 4939 /* Make attachments based on settings. */ 4940 _attachments: function(input, inst) { 4941 var appendText = this._get(inst, 'appendText'); 4942 var isRTL = this._get(inst, 'isRTL'); 4943 if (inst.append) 4944 inst.append.remove(); 4945 if (appendText) { 4946 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>'); 4947 input[isRTL ? 'before' : 'after'](inst.append); 4948 } 4949 input.unbind('focus', this._showDatepicker); 4950 if (inst.trigger) 4951 inst.trigger.remove(); 4952 var showOn = this._get(inst, 'showOn'); 4953 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field 4954 input.focus(this._showDatepicker); 4955 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked 4956 var buttonText = this._get(inst, 'buttonText'); 4957 var buttonImage = this._get(inst, 'buttonImage'); 4958 inst.trigger = $(this._get(inst, 'buttonImageOnly') ? 4959 $('<img/>').addClass(this._triggerClass). 4960 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 4961 $('<button type="button"></button>').addClass(this._triggerClass). 4962 html(buttonImage == '' ? buttonText : $('<img/>').attr( 4963 { src:buttonImage, alt:buttonText, title:buttonText }))); 4964 input[isRTL ? 'before' : 'after'](inst.trigger); 4965 inst.trigger.click(function() { 4966 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) 4967 $.datepicker._hideDatepicker(); 4968 else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) { 4969 $.datepicker._hideDatepicker(); 4970 $.datepicker._showDatepicker(input[0]); 4971 } else 4972 $.datepicker._showDatepicker(input[0]); 4973 return false; 4974 }); 4975 } 4976 }, 4977 4978 /* Apply the maximum length for the date format. */ 4979 _autoSize: function(inst) { 4980 if (this._get(inst, 'autoSize') && !inst.inline) { 4981 var date = new Date(2009, 12 - 1, 20); // Ensure double digits 4982 var dateFormat = this._get(inst, 'dateFormat'); 4983 if (dateFormat.match(/[DM]/)) { 4984 var findMax = function(names) { 4985 var max = 0; 4986 var maxI = 0; 4987 for (var i = 0; i < names.length; i++) { 4988 if (names[i].length > max) { 4989 max = names[i].length; 4990 maxI = i; 4991 } 4992 }
vendor: 4,711 bytes, lines 4993-5108
4993 return maxI; 4994 }; 4995 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 4996 'monthNames' : 'monthNamesShort')))); 4997 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 4998 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay()); 4999 } 5000 inst.input.attr('size', this._formatDate(inst, date).length); 5001 } 5002 }, 5003 5004 /* Attach an inline date picker to a div. */ 5005 _inlineDatepicker: function(target, inst) { 5006 var divSpan = $(target); 5007 if (divSpan.hasClass(this.markerClassName)) 5008 return; 5009 divSpan.addClass(this.markerClassName).append(inst.dpDiv). 5010 bind("setData.datepicker", function(event, key, value){ 5011 inst.settings[key] = value; 5012 }).bind("getData.datepicker", function(event, key){ 5013 return this._get(inst, key); 5014 }); 5015 $.data(target, PROP_NAME, inst); 5016 this._setDate(inst, this._getDefaultDate(inst), true); 5017 this._updateDatepicker(inst); 5018 this._updateAlternate(inst); 5019 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 5020 if( inst.settings.disabled ) { 5021 this._disableDatepicker( target ); 5022 } 5023 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 5024 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 5025 inst.dpDiv.css( "display", "block" ); 5026 }, 5027 5028 /* Pop-up the date picker in a "dialog" box. 5029 @param input element - ignored 5030 @param date string or Date - the initial date to display 5031 @param onSelect function - the function to call when a date is selected 5032 @param settings object - update the dialog date picker instance's settings (anonymous object) 5033 @param pos int[2] - coordinates for the dialog's position within the screen or 5034 event - with x/y coordinates or 5035 leave empty for default (screen centre) 5036 @return the manager object */ 5037 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 5038 var inst = this._dialogInst; // internal instance 5039 if (!inst) { 5040 this.uuid += 1; 5041 var id = 'dp' + this.uuid; 5042 this._dialogInput = $('<input type="text" id="' + id + 5043 '" style="position: absolute; top: -100px; width: 0px;"/>'); 5044 this._dialogInput.keydown(this._doKeyDown); 5045 $('body').append(this._dialogInput); 5046 inst = this._dialogInst = this._newInst(this._dialogInput, false); 5047 inst.settings = {}; 5048 $.data(this._dialogInput[0], PROP_NAME, inst); 5049 } 5050 extendRemove(inst.settings, settings || {}); 5051 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date); 5052 this._dialogInput.val(date); 5053 5054 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 5055 if (!this._pos) { 5056 var browserWidth = document.documentElement.clientWidth; 5057 var browserHeight = document.documentElement.clientHeight; 5058 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 5059 var scrollY = document.documentElement.scrollTop || document.body.scrollTop; 5060 this._pos = // should use actual width/height below 5061 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 5062 } 5063 5064 // move input on screen for focus, but hidden behind dialog 5065 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px'); 5066 inst.settings.onSelect = onSelect; 5067 this._inDialog = true; 5068 this.dpDiv.addClass(this._dialogClass); 5069 this._showDatepicker(this._dialogInput[0]); 5070 if ($.blockUI) 5071 $.blockUI(this.dpDiv); 5072 $.data(this._dialogInput[0], PROP_NAME, inst); 5073 return this; 5074 }, 5075 5076 /* Detach a datepicker from its control. 5077 @param target element - the target input field or division or span */ 5078 _destroyDatepicker: function(target) { 5079 var $target = $(target); 5080 var inst = $.data(target, PROP_NAME); 5081 if (!$target.hasClass(this.markerClassName)) { 5082 return; 5083 } 5084 var nodeName = target.nodeName.toLowerCase(); 5085 $.removeData(target, PROP_NAME); 5086 if (nodeName == 'input') { 5087 inst.append.remove(); 5088 inst.trigger.remove(); 5089 $target.removeClass(this.markerClassName). 5090 unbind('focus', this._showDatepicker). 5091 unbind('keydown', this._doKeyDown). 5092 unbind('keypress', this._doKeyPress). 5093 unbind('keyup', this._doKeyUp); 5094 } else if (nodeName == 'div' || nodeName == 'span') 5095 $target.removeClass(this.markerClassName).empty(); 5096 }, 5097 5098 /* Enable the date picker to a jQuery selection. 5099 @param target element - the target input field or division or span */ 5100 _enableDatepicker: function(target) { 5101 var $target = $(target); 5102 var inst = $.data(target, PROP_NAME); 5103 if (!$target.hasClass(this.markerClassName)) { 5104 return; 5105 } 5106 var nodeName = target.nodeName.toLowerCase(); 5107 if (nodeName == 'input') { 5108 target.disabled = false;
5109 inst.trigger.filter('button'). 5110 each(function() { this.disabled = false; }).end(). 5111 filter('img').css({opacity: '1.0', cursor: ''}); 5112 } 5113 else if (nodeName == 'div' || nodeName == 'span') { 5114 var inline = $target.children('.' + this._inlineClass); 5115 inline.children().removeClass('ui-state-disabled'); 5116 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 5117 prop("disabled", false); 5118 } 5119 this._disabledInputs = $.map(this._disabledInputs, 5120 function(value) { return (value == target ? null : value); }); // delete entry 5121 }, 5122 5123 /* Disable the date picker to a jQuery selection. 5124 @param target element - the target input field or division or span */ 5125 _disableDatepicker: function(target) { 5126 var $target = $(target); 5127 var inst = $.data(target, PROP_NAME); 5128 if (!$target.hasClass(this.markerClassName)) { 5129 return; 5130 } 5131 var nodeName = target.nodeName.toLowerCase(); 5132 if (nodeName == 'input') { 5133 target.disabled = true; 5134 inst.trigger.filter('button'). 5135 each(function() { this.disabled = true; }).end(). 5136 filter('img').css({opacity: '0.5', cursor: 'default'}); 5137 } 5138 else if (nodeName == 'div' || nodeName == 'span') { 5139 var inline = $target.children('.' + this._inlineClass); 5140 inline.children().addClass('ui-state-disabled'); 5141 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 5142 prop("disabled", true); 5143 } 5144 this._disabledInputs = $.map(this._disabledInputs, 5145 function(value) { return (value == target ? null : value); }); // delete entry 5146 this._disabledInputs[this._disabledInputs.length] = target; 5147 }, 5148 5149 /* Is the first field in a jQuery collection disabled as a datepicker? 5150 @param target element - the target input field or division or span 5151 @return boolean - true if disabled, false if enabled */ 5152 _isDisabledDatepicker: function(target) { 5153 if (!target) { 5154 return false; 5155 } 5156 for (var i = 0; i < this._disabledInputs.length; i++) { 5157 if (this._disabledInputs[i] == target) 5158 return true; 5159 } 5160 return false; 5161 }, 5162 5163 /* Retrieve the instance data for the target control. 5164 @param target element - the target input field or division or span 5165 @return object - the associated instance data 5166 @throws error if a jQuery problem getting data */ 5167 _getInst: function(target) { 5168 try { 5169 return $.data(target, PROP_NAME); 5170 } 5171 catch (err) { 5172 throw 'Missing instance data for this datepicker'; 5173 } 5174 }, 5175 5176 /* Update or retrieve the settings for a date picker attached to an input field or division. 5177 @param target element - the target input field or division or span 5178 @param name object - the new settings to update or 5179 string - the name of the setting to change or retrieve, 5180 when retrieving also 'all' for all instance settings or 5181 'defaults' for all global defaults 5182 @param value any - the new value for the setting 5183 (omit if above is an object or to retrieve a value) */ 5184 _optionDatepicker: function(target, name, value) { 5185 var inst = this._getInst(target); 5186 if (arguments.length == 2 && typeof name == 'string') { 5187 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) : 5188 (inst ? (name == 'all' ? $.extend({}, inst.settings) : 5189 this._get(inst, name)) : null)); 5190 } 5191 var settings = name || {}; 5192 if (typeof name == 'string') { 5193 settings = {}; 5194 settings[name] = value; 5195 } 5196 if (inst) { 5197 if (this._curInst == inst) { 5198 this._hideDatepicker(); 5199 } 5200 var date = this._getDateDatepicker(target, true); 5201 var minDate = this._getMinMaxDate(inst, 'min'); 5202 var maxDate = this._getMinMaxDate(inst, 'max'); 5203 extendRemove(inst.settings, settings); 5204 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 5205 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined) 5206 inst.settings.minDate = this._formatDate(inst, minDate); 5207 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined) 5208 inst.settings.maxDate = this._formatDate(inst, maxDate); 5209 this._attachments($(target), inst); 5210 this._autoSize(inst); 5211 this._setDate(inst, date); 5212 this._updateAlternate(inst); 5213 this._updateDatepicker(inst); 5214 } 5215 }, 5216 5217 // change method deprecated 5218 _changeDatepicker: function(target, name, value) { 5219 this._optionDatepicker(target, name, value); 5220 }, 5221 5222 /* Redraw the date picker attached to an input field or division. 5223 @param target element - the target input field or division or span */ 5224 _refreshDatepicker: function(target) { 5225 var inst = this._getInst(target); 5226 if (inst) { 5227 this._updateDatepicker(inst); 5228 } 5229 }, 5230 5231 /* Set the dates for a jQuery selection. 5232 @param target element - the target input field or division or span 5233 @param date Date - the new date */ 5234 _setDateDatepicker: function(target, date) { 5235 var inst = this._getInst(target); 5236 if (inst) { 5237 this._setDate(inst, date); 5238 this._updateDatepicker(inst); 5239 this._updateAlternate(inst); 5240 } 5241 }, 5242 5243 /* Get the date(s) for the first entry in a jQuery selection. 5244 @param target element - the target input field or division or span 5245 @param noDefault boolean - true if no default date is to be used 5246 @return Date - the current date */ 5247 _getDateDatepicker: function(target, noDefault) { 5248 var inst = this._getInst(target); 5249 if (inst && !inst.inline) 5250 this._setDateFromField(inst, noDefault); 5251 return (inst ? this._getDate(inst) : null); 5252 }, 5253 5254 /* Handle keystrokes. */ 5255 _doKeyDown: function(event) { 5256 var inst = $.datepicker._getInst(event.target); 5257 var handled = true; 5258 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); 5259 inst._keyEvent = true; 5260 if ($.datepicker._datepickerShowing) 5261 switch (event.keyCode) { 5262 case 9: $.datepicker._hideDatepicker(); 5263 handled = false;
5264 break; // hide on tab out 5265 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 5266 $.datepicker._currentClass + ')', inst.dpDiv); 5267 if (sel[0]) 5268 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 5269 var onSelect = $.datepicker._get(inst, 'onSelect'); 5270 if (onSelect) { 5271 var dateStr = $.datepicker._formatDate(inst); 5272 5273 // trigger custom callback 5274 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 5275 } 5276 else 5277 $.datepicker._hideDatepicker(); 5278 return false; // don't submit the form 5279 break; // select the value on enter 5280 case 27: $.datepicker._hideDatepicker(); 5281 break; // hide on escape 5282 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 5283 -$.datepicker._get(inst, 'stepBigMonths') : 5284 -$.datepicker._get(inst, 'stepMonths')), 'M'); 5285 break; // previous month/year on page up/+ ctrl 5286 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 5287 +$.datepicker._get(inst, 'stepBigMonths') : 5288 +$.datepicker._get(inst, 'stepMonths')), 'M'); 5289 break; // next month/year on page down/+ ctrl 5290 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); 5291 handled = event.ctrlKey || event.metaKey; 5292 break; // clear on ctrl or command +end 5293 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); 5294 handled = event.ctrlKey || event.metaKey; 5295 break; // current on ctrl or command +home 5296 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); 5297 handled = event.ctrlKey || event.metaKey; 5298 // -1 day on ctrl or command +left 5299 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 5300 -$.datepicker._get(inst, 'stepBigMonths') : 5301 -$.datepicker._get(inst, 'stepMonths')), 'M'); 5302 // next month/year on alt +left on Mac 5303 break; 5304 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); 5305 handled = event.ctrlKey || event.metaKey; 5306 break; // -1 week on ctrl or command +up 5307 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); 5308 handled = event.ctrlKey || event.metaKey; 5309 // +1 day on ctrl or command +right 5310 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 5311 +$.datepicker._get(inst, 'stepBigMonths') : 5312 +$.datepicker._get(inst, 'stepMonths')), 'M'); 5313 // next month/year on alt +right 5314 break; 5315 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); 5316 handled = event.ctrlKey || event.metaKey; 5317 break; // +1 week on ctrl or command +down 5318 default: handled = false; 5319 } 5320 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home 5321 $.datepicker._showDatepicker(this); 5322 else { 5323 handled = false; 5324 } 5325 if (handled) { 5326 event.preventDefault(); 5327 event.stopPropagation(); 5328 } 5329 }, 5330 5331 /* Filter entered characters - based on date format. */ 5332 _doKeyPress: function(event) { 5333 var inst = $.datepicker._getInst(event.target); 5334 if ($.datepicker._get(inst, 'constrainInput')) { 5335 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); 5336 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); 5337 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); 5338 } 5339 }, 5340 5341 /* Synchronise manual entry and field/alternate field. */ 5342 _doKeyUp: function(event) { 5343 var inst = $.datepicker._getInst(event.target);
vendor: 8,608 bytes, lines 5344-5545
5344 if (inst.input.val() != inst.lastVal) { 5345 try { 5346 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 5347 (inst.input ? inst.input.val() : null), 5348 $.datepicker._getFormatConfig(inst)); 5349 if (date) { // only if valid 5350 $.datepicker._setDateFromField(inst); 5351 $.datepicker._updateAlternate(inst); 5352 $.datepicker._updateDatepicker(inst); 5353 } 5354 } 5355 catch (err) { 5356 $.datepicker.log(err); 5357 } 5358 } 5359 return true; 5360 }, 5361 5362 /* Pop-up the date picker for a given input field. 5363 If false returned from beforeShow event handler do not show. 5364 @param input element - the input field attached to the date picker or 5365 event - if triggered by focus */ 5366 _showDatepicker: function(input) { 5367 input = input.target || input; 5368 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger 5369 input = $('input', input.parentNode)[0]; 5370 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here 5371 return; 5372 var inst = $.datepicker._getInst(input); 5373 if ($.datepicker._curInst && $.datepicker._curInst != inst) { 5374 $.datepicker._curInst.dpDiv.stop(true, true); 5375 if ( inst && $.datepicker._datepickerShowing ) { 5376 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 5377 } 5378 } 5379 var beforeShow = $.datepicker._get(inst, 'beforeShow'); 5380 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 5381 if(beforeShowSettings === false){ 5382 //false 5383 return; 5384 } 5385 extendRemove(inst.settings, beforeShowSettings); 5386 inst.lastVal = null; 5387 $.datepicker._lastInput = input; 5388 $.datepicker._setDateFromField(inst); 5389 if ($.datepicker._inDialog) // hide cursor 5390 input.value = ''; 5391 if (!$.datepicker._pos) { // position below input 5392 $.datepicker._pos = $.datepicker._findPos(input); 5393 $.datepicker._pos[1] += input.offsetHeight; // add the height 5394 } 5395 var isFixed = false; 5396 $(input).parents().each(function() { 5397 isFixed |= $(this).css('position') == 'fixed'; 5398 return !isFixed; 5399 }); 5400 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 5401 $.datepicker._pos = null; 5402 //to avoid flashes on Firefox 5403 inst.dpDiv.empty(); 5404 // determine sizing offscreen 5405 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); 5406 $.datepicker._updateDatepicker(inst); 5407 // fix width for dynamic number of date pickers 5408 // and adjust position before showing 5409 offset = $.datepicker._checkOffset(inst, offset, isFixed); 5410 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 5411 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', 5412 left: offset.left + 'px', top: offset.top + 'px'}); 5413 if (!inst.inline) { 5414 var showAnim = $.datepicker._get(inst, 'showAnim'); 5415 var duration = $.datepicker._get(inst, 'duration'); 5416 var postProcess = function() { 5417 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 5418 if( !! cover.length ){ 5419 var borders = $.datepicker._getBorders(inst.dpDiv); 5420 cover.css({left: -borders[0], top: -borders[1], 5421 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}); 5422 } 5423 }; 5424 inst.dpDiv.zIndex($(input).zIndex()+1); 5425 $.datepicker._datepickerShowing = true; 5426 5427 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 5428 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) 5429 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 5430 else 5431 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess); 5432 if (!showAnim || !duration) 5433 postProcess(); 5434 if (inst.input.is(':visible') && !inst.input.is(':disabled')) 5435 inst.input.focus(); 5436 $.datepicker._curInst = inst; 5437 } 5438 }, 5439 5440 /* Generate the date picker content. */ 5441 _updateDatepicker: function(inst) { 5442 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 5443 var borders = $.datepicker._getBorders(inst.dpDiv); 5444 instActive = inst; // for delegate hover events 5445 inst.dpDiv.empty().append(this._generateHTML(inst)); 5446 this._attachHandlers(inst); 5447 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 5448 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6 5449 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) 5450 } 5451 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover(); 5452 var numMonths = this._getNumberOfMonths(inst); 5453 var cols = numMonths[1]; 5454 var width = 17; 5455 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); 5456 if (cols > 1) 5457 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); 5458 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + 5459 'Class']('ui-datepicker-multi'); 5460 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + 5461 'Class']('ui-datepicker-rtl'); 5462 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 5463 // #6694 - don't focus the input if it's already focused 5464 // this breaks the change event in IE 5465 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement) 5466 inst.input.focus(); 5467 // deffered render of the years select (to avoid flashes on Firefox) 5468 if( inst.yearshtml ){ 5469 var origyearshtml = inst.yearshtml; 5470 setTimeout(function(){ 5471 //assure that inst.yearshtml didn't change. 5472 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 5473 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); 5474 } 5475 origyearshtml = inst.yearshtml = null; 5476 }, 0); 5477 } 5478 }, 5479 5480 /* Retrieve the size of left and top borders for an element. 5481 @param elem (jQuery object) the element of interest 5482 @return (number[2]) the left and top borders */ 5483 _getBorders: function(elem) { 5484 var convert = function(value) { 5485 return {thin: 1, medium: 2, thick: 3}[value] || value; 5486 }; 5487 return [parseFloat(convert(elem.css('border-left-width'))), 5488 parseFloat(convert(elem.css('border-top-width')))]; 5489 }, 5490 5491 /* Check positioning to remain on screen. */ 5492 _checkOffset: function(inst, offset, isFixed) { 5493 var dpWidth = inst.dpDiv.outerWidth(); 5494 var dpHeight = inst.dpDiv.outerHeight(); 5495 var inputWidth = inst.input ? inst.input.outerWidth() : 0; 5496 var inputHeight = inst.input ? inst.input.outerHeight() : 0; 5497 var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()); 5498 var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 5499 5500 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); 5501 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; 5502 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 5503 5504 // now check if datepicker is showing outside window viewport - move to a better place if so. 5505 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 5506 Math.abs(offset.left + dpWidth - viewWidth) : 0); 5507 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 5508 Math.abs(dpHeight + inputHeight) : 0); 5509 5510 return offset; 5511 }, 5512 5513 /* Find an object's position on the screen. */ 5514 _findPos: function(obj) { 5515 var inst = this._getInst(obj); 5516 var isRTL = this._get(inst, 'isRTL'); 5517 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) { 5518 obj = obj[isRTL ? 'previousSibling' : 'nextSibling']; 5519 } 5520 var position = $(obj).offset(); 5521 return [position.left, position.top]; 5522 }, 5523 5524 /* Hide the date picker from view. 5525 @param input element - the input field attached to the date picker */ 5526 _hideDatepicker: function(input) { 5527 var inst = this._curInst; 5528 if (!inst || (input && inst != $.data(input, PROP_NAME))) 5529 return; 5530 if (this._datepickerShowing) { 5531 var showAnim = this._get(inst, 'showAnim'); 5532 var duration = this._get(inst, 'duration'); 5533 var postProcess = function() { 5534 $.datepicker._tidyDialog(inst); 5535 }; 5536 5537 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 5538 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) 5539 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 5540 else 5541 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' : 5542 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); 5543 if (!showAnim) 5544 postProcess(); 5545 this._datepickerShowing = false;
5546 var onClose = this._get(inst, 'onClose'); 5547 if (onClose) 5548 onClose.apply((inst.input ? inst.input[0] : null), 5549 [(inst.input ? inst.input.val() : ''), inst]); 5550 this._lastInput = null; 5551 if (this._inDialog) { 5552 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); 5553 if ($.blockUI) { 5554 $.unblockUI(); 5555 $('body').append(this.dpDiv); 5556 } 5557 } 5558 this._inDialog = false; 5559 } 5560 }, 5561 5562 /* Tidy up after a dialog display. */ 5563 _tidyDialog: function(inst) { 5564 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); 5565 }, 5566 5567 /* Close date picker if clicked elsewhere. */ 5568 _checkExternalClick: function(event) { 5569 if (!$.datepicker._curInst) 5570 return; 5571 5572 var $target = $(event.target), 5573 inst = $.datepicker._getInst($target[0]); 5574 5575 if ( ( ( $target[0].id != $.datepicker._mainDivId && 5576 $target.parents('#' + $.datepicker._mainDivId).length == 0 && 5577 !$target.hasClass($.datepicker.markerClassName) && 5578 !$target.closest("." + $.datepicker._triggerClass).length && 5579 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 5580 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) ) 5581 $.datepicker._hideDatepicker(); 5582 }, 5583 5584 /* Adjust one of the date sub-fields. */ 5585 _adjustDate: function(id, offset, period) { 5586 var target = $(id); 5587 var inst = this._getInst(target[0]); 5588 if (this._isDisabledDatepicker(target[0])) { 5589 return; 5590 } 5591 this._adjustInstDate(inst, offset + 5592 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning 5593 period); 5594 this._updateDatepicker(inst); 5595 }, 5596 5597 /* Action for current link. */ 5598 _gotoToday: function(id) { 5599 var target = $(id); 5600 var inst = this._getInst(target[0]); 5601 if (this._get(inst, 'gotoCurrent') && inst.currentDay) { 5602 inst.selectedDay = inst.currentDay; 5603 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 5604 inst.drawYear = inst.selectedYear = inst.currentYear; 5605 } 5606 else { 5607 var date = new Date(); 5608 inst.selectedDay = date.getDate(); 5609 inst.drawMonth = inst.selectedMonth = date.getMonth(); 5610 inst.drawYear = inst.selectedYear = date.getFullYear(); 5611 } 5612 this._notifyChange(inst); 5613 this._adjustDate(target); 5614 }, 5615 5616 /* Action for selecting a new month/year. */ 5617 _selectMonthYear: function(id, select, period) { 5618 var target = $(id); 5619 var inst = this._getInst(target[0]); 5620 inst['selected' + (period == 'M' ? 'Month' : 'Year')] = 5621 inst['draw' + (period == 'M' ? 'Month' : 'Year')] = 5622 parseInt(select.options[select.selectedIndex].value,10); 5623 this._notifyChange(inst); 5624 this._adjustDate(target); 5625 }, 5626 5627 /* Action for selecting a day. */ 5628 _selectDay: function(id, month, year, td) { 5629 var target = $(id); 5630 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 5631 return; 5632 } 5633 var inst = this._getInst(target[0]); 5634 inst.selectedDay = inst.currentDay = $('a', td).html(); 5635 inst.selectedMonth = inst.currentMonth = month; 5636 inst.selectedYear = inst.currentYear = year; 5637 this._selectDate(id, this._formatDate(inst, 5638 inst.currentDay, inst.currentMonth, inst.currentYear)); 5639 }, 5640 5641 /* Erase the input field and hide the date picker. */ 5642 _clearDate: function(id) { 5643 var target = $(id); 5644 var inst = this._getInst(target[0]); 5645 this._selectDate(target, ''); 5646 }, 5647 5648 /* Update the input field with the selected date. */ 5649 _selectDate: function(id, dateStr) { 5650 var target = $(id); 5651 var inst = this._getInst(target[0]); 5652 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 5653 if (inst.input) 5654 inst.input.val(dateStr); 5655 this._updateAlternate(inst); 5656 var onSelect = this._get(inst, 'onSelect'); 5657 if (onSelect) 5658 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 5659 else if (inst.input) 5660 inst.input.trigger('change'); // fire the change event 5661 if (inst.inline) 5662 this._updateDatepicker(inst); 5663 else { 5664 this._hideDatepicker(); 5665 this._lastInput = inst.input[0]; 5666 if (typeof(inst.input[0]) != 'object') 5667 inst.input.focus(); // restore focus 5668 this._lastInput = null; 5669 } 5670 }, 5671 5672 /* Update any alternate field to synchronise with the main field. */ 5673 _updateAlternate: function(inst) { 5674 var altField = this._get(inst, 'altField'); 5675 if (altField) { // update alternate field too 5676 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); 5677 var date = this._getDate(inst); 5678 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 5679 $(altField).each(function() { $(this).val(dateStr); }); 5680 } 5681 }, 5682 5683 /* Set as beforeShowDay function to prevent selection of weekends. 5684 @param date Date - the date to customise 5685 @return [boolean, string] - is this date selectable?, what is its CSS class? */ 5686 noWeekends: function(date) { 5687 var day = date.getDay(); 5688 return [(day > 0 && day < 6), '']; 5689 }, 5690 5691 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 5692 @param date Date - the date to get the week for 5693 @return number - the number of the week within the year that contains this date */ 5694 iso8601Week: function(date) { 5695 var checkDate = new Date(date.getTime()); 5696 // Find Thursday of this week starting on Monday 5697 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 5698 var time = checkDate.getTime(); 5699 checkDate.setMonth(0); // Compare with Jan 1 5700 checkDate.setDate(1); 5701 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 5702 }, 5703 5704 /* Parse a string value into a date object. 5705 See formatDate below for the possible formats. 5706
vendor: 4,158 bytes, lines 5707-5815
5707 @param format string - the expected format of the date 5708 @param value string - the date in the above format 5709 @param settings Object - attributes include: 5710 shortYearCutoff number - the cutoff year for determining the century (optional) 5711 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 5712 dayNames string[7] - names of the days from Sunday (optional) 5713 monthNamesShort string[12] - abbreviated names of the months (optional) 5714 monthNames string[12] - names of the months (optional) 5715 @return Date - the extracted date value or null if value is blank */ 5716 parseDate: function (format, value, settings) { 5717 if (format == null || value == null) 5718 throw 'Invalid arguments'; 5719 value = (typeof value == 'object' ? value.toString() : value + ''); 5720 if (value == '') 5721 return null; 5722 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; 5723 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 5724 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 5725 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 5726 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 5727 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 5728 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 5729 var year = -1; 5730 var month = -1; 5731 var day = -1; 5732 var doy = -1; 5733 var literal = false; 5734 // Check whether a format character is doubled 5735 var lookAhead = function(match) { 5736 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 5737 if (matches) 5738 iFormat++; 5739 return matches; 5740 }; 5741 // Extract a number from the string value 5742 var getNumber = function(match) { 5743 var isDoubled = lookAhead(match); 5744 var size = (match == '@' ? 14 : (match == '!' ? 20 : 5745 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2)))); 5746 var digits = new RegExp('^\\d{1,' + size + '}'); 5747 var num = value.substring(iValue).match(digits); 5748 if (!num) 5749 throw 'Missing number at position ' + iValue; 5750 iValue += num[0].length; 5751 return parseInt(num[0], 10); 5752 }; 5753 // Extract a name from the string value and convert to an index 5754 var getName = function(match, shortNames, longNames) { 5755 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 5756 return [ [k, v] ]; 5757 }).sort(function (a, b) { 5758 return -(a[1].length - b[1].length); 5759 }); 5760 var index = -1; 5761 $.each(names, function (i, pair) { 5762 var name = pair[1]; 5763 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { 5764 index = pair[0]; 5765 iValue += name.length; 5766 return false; 5767 } 5768 }); 5769 if (index != -1) 5770 return index + 1; 5771 else 5772 throw 'Unknown name at position ' + iValue; 5773 }; 5774 // Confirm that a literal character matches the string value 5775 var checkLiteral = function() { 5776 if (value.charAt(iValue) != format.charAt(iFormat)) 5777 throw 'Unexpected literal at position ' + iValue; 5778 iValue++; 5779 }; 5780 var iValue = 0; 5781 for (var iFormat = 0; iFormat < format.length; iFormat++) { 5782 if (literal) 5783 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 5784 literal = false; 5785 else 5786 checkLiteral(); 5787 else 5788 switch (format.charAt(iFormat)) { 5789 case 'd': 5790 day = getNumber('d'); 5791 break; 5792 case 'D': 5793 getName('D', dayNamesShort, dayNames); 5794 break; 5795 case 'o': 5796 doy = getNumber('o'); 5797 break; 5798 case 'm': 5799 month = getNumber('m'); 5800 break; 5801 case 'M': 5802 month = getName('M', monthNamesShort, monthNames); 5803 break; 5804 case 'y': 5805 year = getNumber('y'); 5806 break; 5807 case '@': 5808 var date = new Date(getNumber('@')); 5809 year = date.getFullYear(); 5810 month = date.getMonth() + 1; 5811 day = date.getDate(); 5812 break; 5813 case '!': 5814 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); 5815 year = date.getFullYear();
5816 month = date.getMonth() + 1; 5817 day = date.getDate(); 5818 break; 5819 case "'": 5820 if (lookAhead("'")) 5821 checkLiteral(); 5822 else 5823 literal = true; 5824 break; 5825 default: 5826 checkLiteral(); 5827 } 5828 } 5829 if (iValue < value.length){ 5830 var extra = value.substr(iValue); 5831 if (!/^\s+/.test(extra)) { 5832 throw "Extra/unparsed characters found in date: " + extra; 5833 } 5834 } 5835 if (year == -1) 5836 year = new Date().getFullYear(); 5837 else if (year < 100) 5838 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 5839 (year <= shortYearCutoff ? 0 : -100); 5840 if (doy > -1) { 5841 month = 1; 5842 day = doy; 5843 do { 5844 var dim = this._getDaysInMonth(year, month - 1); 5845 if (day <= dim) 5846 break; 5847 month++; 5848 day -= dim; 5849 } while (true); 5850 } 5851 var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 5852 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) 5853 throw 'Invalid date'; // E.g. 31/02/00 5854 return date; 5855 }, 5856 5857 /* Standard date formats. */ 5858 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) 5859 COOKIE: 'D, dd M yy', 5860 ISO_8601: 'yy-mm-dd', 5861 RFC_822: 'D, d M y', 5862 RFC_850: 'DD, dd-M-y', 5863 RFC_1036: 'D, d M y', 5864 RFC_1123: 'D, d M yy', 5865 RFC_2822: 'D, d M yy', 5866 RSS: 'D, d M y', // RFC 822 5867 TICKS: '!', 5868 TIMESTAMP: '@', 5869 W3C: 'yy-mm-dd', // ISO 8601 5870 5871 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 5872 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 5873 5874 /* Format a date object into a string value. 5875 The format can be combinations of the following: 5876 d - day of month (no leading zero) 5877 dd - day of month (two digit) 5878 o - day of year (no leading zeros) 5879 oo - day of year (three digit) 5880 D - day name short 5881 DD - day name long 5882 m - month of year (no leading zero) 5883 mm - month of year (two digit) 5884 M - month name short 5885 MM - month name long 5886 y - year (two digit) 5887 yy - year (four digit) 5888 @ - Unix timestamp (ms since 01/01/1970) 5889 ! - Windows ticks (100ns since 01/01/0001) 5890 '...' - literal text 5891 '' - single quote 5892 5893 @param format string - the desired format of the date 5894 @param date Date - the date value to format 5895 @param settings Object - attributes include: 5896 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 5897 dayNames string[7] - names of the days from Sunday (optional) 5898 monthNamesShort string[12] - abbreviated names of the months (optional) 5899 monthNames string[12] - names of the months (optional) 5900 @return string - the date in the above format */ 5901 formatDate: function (format, date, settings) { 5902 if (!date) 5903 return ''; 5904 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 5905 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 5906 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 5907 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 5908 // Check whether a format character is doubled 5909 var lookAhead = function(match) { 5910 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 5911 if (matches) 5912 iFormat++; 5913 return matches; 5914 }; 5915 // Format a number, with leading zero if necessary 5916 var formatNumber = function(match, value, len) { 5917 var num = '' + value; 5918 if (lookAhead(match)) 5919 while (num.length < len) 5920 num = '0' + num; 5921 return num; 5922 }; 5923 // Format a name, short or long as requested 5924 var formatName = function(match, value, shortNames, longNames) { 5925 return (lookAhead(match) ? longNames[value] : shortNames[value]); 5926 }; 5927 var output = ''; 5928 var literal = false; 5929 if (date) 5930 for (var iFormat = 0; iFormat < format.length; iFormat++) { 5931 if (literal) 5932 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 5933 literal = false; 5934 else 5935 output += format.charAt(iFormat); 5936 else 5937 switch (format.charAt(iFormat)) { 5938 case 'd': 5939 output += formatNumber('d', date.getDate(), 2); 5940 break; 5941 case 'D': 5942 output += formatName('D', date.getDay(), dayNamesShort, dayNames); 5943 break; 5944 case 'o': 5945 output += formatNumber('o', 5946 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 5947 break; 5948 case 'm': 5949 output += formatNumber('m', date.getMonth() + 1, 2); 5950 break; 5951 case 'M': 5952 output += formatName('M', date.getMonth(), monthNamesShort, monthNames); 5953 break; 5954 case 'y': 5955 output += (lookAhead('y') ? date.getFullYear() : 5956 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); 5957 break; 5958 case '@': 5959 output += date.getTime(); 5960 break; 5961 case '!': 5962 output += date.getTime() * 10000 + this._ticksTo1970; 5963 break;
vendor: 5,981 bytes, lines 5964-6145
5964 case "'": 5965 if (lookAhead("'")) 5966 output += "'"; 5967 else 5968 literal = true; 5969 break; 5970 default: 5971 output += format.charAt(iFormat); 5972 } 5973 } 5974 return output; 5975 }, 5976 5977 /* Extract all possible characters from the date format. */ 5978 _possibleChars: function (format) { 5979 var chars = ''; 5980 var literal = false; 5981 // Check whether a format character is doubled 5982 var lookAhead = function(match) { 5983 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 5984 if (matches) 5985 iFormat++; 5986 return matches; 5987 }; 5988 for (var iFormat = 0; iFormat < format.length; iFormat++) 5989 if (literal) 5990 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 5991 literal = false; 5992 else 5993 chars += format.charAt(iFormat); 5994 else 5995 switch (format.charAt(iFormat)) { 5996 case 'd': case 'm': case 'y': case '@': 5997 chars += '0123456789'; 5998 break; 5999 case 'D': case 'M': 6000 return null; // Accept anything 6001 case "'": 6002 if (lookAhead("'")) 6003 chars += "'"; 6004 else 6005 literal = true; 6006 break; 6007 default: 6008 chars += format.charAt(iFormat); 6009 } 6010 return chars; 6011 }, 6012 6013 /* Get a setting value, defaulting if necessary. */ 6014 _get: function(inst, name) { 6015 return inst.settings[name] !== undefined ? 6016 inst.settings[name] : this._defaults[name]; 6017 }, 6018 6019 /* Parse existing date and initialise date picker. */ 6020 _setDateFromField: function(inst, noDefault) { 6021 if (inst.input.val() == inst.lastVal) { 6022 return; 6023 } 6024 var dateFormat = this._get(inst, 'dateFormat'); 6025 var dates = inst.lastVal = inst.input ? inst.input.val() : null; 6026 var date, defaultDate; 6027 date = defaultDate = this._getDefaultDate(inst); 6028 var settings = this._getFormatConfig(inst); 6029 try { 6030 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 6031 } catch (event) { 6032 this.log(event); 6033 dates = (noDefault ? '' : dates); 6034 } 6035 inst.selectedDay = date.getDate(); 6036 inst.drawMonth = inst.selectedMonth = date.getMonth(); 6037 inst.drawYear = inst.selectedYear = date.getFullYear(); 6038 inst.currentDay = (dates ? date.getDate() : 0); 6039 inst.currentMonth = (dates ? date.getMonth() : 0); 6040 inst.currentYear = (dates ? date.getFullYear() : 0); 6041 this._adjustInstDate(inst); 6042 }, 6043 6044 /* Retrieve the default date shown on opening. */ 6045 _getDefaultDate: function(inst) { 6046 return this._restrictMinMax(inst, 6047 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date())); 6048 }, 6049 6050 /* A date may be specified as an exact value or a relative one. */ 6051 _determineDate: function(inst, date, defaultDate) { 6052 var offsetNumeric = function(offset) { 6053 var date = new Date(); 6054 date.setDate(date.getDate() + offset); 6055 return date; 6056 }; 6057 var offsetString = function(offset) { 6058 try { 6059 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 6060 offset, $.datepicker._getFormatConfig(inst)); 6061 } 6062 catch (e) { 6063 // Ignore 6064 } 6065 var date = (offset.toLowerCase().match(/^c/) ? 6066 $.datepicker._getDate(inst) : null) || new Date(); 6067 var year = date.getFullYear(); 6068 var month = date.getMonth(); 6069 var day = date.getDate(); 6070 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; 6071 var matches = pattern.exec(offset); 6072 while (matches) { 6073 switch (matches[2] || 'd') { 6074 case 'd' : case 'D' : 6075 day += parseInt(matches[1],10); break; 6076 case 'w' : case 'W' : 6077 day += parseInt(matches[1],10) * 7; break; 6078 case 'm' : case 'M' : 6079 month += parseInt(matches[1],10); 6080 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 6081 break; 6082 case 'y': case 'Y' : 6083 year += parseInt(matches[1],10); 6084 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 6085 break; 6086 } 6087 matches = pattern.exec(offset); 6088 } 6089 return new Date(year, month, day); 6090 }; 6091 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) : 6092 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 6093 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate); 6094 if (newDate) { 6095 newDate.setHours(0); 6096 newDate.setMinutes(0); 6097 newDate.setSeconds(0); 6098 newDate.setMilliseconds(0); 6099 } 6100 return this._daylightSavingAdjust(newDate); 6101 }, 6102 6103 /* Handle switch to/from daylight saving. 6104 Hours may be non-zero on daylight saving cut-over: 6105 > 12 when midnight changeover, but then cannot generate 6106 midnight datetime, so jump to 1AM, otherwise reset. 6107 @param date (Date) the date to check 6108 @return (Date) the corrected date */ 6109 _daylightSavingAdjust: function(date) { 6110 if (!date) return null; 6111 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 6112 return date; 6113 }, 6114 6115 /* Set the date(s) directly. */ 6116 _setDate: function(inst, date, noChange) { 6117 var clear = !date; 6118 var origMonth = inst.selectedMonth; 6119 var origYear = inst.selectedYear; 6120 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 6121 inst.selectedDay = inst.currentDay = newDate.getDate(); 6122 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 6123 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 6124 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) 6125 this._notifyChange(inst); 6126 this._adjustInstDate(inst); 6127 if (inst.input) { 6128 inst.input.val(clear ? '' : this._formatDate(inst)); 6129 } 6130 }, 6131 6132 /* Retrieve the date(s) directly. */ 6133 _getDate: function(inst) { 6134 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : 6135 this._daylightSavingAdjust(new Date( 6136 inst.currentYear, inst.currentMonth, inst.currentDay))); 6137 return startDate; 6138 }, 6139 6140 /* Attach the onxxx handlers. These are declared statically so 6141 * they work with static code transformers like Caja. 6142 */ 6143 _attachHandlers: function(inst) { 6144 var stepMonths = this._get(inst, 'stepMonths'); 6145 var id = '#' + inst.id.replace( /\\\\/g, "\\" );
6146 inst.dpDiv.find('[data-handler]').map(function () { 6147 var handler = { 6148 prev: function () { 6149 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M'); 6150 }, 6151 next: function () { 6152 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M'); 6153 }, 6154 hide: function () { 6155 window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker(); 6156 }, 6157 today: function () { 6158 window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id); 6159 }, 6160 selectDay: function () { 6161 window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this); 6162 return false; 6163 }, 6164 selectMonth: function () { 6165 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M'); 6166 return false; 6167 }, 6168 selectYear: function () { 6169 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y'); 6170 return false; 6171 } 6172 }; 6173 $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]); 6174 }); 6175 }, 6176 6177 /* Generate the HTML for the current state of the date picker. */ 6178 _generateHTML: function(inst) { 6179 var today = new Date(); 6180 today = this._daylightSavingAdjust( 6181 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time 6182 var isRTL = this._get(inst, 'isRTL'); 6183 var showButtonPanel = this._get(inst, 'showButtonPanel'); 6184 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); 6185 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); 6186 var numMonths = this._getNumberOfMonths(inst); 6187 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); 6188 var stepMonths = this._get(inst, 'stepMonths'); 6189 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); 6190 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 6191 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 6192 var minDate = this._getMinMaxDate(inst, 'min'); 6193 var maxDate = this._getMinMaxDate(inst, 'max'); 6194 var drawMonth = inst.drawMonth - showCurrentAtPos; 6195 var drawYear = inst.drawYear; 6196 if (drawMonth < 0) { 6197 drawMonth += 12; 6198 drawYear--; 6199 } 6200 if (maxDate) { 6201 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 6202 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 6203 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 6204 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 6205 drawMonth--; 6206 if (drawMonth < 0) { 6207 drawMonth = 11; 6208 drawYear--; 6209 } 6210 } 6211 } 6212 inst.drawMonth = drawMonth; 6213 inst.drawYear = drawYear; 6214 var prevText = this._get(inst, 'prevText'); 6215 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 6216 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 6217 this._getFormatConfig(inst))); 6218 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 6219 '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' + 6220 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : 6221 (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>')); 6222 var nextText = this._get(inst, 'nextText'); 6223 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 6224 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 6225 this._getFormatConfig(inst))); 6226 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 6227 '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' + 6228 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : 6229 (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>')); 6230 var currentText = this._get(inst, 'currentText'); 6231 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); 6232 currentText = (!navigationAsDateFormat ? currentText : 6233 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 6234 var 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">' + 6235 this._get(inst, 'closeText') + '</button>' : ''); 6236 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + 6237 (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"' + 6238 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; 6239 var firstDay = parseInt(this._get(inst, 'firstDay'),10); 6240 firstDay = (isNaN(firstDay) ? 0 : firstDay); 6241 var showWeek = this._get(inst, 'showWeek'); 6242 var dayNames = this._get(inst, 'dayNames'); 6243 var dayNamesShort = this._get(inst, 'dayNamesShort'); 6244 var dayNamesMin = this._get(inst, 'dayNamesMin'); 6245 var monthNames = this._get(inst, 'monthNames'); 6246 var monthNamesShort = this._get(inst, 'monthNamesShort'); 6247 var beforeShowDay = this._get(inst, 'beforeShowDay'); 6248 var showOtherMonths = this._get(inst, 'showOtherMonths'); 6249 var selectOtherMonths = this._get(inst, 'selectOtherMonths'); 6250 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; 6251 var defaultDate = this._getDefaultDate(inst); 6252 var html = ''; 6253 for (var row = 0; row < numMonths[0]; row++) { 6254 var group = ''; 6255 this.maxRows = 4; 6256 for (var col = 0; col < numMonths[1]; col++) { 6257 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 6258 var cornerClass = ' ui-corner-all'; 6259 var calender = ''; 6260 if (isMultiMonth) { 6261 calender += '<div class="ui-datepicker-group'; 6262 if (numMonths[1] > 1) 6263 switch (col) { 6264 case 0: calender += ' ui-datepicker-group-first'; 6265 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; 6266 case numMonths[1]-1: calender += ' ui-datepicker-group-last'; 6267 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; 6268 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break; 6269 } 6270 calender += '">'; 6271 } 6272 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' + 6273 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + 6274 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + 6275 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 6276 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 6277 '</div><table class="ui-datepicker-calendar"><thead>' + 6278 '<tr>'; 6279 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : ''); 6280 for (var dow = 0; dow < 7; dow++) { // days of the week 6281 var day = (dow + firstDay) % 7; 6282 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
6282' + 6283 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>'; 6284 } 6285 calender += thead + '</tr></thead><tbody>'; 6286 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 6287 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) 6288 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 6289 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 6290 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 6291 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 6292 this.maxRows = numRows; 6293 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 6294 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows 6295 calender += '<tr>'; 6296 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' + 6297 this._get(inst, 'calculateWeek')(printDate) + '</td>'); 6298 for (var dow = 0; dow < 7; dow++) { // create date picker days 6299 var daySettings = (beforeShowDay ? 6300 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); 6301 var otherMonth = (printDate.getMonth() != drawMonth); 6302 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 6303 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 6304 tbody += '<td class="' + 6305 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends 6306 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months 6307 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key 6308 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ? 6309 // or defaultDate is current printedDate and defaultDate is selectedDate 6310 ' ' + this._dayOverClass : '') + // highlight selected day 6311 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days 6312 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates 6313 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day 6314 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) 6315 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title 6316 (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions 6317 (otherMonth && !showOtherMonths ? ' ' : // display for other months 6318 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + 6319 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + 6320 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day 6321 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months 6322 '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date 6323 printDate.setDate(printDate.getDate() + 1); 6324 printDate = this._daylightSavingAdjust(printDate); 6325 } 6326 calender += tbody + '</tr>'; 6327 } 6328 drawMonth++; 6329 if (drawMonth > 11) { 6330 drawMonth = 0; 6331 drawYear++; 6332 } 6333 calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 6334 ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : ''); 6335 group += calender; 6336 } 6337 html += group; 6338 } 6339 html += buttonPanel + ($.ui.ie6 && !inst.inline ? 6340 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : ''); 6341 inst._keyEvent = false; 6342 return html; 6343 }, 6344 6345 /* Generate the month and year header. */ 6346 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 6347 secondary, monthNames, monthNamesShort) { 6348 var changeMonth = this._get(inst, 'changeMonth'); 6349 var changeYear = this._get(inst, 'changeYear'); 6350 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); 6351 var html = '<div class="ui-datepicker-title">'; 6352 var monthHtml = ''; 6353 // month selection 6354 if (secondary || !changeMonth) 6355 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>'; 6356 else { 6357 var inMinYear = (minDate && minDate.getFullYear() == drawYear); 6358 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); 6359 monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
6360 for (var month = 0; month < 12; month++) { 6361 if ((!inMinYear || month >= minDate.getMonth()) && 6362 (!inMaxYear || month <= maxDate.getMonth())) 6363 monthHtml += '<option value="' + month + '"' + 6364 (month == drawMonth ? ' selected="selected"' : '') + 6365 '>' + monthNamesShort[month] + '</option>'; 6366 } 6367 monthHtml += '</select>'; 6368 } 6369 if (!showMonthAfterYear) 6370 html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); 6371 // year selection 6372 if ( !inst.yearshtml ) { 6373 inst.yearshtml = ''; 6374 if (secondary || !changeYear) 6375 html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; 6376 else { 6377 // determine range of years to display 6378 var years = this._get(inst, 'yearRange').split(':'); 6379 var thisYear = new Date().getFullYear(); 6380 var determineYear = function(value) { 6381 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : 6382 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : 6383 parseInt(value, 10))); 6384 return (isNaN(year) ? thisYear : year); 6385 }; 6386 var year = determineYear(years[0]); 6387 var endYear = Math.max(year, determineYear(years[1] || '')); 6388 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 6389 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 6390 inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">'; 6391 for (; year <= endYear; year++) { 6392 inst.yearshtml += '<option value="' + year + '"' + 6393 (year == drawYear ? ' selected="selected"' : '') + 6394 '>' + year + '</option>'; 6395 } 6396 inst.yearshtml += '</select>'; 6397 6398 html += inst.yearshtml; 6399 inst.yearshtml = null; 6400 } 6401 } 6402 html += this._get(inst, 'yearSuffix'); 6403 if (showMonthAfterYear) 6404 html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; 6405 html += '</div>'; // Close datepicker_header 6406 return html; 6407 }, 6408 6409 /* Adjust one of the date sub-fields. */ 6410 _adjustInstDate: function(inst, offset, period) { 6411 var year = inst.drawYear + (period == 'Y' ? offset : 0); 6412 var month = inst.drawMonth + (period == 'M' ? offset : 0); 6413 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + 6414 (period == 'D' ? offset : 0); 6415 var date = this._restrictMinMax(inst, 6416 this._daylightSavingAdjust(new Date(year, month, day))); 6417 inst.selectedDay = date.getDate(); 6418 inst.drawMonth = inst.selectedMonth = date.getMonth(); 6419 inst.drawYear = inst.selectedYear = date.getFullYear(); 6420 if (period == 'M' || period == 'Y') 6421 this._notifyChange(inst); 6422 }, 6423 6424 /* Ensure a date is within any min/max bounds. */ 6425 _restrictMinMax: function(inst, date) { 6426 var minDate = this._getMinMaxDate(inst, 'min'); 6427 var maxDate = this._getMinMaxDate(inst, 'max'); 6428 var newDate = (minDate && date < minDate ? minDate : date); 6429 newDate = (maxDate && newDate > maxDate ? maxDate : newDate); 6430 return newDate; 6431 }, 6432 6433 /* Notify change of month/year. */ 6434 _notifyChange: function(inst) { 6435 var onChange = this._get(inst, 'onChangeMonthYear'); 6436 if (onChange) 6437 onChange.apply((inst.input ? inst.input[0] : null), 6438 [inst.selectedYear, inst.selectedMonth + 1, inst]); 6439 }, 6440 6441 /* Determine the number of months to show. */ 6442 _getNumberOfMonths: function(inst) { 6443 var numMonths = this._get(inst, 'numberOfMonths'); 6444 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); 6445 }, 6446 6447 /* Determine the current maximum date - ensure no time components are set. */ 6448 _getMinMaxDate: function(inst, minMax) { 6449 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); 6450 }, 6451 6452 /* Find the number of days in a given month. */ 6453 _getDaysInMonth: function(year, month) { 6454 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 6455 }, 6456 6457 /* Find the day of the week of the first of a month. */ 6458 _getFirstDayOfMonth: function(year, month) { 6459 return new Date(year, month, 1).getDay(); 6460 }, 6461 6462 /* Determines if we should allow a "next/prev" month display change. */ 6463 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 6464 var numMonths = this._getNumberOfMonths(inst); 6465 var date = this._daylightSavingAdjust(new Date(curYear, 6466 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 6467 if (offset < 0) 6468 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 6469 return this._isInRange(inst, date); 6470 }, 6471 6472 /* Is the given date in the accepted range? */ 6473 _isInRange: function(inst, date) { 6474 var minDate = this._getMinMaxDate(inst, 'min'); 6475 var maxDate = this._getMinMaxDate(inst, 'max'); 6476 return ((!minDate || date.getTime() >= minDate.getTime()) && 6477 (!maxDate || date.getTime() <= maxDate.getTime())); 6478 }, 6479 6480 /* Provide the configuration settings for formatting/parsing. */ 6481 _getFormatConfig: function(inst) { 6482 var shortYearCutoff = this._get(inst, 'shortYearCutoff'); 6483 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 6484 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 6485 return {shortYearCutoff: shortYearCutoff, 6486 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), 6487 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; 6488 }, 6489 6490 /* Format the given date for display. */ 6491 _formatDate: function(inst, day, month, year) { 6492 if (!day) { 6493 inst.currentDay = inst.selectedDay; 6494 inst.currentMonth = inst.selectedMonth; 6495 inst.currentYear = inst.selectedYear; 6496 } 6497 var date = (day ? (typeof day == 'object' ? day : 6498 this._daylightSavingAdjust(new Date(year, month, day))) : 6499 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 6500 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); 6501 } 6502}); 6503 6504/* 6505 * Bind hover events for datepicker elements. 6506 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 6507 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 6508 */ 6509function bindHover(dpDiv) { 6510 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; 6511 return dpDiv.delegate(selector, 'mouseout', function() { 6512 $(this).removeClass('ui-state-hover'); 6513 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); 6514 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); 6515 }) 6516 .delegate(selector, 'mouseover', function(){ 6517 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 6518 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); 6519 $(this).addClass('ui-state-hover'); 6520 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); 6521 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); 6522 } 6523 }); 6524} 6525 6526/* jQuery extend now ignores nulls! */ 6527function extendRemove(target, props) { 6528 $.extend(target, props); 6529 for (var name in props) 6530 if (props[name] == null || props[name] == undefined) 6531 target[name] = props[name]; 6532 return target; 6533}; 6534 6535/* Invoke the datepicker functionality. 6536 @param options string - a command, optionally followed by additional parameters or 6537 Object - settings for attaching new datepicker functionality 6538 @return jQuery object */ 6539$.fn.datepicker = function(options){ 6540 6541 /* Verify an empty collection wasn't passed - Fixes #6976 */ 6542 if ( !this.length ) { 6543 return this; 6544 } 6545 6546 /* Initialise the date picker. */ 6547 if (!$.datepicker.initialized) { 6548 $(document).mousedown($.datepicker._checkExternalClick). 6549 find(document.body).append($.datepicker.dpDiv); 6550 $.datepicker.initialized = true; 6551 } 6552 6553 var otherArgs = Array.prototype.slice.call(arguments, 1); 6554 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) 6555 return $.datepicker['_' + options + 'Datepicker']. 6556 apply($.datepicker, [this[0]].concat(otherArgs)); 6557 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') 6558 return $.datepicker['_' + options + 'Datepicker']. 6559 apply($.datepicker, [this[0]].concat(otherArgs)); 6560 return this.each(function() { 6561 typeof options == 'string' ? 6562 $.datepicker['_' + options + 'Datepicker']. 6563 apply($.datepicker, [this].concat(otherArgs)) : 6564 $.datepicker._attachDatepicker(this, options); 6565 }); 6566}; 6567 6568$.datepicker = new Datepicker(); // singleton instance 6569$.datepicker.initialized = false;
6570$.datepicker.uuid = new Date().getTime(); 6571$.datepicker.version = "1.9.2"; 6572 6573// Workaround for #4055 6574// Add another global to avoid noConflict issues with inline event handlers 6575window['DP_jQuery_' + dpuuid] = $; 6576 6577})(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.