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