| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 /* 2 * jQuery UI 1.6 3 * 4 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 5 * Dual licensed under the MIT (MIT-LICENSE.txt) 6 * and GPL (GPL-LICENSE.txt) licenses. 7 * 8 * http://docs.jquery.com/UI 9 */ 10 ;(function($) { 11 12 var _remove = $.fn.remove, 13 isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9); 14 15 //Helper functions and ui object 16 $.ui = { 17 18 version: "1.6", 19 20 // $.ui.plugin is deprecated. Use the proxy pattern instead. 21 plugin: { 22 add: function(module, option, set) { 23 var proto = $.ui[module].prototype; 24 for(var i in set) { 25 proto.plugins[i] = proto.plugins[i] || []; 26 proto.plugins[i].push([option, set[i]]); 27 } 28 }, 29 call: function(instance, name, args) { 30 var set = instance.plugins[name]; 31 if(!set) { return; } 32 33 for (var i = 0; i < set.length; i++) { 34 if (instance.options[set[i][0]]) { 35 set[i][1].apply(instance.element, args); 36 } 37 } 38 } 39 }, 40 41 contains: function(a, b) { 42 var safari2 = $.browser.safari && $.browser.version < 522; 43 if (a.contains && !safari2) { 44 return a.contains(b); 45 } 46 if (a.compareDocumentPosition) 47 return !!(a.compareDocumentPosition(b) & 16); 48 while (b = b.parentNode) 49 if (b == a) return true; 50 return false; 51 }, 52 53 cssCache: {}, 54 css: function(name) { 55 if ($.ui.cssCache[name]) { return $.ui.cssCache[name]; } 56 var tmp = $('<div class="ui-gen">').addClass(name).css({position:'absolute', top:'-5000px', left:'-5000px', display:'block'}).appendTo('body'); 57 58 //if (!$.browser.safari) 59 //tmp.appendTo('body'); 60 61 //Opera and Safari set width and height to 0px instead of auto 62 //Safari returns rgba(0,0,0,0) when bgcolor is not set 63 $.ui.cssCache[name] = !!( 64 (!(/auto|default/).test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) || 65 !(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor'))) 66 ); 67 try { $('body').get(0).removeChild(tmp.get(0)); } catch(e){} 68 return $.ui.cssCache[name]; 69 }, 70 71 hasScroll: function(el, a) { 72 73 //If overflow is hidden, the element might have extra content, but the user wants to hide it 74 if ($(el).css('overflow') == 'hidden') { return false; } 75 76 var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop', 77 has = false; 78 79 if (el[scroll] > 0) { return true; } 80 81 // TODO: determine which cases actually cause this to happen 82 // if the element doesn't have the scroll set, see if it's possible to 83 // set the scroll 84 el[scroll] = 1; 85 has = (el[scroll] > 0); 86 el[scroll] = 0; 87 return has; 88 }, 89 90 isOverAxis: function(x, reference, size) { 91 //Determines when x coordinate is over "b" element axis 92 return (x > reference) && (x < (reference + size)); 93 }, 94 95 isOver: function(y, x, top, left, height, width) { 96 //Determines when x, y coordinates is over "b" element 97 return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width); 98 }, 99 100 keyCode: { 101 BACKSPACE: 8, 102 CAPS_LOCK: 20, 103 COMMA: 188, 104 CONTROL: 17, 105 DELETE: 46, 106 DOWN: 40, 107 END: 35, 108 ENTER: 13, 109 ESCAPE: 27, 110 HOME: 36, 111 INSERT: 45, 112 LEFT: 37, 113 NUMPAD_ADD: 107, 114 NUMPAD_DECIMAL: 110, 115 NUMPAD_DIVIDE: 111, 116 NUMPAD_ENTER: 108, 117 NUMPAD_MULTIPLY: 106, 118 NUMPAD_SUBTRACT: 109, 119 PAGE_DOWN: 34, 120 PAGE_UP: 33, 121 PERIOD: 190, 122 RIGHT: 39, 123 SHIFT: 16, 124 SPACE: 32, 125 TAB: 9, 126 UP: 38 127 } 128 129 }; 130 131 // WAI-ARIA normalization 132 if (isFF2) { 133 var attr = $.attr, 134 removeAttr = $.fn.removeAttr, 135 ariaNS = "http://www.w3.org/2005/07/aaa", 136 ariaState = /^aria-/, 137 ariaRole = /^wairole:/; 138 139 $.attr = function(elem, name, value) { 140 var set = value !== undefined; 141 142 return (name == 'role' 143 ? (set 144 ? attr.call(this, elem, name, "wairole:" + value) 145 : (attr.apply(this, arguments) || "").replace(ariaRole, "")) 146 : (ariaState.test(name) 147 ? (set 148 ? elem.setAttributeNS(ariaNS, 149 name.replace(ariaState, "aaa:"), value) 150 : attr.call(this, elem, name.replace(ariaState, "aaa:"))) 151 : attr.apply(this, arguments))); 152 }; 153 154 $.fn.removeAttr = function(name) { 155 return (ariaState.test(name) 156 ? this.each(function() { 157 this.removeAttributeNS(ariaNS, name.replace(ariaState, "")); 158 }) : removeAttr.call(this, name)); 159 }; 160 } 161 162 //jQuery plugins 163 $.fn.extend({ 164 165 remove: function() { 166 // Safari has a native remove event which actually removes DOM elements, 167 // so we have to use triggerHandler instead of trigger (#3037). 168 $("*", this).add(this).each(function() { 169 $(this).triggerHandler("remove"); 170 }); 171 return _remove.apply(this, arguments ); 172 }, 173 174 enableSelection: function() { 175 return this 176 .attr('unselectable', 'off') 177 .css('MozUserSelect', '') 178 .unbind('selectstart.ui'); 179 }, 180 181 disableSelection: function() { 182 return this 183 .attr('unselectable', 'on') 184 .css('MozUserSelect', 'none') 185 .bind('selectstart.ui', function() { return false; }); 186 }, 187 188 scrollParent: function() { 189 190 var scrollParent; 191 if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { 192 scrollParent = this.parents().filter(function() { 193 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)); 194 }).eq(0); 195 } else { 196 scrollParent = this.parents().filter(function() { 197 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); 198 }).eq(0); 199 } 200 201 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; 202 203 204 } 205 206 }); 207 208 209 //Additional selectors 210 $.extend($.expr[':'], { 211 212 data: function(a, i, m) { 213 return $.data(a, m[3]); 214 }, 215 216 // TODO: add support for object, area 217 tabbable: function(a, i, m) { 218 219 var nodeName = a.nodeName.toLowerCase(); 220 function isVisible(element) { 221 return !($(element).is(':hidden') || $(element).parents(':hidden').length); 222 } 223 224 return ( 225 // in tab order 226 a.tabIndex >= 0 && 227 228 ( // filter node types that participate in the tab order 229 230 // anchor tag 231 ('a' == nodeName && a.href) || 232 233 // enabled form element 234 (/input|select|textarea|button/.test(nodeName) && 235 'hidden' != a.type && !a.disabled) 236 ) && 237 238 // visible on page 239 isVisible(a) 240 ); 241 242 } 243 244 }); 245 246 247 // $.widget is a factory to create jQuery plugins 248 // taking some boilerplate code out of the plugin code 249 function getter(namespace, plugin, method, args) { 250 function getMethods(type) { 251 var methods = $[namespace][plugin][type] || []; 252 return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods); 253 } 254 255 var methods = getMethods('getter'); 256 if (args.length == 1 && typeof args[0] == 'string') { 257 methods = methods.concat(getMethods('getterSetter')); 258 } 259 return ($.inArray(method, methods) != -1); 260 } 261 262 $.widget = function(name, prototype) { 263 var namespace = name.split(".")[0]; 264 name = name.split(".")[1]; 265 266 // create plugin method 267 $.fn[name] = function(options) { 268 var isMethodCall = (typeof options == 'string'), 269 args = Array.prototype.slice.call(arguments, 1); 270 271 // prevent calls to internal methods 272 if (isMethodCall && options.substring(0, 1) == '_') { 273 return this; 274 } 275 276 // handle getter methods 277 if (isMethodCall && getter(namespace, name, options, args)) { 278 var instance = $.data(this[0], name); 279 return (instance ? instance[options].apply(instance, args) 280 : undefined); 281 } 282 283 // handle initialization and non-getter methods 284 return this.each(function() { 285 var instance = $.data(this, name); 286 287 // constructor 288 (!instance && !isMethodCall && 289 $.data(this, name, new $[namespace][name](this, options))); 290 291 // method call 292 (instance && isMethodCall && $.isFunction(instance[options]) && 293 instance[options].apply(instance, args)); 294 }); 295 }; 296 297 // create widget constructor 298 $[namespace] = $[namespace] || {}; 299 $[namespace][name] = function(element, options) { 300 var self = this; 301 302 this.widgetName = name; 303 this.widgetEventPrefix = $[namespace][name].eventPrefix || name; 304 this.widgetBaseClass = namespace + '-' + name; 305 306 this.options = $.extend({}, 307 $.widget.defaults, 308 $[namespace][name].defaults, 309 $.metadata && $.metadata.get(element)[name], 310 options); 311 312 this.element = $(element) 313 .bind('setData.' + name, function(event, key, value) { 314 return self._setData(key, value); 315 }) 316 .bind('getData.' + name, function(event, key) { 317 return self._getData(key); 318 }) 319 .bind('remove', function() { 320 return self.destroy(); 321 }); 322 323 this._init(); 324 }; 325 326 // add widget prototype 327 $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype); 328 329 // TODO: merge getter and getterSetter properties from widget prototype 330 // and plugin prototype 331 $[namespace][name].getterSetter = 'option'; 332 }; 333 334 $.widget.prototype = { 335 _init: function() {}, 336 destroy: function() { 337 this.element.removeData(this.widgetName); 338 }, 339 340 option: function(key, value) { 341 var options = key, 342 self = this; 343 344 if (typeof key == "string") { 345 if (value === undefined) { 346 return this._getData(key); 347 } 348 options = {}; 349 options[key] = value; 350 } 351 352 $.each(options, function(key, value) { 353 self._setData(key, value); 354 }); 355 }, 356 _getData: function(key) { 357 return this.options[key]; 358 }, 359 _setData: function(key, value) { 360 this.options[key] = value; 361 362 if (key == 'disabled') { 363 this.element[value ? 'addClass' : 'removeClass']( 364 this.widgetBaseClass + '-disabled'); 365 } 366 }, 367 368 enable: function() { 369 this._setData('disabled', false); 370 }, 371 disable: function() { 372 this._setData('disabled', true); 373 }, 374 375 _trigger: function(type, event, data) { 376 var eventName = (type == this.widgetEventPrefix 377 ? type : this.widgetEventPrefix + type); 378 event = event || $.event.fix({ type: eventName, target: this.element[0] }); 379 return this.element.triggerHandler(eventName, [event, data], this.options[type]); 380 } 381 }; 382 383 $.widget.defaults = { 384 disabled: false 385 }; 386 387 388 /** Mouse Interaction Plugin **/ 389 390 $.ui.mouse = { 391 _mouseInit: function() { 392 var self = this; 393 394 this.element 395 .bind('mousedown.'+this.widgetName, function(event) { 396 return self._mouseDown(event); 397 }) 398 .bind('click.'+this.widgetName, function(event) { 399 if(self._preventClickEvent) { 400 self._preventClickEvent = false; 401 return false; 402 } 403 }); 404 405 // Prevent text selection in IE 406 if ($.browser.msie) { 407 this._mouseUnselectable = this.element.attr('unselectable'); 408 this.element.attr('unselectable', 'on'); 409 } 410 411 this.started = false; 412 }, 413 414 // TODO: make sure destroying one instance of mouse doesn't mess with 415 // other instances of mouse 416 _mouseDestroy: function() { 417 this.element.unbind('.'+this.widgetName); 418 419 // Restore text selection in IE 420 ($.browser.msie 421 && this.element.attr('unselectable', this._mouseUnselectable)); 422 }, 423 424 _mouseDown: function(event) { 425 // we may have missed mouseup (out of window) 426 (this._mouseStarted && this._mouseUp(event)); 427 428 this._mouseDownEvent = event; 429 430 var self = this, 431 btnIsLeft = (event.which == 1), 432 elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false); 433 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 434 return true; 435 } 436 437 this.mouseDelayMet = !this.options.delay; 438 if (!this.mouseDelayMet) { 439 this._mouseDelayTimer = setTimeout(function() { 440 self.mouseDelayMet = true; 441 }, this.options.delay); 442 } 443 444 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 445 this._mouseStarted = (this._mouseStart(event) !== false); 446 if (!this._mouseStarted) { 447 event.preventDefault(); 448 return true; 449 } 450 } 451 452 // these delegates are required to keep context 453 this._mouseMoveDelegate = function(event) { 454 return self._mouseMove(event); 455 }; 456 this._mouseUpDelegate = function(event) { 457 return self._mouseUp(event); 458 }; 459 $(document) 460 .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 461 .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); 462 463 // preventDefault() is used to prevent the selection of text here - 464 // however, in Safari, this causes select boxes not to be selectable 465 // anymore, so this fix is needed 466 if(!$.browser.safari) event.preventDefault(); 467 return true; 468 }, 469 470 _mouseMove: function(event) { 471 // IE mouseup check - mouseup happened when mouse was out of window 472 if ($.browser.msie && !event.button) { 473 return this._mouseUp(event); 474 } 475 476 if (this._mouseStarted) { 477 this._mouseDrag(event); 478 return event.preventDefault(); 479 } 480 481 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 482 this._mouseStarted = 483 (this._mouseStart(this._mouseDownEvent, event) !== false); 484 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 485 } 486 487 return !this._mouseStarted; 488 }, 489 490 _mouseUp: function(event) { 491 $(document) 492 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 493 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); 494 495 if (this._mouseStarted) { 496 this._mouseStarted = false; 497 this._preventClickEvent = true; 498 this._mouseStop(event); 499 } 500 501 return false; 502 }, 503 504 _mouseDistanceMet: function(event) { 505 return (Math.max( 506 Math.abs(this._mouseDownEvent.pageX - event.pageX), 507 Math.abs(this._mouseDownEvent.pageY - event.pageY) 508 ) >= this.options.distance 509 ); 510 }, 511 512 _mouseDelayMet: function(event) { 513 return this.mouseDelayMet; 514 }, 515 516 // These are placeholder methods, to be overriden by extending plugin 517 _mouseStart: function(event) {}, 518 _mouseDrag: function(event) {}, 519 _mouseStop: function(event) {}, 520 _mouseCapture: function(event) { return true; } 521 }; 522 523 $.ui.mouse.defaults = { 524 cancel: null, 525 distance: 1, 526 delay: 0 527 }; 528 529 })(jQuery); 530 /* 531 * jQuery UI Draggable 1.6 532 * 533 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 534 * Dual licensed under the MIT (MIT-LICENSE.txt) 535 * and GPL (GPL-LICENSE.txt) licenses. 536 * 537 * http://docs.jquery.com/UI/Draggables 538 * 539 * Depends: 540 * ui.core.js 541 */ 542 (function($) { 543 544 $.widget("ui.draggable", $.extend({}, $.ui.mouse, { 545 546 _init: function() { 547 548 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) 549 this.element[0].style.position = 'relative'; 550 551 (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-draggable")); 552 (this.options.disabled && this.element.addClass('ui-draggable-disabled')); 553 554 this._mouseInit(); 555 556 }, 557 558 destroy: function() { 559 if(!this.element.data('draggable')) return; 560 this.element.removeData("draggable").unbind(".draggable").removeClass('ui-draggable ui-draggable-dragging ui-draggable-disabled'); 561 this._mouseDestroy(); 562 }, 563 564 _mouseCapture: function(event) { 565 566 var o = this.options; 567 568 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) 569 return false; 570 571 //Quit if we're not on a valid handle 572 this.handle = this._getHandle(event); 573 if (!this.handle) 574 return false; 575 576 return true; 577 578 }, 579 580 _mouseStart: function(event) { 581 582 var o = this.options; 583 584 //Create and append the visible helper 585 this.helper = this._createHelper(event); 586 587 //Cache the helper size 588 this._cacheHelperProportions(); 589 590 //If ddmanager is used for droppables, set the global draggable 591 if($.ui.ddmanager) 592 $.ui.ddmanager.current = this; 593 594 /* 595 * - Position generation - 596 * This block generates everything position related - it's the core of draggables. 597 */ 598 599 //Cache the margins of the original element 600 this._cacheMargins(); 601 602 //Store the helper's css position 603 this.cssPosition = this.helper.css("position"); 604 this.scrollParent = this.helper.scrollParent(); 605 606 //The element's absolute position on the page minus margins 607 this.offset = this.element.offset(); 608 this.offset = { 609 top: this.offset.top - this.margins.top, 610 left: this.offset.left - this.margins.left 611 }; 612 613 $.extend(this.offset, { 614 click: { //Where the click happened, relative to the element 615 left: event.pageX - this.offset.left, 616 top: event.pageY - this.offset.top 617 }, 618 parent: this._getParentOffset(), 619 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 620 }); 621 622 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 623 if(o.cursorAt) 624 this._adjustOffsetFromHelper(o.cursorAt); 625 626 //Generate the original position 627 this.originalPosition = this._generatePosition(event); 628 629 //Set a containment if given in the options 630 if(o.containment) 631 this._setContainment(); 632 633 //Call plugins and callbacks 634 this._propagate("start", event); 635 636 //Recache the helper size 637 this._cacheHelperProportions(); 638 639 //Prepare the droppable offsets 640 if ($.ui.ddmanager && !o.dropBehaviour) 641 $.ui.ddmanager.prepareOffsets(this, event); 642 643 this.helper.addClass("ui-draggable-dragging"); 644 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 645 return true; 646 }, 647 648 _mouseDrag: function(event, noPropagation) { 649 650 //Compute the helpers position 651 this.position = this._generatePosition(event); 652 this.positionAbs = this._convertPositionTo("absolute"); 653 654 //Call plugins and callbacks and use the resulting position if something is returned 655 if(!noPropagation) this.position = this._propagate("drag", event) || this.position; 656 657 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 658 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 659 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 660 661 return false; 662 }, 663 664 _mouseStop: function(event) { 665 666 //If we are using droppables, inform the manager about the drop 667 var dropped = false; 668 if ($.ui.ddmanager && !this.options.dropBehaviour) 669 var dropped = $.ui.ddmanager.drop(this, event); 670 671 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))) { 672 var self = this; 673 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 674 self._propagate("stop", event); 675 self._clear(); 676 }); 677 } else { 678 this._propagate("stop", event); 679 this._clear(); 680 } 681 682 return false; 683 }, 684 685 _getHandle: function(event) { 686 687 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; 688 $(this.options.handle, this.element) 689 .find("*") 690 .andSelf() 691 .each(function() { 692 if(this == event.target) handle = true; 693 }); 694 695 return handle; 696 697 }, 698 699 _createHelper: function(event) { 700 701 var o = this.options; 702 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element); 703 704 if(!helper.parents('body').length) 705 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); 706 707 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) 708 helper.css("position", "absolute"); 709 710 return helper; 711 712 }, 713 714 _adjustOffsetFromHelper: function(obj) { 715 if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left; 716 if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 717 if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top; 718 if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 719 }, 720 721 _getParentOffset: function() { 722 723 this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); //Get the offsetParent and cache its position 724 725 if((this.offsetParent[0] == document.body && $.browser.mozilla) //Ugly FF3 fix 726 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix 727 po = { top: 0, left: 0 }; 728 729 return { 730 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 731 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 732 }; 733 734 }, 735 736 _getRelativeOffset: function() { 737 738 if(this.cssPosition == "relative") { 739 var p = this.element.position(); 740 return { 741 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 742 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 743 }; 744 } else { 745 return { top: 0, left: 0 }; 746 } 747 748 }, 749 750 _cacheMargins: function() { 751 this.margins = { 752 left: (parseInt(this.element.css("marginLeft"),10) || 0), 753 top: (parseInt(this.element.css("marginTop"),10) || 0) 754 }; 755 }, 756 757 _cacheHelperProportions: function() { 758 this.helperProportions = { 759 width: this.helper.outerWidth(), 760 height: this.helper.outerHeight() 761 }; 762 }, 763 764 _setContainment: function() { 765 766 var o = this.options; 767 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 768 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 769 0 - this.offset.relative.left - this.offset.parent.left, 770 0 - this.offset.relative.top - this.offset.parent.top, 771 $(o.containment == 'document' ? document : window).width() - this.offset.relative.left - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.element.css("marginRight"),10) || 0), 772 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.offset.relative.top - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.element.css("marginBottom"),10) || 0) 773 ]; 774 775 if(!(/^(document|window|parent)$/).test(o.containment)) { 776 var ce = $(o.containment)[0]; 777 var co = $(o.containment).offset(); 778 var over = ($(ce).css("overflow") != 'hidden'); 779 780 this.containment = [ 781 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left, 782 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top, 783 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.helperProportions.width - this.margins.left, 784 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.helperProportions.height - this.margins.top 785 ]; 786 } 787 788 }, 789 790 _convertPositionTo: function(d, pos) { 791 792 if(!pos) pos = this.position; 793 var mod = d == "absolute" ? 1 : -1; 794 var scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 795 796 return { 797 top: ( 798 pos.top // the calculated relative position 799 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 800 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 801 + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod 802 + this.margins.top * mod //Add the margin (you don't want the margin counting in intersection methods) 803 ), 804 left: ( 805 pos.left // the calculated relative position 806 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 807 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 808 + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) * mod 809 + this.margins.left * mod //Add the margin (you don't want the margin counting in intersection methods) 810 ) 811 }; 812 }, 813 814 _generatePosition: function(event) { 815 816 var o = this.options, scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 817 818 var position = { 819 top: ( 820 event.pageY // The absolute mouse position 821 - this.offset.click.top // Click offset (relative to the element) 822 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 823 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 824 + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) 825 ), 826 left: ( 827 event.pageX // The absolute mouse position 828 - this.offset.click.left // Click offset (relative to the element) 829 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 830 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 831 + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) 832 ) 833 }; 834 835 if(!this.originalPosition) return position; //If we are not dragging yet, we won't check for options 836 837 /* 838 * - Position constraining - 839 * Constrain the position to a mix of grid, containment. 840 */ 841 if(this.containment) { 842 if(position.left < this.containment[0]) position.left = this.containment[0]; 843 if(position.top < this.containment[1]) position.top = this.containment[1]; 844 if(position.left > this.containment[2]) position.left = this.containment[2]; 845 if(position.top > this.containment[3]) position.top = this.containment[3]; 846 } 847 848 if(o.grid) { 849 var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1]; 850 position.top = this.containment ? (!(top < this.containment[1] || top > this.containment[3]) ? top : (!(top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; 851 852 var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0]; 853 position.left = this.containment ? (!(left < this.containment[0] || left > this.containment[2]) ? left : (!(left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; 854 } 855 856 return position; 857 }, 858 859 _clear: function() { 860 this.helper.removeClass("ui-draggable-dragging"); 861 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); 862 //if($.ui.ddmanager) $.ui.ddmanager.current = null; 863 this.helper = null; 864 this.cancelHelperRemoval = false; 865 }, 866 867 // From now on bulk stuff - mainly helpers 868 869 _propagate: function(n, event) { 870 $.ui.plugin.call(this, n, [event, this._uiHash()]); 871 if(n == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins 872 return this.element.triggerHandler(n == "drag" ? n : "drag"+n, [event, this._uiHash()], this.options[n]); 873 }, 874 875 plugins: {}, 876 877 _uiHash: function(event) { 878 return { 879 helper: this.helper, 880 position: this.position, 881 absolutePosition: this.positionAbs, 882 options: this.options 883 }; 884 } 885 886 })); 887 888 $.extend($.ui.draggable, { 889 version: "1.6", 890 defaults: { 891 appendTo: "parent", 892 axis: false, 893 cancel: ":input", 894 connectToSortable: false, 895 containment: false, 896 cssNamespace: "ui", 897 cursor: "default", 898 cursorAt: null, 899 delay: 0, 900 distance: 1, 901 grid: false, 902 handle: false, 903 helper: "original", 904 iframeFix: false, 905 opacity: 1, 906 refreshPositions: false, 907 revert: false, 908 revertDuration: 500, 909 scope: "default", 910 scroll: true, 911 scrollSensitivity: 20, 912 scrollSpeed: 20, 913 snap: false, 914 snapMode: "both", 915 snapTolerance: 20, 916 stack: false, 917 zIndex: null 918 } 919 }); 920 921 $.ui.plugin.add("draggable", "connectToSortable", { 922 start: function(event, ui) { 923 924 var inst = $(this).data("draggable"); 925 inst.sortables = []; 926 $(ui.options.connectToSortable).each(function() { 927 // 'this' points to a string, and should therefore resolved as query, but instead, if the string is assigned to a variable, it loops through the strings properties, 928 // so we have to append '' to make it anonymous again 929 $(this+'').each(function() { 930 if($.data(this, 'sortable')) { 931 var sortable = $.data(this, 'sortable'); 932 inst.sortables.push({ 933 instance: sortable, 934 shouldRevert: sortable.options.revert 935 }); 936 sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache 937 sortable._propagate("activate", event, inst); 938 } 939 }); 940 }); 941 942 }, 943 stop: function(event, ui) { 944 945 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 946 var inst = $(this).data("draggable"); 947 948 $.each(inst.sortables, function() { 949 if(this.instance.isOver) { 950 this.instance.isOver = 0; 951 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 952 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 953 if(this.shouldRevert) this.instance.options.revert = true; //revert here 954 this.instance._mouseStop(event); 955 956 //Also propagate receive event, since the sortable is actually receiving a element 957 this.instance.element.triggerHandler("sortreceive", [event, $.extend(this.instance._ui(), { sender: inst.element })], this.instance.options["receive"]); 958 959 this.instance.options.helper = this.instance.options._helper; 960 961 if(inst.options.helper == 'original') { 962 this.instance.currentItem.css({ top: 'auto', left: 'auto' }); 963 } 964 965 } else { 966 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 967 this.instance._propagate("deactivate", event, inst); 968 } 969 970 }); 971 972 }, 973 drag: function(event, ui) { 974 975 var inst = $(this).data("draggable"), self = this; 976 977 var checkPos = function(o) { 978 var dyClick = this.offset.click.top, dxClick = this.offset.click.left; 979 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; 980 var itemHeight = o.height, itemWidth = o.width; 981 var itemTop = o.top, itemLeft = o.left; 982 983 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); 984 }; 985 986 $.each(inst.sortables, function(i) { 987 988 if(checkPos.call(inst, this.instance.containerCache)) { 989 990 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 991 if(!this.instance.isOver) { 992 this.instance.isOver = 1; 993 //Now we fake the start of dragging for the sortable instance, 994 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 995 //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) 996 this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true); 997 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 998 this.instance.options.helper = function() { return ui.helper[0]; }; 999 1000 event.target = this.instance.currentItem[0]; 1001 this.instance._mouseCapture(event, true); 1002 this.instance._mouseStart(event, true, true); 1003 1004 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 1005 this.instance.offset.click.top = inst.offset.click.top; 1006 this.instance.offset.click.left = inst.offset.click.left; 1007 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 1008 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 1009 1010 inst._propagate("toSortable", event); 1011 1012 } 1013 1014 //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 1015 if(this.instance.currentItem) this.instance._mouseDrag(event); 1016 1017 } else { 1018 1019 //If it doesn't intersect with the sortable, and it intersected before, 1020 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 1021 if(this.instance.isOver) { 1022 this.instance.isOver = 0; 1023 this.instance.cancelHelperRemoval = true; 1024 this.instance.options.revert = false; //No revert here 1025 this.instance._mouseStop(event, true); 1026 this.instance.options.helper = this.instance.options._helper; 1027 1028 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 1029 this.instance.currentItem.remove(); 1030 if(this.instance.placeholder) this.instance.placeholder.remove(); 1031 1032 inst._propagate("fromSortable", event); 1033 } 1034 1035 }; 1036 1037 }); 1038 1039 } 1040 }); 1041 1042 $.ui.plugin.add("draggable", "cursor", { 1043 start: function(event, ui) { 1044 var t = $('body'); 1045 if (t.css("cursor")) ui.options._cursor = t.css("cursor"); 1046 t.css("cursor", ui.options.cursor); 1047 }, 1048 stop: function(event, ui) { 1049 if (ui.options._cursor) $('body').css("cursor", ui.options._cursor); 1050 } 1051 }); 1052 1053 $.ui.plugin.add("draggable", "iframeFix", { 1054 start: function(event, ui) { 1055 $(ui.options.iframeFix === true ? "iframe" : ui.options.iframeFix).each(function() { 1056 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>') 1057 .css({ 1058 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1059 position: "absolute", opacity: "0.001", zIndex: 1000 1060 }) 1061 .css($(this).offset()) 1062 .appendTo("body"); 1063 }); 1064 }, 1065 stop: function(event, ui) { 1066 $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers 1067 } 1068 }); 1069 1070 $.ui.plugin.add("draggable", "opacity", { 1071 start: function(event, ui) { 1072 var t = $(ui.helper); 1073 if(t.css("opacity")) ui.options._opacity = t.css("opacity"); 1074 t.css('opacity', ui.options.opacity); 1075 }, 1076 stop: function(event, ui) { 1077 if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity); 1078 } 1079 }); 1080 1081 $.ui.plugin.add("draggable", "scroll", { 1082 start: function(event, ui) { 1083 var o = ui.options; 1084 var i = $(this).data("draggable"); 1085 1086 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); 1087 1088 }, 1089 drag: function(event, ui) { 1090 1091 var o = ui.options, scrolled = false; 1092 var i = $(this).data("draggable"); 1093 1094 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { 1095 1096 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 1097 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 1098 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) 1099 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 1100 1101 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 1102 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 1103 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) 1104 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 1105 1106 } else { 1107 1108 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 1109 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 1110 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 1111 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 1112 1113 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 1114 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 1115 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 1116 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 1117 1118 } 1119 1120 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 1121 $.ui.ddmanager.prepareOffsets(i, event); 1122 1123 1124 1125 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1126 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1127 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1128 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1129 if(scrolled !== false && i.cssPosition == 'absolute' && i.scrollParent[0] != document && $.ui.contains(i.scrollParent[0], i.offsetParent[0])) { 1130 i.offset.parent = i._getParentOffset(); 1131 1132 } 1133 1134 // This is another very weird special case that only happens for relative elements: 1135 // 1. If the css position is relative 1136 // 2. and the scroll parent is the document or similar to the offset parent 1137 // we have to refresh the relative offset during the scroll so there are no jumps 1138 if(scrolled !== false && i.cssPosition == 'relative' && !(i.scrollParent[0] != document && i.scrollParent[0] != i.offsetParent[0])) { 1139 i.offset.relative = i._getRelativeOffset(); 1140 } 1141 1142 1143 } 1144 }); 1145 1146 $.ui.plugin.add("draggable", "snap", { 1147 start: function(event, ui) { 1148 1149 var inst = $(this).data("draggable"); 1150 inst.snapElements = []; 1151 1152 $(ui.options.snap.constructor != String ? ( ui.options.snap.items || ':data(draggable)' ) : ui.options.snap).each(function() { 1153 var $t = $(this); var $o = $t.offset(); 1154 if(this != inst.element[0]) inst.snapElements.push({ 1155 item: this, 1156 width: $t.outerWidth(), height: $t.outerHeight(), 1157 top: $o.top, left: $o.left 1158 }); 1159 }); 1160 1161 }, 1162 drag: function(event, ui) { 1163 1164 var inst = $(this).data("draggable"); 1165 var d = ui.options.snapTolerance; 1166 1167 var x1 = ui.absolutePosition.left, x2 = x1 + inst.helperProportions.width, 1168 y1 = ui.absolutePosition.top, y2 = y1 + inst.helperProportions.height; 1169 1170 for (var i = inst.snapElements.length - 1; i >= 0; i--){ 1171 1172 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, 1173 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; 1174 1175 //Yes, I know, this is insane ;) 1176 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))) { 1177 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 }))); 1178 inst.snapElements[i].snapping = false; 1179 continue; 1180 } 1181 1182 if(ui.options.snapMode != 'inner') { 1183 var ts = Math.abs(t - y2) <= d; 1184 var bs = Math.abs(b - y1) <= d; 1185 var ls = Math.abs(l - x2) <= d; 1186 var rs = Math.abs(r - x1) <= d; 1187 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top; 1188 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top; 1189 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left; 1190 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left; 1191 } 1192 1193 var first = (ts || bs || ls || rs); 1194 1195 if(ui.options.snapMode != 'outer') { 1196 var ts = Math.abs(t - y1) <= d; 1197 var bs = Math.abs(b - y2) <= d; 1198 var ls = Math.abs(l - x1) <= d; 1199 var rs = Math.abs(r - x2) <= d; 1200 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top; 1201 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top; 1202 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left; 1203 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left; 1204 } 1205 1206 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) 1207 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1208 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 1209 1210 }; 1211 1212 } 1213 }); 1214 1215 $.ui.plugin.add("draggable", "stack", { 1216 start: function(event, ui) { 1217 var group = $.makeArray($(ui.options.stack.group)).sort(function(a,b) { 1218 return (parseInt($(a).css("zIndex"),10) || ui.options.stack.min) - (parseInt($(b).css("zIndex"),10) || ui.options.stack.min); 1219 }); 1220 1221 $(group).each(function(i) { 1222 this.style.zIndex = ui.options.stack.min + i; 1223 }); 1224 1225 this[0].style.zIndex = ui.options.stack.min + group.length; 1226 } 1227 }); 1228 1229 $.ui.plugin.add("draggable", "zIndex", { 1230 start: function(event, ui) { 1231 var t = $(ui.helper); 1232 if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex"); 1233 t.css('zIndex', ui.options.zIndex); 1234 }, 1235 stop: function(event, ui) { 1236 if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex); 1237 } 1238 }); 1239 1240 })(jQuery); 1241 /* 1242 * jQuery UI Droppable 1.6 1243 * 1244 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 1245 * Dual licensed under the MIT (MIT-LICENSE.txt) 1246 * and GPL (GPL-LICENSE.txt) licenses. 1247 * 1248 * http://docs.jquery.com/UI/Droppables 1249 * 1250 * Depends: 1251 * ui.core.js 1252 * ui.draggable.js 1253 */ 1254 (function($) { 1255 1256 $.widget("ui.droppable", { 1257 1258 _init: function() { 1259 1260 var o = this.options, accept = o.accept; 1261 this.isover = 0; this.isout = 1; 1262 1263 this.options.accept = this.options.accept && $.isFunction(this.options.accept) ? this.options.accept : function(d) { 1264 return d.is(accept); 1265 }; 1266 1267 //Store the droppable's proportions 1268 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 1269 1270 // Add the reference and positions to the manager 1271 $.ui.ddmanager.droppables[this.options.scope] = $.ui.ddmanager.droppables[this.options.scope] || []; 1272 $.ui.ddmanager.droppables[this.options.scope].push(this); 1273 1274 (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-droppable")); 1275 1276 }, 1277 1278 destroy: function() { 1279 var drop = $.ui.ddmanager.droppables[this.options.scope]; 1280 for ( var i = 0; i < drop.length; i++ ) 1281 if ( drop[i] == this ) 1282 drop.splice(i, 1); 1283 1284 this.element 1285 .removeClass("ui-droppable-disabled") 1286 .removeData("droppable") 1287 .unbind(".droppable"); 1288 }, 1289 1290 _setData: function(key, value) { 1291 1292 if(key == 'accept') { 1293 this.options.accept = value && $.isFunction(value) ? value : function(d) { 1294 return d.is(accept); 1295 }; 1296 } else { 1297 $.widget.prototype._setData.apply(this, arguments); 1298 } 1299 1300 }, 1301 1302 _activate: function(event) { 1303 1304 var draggable = $.ui.ddmanager.current; 1305 $.ui.plugin.call(this, 'activate', [event, this.ui(draggable)]); 1306 if(draggable) this.element.triggerHandler("dropactivate", [event, this.ui(draggable)], this.options.activate); 1307 1308 }, 1309 1310 _deactivate: function(event) { 1311 1312 var draggable = $.ui.ddmanager.current; 1313 $.ui.plugin.call(this, 'deactivate', [event, this.ui(draggable)]); 1314 if(draggable) this.element.triggerHandler("dropdeactivate", [event, this.ui(draggable)], this.options.deactivate); 1315 1316 }, 1317 1318 _over: function(event) { 1319 1320 var draggable = $.ui.ddmanager.current; 1321 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 1322 1323 if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) { 1324 $.ui.plugin.call(this, 'over', [event, this.ui(draggable)]); 1325 this.element.triggerHandler("dropover", [event, this.ui(draggable)], this.options.over); 1326 } 1327 1328 }, 1329 1330 _out: function(event) { 1331 1332 var draggable = $.ui.ddmanager.current; 1333 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 1334 1335 if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) { 1336 $.ui.plugin.call(this, 'out', [event, this.ui(draggable)]); 1337 this.element.triggerHandler("dropout", [event, this.ui(draggable)], this.options.out); 1338 } 1339 1340 }, 1341 1342 _drop: function(event,custom) { 1343 1344 var draggable = custom || $.ui.ddmanager.current; 1345 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element 1346 1347 var childrenIntersection = false; 1348 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { 1349 var inst = $.data(this, 'droppable'); 1350 if(inst.options.greedy && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) { 1351 childrenIntersection = true; return false; 1352 } 1353 }); 1354 if(childrenIntersection) return false; 1355 1356 if(this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) { 1357 $.ui.plugin.call(this, 'drop', [event, this.ui(draggable)]); 1358 this.element.triggerHandler("drop", [event, this.ui(draggable)], this.options.drop); 1359 return this.element; 1360 } 1361 1362 return false; 1363 1364 }, 1365 1366 plugins: {}, 1367 1368 ui: function(c) { 1369 return { 1370 draggable: (c.currentItem || c.element), 1371 helper: c.helper, 1372 position: c.position, 1373 absolutePosition: c.positionAbs, 1374 options: this.options, 1375 element: this.element 1376 }; 1377 } 1378 1379 }); 1380 1381 $.extend($.ui.droppable, { 1382 version: "1.6", 1383 defaults: { 1384 accept: '*', 1385 activeClass: null, 1386 cssNamespace: 'ui', 1387 greedy: false, 1388 hoverClass: null, 1389 scope: 'default', 1390 tolerance: 'intersect' 1391 } 1392 }); 1393 1394 $.ui.intersect = function(draggable, droppable, toleranceMode) { 1395 1396 if (!droppable.offset) return false; 1397 1398 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 1399 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; 1400 var l = droppable.offset.left, r = l + droppable.proportions.width, 1401 t = droppable.offset.top, b = t + droppable.proportions.height; 1402 1403 switch (toleranceMode) { 1404 case 'fit': 1405 return (l < x1 && x2 < r 1406 && t < y1 && y2 < b); 1407 break; 1408 case 'intersect': 1409 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half 1410 && x2 - (draggable.helperProportions.width / 2) < r // Left Half 1411 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half 1412 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 1413 break; 1414 case 'pointer': 1415 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), 1416 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), 1417 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); 1418 return isOver; 1419 break; 1420 case 'touch': 1421 return ( 1422 (y1 >= t && y1 <= b) || // Top edge touching 1423 (y2 >= t && y2 <= b) || // Bottom edge touching 1424 (y1 < t && y2 > b) // Surrounded vertically 1425 ) && ( 1426 (x1 >= l && x1 <= r) || // Left edge touching 1427 (x2 >= l && x2 <= r) || // Right edge touching 1428 (x1 < l && x2 > r) // Surrounded horizontally 1429 ); 1430 break; 1431 default: 1432 return false; 1433 break; 1434 } 1435 1436 }; 1437 1438 /* 1439 This manager tracks offsets of draggables and droppables 1440 */ 1441 $.ui.ddmanager = { 1442 current: null, 1443 droppables: { 'default': [] }, 1444 prepareOffsets: function(t, event) { 1445 1446 var m = $.ui.ddmanager.droppables[t.options.scope]; 1447 var type = event ? event.type : null; // workaround for #2317 1448 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); 1449 1450 droppablesLoop: for (var i = 0; i < m.length; i++) { 1451 1452 if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element,(t.currentItem || t.element)))) continue; //No disabled and non-accepted 1453 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 1454 m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue 1455 1456 m[i].offset = m[i].element.offset(); 1457 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 1458 1459 if(type == "dragstart" || type == "sortactivate") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables 1460 1461 } 1462 1463 }, 1464 drop: function(draggable, event) { 1465 1466 var dropped = false; 1467 $.each($.ui.ddmanager.droppables[draggable.options.scope], function() { 1468 1469 if(!this.options) return; 1470 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) 1471 dropped = this._drop.call(this, event); 1472 1473 if (!this.options.disabled && this.visible && this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) { 1474 this.isout = 1; this.isover = 0; 1475 this._deactivate.call(this, event); 1476 } 1477 1478 }); 1479 return dropped; 1480 1481 }, 1482 drag: function(draggable, event) { 1483 1484 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 1485 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); 1486 1487 //Run through all droppables and check their positions based on specific tolerance options 1488 1489 $.each($.ui.ddmanager.droppables[draggable.options.scope], function() { 1490 1491 if(this.options.disabled || this.greedyChild || !this.visible) return; 1492 var intersects = $.ui.intersect(draggable, this, this.options.tolerance); 1493 1494 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); 1495 if(!c) return; 1496 1497 var parentInstance; 1498 if (this.options.greedy) { 1499 var parent = this.element.parents(':data(droppable):eq(0)'); 1500 if (parent.length) { 1501 parentInstance = $.data(parent[0], 'droppable'); 1502 parentInstance.greedyChild = (c == 'isover' ? 1 : 0); 1503 } 1504 } 1505 1506 // we just moved into a greedy child 1507 if (parentInstance && c == 'isover') { 1508 parentInstance['isover'] = 0; 1509 parentInstance['isout'] = 1; 1510 parentInstance._out.call(parentInstance, event); 1511 } 1512 1513 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; 1514 this[c == "isover" ? "_over" : "_out"].call(this, event); 1515 1516 // we just moved out of a greedy child 1517 if (parentInstance && c == 'isout') { 1518 parentInstance['isout'] = 0; 1519 parentInstance['isover'] = 1; 1520 parentInstance._over.call(parentInstance, event); 1521 } 1522 }); 1523 1524 } 1525 }; 1526 1527 /* 1528 * Droppable Extensions 1529 */ 1530 1531 $.ui.plugin.add("droppable", "activeClass", { 1532 activate: function(event, ui) { 1533 $(this).addClass(ui.options.activeClass); 1534 }, 1535 deactivate: function(event, ui) { 1536 $(this).removeClass(ui.options.activeClass); 1537 }, 1538 drop: function(event, ui) { 1539 $(this).removeClass(ui.options.activeClass); 1540 } 1541 }); 1542 1543 $.ui.plugin.add("droppable", "hoverClass", { 1544 over: function(event, ui) { 1545 $(this).addClass(ui.options.hoverClass); 1546 }, 1547 out: function(event, ui) { 1548 $(this).removeClass(ui.options.hoverClass); 1549 }, 1550 drop: function(event, ui) { 1551 $(this).removeClass(ui.options.hoverClass); 1552 } 1553 }); 1554 1555 })(jQuery); 1556 /* 1557 * jQuery UI Resizable 1.6 1558 * 1559 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 1560 * Dual licensed under the MIT (MIT-LICENSE.txt) 1561 * and GPL (GPL-LICENSE.txt) licenses. 1562 * 1563 * http://docs.jquery.com/UI/Resizables 1564 * 1565 * Depends: 1566 * ui.core.js 1567 */ 1568 (function($) { 1569 1570 $.widget("ui.resizable", $.extend({}, $.ui.mouse, { 1571 1572 _init: function() { 1573 1574 var self = this, o = this.options; 1575 1576 var elpos = this.element.css('position'); 1577 1578 this.originalElement = this.element; 1579 1580 // simulate .ui-resizable { position: relative; } 1581 this.element.addClass("ui-resizable").css({ position: /static/.test(elpos) ? 'relative' : elpos }); 1582 1583 $.extend(o, { 1584 _aspectRatio: !!(o.aspectRatio), 1585 helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null, 1586 knobHandles: o.knobHandles === true ? 'ui-resizable-knob-handle' : o.knobHandles 1587 }); 1588 1589 //Default Theme 1590 var aBorder = '1px solid #DEDEDE'; 1591 1592 o.defaultTheme = { 1593 'ui-resizable': { display: 'block' }, 1594 'ui-resizable-handle': { position: 'absolute', background: '#F2F2F2', fontSize: '0.1px' }, 1595 'ui-resizable-n': { cursor: 'n-resize', height: '4px', left: '0px', right: '0px', borderTop: aBorder }, 1596 'ui-resizable-s': { cursor: 's-resize', height: '4px', left: '0px', right: '0px', borderBottom: aBorder }, 1597 'ui-resizable-e': { cursor: 'e-resize', width: '4px', top: '0px', bottom: '0px', borderRight: aBorder }, 1598 'ui-resizable-w': { cursor: 'w-resize', width: '4px', top: '0px', bottom: '0px', borderLeft: aBorder }, 1599 'ui-resizable-se': { cursor: 'se-resize', width: '4px', height: '4px', borderRight: aBorder, borderBottom: aBorder }, 1600 'ui-resizable-sw': { cursor: 'sw-resize', width: '4px', height: '4px', borderBottom: aBorder, borderLeft: aBorder }, 1601 'ui-resizable-ne': { cursor: 'ne-resize', width: '4px', height: '4px', borderRight: aBorder, borderTop: aBorder }, 1602 'ui-resizable-nw': { cursor: 'nw-resize', width: '4px', height: '4px', borderLeft: aBorder, borderTop: aBorder } 1603 }; 1604 1605 o.knobTheme = { 1606 'ui-resizable-handle': { background: '#F2F2F2', border: '1px solid #808080', height: '8px', width: '8px' }, 1607 'ui-resizable-n': { cursor: 'n-resize', top: '0px', left: '45%' }, 1608 'ui-resizable-s': { cursor: 's-resize', bottom: '0px', left: '45%' }, 1609 'ui-resizable-e': { cursor: 'e-resize', right: '0px', top: '45%' }, 1610 'ui-resizable-w': { cursor: 'w-resize', left: '0px', top: '45%' }, 1611 'ui-resizable-se': { cursor: 'se-resize', right: '0px', bottom: '0px' }, 1612 'ui-resizable-sw': { cursor: 'sw-resize', left: '0px', bottom: '0px' }, 1613 'ui-resizable-nw': { cursor: 'nw-resize', left: '0px', top: '0px' }, 1614 'ui-resizable-ne': { cursor: 'ne-resize', right: '0px', top: '0px' } 1615 }; 1616 1617 o._nodeName = this.element[0].nodeName; 1618 1619 //Wrap the element if it cannot hold child nodes 1620 if(o._nodeName.match(/canvas|textarea|input|select|button|img/i)) { 1621 var el = this.element; 1622 1623 //Opera fixing relative position 1624 if (/relative/.test(el.css('position')) && $.browser.opera) 1625 el.css({ position: 'relative', top: 'auto', left: 'auto' }); 1626 1627 //Create a wrapper element and set the wrapper to the new current internal element 1628 el.wrap( 1629 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css( { 1630 position: el.css('position'), 1631 width: el.outerWidth(), 1632 height: el.outerHeight(), 1633 top: el.css('top'), 1634 left: el.css('left') 1635 }) 1636 ); 1637 1638 var oel = this.element; this.element = this.element.parent(); 1639 1640 // store instance on wrapper 1641 this.element.data('resizable', this); 1642 1643 //Move margins to the wrapper 1644 this.element.css({ marginLeft: oel.css("marginLeft"), marginTop: oel.css("marginTop"), 1645 marginRight: oel.css("marginRight"), marginBottom: oel.css("marginBottom") 1646 }); 1647 1648 oel.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 1649 1650 //Prevent Safari textarea resize 1651 if ($.browser.safari && o.preventDefault) oel.css('resize', 'none'); 1652 1653 o.proportionallyResize = oel.css({ position: 'static', zoom: 1, display: 'block' }); 1654 1655 // avoid IE jump 1656 this.element.css({ margin: oel.css('margin') }); 1657 1658 // fix handlers offset 1659 this._proportionallyResize(); 1660 } 1661 1662 if(!o.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' }; 1663 if(o.handles.constructor == String) { 1664 1665 o.zIndex = o.zIndex || 1000; 1666 1667 if(o.handles == 'all') o.handles = 'n,e,s,w,se,sw,ne,nw'; 1668 1669 var n = o.handles.split(","); o.handles = {}; 1670 1671 // insertions are applied when don't have theme loaded 1672 var insertionsDefault = { 1673 handle: 'position: absolute; display: none; overflow:hidden;', 1674 n: 'top: 0pt; width:100%;', 1675 e: 'right: 0pt; height:100%;', 1676 s: 'bottom: 0pt; width:100%;', 1677 w: 'left: 0pt; height:100%;', 1678 se: 'bottom: 0pt; right: 0px;', 1679 sw: 'bottom: 0pt; left: 0px;', 1680 ne: 'top: 0pt; right: 0px;', 1681 nw: 'top: 0pt; left: 0px;' 1682 }; 1683 1684 for(var i = 0; i < n.length; i++) { 1685 var handle = $.trim(n[i]), dt = o.defaultTheme, hname = 'ui-resizable-'+handle, loadDefault = !$.ui.css(hname) && !o.knobHandles, userKnobClass = $.ui.css('ui-resizable-knob-handle'), 1686 allDefTheme = $.extend(dt[hname], dt['ui-resizable-handle']), allKnobTheme = $.extend(o.knobTheme[hname], !userKnobClass ? o.knobTheme['ui-resizable-handle'] : {}); 1687 1688 // increase zIndex of sw, se, ne, nw axis 1689 var applyZIndex = /sw|se|ne|nw/.test(handle) ? { zIndex: ++o.zIndex } : {}; 1690 1691 var defCss = (loadDefault ? insertionsDefault[handle] : ''), 1692 axis = $(['<div class="ui-resizable-handle ', hname, '" style="', defCss, insertionsDefault.handle, '"></div>'].join('')).css( applyZIndex ); 1693 o.handles[handle] = '.ui-resizable-'+handle; 1694 1695 this.element.append( 1696 //Theme detection, if not loaded, load o.defaultTheme 1697 axis.css( loadDefault ? allDefTheme : {} ) 1698 // Load the knobHandle css, fix width, height, top, left... 1699 .css( o.knobHandles ? allKnobTheme : {} ).addClass(o.knobHandles ? 'ui-resizable-knob-handle' : '').addClass(o.knobHandles) 1700 ); 1701 } 1702 1703 if (o.knobHandles) this.element.addClass('ui-resizable-knob').css( !$.ui.css('ui-resizable-knob') ? { /*border: '1px #fff dashed'*/ } : {} ); 1704 } 1705 1706 this._renderAxis = function(target) { 1707 target = target || this.element; 1708 1709 for(var i in o.handles) { 1710 if(o.handles[i].constructor == String) 1711 o.handles[i] = $(o.handles[i], this.element).show(); 1712 1713 if (o.transparent) 1714 o.handles[i].css({opacity:0}); 1715 1716 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 1717 if (this.element.is('.ui-wrapper') && 1718 o._nodeName.match(/textarea|input|select|button/i)) { 1719 1720 var axis = $(o.handles[i], this.element), padWrapper = 0; 1721 1722 //Checking the correct pad and border 1723 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 1724 1725 //The padding type i have to apply... 1726 var padPos = [ 'padding', 1727 /ne|nw|n/.test(i) ? 'Top' : 1728 /se|sw|s/.test(i) ? 'Bottom' : 1729 /^e$/.test(i) ? 'Right' : 'Left' ].join(""); 1730 1731 if (!o.transparent) 1732 target.css(padPos, padWrapper); 1733 1734 this._proportionallyResize(); 1735 } 1736 if(!$(o.handles[i]).length) continue; 1737 } 1738 }; 1739 1740 this._renderAxis(this.element); 1741 o._handles = $('.ui-resizable-handle', self.element); 1742 1743 if (o.disableSelection) 1744 o._handles.disableSelection(); 1745 1746 //Matching axis name 1747 o._handles.mouseover(function() { 1748 if (!o.resizing) { 1749 if (this.className) 1750 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 1751 //Axis, default = se 1752 self.axis = o.axis = axis && axis[1] ? axis[1] : 'se'; 1753 } 1754 }); 1755 1756 //If we want to auto hide the elements 1757 if (o.autoHide) { 1758 o._handles.hide(); 1759 $(self.element).addClass("ui-resizable-autohide").hover(function() { 1760 $(this).removeClass("ui-resizable-autohide"); 1761 o._handles.show(); 1762 }, 1763 function(){ 1764 if (!o.resizing) { 1765 $(this).addClass("ui-resizable-autohide"); 1766 o._handles.hide(); 1767 } 1768 }); 1769 } 1770 1771 this._mouseInit(); 1772 }, 1773 1774 destroy: function() { 1775 var el = this.element, wrapped = el.children(".ui-resizable").get(0); 1776 1777 this._mouseDestroy(); 1778 1779 var _destroy = function(exp) { 1780 $(exp).removeClass("ui-resizable ui-resizable-disabled") 1781 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); 1782 }; 1783 1784 _destroy(el); 1785 1786 if (el.is('.ui-wrapper') && wrapped) { 1787 el.parent().append( 1788 $(wrapped).css({ 1789 position: el.css('position'), 1790 width: el.outerWidth(), 1791 height: el.outerHeight(), 1792 top: el.css('top'), 1793 left: el.css('left') 1794 }) 1795 ).end().remove(); 1796 1797 _destroy(wrapped); 1798 } 1799 }, 1800 1801 _mouseCapture: function(event) { 1802 1803 if(this.options.disabled) return false; 1804 1805 var handle = false; 1806 for(var i in this.options.handles) { 1807 if($(this.options.handles[i])[0] == event.target) handle = true; 1808 } 1809 if (!handle) return false; 1810 1811 return true; 1812 1813 }, 1814 1815 _mouseStart: function(event) { 1816 1817 var o = this.options, iniPos = this.element.position(), el = this.element, 1818 ie6 = $.browser.msie && $.browser.version < 7; 1819 o.resizing = true; 1820 o.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; 1821 1822 // bugfix #1749 1823 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { 1824 1825 // sOffset decides if document scrollOffset will be added to the top/left of the resizable element 1826 var sOffset = $.browser.msie && !o.containment && (/absolute/).test(el.css('position')) && !(/relative/).test(el.parent().css('position')); 1827 var dscrollt = sOffset ? this.documentScroll.top : 0, dscrolll = sOffset ? this.documentScroll.left : 0; 1828 1829 el.css({ position: 'absolute', top: (iniPos.top + dscrollt), left: (iniPos.left + dscrolll) }); 1830 } 1831 1832 //Opera fixing relative position 1833 if ($.browser.opera && (/relative/).test(el.css('position'))) 1834 el.css({ position: 'relative', top: 'auto', left: 'auto' }); 1835 1836 this._renderProxy(); 1837 1838 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); 1839 1840 if (o.containment) { 1841 curleft += $(o.containment).scrollLeft()||0; 1842 curtop += $(o.containment).scrollTop()||0; 1843 } 1844 1845 //Store needed variables 1846 this.offset = this.helper.offset(); 1847 this.position = { left: curleft, top: curtop }; 1848 this.size = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 1849 this.originalSize = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 1850 this.originalPosition = { left: curleft, top: curtop }; 1851 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 1852 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 1853 1854 //Aspect Ratio 1855 o.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height)||1); 1856 1857 if (o.preserveCursor) { 1858 var cursor = $('.ui-resizable-' + this.axis).css('cursor'); 1859 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); 1860 } 1861 1862 this._propagate("start", event); 1863 return true; 1864 }, 1865 1866 _mouseDrag: function(event) { 1867 1868 //Increase performance, avoid regex 1869 var el = this.helper, o = this.options, props = {}, 1870 self = this, smp = this.originalMousePosition, a = this.axis; 1871 1872 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; 1873 var trigger = this._change[a]; 1874 if (!trigger) return false; 1875 1876 // Calculate the attrs that will be change 1877 var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; 1878 1879 if (o._aspectRatio || event.shiftKey) 1880 data = this._updateRatio(data, event); 1881 1882 data = this._respectSize(data, event); 1883 1884 // plugins callbacks need to be called first 1885 this._propagate("resize", event); 1886 1887 el.css({ 1888 top: this.position.top + "px", left: this.position.left + "px", 1889 width: this.size.width + "px", height: this.size.height + "px" 1890 }); 1891 1892 if (!o.helper && o.proportionallyResize) 1893 this._proportionallyResize(); 1894 1895 this._updateCache(data); 1896 1897 // calling the user callback at the end 1898 this.element.triggerHandler("resize", [event, this.ui()], this.options["resize"]); 1899 1900 return false; 1901 }, 1902 1903 _mouseStop: function(event) { 1904 1905 this.options.resizing = false; 1906 var o = this.options, self = this; 1907 1908 if(o.helper) { 1909 var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName), 1910 soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, 1911 soffsetw = ista ? 0 : self.sizeDiff.width; 1912 1913 var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, 1914 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, 1915 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; 1916 1917 if (!o.animate) 1918 this.element.css($.extend(s, { top: top, left: left })); 1919 1920 if (o.helper && !o.animate) this._proportionallyResize(); 1921 } 1922 1923 if (o.preserveCursor) 1924 $('body').css('cursor', 'auto'); 1925 1926 this._propagate("stop", event); 1927 1928 if (o.helper) this.helper.remove(); 1929 1930 return false; 1931 }, 1932 1933 _updateCache: function(data) { 1934 var o = this.options; 1935 this.offset = this.helper.offset(); 1936 if (data.left) this.position.left = data.left; 1937 if (data.top) this.position.top = data.top; 1938 if (data.height) this.size.height = data.height; 1939 if (data.width) this.size.width = data.width; 1940 }, 1941 1942 _updateRatio: function(data, event) { 1943 1944 var o = this.options, cpos = this.position, csize = this.size, a = this.axis; 1945 1946 if (data.height) data.width = (csize.height * o.aspectRatio); 1947 else if (data.width) data.height = (csize.width / o.aspectRatio); 1948 1949 if (a == 'sw') { 1950 data.left = cpos.left + (csize.width - data.width); 1951 data.top = null; 1952 } 1953 if (a == 'nw') { 1954 data.top = cpos.top + (csize.height - data.height); 1955 data.left = cpos.left + (csize.width - data.width); 1956 } 1957 1958 return data; 1959 }, 1960 1961 _respectSize: function(data, event) { 1962 1963 var el = this.helper, o = this.options, pRatio = o._aspectRatio || event.shiftKey, a = this.axis, 1964 ismaxw = data.width && o.maxWidth && o.maxWidth < data.width, ismaxh = data.height && o.maxHeight && o.maxHeight < data.height, 1965 isminw = data.width && o.minWidth && o.minWidth > data.width, isminh = data.height && o.minHeight && o.minHeight > data.height; 1966 1967 if (isminw) data.width = o.minWidth; 1968 if (isminh) data.height = o.minHeight; 1969 if (ismaxw) data.width = o.maxWidth; 1970 if (ismaxh) data.height = o.maxHeight; 1971 1972 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; 1973 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 1974 1975 if (isminw && cw) data.left = dw - o.minWidth; 1976 if (ismaxw && cw) data.left = dw - o.maxWidth; 1977 if (isminh && ch) data.top = dh - o.minHeight; 1978 if (ismaxh && ch) data.top = dh - o.maxHeight; 1979 1980 // fixing jump error on top/left - bug #2330 1981 var isNotwh = !data.width && !data.height; 1982 if (isNotwh && !data.left && data.top) data.top = null; 1983 else if (isNotwh && !data.top && data.left) data.left = null; 1984 1985 return data; 1986 }, 1987 1988 _proportionallyResize: function() { 1989 var o = this.options; 1990 if (!o.proportionallyResize) return; 1991 var prel = o.proportionallyResize, el = this.helper || this.element; 1992 1993 if (!o.borderDif) { 1994 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], 1995 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; 1996 1997 o.borderDif = $.map(b, function(v, i) { 1998 var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; 1999 return border + padding; 2000 }); 2001 } 2002 prel.css({ 2003 height: (el.height() - o.borderDif[0] - o.borderDif[2]) + "px", 2004 width: (el.width() - o.borderDif[1] - o.borderDif[3]) + "px" 2005 }); 2006 }, 2007 2008 _renderProxy: function() { 2009 var el = this.element, o = this.options; 2010 this.elementOffset = el.offset(); 2011 2012 if(o.helper) { 2013 this.helper = this.helper || $('<div style="overflow:hidden;"></div>'); 2014 2015 // fix ie6 offset 2016 var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0), 2017 pxyoffset = ( ie6 ? 2 : -1 ); 2018 2019 this.helper.addClass(o.helper).css({ 2020 width: el.outerWidth() + pxyoffset, 2021 height: el.outerHeight() + pxyoffset, 2022 position: 'absolute', 2023 left: this.elementOffset.left - ie6offset +'px', 2024 top: this.elementOffset.top - ie6offset +'px', 2025 zIndex: ++o.zIndex 2026 }); 2027 2028 this.helper.appendTo("body"); 2029 2030 if (o.disableSelection) 2031 this.helper.disableSelection(); 2032 2033 } else { 2034 this.helper = el; 2035 } 2036 }, 2037 2038 _change: { 2039 e: function(event, dx, dy) { 2040 return { width: this.originalSize.width + dx }; 2041 }, 2042 w: function(event, dx, dy) { 2043 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 2044 return { left: sp.left + dx, width: cs.width - dx }; 2045 }, 2046 n: function(event, dx, dy) { 2047 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 2048 return { top: sp.top + dy, height: cs.height - dy }; 2049 }, 2050 s: function(event, dx, dy) { 2051 return { height: this.originalSize.height + dy }; 2052 }, 2053 se: function(event, dx, dy) { 2054 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2055 }, 2056 sw: function(event, dx, dy) { 2057 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2058 }, 2059 ne: function(event, dx, dy) { 2060 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2061 }, 2062 nw: function(event, dx, dy) { 2063 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2064 } 2065 }, 2066 2067 _propagate: function(n, event) { 2068 $.ui.plugin.call(this, n, [event, this.ui()]); 2069 if (n != "resize") this.element.triggerHandler(["resize", n].join(""), [event, this.ui()], this.options[n]); 2070 }, 2071 2072 plugins: {}, 2073 2074 ui: function() { 2075 return { 2076 originalElement: this.originalElement, 2077 element: this.element, 2078 helper: this.helper, 2079 position: this.position, 2080 size: this.size, 2081 options: this.options, 2082 originalSize: this.originalSize, 2083 originalPosition: this.originalPosition 2084 }; 2085 } 2086 2087 })); 2088 2089 $.extend($.ui.resizable, { 2090 version: "1.6", 2091 defaults: { 2092 alsoResize: false, 2093 animate: false, 2094 animateDuration: "slow", 2095 animateEasing: "swing", 2096 aspectRatio: false, 2097 autoHide: false, 2098 cancel: ":input", 2099 containment: false, 2100 disableSelection: true, 2101 distance: 1, 2102 delay: 0, 2103 ghost: false, 2104 grid: false, 2105 knobHandles: false, 2106 maxHeight: null, 2107 maxWidth: null, 2108 minHeight: 10, 2109 minWidth: 10, 2110 preserveCursor: true, 2111 preventDefault: true, 2112 proportionallyResize: false, 2113 transparent: false 2114 } 2115 }); 2116 2117 /* 2118 * Resizable Extensions 2119 */ 2120 2121 $.ui.plugin.add("resizable", "alsoResize", { 2122 2123 start: function(event, ui) { 2124 var o = ui.options, self = $(this).data("resizable"), 2125 2126 _store = function(exp) { 2127 $(exp).each(function() { 2128 $(this).data("resizable-alsoresize", { 2129 width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10), 2130 left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10) 2131 }); 2132 }); 2133 }; 2134 2135 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { 2136 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 2137 else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); } 2138 }else{ 2139 _store(o.alsoResize); 2140 } 2141 }, 2142 2143 resize: function(event, ui){ 2144 var o = ui.options, self = $(this).data("resizable"), os = self.originalSize, op = self.originalPosition; 2145 2146 var delta = { 2147 height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0, 2148 top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 2149 }, 2150 2151 _alsoResize = function(exp, c) { 2152 $(exp).each(function() { 2153 var start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left']; 2154 2155 $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) { 2156 var sum = (start[prop]||0) + (delta[prop]||0); 2157 if (sum && sum >= 0) 2158 style[prop] = sum || null; 2159 }); 2160 $(this).css(style); 2161 }); 2162 }; 2163 2164 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { 2165 $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); }); 2166 }else{ 2167 _alsoResize(o.alsoResize); 2168 } 2169 }, 2170 2171 stop: function(event, ui){ 2172 $(this).removeData("resizable-alsoresize-start"); 2173 } 2174 }); 2175 2176 $.ui.plugin.add("resizable", "animate", { 2177 2178 stop: function(event, ui) { 2179 var o = ui.options, self = $(this).data("resizable"); 2180 2181 var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName), 2182 soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, 2183 soffsetw = ista ? 0 : self.sizeDiff.width; 2184 2185 var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, 2186 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, 2187 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; 2188 2189 self.element.animate( 2190 $.extend(style, top && left ? { top: top, left: left } : {}), { 2191 duration: o.animateDuration, 2192 easing: o.animateEasing, 2193 step: function() { 2194 2195 var data = { 2196 width: parseInt(self.element.css('width'), 10), 2197 height: parseInt(self.element.css('height'), 10), 2198 top: parseInt(self.element.css('top'), 10), 2199 left: parseInt(self.element.css('left'), 10) 2200 }; 2201 2202 if (pr) pr.css({ width: data.width, height: data.height }); 2203 2204 // propagating resize, and updating values for each animation step 2205 self._updateCache(data); 2206 self._propagate("animate", event); 2207 2208 } 2209 } 2210 ); 2211 } 2212 2213 }); 2214 2215 $.ui.plugin.add("resizable", "containment", { 2216 2217 start: function(event, ui) { 2218 var o = ui.options, self = $(this).data("resizable"), el = self.element; 2219 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 2220 if (!ce) return; 2221 2222 self.containerElement = $(ce); 2223 2224 if (/document/.test(oc) || oc == document) { 2225 self.containerOffset = { left: 0, top: 0 }; 2226 self.containerPosition = { left: 0, top: 0 }; 2227 2228 self.parentData = { 2229 element: $(document), left: 0, top: 0, 2230 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 2231 }; 2232 } 2233 2234 // i'm a node, so compute top, left, right, bottom 2235 else{ 2236 var element = $(ce), p = []; 2237 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 2238 2239 self.containerOffset = element.offset(); 2240 self.containerPosition = element.position(); 2241 self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 2242 2243 var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width, 2244 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 2245 2246 self.parentData = { 2247 element: ce, left: co.left, top: co.top, width: width, height: height 2248 }; 2249 } 2250 }, 2251 2252 resize: function(event, ui) { 2253 var o = ui.options, self = $(this).data("resizable"), 2254 ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position, 2255 pRatio = o._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement; 2256 2257 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; 2258 2259 if (cp.left < (o.helper ? co.left : 0)) { 2260 self.size.width = self.size.width + (o.helper ? (self.position.left - co.left) : (self.position.left - cop.left)); 2261 if (pRatio) self.size.height = self.size.width / o.aspectRatio; 2262 self.position.left = o.helper ? co.left : 0; 2263 } 2264 2265 if (cp.top < (o.helper ? co.top : 0)) { 2266 self.size.height = self.size.height + (o.helper ? (self.position.top - co.top) : self.position.top); 2267 if (pRatio) self.size.width = self.size.height * o.aspectRatio; 2268 self.position.top = o.helper ? co.top : 0; 2269 } 2270 2271 self.offset.left = self.parentData.left+self.position.left; 2272 self.offset.top = self.parentData.top+self.position.top; 2273 2274 var woset = Math.abs( (o.helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ), 2275 hoset = Math.abs( (o.helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height ); 2276 2277 var isParent = self.containerElement.get(0) == self.element.parent().get(0), 2278 isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position')); 2279 2280 if(isParent && isOffsetRelative) woset -= self.parentData.left; 2281 2282 if (woset + self.size.width >= self.parentData.width) { 2283 self.size.width = self.parentData.width - woset; 2284 if (pRatio) self.size.height = self.size.width / o.aspectRatio; 2285 } 2286 2287 if (hoset + self.size.height >= self.parentData.height) { 2288 self.size.height = self.parentData.height - hoset; 2289 if (pRatio) self.size.width = self.size.height * o.aspectRatio; 2290 } 2291 }, 2292 2293 stop: function(event, ui){ 2294 var o = ui.options, self = $(this).data("resizable"), cp = self.position, 2295 co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement; 2296 2297 var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height; 2298 2299 if (o.helper && !o.animate && (/relative/).test(ce.css('position'))) 2300 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 2301 2302 if (o.helper && !o.animate && (/static/).test(ce.css('position'))) 2303 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 2304 2305 } 2306 }); 2307 2308 $.ui.plugin.add("resizable", "ghost", { 2309 2310 start: function(event, ui) { 2311 var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize, cs = self.size; 2312 2313 if (!pr) self.ghost = self.element.clone(); 2314 else self.ghost = pr.clone(); 2315 2316 self.ghost.css( 2317 { opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 } 2318 ) 2319 .addClass('ui-resizable-ghost').addClass(typeof o.ghost == 'string' ? o.ghost : ''); 2320 2321 self.ghost.appendTo(self.helper); 2322 2323 }, 2324 2325 resize: function(event, ui){ 2326 var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize; 2327 2328 if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width }); 2329 2330 }, 2331 2332 stop: function(event, ui){ 2333 var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize; 2334 if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0)); 2335 } 2336 2337 }); 2338 2339 $.ui.plugin.add("resizable", "grid", { 2340 2341 resize: function(event, ui) { 2342 var o = ui.options, self = $(this).data("resizable"), cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey; 2343 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; 2344 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); 2345 2346 if (/^(se|s|e)$/.test(a)) { 2347 self.size.width = os.width + ox; 2348 self.size.height = os.height + oy; 2349 } 2350 else if (/^(ne)$/.test(a)) { 2351 self.size.width = os.width + ox; 2352 self.size.height = os.height + oy; 2353 self.position.top = op.top - oy; 2354 } 2355 else if (/^(sw)$/.test(a)) { 2356 self.size.width = os.width + ox; 2357 self.size.height = os.height + oy; 2358 self.position.left = op.left - ox; 2359 } 2360 else { 2361 self.size.width = os.width + ox; 2362 self.size.height = os.height + oy; 2363 self.position.top = op.top - oy; 2364 self.position.left = op.left - ox; 2365 } 2366 } 2367 2368 }); 2369 2370 var num = function(v) { 2371 return parseInt(v, 10) || 0; 2372 }; 2373 2374 })(jQuery); 2375 /* 2376 * jQuery UI Selectable 1.6 2377 * 2378 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 2379 * Dual licensed under the MIT (MIT-LICENSE.txt) 2380 * and GPL (GPL-LICENSE.txt) licenses. 2381 * 2382 * http://docs.jquery.com/UI/Selectables 2383 * 2384 * Depends: 2385 * ui.core.js 2386 */ 2387 (function($) { 2388 2389 $.widget("ui.selectable", $.extend({}, $.ui.mouse, { 2390 2391 _init: function() { 2392 var self = this; 2393 2394 this.element.addClass("ui-selectable"); 2395 2396 this.dragged = false; 2397 2398 // cache selectee children based on filter 2399 var selectees; 2400 this.refresh = function() { 2401 selectees = $(self.options.filter, self.element[0]); 2402 selectees.each(function() { 2403 var $this = $(this); 2404 var pos = $this.offset(); 2405 $.data(this, "selectable-item", { 2406 element: this, 2407 $element: $this, 2408 left: pos.left, 2409 top: pos.top, 2410 right: pos.left + $this.width(), 2411 bottom: pos.top + $this.height(), 2412 startselected: false, 2413 selected: $this.hasClass('ui-selected'), 2414 selecting: $this.hasClass('ui-selecting'), 2415 unselecting: $this.hasClass('ui-unselecting') 2416 }); 2417 }); 2418 }; 2419 this.refresh(); 2420 2421 this.selectees = selectees.addClass("ui-selectee"); 2422 2423 this._mouseInit(); 2424 2425 this.helper = $(document.createElement('div')) 2426 .css({border:'1px dotted black'}) 2427 .addClass("ui-selectable-helper"); 2428 }, 2429 2430 destroy: function() { 2431 this.element 2432 .removeClass("ui-selectable ui-selectable-disabled") 2433 .removeData("selectable") 2434 .unbind(".selectable"); 2435 this._mouseDestroy(); 2436 }, 2437 2438 _mouseStart: function(event) { 2439 var self = this; 2440 2441 this.opos = [event.pageX, event.pageY]; 2442 2443 if (this.options.disabled) 2444 return; 2445 2446 var options = this.options; 2447 2448 this.selectees = $(options.filter, this.element[0]); 2449 2450 // selectable START callback 2451 this.element.triggerHandler("selectablestart", [event, { 2452 "selectable": this.element[0], 2453 "options": options 2454 }], options.start); 2455 2456 $('body').append(this.helper); 2457 // position helper (lasso) 2458 this.helper.css({ 2459 "z-index": 100, 2460 "position": "absolute", 2461 "left": event.clientX, 2462 "top": event.clientY, 2463 "width": 0, 2464 "height": 0 2465 }); 2466 2467 if (options.autoRefresh) { 2468 this.refresh(); 2469 } 2470 2471 this.selectees.filter('.ui-selected').each(function() { 2472 var selectee = $.data(this, "selectable-item"); 2473 selectee.startselected = true; 2474 if (!event.metaKey) { 2475 selectee.$element.removeClass('ui-selected'); 2476 selectee.selected = false; 2477 selectee.$element.addClass('ui-unselecting'); 2478 selectee.unselecting = true; 2479 // selectable UNSELECTING callback 2480 self.element.triggerHandler("selectableunselecting", [event, { 2481 selectable: self.element[0], 2482 unselecting: selectee.element, 2483 options: options 2484 }], options.unselecting); 2485 } 2486 }); 2487 2488 var isSelectee = false; 2489 $(event.target).parents().andSelf().each(function() { 2490 if($.data(this, "selectable-item")) isSelectee = true; 2491 }); 2492 return this.options.keyboard ? !isSelectee : true; 2493 }, 2494 2495 _mouseDrag: function(event) { 2496 var self = this; 2497 this.dragged = true; 2498 2499 if (this.options.disabled) 2500 return; 2501 2502 var options = this.options; 2503 2504 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; 2505 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } 2506 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } 2507 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 2508 2509 this.selectees.each(function() { 2510 var selectee = $.data(this, "selectable-item"); 2511 //prevent helper from being selected if appendTo: selectable 2512 if (!selectee || selectee.element == self.element[0]) 2513 return; 2514 var hit = false; 2515 if (options.tolerance == 'touch') { 2516 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 2517 } else if (options.tolerance == 'fit') { 2518 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 2519 } 2520 2521 if (hit) { 2522 // SELECT 2523 if (selectee.selected) { 2524 selectee.$element.removeClass('ui-selected'); 2525 selectee.selected = false; 2526 } 2527 if (selectee.unselecting) { 2528 selectee.$element.removeClass('ui-unselecting'); 2529 selectee.unselecting = false; 2530 } 2531 if (!selectee.selecting) { 2532 selectee.$element.addClass('ui-selecting'); 2533 selectee.selecting = true; 2534 // selectable SELECTING callback 2535 self.element.triggerHandler("selectableselecting", [event, { 2536 selectable: self.element[0], 2537 selecting: selectee.element, 2538 options: options 2539 }], options.selecting); 2540 } 2541 } else { 2542 // UNSELECT 2543 if (selectee.selecting) { 2544 if (event.metaKey && selectee.startselected) { 2545 selectee.$element.removeClass('ui-selecting'); 2546 selectee.selecting = false; 2547 selectee.$element.addClass('ui-selected'); 2548 selectee.selected = true; 2549 } else { 2550 selectee.$element.removeClass('ui-selecting'); 2551 selectee.selecting = false; 2552 if (selectee.startselected) { 2553 selectee.$element.addClass('ui-unselecting'); 2554 selectee.unselecting = true; 2555 } 2556 // selectable UNSELECTING callback 2557 self.element.triggerHandler("selectableunselecting", [event, { 2558 selectable: self.element[0], 2559 unselecting: selectee.element, 2560 options: options 2561 }], options.unselecting); 2562 } 2563 } 2564 if (selectee.selected) { 2565 if (!event.metaKey && !selectee.startselected) { 2566 selectee.$element.removeClass('ui-selected'); 2567 selectee.selected = false; 2568 2569 selectee.$element.addClass('ui-unselecting'); 2570 selectee.unselecting = true; 2571 // selectable UNSELECTING callback 2572 self.element.triggerHandler("selectableunselecting", [event, { 2573 selectable: self.element[0], 2574 unselecting: selectee.element, 2575 options: options 2576 }], options.unselecting); 2577 } 2578 } 2579 } 2580 }); 2581 2582 return false; 2583 }, 2584 2585 _mouseStop: function(event) { 2586 var self = this; 2587 2588 this.dragged = false; 2589 2590 var options = this.options; 2591 2592 $('.ui-unselecting', this.element[0]).each(function() { 2593 var selectee = $.data(this, "selectable-item"); 2594 selectee.$element.removeClass('ui-unselecting'); 2595 selectee.unselecting = false; 2596 selectee.startselected = false; 2597 self.element.triggerHandler("selectableunselected", [event, { 2598 selectable: self.element[0], 2599 unselected: selectee.element, 2600 options: options 2601 }], options.unselected); 2602 }); 2603 $('.ui-selecting', this.element[0]).each(function() { 2604 var selectee = $.data(this, "selectable-item"); 2605 selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); 2606 selectee.selecting = false; 2607 selectee.selected = true; 2608 selectee.startselected = true; 2609 self.element.triggerHandler("selectableselected", [event, { 2610 selectable: self.element[0], 2611 selected: selectee.element, 2612 options: options 2613 }], options.selected); 2614 }); 2615 this.element.triggerHandler("selectablestop", [event, { 2616 selectable: self.element[0], 2617 options: this.options 2618 }], this.options.stop); 2619 2620 this.helper.remove(); 2621 2622 return false; 2623 } 2624 2625 })); 2626 2627 $.extend($.ui.selectable, { 2628 version: "1.6", 2629 defaults: { 2630 appendTo: 'body', 2631 autoRefresh: true, 2632 cancel: ":input", 2633 delay: 0, 2634 distance: 1, 2635 filter: '*', 2636 tolerance: 'touch' 2637 } 2638 }); 2639 2640 })(jQuery); 2641 /* 2642 * jQuery UI Sortable 1.6 2643 * 2644 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 2645 * Dual licensed under the MIT (MIT-LICENSE.txt) 2646 * and GPL (GPL-LICENSE.txt) licenses. 2647 * 2648 * http://docs.jquery.com/UI/Sortables 2649 * 2650 * Depends: 2651 * ui.core.js 2652 */ 2653 (function($) { 2654 2655 $.widget("ui.sortable", $.extend({}, $.ui.mouse, { 2656 _init: function() { 2657 2658 var o = this.options; 2659 this.containerCache = {}; 2660 this.element.addClass("ui-sortable"); 2661 2662 //Get the items 2663 this.refresh(); 2664 2665 //Let's determine if the items are floating 2666 this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false; 2667 2668 //Let's determine the parent's offset 2669 this.offset = this.element.offset(); 2670 2671 //Initialize mouse events for interaction 2672 this._mouseInit(); 2673 2674 }, 2675 2676 destroy: function() { 2677 this.element 2678 .removeClass("ui-sortable ui-sortable-disabled") 2679 .removeData("sortable") 2680 .unbind(".sortable"); 2681 this._mouseDestroy(); 2682 2683 for ( var i = this.items.length - 1; i >= 0; i-- ) 2684 this.items[i].item.removeData("sortable-item"); 2685 }, 2686 2687 _mouseCapture: function(event, overrideHandle) { 2688 2689 if (this.reverting) { 2690 return false; 2691 } 2692 2693 if(this.options.disabled || this.options.type == 'static') return false; 2694 2695 //We have to refresh the items data once first 2696 this._refreshItems(event); 2697 2698 //Find out if the clicked node (or one of its parents) is a actual item in this.items 2699 var currentItem = null, self = this, nodes = $(event.target).parents().each(function() { 2700 if($.data(this, 'sortable-item') == self) { 2701 currentItem = $(this); 2702 return false; 2703 } 2704 }); 2705 if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target); 2706 2707 if(!currentItem) return false; 2708 if(this.options.handle && !overrideHandle) { 2709 var validHandle = false; 2710 2711 $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); 2712 if(!validHandle) return false; 2713 } 2714 2715 this.currentItem = currentItem; 2716 this._removeCurrentsFromItems(); 2717 return true; 2718 2719 }, 2720 2721 _mouseStart: function(event, overrideHandle, noActivation) { 2722 2723 var o = this.options; 2724 this.currentContainer = this; 2725 2726 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 2727 this.refreshPositions(); 2728 2729 //Create and append the visible helper 2730 this.helper = this._createHelper(event); 2731 2732 //Cache the helper size 2733 this._cacheHelperProportions(); 2734 2735 /* 2736 * - Position generation - 2737 * This block generates everything position related - it's the core of draggables. 2738 */ 2739 2740 //Cache the margins of the original element 2741 this._cacheMargins(); 2742 2743 //Get the next scrolling parent 2744 this.scrollParent = this.helper.scrollParent(); 2745 2746 //The element's absolute position on the page minus margins 2747 this.offset = this.currentItem.offset(); 2748 2749 this.offset = { 2750 top: this.offset.top - this.margins.top, 2751 left: this.offset.left - this.margins.left 2752 }; 2753 2754 // Only after we got the offset, we can change the helper's position to absolute 2755 // TODO: Still need to figure out a way to make relative sorting possible 2756 this.helper.css("position", "absolute"); 2757 this.cssPosition = this.helper.css("position"); 2758 2759 $.extend(this.offset, { 2760 click: { //Where the click happened, relative to the element 2761 left: event.pageX - this.offset.left, 2762 top: event.pageY - this.offset.top 2763 }, 2764 parent: this._getParentOffset(), 2765 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 2766 }); 2767 2768 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 2769 if(o.cursorAt) 2770 this._adjustOffsetFromHelper(o.cursorAt); 2771 2772 //Generate the original position 2773 this.originalPosition = this._generatePosition(event); 2774 2775 //Cache the former DOM position 2776 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 2777 2778 //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 2779 if(this.helper[0] != this.currentItem[0]) { 2780 this.currentItem.hide(); 2781 } 2782 2783 //Create the placeholder 2784 this._createPlaceholder(); 2785 2786 //Set a containment if given in the options 2787 if(o.containment) 2788 this._setContainment(); 2789 2790 //Call plugins and callbacks 2791 this._propagate("start", event); 2792 2793 //Recache the helper size 2794 if(!this._preserveHelperProportions) 2795 this._cacheHelperProportions(); 2796 2797 2798 //Post 'activate' events to possible containers 2799 if(!noActivation) { 2800 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._propagate("activate", event, this); } 2801 } 2802 2803 //Prepare possible droppables 2804 if($.ui.ddmanager) 2805 $.ui.ddmanager.current = this; 2806 2807 if ($.ui.ddmanager && !o.dropBehaviour) 2808 $.ui.ddmanager.prepareOffsets(this, event); 2809 2810 this.dragging = true; 2811 2812 this.helper.addClass('ui-sortable-helper'); 2813 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 2814 return true; 2815 2816 }, 2817 2818 _mouseDrag: function(event) { 2819 2820 //Compute the helpers position 2821 this.position = this._generatePosition(event); 2822 this.positionAbs = this._convertPositionTo("absolute"); 2823 2824 if (!this.lastPositionAbs) { 2825 this.lastPositionAbs = this.positionAbs; 2826 } 2827 2828 //Call the internal plugins 2829 $.ui.plugin.call(this, "sort", [event, this._ui()]); 2830 2831 //Regenerate the absolute position used for position checks 2832 this.positionAbs = this._convertPositionTo("absolute"); 2833 2834 //Set the helper position 2835 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 2836 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 2837 2838 //Rearrange 2839 for (var i = this.items.length - 1; i >= 0; i--) { 2840 2841 //Cache variables and intersection, continue if no intersection 2842 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); 2843 if (!intersection) continue; 2844 2845 if(itemElement != this.currentItem[0] //cannot intersect with itself 2846 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before 2847 && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked 2848 && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true) 2849 ) { 2850 2851 this.direction = intersection == 1 ? "down" : "up"; 2852 2853 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { 2854 this.options.sortIndicator.call(this, event, item); 2855 } else { 2856 break; 2857 } 2858 2859 this._propagate("change", event); //Call plugins and callbacks 2860 break; 2861 } 2862 } 2863 2864 //Post events to containers 2865 this._contactContainers(event); 2866 2867 //Interconnect with droppables 2868 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 2869 2870 //Call callbacks 2871 this._trigger('sort', event, this._ui()); 2872 2873 this.lastPositionAbs = this.positionAbs; 2874 return false; 2875 2876 }, 2877 2878 _mouseStop: function(event, noPropagation) { 2879 2880 if(!event) return; 2881 2882 //If we are using droppables, inform the manager about the drop 2883 if ($.ui.ddmanager && !this.options.dropBehaviour) 2884 $.ui.ddmanager.drop(this, event); 2885 2886 if(this.options.revert) { 2887 var self = this; 2888 var cur = self.placeholder.offset(); 2889 2890 self.reverting = true; 2891 2892 $(this.helper).animate({ 2893 left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), 2894 top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) 2895 }, parseInt(this.options.revert, 10) || 500, function() { 2896 self._clear(event); 2897 }); 2898 } else { 2899 this._clear(event, noPropagation); 2900 } 2901 2902 return false; 2903 2904 }, 2905 2906 cancel: function() { 2907 2908 if(this.dragging) { 2909 2910 this._mouseUp(); 2911 2912 if(this.options.helper == "original") 2913 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 2914 else 2915 this.currentItem.show(); 2916 2917 //Post deactivating events to containers 2918 for (var i = this.containers.length - 1; i >= 0; i--){ 2919 this.containers[i]._propagate("deactivate", null, this); 2920 if(this.containers[i].containerCache.over) { 2921 this.containers[i]._propagate("out", null, this); 2922 this.containers[i].containerCache.over = 0; 2923 } 2924 } 2925 2926 } 2927 2928 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 2929 if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 2930 if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); 2931 2932 $.extend(this, { 2933 helper: null, 2934 dragging: false, 2935 reverting: false, 2936 _noFinalSort: null 2937 }); 2938 2939 if(this.domPosition.prev) { 2940 $(this.domPosition.prev).after(this.currentItem); 2941 } else { 2942 $(this.domPosition.parent).prepend(this.currentItem); 2943 } 2944 2945 return true; 2946 2947 }, 2948 2949 serialize: function(o) { 2950 2951 var items = this._getItemsAsjQuery(o && o.connected); 2952 var str = []; o = o || {}; 2953 2954 $(items).each(function() { 2955 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); 2956 if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); 2957 }); 2958 2959 return str.join('&'); 2960 2961 }, 2962 2963 toArray: function(o) { 2964 2965 var items = this._getItemsAsjQuery(o && o.connected); 2966 var ret = []; o = o || {}; 2967 2968 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); 2969 return ret; 2970 2971 }, 2972 2973 /* Be careful with the following core functions */ 2974 _intersectsWith: function(item) { 2975 2976 var x1 = this.positionAbs.left, 2977 x2 = x1 + this.helperProportions.width, 2978 y1 = this.positionAbs.top, 2979 y2 = y1 + this.helperProportions.height; 2980 2981 var l = item.left, 2982 r = l + item.width, 2983 t = item.top, 2984 b = t + item.height; 2985 2986 var dyClick = this.offset.click.top, 2987 dxClick = this.offset.click.left; 2988 2989 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 2990 2991 if( this.options.tolerance == "pointer" 2992 || this.options.forcePointerForContainers 2993 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) 2994 ) { 2995 return isOverElement; 2996 } else { 2997 2998 return (l < x1 + (this.helperProportions.width / 2) // Right Half 2999 && x2 - (this.helperProportions.width / 2) < r // Left Half 3000 && t < y1 + (this.helperProportions.height / 2) // Bottom Half 3001 && y2 - (this.helperProportions.height / 2) < b ); // Top Half 3002 3003 } 3004 }, 3005 3006 _intersectsWithPointer: function(item) { 3007 3008 var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 3009 isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 3010 isOverElement = isOverElementHeight && isOverElementWidth, 3011 verticalDirection = this._getDragVerticalDirection(), 3012 horizontalDirection = this._getDragHorizontalDirection(); 3013 3014 if (!isOverElement) 3015 return false; 3016 3017 return this.floating ? 3018 ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) 3019 : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); 3020 3021 }, 3022 3023 _intersectsWithSides: function(item) { 3024 3025 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 3026 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 3027 verticalDirection = this._getDragVerticalDirection(), 3028 horizontalDirection = this._getDragHorizontalDirection(); 3029 3030 if (this.floating && horizontalDirection) { 3031 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); 3032 } else { 3033 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); 3034 } 3035 3036 }, 3037 3038 _getDragVerticalDirection: function() { 3039 var delta = this.positionAbs.top - this.lastPositionAbs.top; 3040 return delta != 0 && (delta > 0 ? "down" : "up"); 3041 }, 3042 3043 _getDragHorizontalDirection: function() { 3044 var delta = this.positionAbs.left - this.lastPositionAbs.left; 3045 return delta != 0 && (delta > 0 ? "right" : "left"); 3046 }, 3047 3048 refresh: function(event) { 3049 this._refreshItems(event); 3050 this.refreshPositions(); 3051 }, 3052 3053 _getItemsAsjQuery: function(connected) { 3054 3055 var self = this; 3056 var items = []; 3057 var queries = []; 3058 3059 if(this.options.connectWith && connected) { 3060 for (var i = this.options.connectWith.length - 1; i >= 0; i--){ 3061 var cur = $(this.options.connectWith[i]); 3062 for (var j = cur.length - 1; j >= 0; j--){ 3063 var inst = $.data(cur[j], 'sortable'); 3064 if(inst && inst != this && !inst.options.disabled) { 3065 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper"), inst]); 3066 } 3067 }; 3068 }; 3069 } 3070 3071 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"), this]); 3072 3073 for (var i = queries.length - 1; i >= 0; i--){ 3074 queries[i][0].each(function() { 3075 items.push(this); 3076 }); 3077 }; 3078 3079 return $(items); 3080 3081 }, 3082 3083 _removeCurrentsFromItems: function() { 3084 3085 var list = this.currentItem.find(":data(sortable-item)"); 3086 3087 for (var i=0; i < this.items.length; i++) { 3088 3089 for (var j=0; j < list.length; j++) { 3090 if(list[j] == this.items[i].item[0]) 3091 this.items.splice(i,1); 3092 }; 3093 3094 }; 3095 3096 }, 3097 3098 _refreshItems: function(event) { 3099 3100 this.items = []; 3101 this.containers = [this]; 3102 var items = this.items; 3103 var self = this; 3104 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; 3105 3106 if(this.options.connectWith) { 3107 for (var i = this.options.connectWith.length - 1; i >= 0; i--){ 3108 var cur = $(this.options.connectWith[i]); 3109 for (var j = cur.length - 1; j >= 0; j--){ 3110 var inst = $.data(cur[j], 'sortable'); 3111 if(inst && inst != this && !inst.options.disabled) { 3112 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 3113 this.containers.push(inst); 3114 } 3115 }; 3116 }; 3117 } 3118 3119 for (var i = queries.length - 1; i >= 0; i--) { 3120 var targetData = queries[i][1]; 3121 var _queries = queries[i][0]; 3122 3123 for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { 3124 var item = $(_queries[j]); 3125 3126 item.data('sortable-item', targetData); // Data for target checking (mouse manager) 3127 3128 items.push({ 3129 item: item, 3130 instance: targetData, 3131 width: 0, height: 0, 3132 left: 0, top: 0 3133 }); 3134 }; 3135 }; 3136 3137 }, 3138 3139 refreshPositions: function(fast) { 3140 3141 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 3142 if(this.offsetParent && this.helper) { 3143 this.offset.parent = this._getParentOffset(); 3144 } 3145 3146 for (var i = this.items.length - 1; i >= 0; i--){ 3147 var item = this.items[i]; 3148 3149 //We ignore calculating positions of all connected containers when we're not over them 3150 if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) 3151 continue; 3152 3153 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 3154 3155 if (!fast) { 3156 if (this.options.accurateIntersection) { 3157 item.width = t.outerWidth(); 3158 item.height = t.outerHeight(); 3159 } 3160 else { 3161 item.width = t[0].offsetWidth; 3162 item.height = t[0].offsetHeight; 3163 } 3164 } 3165 3166 var p = t.offset(); 3167 item.left = p.left; 3168 item.top = p.top; 3169 }; 3170 3171 if(this.options.custom && this.options.custom.refreshContainers) { 3172 this.options.custom.refreshContainers.call(this); 3173 } else { 3174 for (var i = this.containers.length - 1; i >= 0; i--){ 3175 var p = this.containers[i].element.offset(); 3176 this.containers[i].containerCache.left = p.left; 3177 this.containers[i].containerCache.top = p.top; 3178 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 3179 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 3180 }; 3181 } 3182 3183 }, 3184 3185 _createPlaceholder: function(that) { 3186 3187 var self = that || this, o = self.options; 3188 3189 if(!o.placeholder || o.placeholder.constructor == String) { 3190 var className = o.placeholder; 3191 o.placeholder = { 3192 element: function() { 3193 3194 var el = $(document.createElement(self.currentItem[0].nodeName)) 3195 .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder") 3196 .removeClass('ui-sortable-helper')[0]; 3197 3198 if(!className) { 3199 el.style.visibility = "hidden"; 3200 document.body.appendChild(el); 3201 // Name attributes are removed, otherwice causes elements to be unchecked 3202 // Expando attributes also have to be removed because of stupid IE (no condition, doesn't hurt in other browsers) 3203 el.innerHTML = self.currentItem[0].innerHTML.replace(/name\=\"[^\"\']+\"/g, '').replace(/jQuery[0-9]+\=\"[^\"\']+\"/g, ''); 3204 document.body.removeChild(el); 3205 }; 3206 3207 return el; 3208 }, 3209 update: function(container, p) { 3210 if(className && !o.forcePlaceholderSize) return; 3211 if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); }; 3212 if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); }; 3213 } 3214 }; 3215 } 3216 3217 //Create the placeholder 3218 self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem)); 3219 3220 //Append it after the actual current item 3221 self.currentItem.after(self.placeholder); 3222 3223 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 3224 o.placeholder.update(self, self.placeholder); 3225 3226 }, 3227 3228 _contactContainers: function(event) { 3229 for (var i = this.containers.length - 1; i >= 0; i--){ 3230 3231 if(this._intersectsWith(this.containers[i].containerCache)) { 3232 if(!this.containers[i].containerCache.over) { 3233 3234 if(this.currentContainer != this.containers[i]) { 3235 3236 //When entering a new container, we will find the item with the least distance and append our item near it 3237 var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[i].floating ? 'left' : 'top']; 3238 for (var j = this.items.length - 1; j >= 0; j--) { 3239 if(!$.ui.contains(this.containers[i].element[0], this.items[j].item[0])) continue; 3240 var cur = this.items[j][this.containers[i].floating ? 'left' : 'top']; 3241 if(Math.abs(cur - base) < dist) { 3242 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 3243 } 3244 } 3245 3246 if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 3247 continue; 3248 3249 this.currentContainer = this.containers[i]; 3250 itemWithLeastDistance ? this.options.sortIndicator.call(this, event, itemWithLeastDistance, null, true) : this.options.sortIndicator.call(this, event, null, this.containers[i].element, true); 3251 this._propagate("change", event); //Call plugins and callbacks 3252 this.containers[i]._propagate("change", event, this); //Call plugins and callbacks 3253 3254 //Update the placeholder 3255 this.options.placeholder.update(this.currentContainer, this.placeholder); 3256 3257 } 3258 3259 this.containers[i]._propagate("over", event, this); 3260 this.containers[i].containerCache.over = 1; 3261 } 3262 } else { 3263 if(this.containers[i].containerCache.over) { 3264 this.containers[i]._propagate("out", event, this); 3265 this.containers[i].containerCache.over = 0; 3266 } 3267 } 3268 3269 }; 3270 }, 3271 3272 _createHelper: function(event) { 3273 3274 var o = this.options; 3275 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); 3276 3277 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already 3278 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 3279 3280 if(helper[0] == this.currentItem[0]) 3281 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") }; 3282 3283 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); 3284 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); 3285 3286 return helper; 3287 3288 }, 3289 3290 _adjustOffsetFromHelper: function(obj) { 3291 if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left; 3292 if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 3293 if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top; 3294 if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 3295 }, 3296 3297 _getParentOffset: function() { 3298 3299 //Get the offsetParent and cache its position 3300 this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); 3301 3302 if((this.offsetParent[0] == document.body && $.browser.mozilla) //Ugly FF3 fix 3303 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix 3304 po = { top: 0, left: 0 }; 3305 3306 return { 3307 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 3308 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 3309 }; 3310 3311 }, 3312 3313 _getRelativeOffset: function() { 3314 3315 if(this.cssPosition == "relative") { 3316 var p = this.currentItem.position(); 3317 return { 3318 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 3319 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 3320 }; 3321 } else { 3322 return { top: 0, left: 0 }; 3323 } 3324 3325 }, 3326 3327 _cacheMargins: function() { 3328 this.margins = { 3329 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 3330 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 3331 }; 3332 }, 3333 3334 _cacheHelperProportions: function() { 3335 this.helperProportions = { 3336 width: this.helper.outerWidth(), 3337 height: this.helper.outerHeight() 3338 }; 3339 }, 3340 3341 _setContainment: function() { 3342 3343 var o = this.options; 3344 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 3345 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 3346 0 - this.offset.relative.left - this.offset.parent.left, 3347 0 - this.offset.relative.top - this.offset.parent.top, 3348 $(o.containment == 'document' ? document : window).width() - this.offset.relative.left - this.offset.parent.left - this.margins.left - (parseInt(this.currentItem.css("marginRight"),10) || 0), 3349 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.offset.relative.top - this.offset.parent.top - this.margins.top - (parseInt(this.currentItem.css("marginBottom"),10) || 0) 3350 ]; 3351 3352 if(!(/^(document|window|parent)$/).test(o.containment)) { 3353 var ce = $(o.containment)[0]; 3354 var co = $(o.containment).offset(); 3355 var over = ($(ce).css("overflow") != 'hidden'); 3356 3357 this.containment = [ 3358 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left, 3359 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top, 3360 co.left + (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left, 3361 co.top + (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top 3362 ]; 3363 } 3364 3365 }, 3366 3367 _convertPositionTo: function(d, pos) { 3368 3369 if(!pos) pos = this.position; 3370 var mod = d == "absolute" ? 1 : -1; 3371 var scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 3372 3373 return { 3374 top: ( 3375 pos.top // the calculated relative position 3376 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 3377 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 3378 + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod 3379 + this.margins.top * mod //Add the margin (you don't want the margin counting in intersection methods) 3380 ), 3381 left: ( 3382 pos.left // the calculated relative position 3383 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 3384 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 3385 + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) * mod 3386 + this.margins.left * mod //Add the margin (you don't want the margin counting in intersection methods) 3387 ) 3388 }; 3389 }, 3390 3391 _generatePosition: function(event) { 3392 3393 var o = this.options, scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 3394 3395 var position = { 3396 top: ( 3397 event.pageY // The absolute mouse position 3398 - this.offset.click.top // Click offset (relative to the element) 3399 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 3400 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 3401 + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) 3402 ), 3403 left: ( 3404 event.pageX // The absolute mouse position 3405 - this.offset.click.left // Click offset (relative to the element) 3406 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 3407 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 3408 + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) 3409 ) 3410 }; 3411 3412 if(!this.originalPosition) return position; //If we are not dragging yet, we won't check for options 3413 3414 /* 3415 * - Position constraining - 3416 * Constrain the position to a mix of grid, containment. 3417 */ 3418 if(this.containment) { 3419 if(position.left < this.containment[0]) position.left = this.containment[0]; 3420 if(position.top < this.containment[1]) position.top = this.containment[1]; 3421 if(position.left + this.helperProportions.width > this.containment[2]) position.left = this.containment[2] - this.helperProportions.width; 3422 if(position.top + this.helperProportions.height > this.containment[3]) position.top = this.containment[3] - this.helperProportions.height; 3423 } 3424 3425 if(o.grid) { 3426 var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1]; 3427 position.top = this.containment ? (!(top < this.containment[1] || top > this.containment[3]) ? top : (!(top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; 3428 3429 var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0]; 3430 position.left = this.containment ? (!(left < this.containment[0] || left > this.containment[2]) ? left : (!(left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; 3431 } 3432 3433 return position; 3434 }, 3435 3436 _rearrange: function(event, i, a, hardRefresh) { 3437 3438 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)); 3439 3440 //Various things done here to improve the performance: 3441 // 1. we create a setTimeout, that calls refreshPositions 3442 // 2. on the instance, we have a counter variable, that get's higher after every append 3443 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 3444 // 4. this lets only the last addition to the timeout stack through 3445 this.counter = this.counter ? ++this.counter : 1; 3446 var self = this, counter = this.counter; 3447 3448 window.setTimeout(function() { 3449 if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 3450 },0); 3451 3452 }, 3453 3454 _clear: function(event, noPropagation) { 3455 3456 this.reverting = false; 3457 3458 //We first have to update the dom position of the actual currentItem 3459 if(!this._noFinalSort) this.placeholder.before(this.currentItem); 3460 this._noFinalSort = null; 3461 3462 if(this.helper[0] == this.currentItem[0]) { 3463 for(var i in this._storedCSS) { 3464 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; 3465 } 3466 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 3467 } else { 3468 this.currentItem.show(); 3469 } 3470 3471 if(this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) this._propagate("update", event, null, noPropagation); //Trigger update callback if the DOM position has changed 3472 if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element 3473 this._propagate("remove", event, null, noPropagation); 3474 for (var i = this.containers.length - 1; i >= 0; i--){ 3475 if($.ui.contains(this.containers[i].element[0], this.currentItem[0])) { 3476 this.containers[i]._propagate("update", event, this, noPropagation); 3477 this.containers[i]._propagate("receive", event, this, noPropagation); 3478 } 3479 }; 3480 }; 3481 3482 //Post events to containers 3483 for (var i = this.containers.length - 1; i >= 0; i--){ 3484 this.containers[i]._propagate("deactivate", event, this, noPropagation); 3485 if(this.containers[i].containerCache.over) { 3486 this.containers[i]._propagate("out", event, this); 3487 this.containers[i].containerCache.over = 0; 3488 } 3489 } 3490 3491 this.dragging = false; 3492 if(this.cancelHelperRemoval) { 3493 this._propagate("beforeStop", event, null, noPropagation); 3494 this._propagate("stop", event, null, noPropagation); 3495 return false; 3496 } 3497 3498 this._propagate("beforeStop", event, null, noPropagation); 3499 3500 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 3501 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 3502 3503 if(this.options.helper != "original") this.helper.remove(); this.helper = null; 3504 this._propagate("stop", event, null, noPropagation); 3505 3506 return true; 3507 3508 }, 3509 3510 _propagate: function(n, event, inst, noPropagation) { 3511 $.ui.plugin.call(this, n, [event, this._ui(inst)]); 3512 var dontCancel = !noPropagation ? this.element.triggerHandler(n == "sort" ? n : "sort"+n, [event, this._ui(inst)], this.options[n]) : true; 3513 if(dontCancel === false) this.cancel(); 3514 }, 3515 3516 plugins: {}, 3517 3518 _ui: function(inst) { 3519 var self = inst || this; 3520 return { 3521 helper: self.helper, 3522 placeholder: self.placeholder || $([]), 3523 position: self.position, 3524 absolutePosition: self.positionAbs, 3525 item: self.currentItem, 3526 sender: inst ? inst.element : null 3527 }; 3528 } 3529 3530 })); 3531 3532 $.extend($.ui.sortable, { 3533 getter: "serialize toArray", 3534 version: "1.6", 3535 defaults: { 3536 accurateIntersection: true, 3537 appendTo: "parent", 3538 cancel: ":input", 3539 delay: 0, 3540 distance: 1, 3541 dropOnEmpty: true, 3542 forcePlaceholderSize: false, 3543 forceHelperSize: false, 3544 helper: "original", 3545 items: '> *', 3546 scope: "default", 3547 scroll: true, 3548 scrollSensitivity: 20, 3549 scrollSpeed: 20, 3550 sortIndicator: $.ui.sortable.prototype._rearrange, 3551 tolerance: "default", 3552 zIndex: 1000 3553 } 3554 }); 3555 3556 /* 3557 * Sortable Extensions 3558 */ 3559 3560 $.ui.plugin.add("sortable", "cursor", { 3561 start: function(event, ui) { 3562 var t = $('body'), i = $(this).data('sortable'); 3563 if (t.css("cursor")) i.options._cursor = t.css("cursor"); 3564 t.css("cursor", i.options.cursor); 3565 }, 3566 beforeStop: function(event, ui) { 3567 var i = $(this).data('sortable'); 3568 if (i.options._cursor) $('body').css("cursor", i.options._cursor); 3569 } 3570 }); 3571 3572 $.ui.plugin.add("sortable", "opacity", { 3573 start: function(event, ui) { 3574 var t = ui.helper, i = $(this).data('sortable'); 3575 if(t.css("opacity")) i.options._opacity = t.css("opacity"); 3576 t.css('opacity', i.options.opacity); 3577 }, 3578 beforeStop: function(event, ui) { 3579 var i = $(this).data('sortable'); 3580 if(i.options._opacity) $(ui.helper).css('opacity', i.options._opacity); 3581 } 3582 }); 3583 3584 $.ui.plugin.add("sortable", "scroll", { 3585 start: function(event, ui) { 3586 var i = $(this).data("sortable"), o = i.options; 3587 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); 3588 }, 3589 sort: function(event, ui) { 3590 3591 var i = $(this).data("sortable"), o = i.options, scrolled = false; 3592 3593 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { 3594 3595 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 3596 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 3597 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) 3598 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 3599 3600 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 3601 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 3602 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) 3603 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 3604 3605 } else { 3606 3607 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 3608 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3609 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 3610 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3611 3612 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 3613 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3614 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 3615 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3616 3617 } 3618 3619 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 3620 $.ui.ddmanager.prepareOffsets(i, event); 3621 3622 3623 3624 //This is a special case where we need to modify a offset calculated on start, since the following happened: 3625 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 3626 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 3627 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 3628 if(scrolled !== false && i.cssPosition == 'absolute' && i.scrollParent[0] != document && $.ui.contains(i.scrollParent[0], i.offsetParent[0])) { 3629 i.offset.parent = i._getParentOffset(); 3630 } 3631 3632 // This is another very weird special case that only happens for relative elements: 3633 // 1. If the css position is relative 3634 // 2. and the scroll parent is the document or similar to the offset parent 3635 // we have to refresh the relative offset during the scroll so there are no jumps 3636 if(scrolled !== false && i.cssPosition == 'relative' && !(i.scrollParent[0] != document && i.scrollParent[0] != i.offsetParent[0])) { 3637 i.offset.relative = i._getRelativeOffset(); 3638 } 3639 3640 } 3641 }); 3642 3643 $.ui.plugin.add("sortable", "zIndex", { 3644 start: function(event, ui) { 3645 var t = ui.helper, i = $(this).data('sortable'); 3646 if(t.css("zIndex")) i.options._zIndex = t.css("zIndex"); 3647 t.css('zIndex', i.options.zIndex); 3648 }, 3649 beforeStop: function(event, ui) { 3650 var i = $(this).data('sortable'); 3651 if(i.options._zIndex) $(ui.helper).css('zIndex', i.options._zIndex == 'auto' ? '' : i.options._zIndex); 3652 } 3653 }); 3654 3655 })(jQuery); 3656 /* 3657 * jQuery UI Effects 1.6 3658 * 3659 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 3660 * Dual licensed under the MIT (MIT-LICENSE.txt) 3661 * and GPL (GPL-LICENSE.txt) licenses. 3662 * 3663 * http://docs.jquery.com/UI/Effects/ 3664 */ 3665 ;(function($) { 3666 3667 $.effects = $.effects || {}; //Add the 'effects' scope 3668 3669 $.extend($.effects, { 3670 version: "1.6", 3671 save: function(el, set) { 3672 for(var i=0;i<set.length;i++) { 3673 if(set[i] !== null) $.data(el[0], "ec.storage."+set[i], el[0].style[set[i]]); 3674 } 3675 }, 3676 restore: function(el, set) { 3677 for(var i=0;i<set.length;i++) { 3678 if(set[i] !== null) el.css(set[i], $.data(el[0], "ec.storage."+set[i])); 3679 } 3680 }, 3681 setMode: function(el, mode) { 3682 if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle 3683 return mode; 3684 }, 3685 getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value 3686 // this should be a little more flexible in the future to handle a string & hash 3687 var y, x; 3688 switch (origin[0]) { 3689 case 'top': y = 0; break; 3690 case 'middle': y = 0.5; break; 3691 case 'bottom': y = 1; break; 3692 default: y = origin[0] / original.height; 3693 }; 3694 switch (origin[1]) { 3695 case 'left': x = 0; break; 3696 case 'center': x = 0.5; break; 3697 case 'right': x = 1; break; 3698 default: x = origin[1] / original.width; 3699 }; 3700 return {x: x, y: y}; 3701 }, 3702 createWrapper: function(el) { 3703 if (el.parent().attr('id') == 'fxWrapper') 3704 return el; 3705 var props = {width: el.outerWidth({margin:true}), height: el.outerHeight({margin:true}), 'float': el.css('float')}; 3706 el.wrap('<div id="fxWrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>'); 3707 var wrapper = el.parent(); 3708 if (el.css('position') == 'static'){ 3709 wrapper.css({position: 'relative'}); 3710 el.css({position: 'relative'}); 3711 } else { 3712 var top = el.css('top'); if(isNaN(parseInt(top))) top = 'auto'; 3713 var left = el.css('left'); if(isNaN(parseInt(left))) left = 'auto'; 3714 wrapper.css({ position: el.css('position'), top: top, left: left, zIndex: el.css('z-index') }).show(); 3715 el.css({position: 'relative', top:0, left:0}); 3716 } 3717 wrapper.css(props); 3718 return wrapper; 3719 }, 3720 removeWrapper: function(el) { 3721 if (el.parent().attr('id') == 'fxWrapper') 3722 return el.parent().replaceWith(el); 3723 return el; 3724 }, 3725 setTransition: function(el, list, factor, val) { 3726 val = val || {}; 3727 $.each(list,function(i, x){ 3728 unit = el.cssUnit(x); 3729 if (unit[0] > 0) val[x] = unit[0] * factor + unit[1]; 3730 }); 3731 return val; 3732 }, 3733 animateClass: function(value, duration, easing, callback) { 3734 3735 var cb = (typeof easing == "function" ? easing : (callback ? callback : null)); 3736 var ea = (typeof easing == "object" ? easing : null); 3737 3738 return this.each(function() { 3739 3740 var offset = {}; var that = $(this); var oldStyleAttr = that.attr("style") || ''; 3741 if(typeof oldStyleAttr == 'object') oldStyleAttr = oldStyleAttr["cssText"]; /* Stupidly in IE, style is a object.. */ 3742 if(value.toggle) { that.hasClass(value.toggle) ? value.remove = value.toggle : value.add = value.toggle; } 3743 3744 //Let's get a style offset 3745 var oldStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle)); 3746 if(value.add) that.addClass(value.add); if(value.remove) that.removeClass(value.remove); 3747 var newStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle)); 3748 if(value.add) that.removeClass(value.add); if(value.remove) that.addClass(value.remove); 3749 3750 // The main function to form the object for animation 3751 for(var n in newStyle) { 3752 if( typeof newStyle[n] != "function" && newStyle[n] /* No functions and null properties */ 3753 && n.indexOf("Moz") == -1 && n.indexOf("length") == -1 /* No mozilla spezific render properties. */ 3754 && newStyle[n] != oldStyle[n] /* Only values that have changed are used for the animation */ 3755 && (n.match(/color/i) || (!n.match(/color/i) && !isNaN(parseInt(newStyle[n],10)))) /* Only things that can be parsed to integers or colors */ 3756 && (oldStyle.position != "static" || (oldStyle.position == "static" && !n.match(/left|top|bottom|right/))) /* No need for positions when dealing with static positions */ 3757 ) offset[n] = newStyle[n]; 3758 } 3759 3760 that.animate(offset, duration, ea, function() { // Animate the newly constructed offset object 3761 // Change style attribute back to original. For stupid IE, we need to clear the damn object. 3762 if(typeof $(this).attr("style") == 'object') { $(this).attr("style")["cssText"] = ""; $(this).attr("style")["cssText"] = oldStyleAttr; } else $(this).attr("style", oldStyleAttr); 3763 if(value.add) $(this).addClass(value.add); if(value.remove) $(this).removeClass(value.remove); 3764 if(cb) cb.apply(this, arguments); 3765 }); 3766 3767 }); 3768 } 3769 }); 3770 3771 //Extend the methods of jQuery 3772 $.fn.extend({ 3773 //Save old methods 3774 _show: $.fn.show, 3775 _hide: $.fn.hide, 3776 __toggle: $.fn.toggle, 3777 _addClass: $.fn.addClass, 3778 _removeClass: $.fn.removeClass, 3779 _toggleClass: $.fn.toggleClass, 3780 // New ec methods 3781 effect: function(fx,o,speed,callback) { 3782 return $.effects[fx] ? $.effects[fx].call(this, {method: fx, options: o || {}, duration: speed, callback: callback }) : null; 3783 }, 3784 show: function() { 3785 if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0]))) 3786 return this._show.apply(this, arguments); 3787 else { 3788 var o = arguments[1] || {}; o['mode'] = 'show'; 3789 return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]); 3790 } 3791 }, 3792 hide: function() { 3793 if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0]))) 3794 return this._hide.apply(this, arguments); 3795 else { 3796 var o = arguments[1] || {}; o['mode'] = 'hide'; 3797 return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]); 3798 } 3799 }, 3800 toggle: function(){ 3801 if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])) || (arguments[0].constructor == Function)) 3802 return this.__toggle.apply(this, arguments); 3803 else { 3804 var o = arguments[1] || {}; o['mode'] = 'toggle'; 3805 return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]); 3806 } 3807 }, 3808 addClass: function(classNames,speed,easing,callback) { 3809 return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames); 3810 }, 3811 removeClass: function(classNames,speed,easing,callback) { 3812 return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames); 3813 }, 3814 toggleClass: function(classNames,speed,easing,callback) { 3815 return speed ? $.effects.animateClass.apply(this, [{ toggle: classNames },speed,easing,callback]) : this._toggleClass(classNames); 3816 }, 3817 morph: function(remove,add,speed,easing,callback) { 3818 return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]); 3819 }, 3820 switchClass: function() { 3821 return this.morph.apply(this, arguments); 3822 }, 3823 // helper functions 3824 cssUnit: function(key) { 3825 var style = this.css(key), val = []; 3826 $.each( ['em','px','%','pt'], function(i, unit){ 3827 if(style.indexOf(unit) > 0) 3828 val = [parseFloat(style), unit]; 3829 }); 3830 return val; 3831 } 3832 }); 3833 3834 /* 3835 * jQuery Color Animations 3836 * Copyright 2007 John Resig 3837 * Released under the MIT and GPL licenses. 3838 */ 3839 3840 // We override the animation for all of these color styles 3841 $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){ 3842 $.fx.step[attr] = function(fx){ 3843 if ( fx.state == 0 ) { 3844 fx.start = getColor( fx.elem, attr ); 3845 fx.end = getRGB( fx.end ); 3846 } 3847 3848 fx.elem.style[attr] = "rgb(" + [ 3849 Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0), 3850 Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0), 3851 Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0) 3852 ].join(",") + ")"; 3853 } 3854 }); 3855 3856 // Color Conversion functions from highlightFade 3857 // By Blair Mitchelmore 3858 // http://jquery.offput.ca/highlightFade/ 3859 3860 // Parse strings looking for color tuples [255,255,255] 3861 function getRGB(color) { 3862 var result; 3863 3864 // Check if we're already dealing with an array of colors 3865 if ( color && color.constructor == Array && color.length == 3 ) 3866 return color; 3867 3868 // Look for rgb(num,num,num) 3869 if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) 3870 return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])]; 3871 3872 // Look for rgb(num%,num%,num%) 3873 if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) 3874 return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55]; 3875 3876 // Look for #a0b1c2 3877 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) 3878 return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; 3879 3880 // Look for #fff 3881 if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) 3882 return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; 3883 3884 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 3885 if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) 3886 return colors['transparent']; 3887 3888 // Otherwise, we're most likely dealing with a named color 3889 return colors[$.trim(color).toLowerCase()]; 3890 } 3891 3892 function getColor(elem, attr) { 3893 var color; 3894 3895 do { 3896 color = $.curCSS(elem, attr); 3897 3898 // Keep going until we find an element that has color, or we hit the body 3899 if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") ) 3900 break; 3901 3902 attr = "backgroundColor"; 3903 } while ( elem = elem.parentNode ); 3904 3905 return getRGB(color); 3906 }; 3907 3908 // Some named colors to work with 3909 // From Interface by Stefan Petre 3910 // http://interface.eyecon.ro/ 3911 3912 var colors = { 3913 aqua:[0,255,255], 3914 azure:[240,255,255], 3915 beige:[245,245,220], 3916 black:[0,0,0], 3917 blue:[0,0,255], 3918 brown:[165,42,42], 3919 cyan:[0,255,255], 3920 darkblue:[0,0,139], 3921 darkcyan:[0,139,139], 3922 darkgrey:[169,169,169], 3923 darkgreen:[0,100,0], 3924 darkkhaki:[189,183,107], 3925 darkmagenta:[139,0,139], 3926 darkolivegreen:[85,107,47], 3927 darkorange:[255,140,0], 3928 darkorchid:[153,50,204], 3929 darkred:[139,0,0], 3930 darksalmon:[233,150,122], 3931 darkviolet:[148,0,211], 3932 fuchsia:[255,0,255], 3933 gold:[255,215,0], 3934 green:[0,128,0], 3935 indigo:[75,0,130], 3936 khaki:[240,230,140], 3937 lightblue:[173,216,230], 3938 lightcyan:[224,255,255], 3939 lightgreen:[144,238,144], 3940 lightgrey:[211,211,211], 3941 lightpink:[255,182,193], 3942 lightyellow:[255,255,224], 3943 lime:[0,255,0], 3944 magenta:[255,0,255], 3945 maroon:[128,0,0], 3946 navy:[0,0,128], 3947 olive:[128,128,0], 3948 orange:[255,165,0], 3949 pink:[255,192,203], 3950 purple:[128,0,128], 3951 violet:[128,0,128], 3952 red:[255,0,0], 3953 silver:[192,192,192], 3954 white:[255,255,255], 3955 yellow:[255,255,0], 3956 transparent: [255,255,255] 3957 }; 3958 3959 /* 3960 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ 3961 * 3962 * Uses the built in easing capabilities added In jQuery 1.1 3963 * to offer multiple easing options 3964 * 3965 * TERMS OF USE - jQuery Easing 3966 * 3967 * Open source under the BSD License. 3968 * 3969 * Copyright © 2008 George McGinley Smith 3970 * All rights reserved. 3971 * 3972 * Redistribution and use in source and binary forms, with or without modification, 3973 * are permitted provided that the following conditions are met: 3974 * 3975 * Redistributions of source code must retain the above copyright notice, this list of 3976 * conditions and the following disclaimer. 3977 * Redistributions in binary form must reproduce the above copyright notice, this list 3978 * of conditions and the following disclaimer in the documentation and/or other materials 3979 * provided with the distribution. 3980 * 3981 * Neither the name of the author nor the names of contributors may be used to endorse 3982 * or promote products derived from this software without specific prior written permission. 3983 * 3984 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 3985 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 3986 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 3987 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 3988 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 3989 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 3990 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3991 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 3992 * OF THE POSSIBILITY OF SUCH DAMAGE. 3993 * 3994 */ 3995 3996 // t: current time, b: begInnIng value, c: change In value, d: duration 3997 $.easing.jswing = $.easing.swing; 3998 3999 $.extend($.easing, 4000 { 4001 def: 'easeOutQuad', 4002 swing: function (x, t, b, c, d) { 4003 //alert($.easing.default); 4004 return $.easing[$.easing.def](x, t, b, c, d); 4005 }, 4006 easeInQuad: function (x, t, b, c, d) { 4007 return c*(t/=d)*t + b; 4008 }, 4009 easeOutQuad: function (x, t, b, c, d) { 4010 return -c *(t/=d)*(t-2) + b; 4011 }, 4012 easeInOutQuad: function (x, t, b, c, d) { 4013 if ((t/=d/2) < 1) return c/2*t*t + b; 4014 return -c/2 * ((--t)*(t-2) - 1) + b; 4015 }, 4016 easeInCubic: function (x, t, b, c, d) { 4017 return c*(t/=d)*t*t + b; 4018 }, 4019 easeOutCubic: function (x, t, b, c, d) { 4020 return c*((t=t/d-1)*t*t + 1) + b; 4021 }, 4022 easeInOutCubic: function (x, t, b, c, d) { 4023 if ((t/=d/2) < 1) return c/2*t*t*t + b; 4024 return c/2*((t-=2)*t*t + 2) + b; 4025 }, 4026 easeInQuart: function (x, t, b, c, d) { 4027 return c*(t/=d)*t*t*t + b; 4028 }, 4029 easeOutQuart: function (x, t, b, c, d) { 4030 return -c * ((t=t/d-1)*t*t*t - 1) + b; 4031 }, 4032 easeInOutQuart: function (x, t, b, c, d) { 4033 if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 4034 return -c/2 * ((t-=2)*t*t*t - 2) + b; 4035 }, 4036 easeInQuint: function (x, t, b, c, d) { 4037 return c*(t/=d)*t*t*t*t + b; 4038 }, 4039 easeOutQuint: function (x, t, b, c, d) { 4040 return c*((t=t/d-1)*t*t*t*t + 1) + b; 4041 }, 4042 easeInOutQuint: function (x, t, b, c, d) { 4043 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 4044 return c/2*((t-=2)*t*t*t*t + 2) + b; 4045 }, 4046 easeInSine: function (x, t, b, c, d) { 4047 return -c * Math.cos(t/d * (Math.PI/2)) + c + b; 4048 }, 4049 easeOutSine: function (x, t, b, c, d) { 4050 return c * Math.sin(t/d * (Math.PI/2)) + b; 4051 }, 4052 easeInOutSine: function (x, t, b, c, d) { 4053 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; 4054 }, 4055 easeInExpo: function (x, t, b, c, d) { 4056 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; 4057 }, 4058 easeOutExpo: function (x, t, b, c, d) { 4059 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 4060 }, 4061 easeInOutExpo: function (x, t, b, c, d) { 4062 if (t==0) return b; 4063 if (t==d) return b+c; 4064 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 4065 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 4066 }, 4067 easeInCirc: function (x, t, b, c, d) { 4068 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; 4069 }, 4070 easeOutCirc: function (x, t, b, c, d) { 4071 return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 4072 }, 4073 easeInOutCirc: function (x, t, b, c, d) { 4074 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 4075 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 4076 }, 4077 easeInElastic: function (x, t, b, c, d) { 4078 var s=1.70158;var p=0;var a=c; 4079 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 4080 if (a < Math.abs(c)) { a=c; var s=p/4; } 4081 else var s = p/(2*Math.PI) * Math.asin (c/a); 4082 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 4083 }, 4084 easeOutElastic: function (x, t, b, c, d) { 4085 var s=1.70158;var p=0;var a=c; 4086 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 4087 if (a < Math.abs(c)) { a=c; var s=p/4; } 4088 else var s = p/(2*Math.PI) * Math.asin (c/a); 4089 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; 4090 }, 4091 easeInOutElastic: function (x, t, b, c, d) { 4092 var s=1.70158;var p=0;var a=c; 4093 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); 4094 if (a < Math.abs(c)) { a=c; var s=p/4; } 4095 else var s = p/(2*Math.PI) * Math.asin (c/a); 4096 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 4097 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; 4098 }, 4099 easeInBack: function (x, t, b, c, d, s) { 4100 if (s == undefined) s = 1.70158; 4101 return c*(t/=d)*t*((s+1)*t - s) + b; 4102 }, 4103 easeOutBack: function (x, t, b, c, d, s) { 4104 if (s == undefined) s = 1.70158; 4105 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 4106 }, 4107 easeInOutBack: function (x, t, b, c, d, s) { 4108 if (s == undefined) s = 1.70158; 4109 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; 4110 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; 4111 }, 4112 easeInBounce: function (x, t, b, c, d) { 4113 return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b; 4114 }, 4115 easeOutBounce: function (x, t, b, c, d) { 4116 if ((t/=d) < (1/2.75)) { 4117 return c*(7.5625*t*t) + b; 4118 } else if (t < (2/2.75)) { 4119 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; 4120 } else if (t < (2.5/2.75)) { 4121 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; 4122 } else { 4123 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; 4124 } 4125 }, 4126 easeInOutBounce: function (x, t, b, c, d) { 4127 if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; 4128 return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; 4129 } 4130 }); 4131 4132 /* 4133 * 4134 * TERMS OF USE - EASING EQUATIONS 4135 * 4136 * Open source under the BSD License. 4137 * 4138 * Copyright © 2001 Robert Penner 4139 * All rights reserved. 4140 * 4141 * Redistribution and use in source and binary forms, with or without modification, 4142 * are permitted provided that the following conditions are met: 4143 * 4144 * Redistributions of source code must retain the above copyright notice, this list of 4145 * conditions and the following disclaimer. 4146 * Redistributions in binary form must reproduce the above copyright notice, this list 4147 * of conditions and the following disclaimer in the documentation and/or other materials 4148 * provided with the distribution. 4149 * 4150 * Neither the name of the author nor the names of contributors may be used to endorse 4151 * or promote products derived from this software without specific prior written permission. 4152 * 4153 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 4154 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 4155 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 4156 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 4157 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 4158 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 4159 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 4160 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 4161 * OF THE POSSIBILITY OF SUCH DAMAGE. 4162 * 4163 */ 4164 4165 })(jQuery); 4166 /* 4167 * jQuery UI Effects Blind 1.6 4168 * 4169 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4170 * Dual licensed under the MIT (MIT-LICENSE.txt) 4171 * and GPL (GPL-LICENSE.txt) licenses. 4172 * 4173 * http://docs.jquery.com/UI/Effects/Blind 4174 * 4175 * Depends: 4176 * effects.core.js 4177 */ 4178 (function($) { 4179 4180 $.effects.blind = function(o) { 4181 4182 return this.queue(function() { 4183 4184 // Create element 4185 var el = $(this), props = ['position','top','left']; 4186 4187 // Set options 4188 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode 4189 var direction = o.options.direction || 'vertical'; // Default direction 4190 4191 // Adjust 4192 $.effects.save(el, props); el.show(); // Save & Show 4193 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper 4194 var ref = (direction == 'vertical') ? 'height' : 'width'; 4195 var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width(); 4196 if(mode == 'show') wrapper.css(ref, 0); // Shift 4197 4198 // Animation 4199 var animation = {}; 4200 animation[ref] = mode == 'show' ? distance : 0; 4201 4202 // Animate 4203 wrapper.animate(animation, o.duration, o.options.easing, function() { 4204 if(mode == 'hide') el.hide(); // Hide 4205 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 4206 if(o.callback) o.callback.apply(el[0], arguments); // Callback 4207 el.dequeue(); 4208 }); 4209 4210 }); 4211 4212 }; 4213 4214 })(jQuery); 4215 /* 4216 * jQuery UI Effects Bounce 1.6 4217 * 4218 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4219 * Dual licensed under the MIT (MIT-LICENSE.txt) 4220 * and GPL (GPL-LICENSE.txt) licenses. 4221 * 4222 * http://docs.jquery.com/UI/Effects/Bounce 4223 * 4224 * Depends: 4225 * effects.core.js 4226 */ 4227 (function($) { 4228 4229 $.effects.bounce = function(o) { 4230 4231 return this.queue(function() { 4232 4233 // Create element 4234 var el = $(this), props = ['position','top','left']; 4235 4236 // Set options 4237 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode 4238 var direction = o.options.direction || 'up'; // Default direction 4239 var distance = o.options.distance || 20; // Default distance 4240 var times = o.options.times || 5; // Default # of times 4241 var speed = o.duration || 250; // Default speed per bounce 4242 if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE 4243 4244 // Adjust 4245 $.effects.save(el, props); el.show(); // Save & Show 4246 $.effects.createWrapper(el); // Create Wrapper 4247 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; 4248 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; 4249 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3); 4250 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift 4251 if (mode == 'hide') distance = distance / (times * 2); 4252 if (mode != 'hide') times--; 4253 4254 // Animate 4255 if (mode == 'show') { // Show Bounce 4256 var animation = {opacity: 1}; 4257 animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance; 4258 el.animate(animation, speed / 2, o.options.easing); 4259 distance = distance / 2; 4260 times--; 4261 }; 4262 for (var i = 0; i < times; i++) { // Bounces 4263 var animation1 = {}, animation2 = {}; 4264 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; 4265 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; 4266 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing); 4267 distance = (mode == 'hide') ? distance * 2 : distance / 2; 4268 }; 4269 if (mode == 'hide') { // Last Bounce 4270 var animation = {opacity: 0}; 4271 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance; 4272 el.animate(animation, speed / 2, o.options.easing, function(){ 4273 el.hide(); // Hide 4274 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 4275 if(o.callback) o.callback.apply(this, arguments); // Callback 4276 }); 4277 } else { 4278 var animation1 = {}, animation2 = {}; 4279 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; 4280 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; 4281 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){ 4282 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 4283 if(o.callback) o.callback.apply(this, arguments); // Callback 4284 }); 4285 }; 4286 el.queue('fx', function() { el.dequeue(); }); 4287 el.dequeue(); 4288 }); 4289 4290 }; 4291 4292 })(jQuery); 4293 /* 4294 * jQuery UI Effects Clip 1.6 4295 * 4296 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4297 * Dual licensed under the MIT (MIT-LICENSE.txt) 4298 * and GPL (GPL-LICENSE.txt) licenses. 4299 * 4300 * http://docs.jquery.com/UI/Effects/Clip 4301 * 4302 * Depends: 4303 * effects.core.js 4304 */ 4305 (function($) { 4306 4307 $.effects.clip = function(o) { 4308 4309 return this.queue(function() { 4310 4311 // Create element 4312 var el = $(this), props = ['position','top','left','height','width']; 4313 4314 // Set options 4315 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode 4316 var direction = o.options.direction || 'vertical'; // Default direction 4317 4318 // Adjust 4319 $.effects.save(el, props); el.show(); // Save & Show 4320 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper 4321 var animate = el[0].tagName == 'IMG' ? wrapper : el; 4322 var ref = { 4323 size: (direction == 'vertical') ? 'height' : 'width', 4324 position: (direction == 'vertical') ? 'top' : 'left' 4325 }; 4326 var distance = (direction == 'vertical') ? animate.height() : animate.width(); 4327 if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift 4328 4329 // Animation 4330 var animation = {}; 4331 animation[ref.size] = mode == 'show' ? distance : 0; 4332 animation[ref.position] = mode == 'show' ? 0 : distance / 2; 4333 4334 // Animate 4335 animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { 4336 if(mode == 'hide') el.hide(); // Hide 4337 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 4338 if(o.callback) o.callback.apply(el[0], arguments); // Callback 4339 el.dequeue(); 4340 }}); 4341 4342 }); 4343 4344 }; 4345 4346 })(jQuery); 4347 /* 4348 * jQuery UI Effects Drop 1.6 4349 * 4350 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4351 * Dual licensed under the MIT (MIT-LICENSE.txt) 4352 * and GPL (GPL-LICENSE.txt) licenses. 4353 * 4354 * http://docs.jquery.com/UI/Effects/Drop 4355 * 4356 * Depends: 4357 * effects.core.js 4358 */ 4359 (function($) { 4360 4361 $.effects.drop = function(o) { 4362 4363 return this.queue(function() { 4364 4365 // Create element 4366 var el = $(this), props = ['position','top','left','opacity']; 4367 4368 // Set options 4369 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode 4370 var direction = o.options.direction || 'left'; // Default Direction 4371 4372 // Adjust 4373 $.effects.save(el, props); el.show(); // Save & Show 4374 $.effects.createWrapper(el); // Create Wrapper 4375 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; 4376 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; 4377 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2); 4378 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift 4379 4380 // Animation 4381 var animation = {opacity: mode == 'show' ? 1 : 0}; 4382 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance; 4383 4384 // Animate 4385 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { 4386 if(mode == 'hide') el.hide(); // Hide 4387 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 4388 if(o.callback) o.callback.apply(this, arguments); // Callback 4389 el.dequeue(); 4390 }}); 4391 4392 }); 4393 4394 }; 4395 4396 })(jQuery); 4397 /* 4398 * jQuery UI Effects Explode 1.6 4399 * 4400 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4401 * Dual licensed under the MIT (MIT-LICENSE.txt) 4402 * and GPL (GPL-LICENSE.txt) licenses. 4403 * 4404 * http://docs.jquery.com/UI/Effects/Explode 4405 * 4406 * Depends: 4407 * effects.core.js 4408 */ 4409 (function($) { 4410 4411 $.effects.explode = function(o) { 4412 4413 return this.queue(function() { 4414 4415 var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3; 4416 var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3; 4417 4418 o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode; 4419 var el = $(this).show().css('visibility', 'hidden'); 4420 var offset = el.offset(); 4421 4422 //Substract the margins - not fixing the problem yet. 4423 offset.top -= parseInt(el.css("marginTop")) || 0; 4424 offset.left -= parseInt(el.css("marginLeft")) || 0; 4425 4426 var width = el.outerWidth(true); 4427 var height = el.outerHeight(true); 4428 4429 for(var i=0;i<rows;i++) { // = 4430 for(var j=0;j<cells;j++) { // || 4431 el 4432 .clone() 4433 .appendTo('body') 4434 .wrap('<div></div>') 4435 .css({ 4436 position: 'absolute', 4437 visibility: 'visible', 4438 left: -j*(width/cells), 4439 top: -i*(height/rows) 4440 }) 4441 .parent() 4442 .addClass('effects-explode') 4443 .css({ 4444 position: 'absolute', 4445 overflow: 'hidden', 4446 width: width/cells, 4447 height: height/rows, 4448 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0), 4449 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0), 4450 opacity: o.options.mode == 'show' ? 0 : 1 4451 }).animate({ 4452 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)), 4453 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)), 4454 opacity: o.options.mode == 'show' ? 1 : 0 4455 }, o.duration || 500); 4456 } 4457 } 4458 4459 // Set a timeout, to call the callback approx. when the other animations have finished 4460 setTimeout(function() { 4461 4462 o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide(); 4463 if(o.callback) o.callback.apply(el[0]); // Callback 4464 el.dequeue(); 4465 4466 $('.effects-explode').remove(); 4467 4468 }, o.duration || 500); 4469 4470 4471 }); 4472 4473 }; 4474 4475 })(jQuery); 4476 /* 4477 * jQuery UI Effects Fold 1.6 4478 * 4479 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4480 * Dual licensed under the MIT (MIT-LICENSE.txt) 4481 * and GPL (GPL-LICENSE.txt) licenses. 4482 * 4483 * http://docs.jquery.com/UI/Effects/Fold 4484 * 4485 * Depends: 4486 * effects.core.js 4487 */ 4488 (function($) { 4489 4490 $.effects.fold = function(o) { 4491 4492 return this.queue(function() { 4493 4494 // Create element 4495 var el = $(this), props = ['position','top','left']; 4496 4497 // Set options 4498 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode 4499 var size = o.options.size || 15; // Default fold size 4500 var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value 4501 4502 // Adjust 4503 $.effects.save(el, props); el.show(); // Save & Show 4504 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper 4505 var widthFirst = ((mode == 'show') != horizFirst); 4506 var ref = widthFirst ? ['width', 'height'] : ['height', 'width']; 4507 var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()]; 4508 var percent = /([0-9]+)%/.exec(size); 4509 if(percent) size = parseInt(percent[1]) / 100 * distance[mode == 'hide' ? 0 : 1]; 4510 if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift 4511 4512 // Animation 4513 var animation1 = {}, animation2 = {}; 4514 animation1[ref[0]] = mode == 'show' ? distance[0] : size; 4515 animation2[ref[1]] = mode == 'show' ? distance[1] : 0; 4516 4517 // Animate 4518 wrapper.animate(animation1, o.duration / 2, o.options.easing) 4519 .animate(animation2, o.duration / 2, o.options.easing, function() { 4520 if(mode == 'hide') el.hide(); // Hide 4521 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 4522 if(o.callback) o.callback.apply(el[0], arguments); // Callback 4523 el.dequeue(); 4524 }); 4525 4526 }); 4527 4528 }; 4529 4530 })(jQuery); 4531 /* 4532 * jQuery UI Effects Highlight 1.6 4533 * 4534 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4535 * Dual licensed under the MIT (MIT-LICENSE.txt) 4536 * and GPL (GPL-LICENSE.txt) licenses. 4537 * 4538 * http://docs.jquery.com/UI/Effects/Highlight 4539 * 4540 * Depends: 4541 * effects.core.js 4542 */ 4543 (function($) { 4544 4545 $.effects.highlight = function(o) { 4546 4547 return this.queue(function() { 4548 4549 // Create element 4550 var el = $(this), props = ['backgroundImage','backgroundColor','opacity']; 4551 4552 // Set options 4553 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode 4554 var color = o.options.color || "#ffff99"; // Default highlight color 4555 var oldColor = el.css("backgroundColor"); 4556 4557 // Adjust 4558 $.effects.save(el, props); el.show(); // Save & Show 4559 el.css({backgroundImage: 'none', backgroundColor: color}); // Shift 4560 4561 // Animation 4562 var animation = {backgroundColor: oldColor }; 4563 if (mode == "hide") animation['opacity'] = 0; 4564 4565 // Animate 4566 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { 4567 if(mode == "hide") el.hide(); 4568 $.effects.restore(el, props); 4569 if (mode == "show" && $.browser.msie) this.style.removeAttribute('filter'); 4570 if(o.callback) o.callback.apply(this, arguments); 4571 el.dequeue(); 4572 }}); 4573 4574 }); 4575 4576 }; 4577 4578 })(jQuery); 4579 /* 4580 * jQuery UI Effects Pulsate 1.6 4581 * 4582 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4583 * Dual licensed under the MIT (MIT-LICENSE.txt) 4584 * and GPL (GPL-LICENSE.txt) licenses. 4585 * 4586 * http://docs.jquery.com/UI/Effects/Pulsate 4587 * 4588 * Depends: 4589 * effects.core.js 4590 */ 4591 (function($) { 4592 4593 $.effects.pulsate = function(o) { 4594 4595 return this.queue(function() { 4596 4597 // Create element 4598 var el = $(this); 4599 4600 // Set options 4601 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode 4602 var times = o.options.times || 5; // Default # of times 4603 4604 // Adjust 4605 if (mode == 'hide') times--; 4606 if (el.is(':hidden')) { // Show fadeIn 4607 el.css('opacity', 0); 4608 el.show(); // Show 4609 el.animate({opacity: 1}, o.duration / 2, o.options.easing); 4610 times = times-2; 4611 } 4612 4613 // Animate 4614 for (var i = 0; i < times; i++) { // Pulsate 4615 el.animate({opacity: 0}, o.duration / 2, o.options.easing).animate({opacity: 1}, o.duration / 2, o.options.easing); 4616 }; 4617 if (mode == 'hide') { // Last Pulse 4618 el.animate({opacity: 0}, o.duration / 2, o.options.easing, function(){ 4619 el.hide(); // Hide 4620 if(o.callback) o.callback.apply(this, arguments); // Callback 4621 }); 4622 } else { 4623 el.animate({opacity: 0}, o.duration / 2, o.options.easing).animate({opacity: 1}, o.duration / 2, o.options.easing, function(){ 4624 if(o.callback) o.callback.apply(this, arguments); // Callback 4625 }); 4626 }; 4627 el.queue('fx', function() { el.dequeue(); }); 4628 el.dequeue(); 4629 }); 4630 4631 }; 4632 4633 })(jQuery); 4634 /* 4635 * jQuery UI Effects Scale 1.6 4636 * 4637 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4638 * Dual licensed under the MIT (MIT-LICENSE.txt) 4639 * and GPL (GPL-LICENSE.txt) licenses. 4640 * 4641 * http://docs.jquery.com/UI/Effects/Scale 4642 * 4643 * Depends: 4644 * effects.core.js 4645 */ 4646 (function($) { 4647 4648 $.effects.puff = function(o) { 4649 4650 return this.queue(function() { 4651 4652 // Create element 4653 var el = $(this); 4654 4655 // Set options 4656 var options = $.extend(true, {}, o.options); 4657 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode 4658 var percent = parseInt(o.options.percent) || 150; // Set default puff percent 4659 options.fade = true; // It's not a puff if it doesn't fade! :) 4660 var original = {height: el.height(), width: el.width()}; // Save original 4661 4662 // Adjust 4663 var factor = percent / 100; 4664 el.from = (mode == 'hide') ? original : {height: original.height * factor, width: original.width * factor}; 4665 4666 // Animation 4667 options.from = el.from; 4668 options.percent = (mode == 'hide') ? percent : 100; 4669 options.mode = mode; 4670 4671 // Animate 4672 el.effect('scale', options, o.duration, o.callback); 4673 el.dequeue(); 4674 }); 4675 4676 }; 4677 4678 $.effects.scale = function(o) { 4679 4680 return this.queue(function() { 4681 4682 // Create element 4683 var el = $(this); 4684 4685 // Set options 4686 var options = $.extend(true, {}, o.options); 4687 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode 4688 var percent = parseInt(o.options.percent) || (parseInt(o.options.percent) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent 4689 var direction = o.options.direction || 'both'; // Set default axis 4690 var origin = o.options.origin; // The origin of the scaling 4691 if (mode != 'effect') { // Set default origin and restore for show/hide 4692 options.origin = origin || ['middle','center']; 4693 options.restore = true; 4694 } 4695 var original = {height: el.height(), width: el.width()}; // Save original 4696 el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state 4697 4698 // Adjust 4699 var factor = { // Set scaling factor 4700 y: direction != 'horizontal' ? (percent / 100) : 1, 4701 x: direction != 'vertical' ? (percent / 100) : 1 4702 }; 4703 el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state 4704 4705 if (o.options.fade) { // Fade option to support puff 4706 if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;}; 4707 if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;}; 4708 }; 4709 4710 // Animation 4711 options.from = el.from; options.to = el.to; options.mode = mode; 4712 4713 // Animate 4714 el.effect('size', options, o.duration, o.callback); 4715 el.dequeue(); 4716 }); 4717 4718 }; 4719 4720 $.effects.size = function(o) { 4721 4722 return this.queue(function() { 4723 4724 // Create element 4725 var el = $(this), props = ['position','top','left','width','height','overflow','opacity']; 4726 var props1 = ['position','top','left','overflow','opacity']; // Always restore 4727 var props2 = ['width','height','overflow']; // Copy for children 4728 var cProps = ['fontSize']; 4729 var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom']; 4730 var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight']; 4731 4732 // Set options 4733 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode 4734 var restore = o.options.restore || false; // Default restore 4735 var scale = o.options.scale || 'both'; // Default scale mode 4736 var origin = o.options.origin; // The origin of the sizing 4737 var original = {height: el.height(), width: el.width()}; // Save original 4738 el.from = o.options.from || original; // Default from state 4739 el.to = o.options.to || original; // Default to state 4740 // Adjust 4741 if (origin) { // Calculate baseline shifts 4742 var baseline = $.effects.getBaseline(origin, original); 4743 el.from.top = (original.height - el.from.height) * baseline.y; 4744 el.from.left = (original.width - el.from.width) * baseline.x; 4745 el.to.top = (original.height - el.to.height) * baseline.y; 4746 el.to.left = (original.width - el.to.width) * baseline.x; 4747 }; 4748 var factor = { // Set scaling factor 4749 from: {y: el.from.height / original.height, x: el.from.width / original.width}, 4750 to: {y: el.to.height / original.height, x: el.to.width / original.width} 4751 }; 4752 if (scale == 'box' || scale == 'both') { // Scale the css box 4753 if (factor.from.y != factor.to.y) { // Vertical props scaling 4754 props = props.concat(vProps); 4755 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from); 4756 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to); 4757 }; 4758 if (factor.from.x != factor.to.x) { // Horizontal props scaling 4759 props = props.concat(hProps); 4760 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from); 4761 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to); 4762 }; 4763 }; 4764 if (scale == 'content' || scale == 'both') { // Scale the content 4765 if (factor.from.y != factor.to.y) { // Vertical props scaling 4766 props = props.concat(cProps); 4767 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from); 4768 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to); 4769 }; 4770 }; 4771 $.effects.save(el, restore ? props : props1); el.show(); // Save & Show 4772 $.effects.createWrapper(el); // Create Wrapper 4773 el.css('overflow','hidden').css(el.from); // Shift 4774 4775 // Animate 4776 if (scale == 'content' || scale == 'both') { // Scale the children 4777 vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size 4778 hProps = hProps.concat(['marginLeft','marginRight']); // Add margins 4779 props2 = props.concat(vProps).concat(hProps); // Concat 4780 el.find("*[width]").each(function(){ 4781 child = $(this); 4782 if (restore) $.effects.save(child, props2); 4783 var c_original = {height: child.height(), width: child.width()}; // Save original 4784 child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x}; 4785 child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x}; 4786 if (factor.from.y != factor.to.y) { // Vertical props scaling 4787 child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from); 4788 child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to); 4789 }; 4790 if (factor.from.x != factor.to.x) { // Horizontal props scaling 4791 child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from); 4792 child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to); 4793 }; 4794 child.css(child.from); // Shift children 4795 child.animate(child.to, o.duration, o.options.easing, function(){ 4796 if (restore) $.effects.restore(child, props2); // Restore children 4797 }); // Animate children 4798 }); 4799 }; 4800 4801 // Animate 4802 el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { 4803 if(mode == 'hide') el.hide(); // Hide 4804 $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore 4805 if(o.callback) o.callback.apply(this, arguments); // Callback 4806 el.dequeue(); 4807 }}); 4808 4809 }); 4810 4811 }; 4812 4813 })(jQuery); 4814 /* 4815 * jQuery UI Effects Shake 1.6 4816 * 4817 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4818 * Dual licensed under the MIT (MIT-LICENSE.txt) 4819 * and GPL (GPL-LICENSE.txt) licenses. 4820 * 4821 * http://docs.jquery.com/UI/Effects/Shake 4822 * 4823 * Depends: 4824 * effects.core.js 4825 */ 4826 (function($) { 4827 4828 $.effects.shake = function(o) { 4829 4830 return this.queue(function() { 4831 4832 // Create element 4833 var el = $(this), props = ['position','top','left']; 4834 4835 // Set options 4836 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode 4837 var direction = o.options.direction || 'left'; // Default direction 4838 var distance = o.options.distance || 20; // Default distance 4839 var times = o.options.times || 3; // Default # of times 4840 var speed = o.duration || o.options.duration || 140; // Default speed per shake 4841 4842 // Adjust 4843 $.effects.save(el, props); el.show(); // Save & Show 4844 $.effects.createWrapper(el); // Create Wrapper 4845 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; 4846 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; 4847 4848 // Animation 4849 var animation = {}, animation1 = {}, animation2 = {}; 4850 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance; 4851 animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2; 4852 animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2; 4853 4854 // Animate 4855 el.animate(animation, speed, o.options.easing); 4856 for (var i = 1; i < times; i++) { // Shakes 4857 el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing); 4858 }; 4859 el.animate(animation1, speed, o.options.easing). 4860 animate(animation, speed / 2, o.options.easing, function(){ // Last shake 4861 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 4862 if(o.callback) o.callback.apply(this, arguments); // Callback 4863 }); 4864 el.queue('fx', function() { el.dequeue(); }); 4865 el.dequeue(); 4866 }); 4867 4868 }; 4869 4870 })(jQuery); 4871 /* 4872 * jQuery UI Effects Slide 1.6 4873 * 4874 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4875 * Dual licensed under the MIT (MIT-LICENSE.txt) 4876 * and GPL (GPL-LICENSE.txt) licenses. 4877 * 4878 * http://docs.jquery.com/UI/Effects/Slide 4879 * 4880 * Depends: 4881 * effects.core.js 4882 */ 4883 (function($) { 4884 4885 $.effects.slide = function(o) { 4886 4887 return this.queue(function() { 4888 4889 // Create element 4890 var el = $(this), props = ['position','top','left']; 4891 4892 // Set options 4893 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode 4894 var direction = o.options.direction || 'left'; // Default Direction 4895 4896 // Adjust 4897 $.effects.save(el, props); el.show(); // Save & Show 4898 $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper 4899 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; 4900 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; 4901 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true})); 4902 if (mode == 'show') el.css(ref, motion == 'pos' ? -distance : distance); // Shift 4903 4904 // Animation 4905 var animation = {}; 4906 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance; 4907 4908 // Animate 4909 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { 4910 if(mode == 'hide') el.hide(); // Hide 4911 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 4912 if(o.callback) o.callback.apply(this, arguments); // Callback 4913 el.dequeue(); 4914 }}); 4915 4916 }); 4917 4918 }; 4919 4920 })(jQuery); 4921 /* 4922 * jQuery UI Effects Transfer 1.6 4923 * 4924 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4925 * Dual licensed under the MIT (MIT-LICENSE.txt) 4926 * and GPL (GPL-LICENSE.txt) licenses. 4927 * 4928 * http://docs.jquery.com/UI/Effects/Transfer 4929 * 4930 * Depends: 4931 * effects.core.js 4932 */ 4933 (function($) { 4934 4935 $.effects.transfer = function(o) { 4936 4937 return this.queue(function() { 4938 4939 // Create element 4940 var el = $(this); 4941 4942 // Set options 4943 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode 4944 var target = $(o.options.to); // Find Target 4945 var position = el.offset(); 4946 var transfer = $('<div class="ui-effects-transfer"></div>').appendTo(document.body); 4947 if(o.options.className) transfer.addClass(o.options.className); 4948 4949 // Set target css 4950 transfer.addClass(o.options.className); 4951 transfer.css({ 4952 top: position.top, 4953 left: position.left, 4954 height: el.outerHeight() - parseInt(transfer.css('borderTopWidth')) - parseInt(transfer.css('borderBottomWidth')), 4955 width: el.outerWidth() - parseInt(transfer.css('borderLeftWidth')) - parseInt(transfer.css('borderRightWidth')), 4956 position: 'absolute' 4957 }); 4958 4959 // Animation 4960 position = target.offset(); 4961 animation = { 4962 top: position.top, 4963 left: position.left, 4964 height: target.outerHeight() - parseInt(transfer.css('borderTopWidth')) - parseInt(transfer.css('borderBottomWidth')), 4965 width: target.outerWidth() - parseInt(transfer.css('borderLeftWidth')) - parseInt(transfer.css('borderRightWidth')) 4966 }; 4967 4968 // Animate 4969 transfer.animate(animation, o.duration, o.options.easing, function() { 4970 transfer.remove(); // Remove div 4971 if(o.callback) o.callback.apply(el[0], arguments); // Callback 4972 el.dequeue(); 4973 }); 4974 4975 }); 4976 4977 }; 4978 4979 })(jQuery); 4980 /* 4981 * jQuery UI Accordion 1.6 4982 * 4983 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 4984 * Dual licensed under the MIT (MIT-LICENSE.txt) 4985 * and GPL (GPL-LICENSE.txt) licenses. 4986 * 4987 * http://docs.jquery.com/UI/Accordion 4988 * 4989 * Depends: 4990 * ui.core.js 4991 */ 4992 (function($) { 4993 4994 $.widget("ui.accordion", { 4995 4996 _init: function() { 4997 var options = this.options; 4998 4999 if ( options.navigation ) { 5000 var current = this.element.find("a").filter(options.navigationFilter); 5001 if ( current.length ) { 5002 if ( current.filter(options.header).length ) { 5003 options.active = current; 5004 } else { 5005 options.active = current.parent().parent().prev(); 5006 current.addClass("current"); 5007 } 5008 } 5009 } 5010 5011 // calculate active if not specified, using the first header 5012 options.headers = this.element.find(options.header); 5013 options.active = findActive(options.headers, options.active); 5014 5015 // IE7-/Win - Extra vertical space in Lists fixed 5016 if ($.browser.msie) { 5017 this.element.find('a').css('zoom', '1'); 5018 } 5019 5020 if (!this.element.hasClass("ui-accordion")) { 5021 this.element.addClass("ui-accordion"); 5022 $('<span class="ui-accordion-left"></span>').insertBefore(options.headers); 5023 $('<span class="ui-accordion-right"></span>').appendTo(options.headers); 5024 options.headers.addClass("ui-accordion-header"); 5025 } 5026 5027 var maxHeight; 5028 if ( options.fillSpace ) { 5029 maxHeight = this.element.parent().height(); 5030 options.headers.each(function() { 5031 maxHeight -= $(this).outerHeight(); 5032 }); 5033 var maxPadding = 0; 5034 options.headers.next().each(function() { 5035 maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height()); 5036 }).height(maxHeight - maxPadding); 5037 } else if ( options.autoHeight ) { 5038 maxHeight = 0; 5039 options.headers.next().each(function() { 5040 maxHeight = Math.max(maxHeight, $(this).outerHeight()); 5041 }).height(maxHeight); 5042 } 5043 5044 this.element.attr('role','tablist'); 5045 5046 var self=this; 5047 options.headers 5048 .attr('role','tab') 5049 .bind('keydown', function(event) { return self._keydown(event); }) 5050 .next() 5051 .attr('role','tabpanel'); 5052 5053 options.headers 5054 .not(options.active || "") 5055 .attr('aria-expanded','false') 5056 .attr("tabIndex", "-1") 5057 .next() 5058 .hide(); 5059 5060 // make sure at least one header is in the tab order 5061 if (!options.active.length) { 5062 options.headers.eq(0).attr('tabIndex','0'); 5063 } else { 5064 options.active 5065 .attr('aria-expanded','true') 5066 .attr("tabIndex", "0") 5067 .parent().andSelf().addClass(options.selectedClass); 5068 } 5069 5070 // only need links in taborder for Safari 5071 if (!$.browser.safari) 5072 options.headers.find('a').attr('tabIndex','-1'); 5073 5074 if (options.event) { 5075 this.element.bind((options.event) + ".accordion", clickHandler); 5076 } 5077 }, 5078 5079 destroy: function() { 5080 this.options.headers.parent().andSelf().removeClass(this.options.selectedClass); 5081 this.options.headers.prev(".ui-accordion-left").remove(); 5082 this.options.headers.children(".ui-accordion-right").remove(); 5083 this.options.headers.next().css("display", ""); 5084 if ( this.options.fillSpace || this.options.autoHeight ) { 5085 this.options.headers.next().css("height", ""); 5086 } 5087 $.removeData(this.element[0], "accordion"); 5088 5089 this.element.removeClass("ui-accordion").unbind(".accordion"); 5090 }, 5091 5092 _keydown: function(event) { 5093 if (this.options.disabled || event.altKey || event.ctrlKey) 5094 return; 5095 5096 var keyCode = $.ui.keyCode; 5097 5098 var length = this.options.headers.length; 5099 var currentIndex = this.options.headers.index(event.target); 5100 var toFocus = false; 5101 5102 switch(event.keyCode) { 5103 case keyCode.RIGHT: 5104 case keyCode.DOWN: 5105 toFocus = this.options.headers[(currentIndex + 1) % length]; 5106 break; 5107 case keyCode.LEFT: 5108 case keyCode.UP: 5109 toFocus = this.options.headers[(currentIndex - 1 + length) % length]; 5110 break; 5111 case keyCode.SPACE: 5112 case keyCode.ENTER: 5113 return clickHandler.call(this.element[0], { target: event.target }); 5114 } 5115 5116 if (toFocus) { 5117 $(event.target).attr('tabIndex','-1'); 5118 $(toFocus).attr('tabIndex','0'); 5119 toFocus.focus(); 5120 return false; 5121 } 5122 5123 return true; 5124 }, 5125 5126 activate: function(index) { 5127 // call clickHandler with custom event 5128 clickHandler.call(this.element[0], { 5129 target: findActive( this.options.headers, index )[0] 5130 }); 5131 } 5132 5133 }); 5134 5135 function scopeCallback(callback, scope) { 5136 return function() { 5137 return callback.apply(scope, arguments); 5138 }; 5139 }; 5140 5141 function completed(cancel) { 5142 // if removed while animated data can be empty 5143 if (!$.data(this, "accordion")) { 5144 return; 5145 } 5146 5147 var instance = $.data(this, "accordion"); 5148 var options = instance.options; 5149 options.running = cancel ? 0 : --options.running; 5150 if ( options.running ) { 5151 return; 5152 } 5153 if ( options.clearStyle ) { 5154 options.toShow.add(options.toHide).css({ 5155 height: "", 5156 overflow: "" 5157 }); 5158 } 5159 instance._trigger('change', null, options.data); 5160 } 5161 5162 function toggle(toShow, toHide, data, clickedActive, down) { 5163 var options = $.data(this, "accordion").options; 5164 options.toShow = toShow; 5165 options.toHide = toHide; 5166 options.data = data; 5167 var complete = scopeCallback(completed, this); 5168 5169 $.data(this, "accordion")._trigger("changestart", null, options.data); 5170 5171 // count elements to animate 5172 options.running = toHide.size() === 0 ? toShow.size() : toHide.size(); 5173 5174 if ( options.animated ) { 5175 var animOptions = {}; 5176 5177 if ( !options.alwaysOpen && clickedActive ) { 5178 animOptions = { 5179 toShow: $([]), 5180 toHide: toHide, 5181 complete: complete, 5182 down: down, 5183 autoHeight: options.autoHeight 5184 }; 5185 } else { 5186 animOptions = { 5187 toShow: toShow, 5188 toHide: toHide, 5189 complete: complete, 5190 down: down, 5191 autoHeight: options.autoHeight 5192 }; 5193 } 5194 5195 if (!options.proxied) { 5196 options.proxied = options.animated; 5197 } 5198 5199 if (!options.proxiedDuration) { 5200 options.proxiedDuration = options.duration; 5201 } 5202 5203 options.animated = $.isFunction(options.proxied) ? 5204 options.proxied(animOptions) : options.proxied; 5205 5206 options.duration = $.isFunction(options.proxiedDuration) ? 5207 options.proxiedDuration(animOptions) : options.proxiedDuration; 5208 5209 var animations = $.ui.accordion.animations, 5210 duration = options.duration, 5211 easing = options.animated; 5212 5213 if (!animations[easing]) { 5214 animations[easing] = function(options) { 5215 this.slide(options, { 5216 easing: easing, 5217 duration: duration || 700 5218 }); 5219 }; 5220 } 5221 5222 animations[easing](animOptions); 5223 5224 } else { 5225 if ( !options.alwaysOpen && clickedActive ) { 5226 toShow.toggle(); 5227 } else { 5228 toHide.hide(); 5229 toShow.show(); 5230 } 5231 complete(true); 5232 } 5233 toHide.prev().attr('aria-expanded','false').attr("tabIndex", "-1"); 5234 toShow.prev().attr('aria-expanded','true').attr("tabIndex", "0").focus();; 5235 } 5236 5237 function clickHandler(event) { 5238 var options = $.data(this, "accordion").options; 5239 if (options.disabled) { 5240 return false; 5241 } 5242 5243 // called only when using activate(false) to close all parts programmatically 5244 if ( !event.target && !options.alwaysOpen ) { 5245 options.active.parent().andSelf().toggleClass(options.selectedClass); 5246 var toHide = options.active.next(), 5247 data = { 5248 options: options, 5249 newHeader: $([]), 5250 oldHeader: options.active, 5251 newContent: $([]), 5252 oldContent: toHide 5253 }, 5254 toShow = (options.active = $([])); 5255 toggle.call(this, toShow, toHide, data ); 5256 return false; 5257 } 5258 // get the click target 5259 var clicked = $(event.target); 5260 5261 // due to the event delegation model, we have to check if one 5262 // of the parent elements is our actual header, and find that 5263 // otherwise stick with the initial target 5264 clicked = $( clicked.parents(options.header)[0] || clicked ); 5265 5266 var clickedActive = clicked[0] == options.active[0]; 5267 5268 // if animations are still active, or the active header is the target, ignore click 5269 if (options.running || (options.alwaysOpen && clickedActive)) { 5270 return false; 5271 } 5272 if (!clicked.is(options.header)) { 5273 return; 5274 } 5275 5276 // switch classes 5277 options.active.parent().andSelf().toggleClass(options.selectedClass); 5278 if ( !clickedActive ) { 5279 clicked.parent().andSelf().addClass(options.selectedClass); 5280 } 5281 5282 // find elements to show and hide 5283 var toShow = clicked.next(), 5284 toHide = options.active.next(), 5285 data = { 5286 options: options, 5287 newHeader: clickedActive && !options.alwaysOpen ? $([]) : clicked, 5288 oldHeader: options.active, 5289 newContent: clickedActive && !options.alwaysOpen ? $([]) : toShow, 5290 oldContent: toHide 5291 }, 5292 down = options.headers.index( options.active[0] ) > options.headers.index( clicked[0] ); 5293 5294 options.active = clickedActive ? $([]) : clicked; 5295 toggle.call(this, toShow, toHide, data, clickedActive, down ); 5296 5297 return false; 5298 }; 5299 5300 function findActive(headers, selector) { 5301 return selector 5302 ? typeof selector == "number" 5303 ? headers.filter(":eq(" + selector + ")") 5304 : headers.not(headers.not(selector)) 5305 : selector === false 5306 ? $([]) 5307 : headers.filter(":eq(0)"); 5308 } 5309 5310 $.extend($.ui.accordion, { 5311 version: "1.6", 5312 defaults: { 5313 autoHeight: true, 5314 alwaysOpen: true, 5315 animated: 'slide', 5316 event: "click", 5317 header: "a", 5318 navigationFilter: function() { 5319 return this.href.toLowerCase() == location.href.toLowerCase(); 5320 }, 5321 running: 0, 5322 selectedClass: "selected" 5323 }, 5324 animations: { 5325 slide: function(options, additions) { 5326 options = $.extend({ 5327 easing: "swing", 5328 duration: 300 5329 }, options, additions); 5330 if ( !options.toHide.size() ) { 5331 options.toShow.animate({height: "show"}, options); 5332 return; 5333 } 5334 var hideHeight = options.toHide.height(), 5335 showHeight = options.toShow.height(), 5336 difference = showHeight / hideHeight, 5337 padding = options.toShow.outerHeight() - options.toShow.height(), 5338 margin = options.toShow.css('marginBottom'), 5339 overflow = options.toShow.css('overflow') 5340 tmargin = options.toShow.css('marginTop'); 5341 options.toShow.css({ height: 0, overflow: 'hidden', marginTop: 0, marginBottom: -padding }).show(); 5342 options.toHide.filter(":hidden").each(options.complete).end().filter(":visible").animate({height:"hide"},{ 5343 step: function(now) { 5344 var current = (hideHeight - now) * difference; 5345 if ($.browser.msie || $.browser.opera) { 5346 current = Math.ceil(current); 5347 } 5348 options.toShow.height( current ); 5349 }, 5350 duration: options.duration, 5351 easing: options.easing, 5352 complete: function() { 5353 if ( !options.autoHeight ) { 5354 options.toShow.css("height", "auto"); 5355 } 5356 options.toShow.css({marginTop: tmargin, marginBottom: margin, overflow: overflow}); 5357 options.complete(); 5358 } 5359 }); 5360 }, 5361 bounceslide: function(options) { 5362 this.slide(options, { 5363 easing: options.down ? "easeOutBounce" : "swing", 5364 duration: options.down ? 1000 : 200 5365 }); 5366 }, 5367 easeslide: function(options) { 5368 this.slide(options, { 5369 easing: "easeinout", 5370 duration: 700 5371 }); 5372 } 5373 } 5374 }); 5375 5376 })(jQuery); 5377 /* 5378 * jQuery UI Datepicker 1.6 5379 * 5380 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 5381 * Dual licensed under the MIT (MIT-LICENSE.txt) 5382 * and GPL (GPL-LICENSE.txt) licenses. 5383 * 5384 * http://docs.jquery.com/UI/Datepicker 5385 * 5386 * Depends: 5387 * ui.core.js 5388 */ 5389 5390 (function($) { // hide the namespace 5391 5392 $.extend($.ui, { datepicker: { version: "1.6" } }); 5393 5394 var PROP_NAME = 'datepicker'; 5395 5396 /* Date picker manager. 5397 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 5398 Settings for (groups of) date pickers are maintained in an instance object, 5399 allowing multiple different settings on the same page. */ 5400 5401 function Datepicker() { 5402 this.debug = false; // Change this to true to start debugging 5403 this._curInst = null; // The current instance in use 5404 this._keyEvent = false; // If the last event was a key event 5405 this._disabledInputs = []; // List of date picker inputs that have been disabled 5406 this._datepickerShowing = false; // True if the popup picker is showing , false if not 5407 this._inDialog = false; // True if showing within a "dialog", false if not 5408 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division 5409 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class 5410 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class 5411 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class 5412 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class 5413 this._promptClass = 'ui-datepicker-prompt'; // The name of the dialog prompt marker class 5414 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class 5415 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class 5416 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class 5417 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class 5418 this._weekOverClass = 'ui-datepicker-week-over'; // The name of the week hover marker class 5419 this.regional = []; // Available regional settings, indexed by language code 5420 this.regional[''] = { // Default regional settings 5421 clearText: 'Clear', // Display text for clear link 5422 clearStatus: 'Erase the current date', // Status text for clear link 5423 closeText: 'Close', // Display text for close link 5424 closeStatus: 'Close without change', // Status text for close link 5425 prevText: '<Prev', // Display text for previous month link 5426 prevStatus: 'Show the previous month', // Status text for previous month link 5427 prevBigText: '<<', // Display text for previous year link 5428 prevBigStatus: 'Show the previous year', // Status text for previous year link 5429 nextText: 'Next>', // Display text for next month link 5430 nextStatus: 'Show the next month', // Status text for next month link 5431 nextBigText: '>>', // Display text for next year link 5432 nextBigStatus: 'Show the next year', // Status text for next year link 5433 currentText: 'Today', // Display text for current month link 5434 currentStatus: 'Show the current month', // Status text for current month link 5435 monthNames: ['January','February','March','April','May','June', 5436 'July','August','September','October','November','December'], // Names of months for drop-down and formatting 5437 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting 5438 monthStatus: 'Show a different month', // Status text for selecting a month 5439 yearStatus: 'Show a different year', // Status text for selecting a year 5440 weekHeader: 'Wk', // Header for the week of the year column 5441 weekStatus: 'Week of the year', // Status text for the week of the year column 5442 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting 5443 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting 5444 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday 5445 dayStatus: 'Set DD as first week day', // Status text for the day of the week selection 5446 dateStatus: 'Select DD, M d', // Status text for the date selection 5447 dateFormat: 'mm/dd/yy', // See format options on parseDate 5448 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 5449 initStatus: 'Select a date', // Initial Status text on opening 5450 isRTL: false // True if right-to-left language, false if left-to-right 5451 }; 5452 this._defaults = { // Global defaults for all the date picker instances 5453 showOn: 'focus', // 'focus' for popup on focus, 5454 // 'button' for trigger button, or 'both' for either 5455 showAnim: 'show', // Name of jQuery animation for popup 5456 showOptions: {}, // Options for enhanced animations 5457 defaultDate: null, // Used when field is blank: actual date, 5458 // +/-number for offset from today, null for today 5459 appendText: '', // Display text following the input box, e.g. showing the format 5460 buttonText: '...', // Text for trigger button 5461 buttonImage: '', // URL for trigger button image 5462 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 5463 closeAtTop: true, // True to have the clear/close at the top, 5464 // false to have them at the bottom 5465 mandatory: false, // True to hide the Clear link, false to include it 5466 hideIfNoPrevNext: false, // True to hide next/previous month links 5467 // if not applicable, false to just disable them 5468 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 5469 showBigPrevNext: false, // True to show big prev/next links 5470 gotoCurrent: false, // True if today link goes back to current selection instead 5471 changeMonth: true, // True if month can be selected directly, false if only prev/next 5472 changeYear: true, // True if year can be selected directly, false if only prev/next 5473 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 5474 yearRange: '-10:+10', // Range of years to display in drop-down, 5475 // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn) 5476 changeFirstDay: true, // True to click on day name to change, false to remain as set 5477 highlightWeek: false, // True to highlight the selected week 5478 showOtherMonths: false, // True to show dates in other months, false to leave blank 5479 showWeeks: false, // True to show week of the year, false to omit 5480 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 5481 // takes a Date and returns the number of the week for it 5482 shortYearCutoff: '+10', // Short year values < this are in the current century, 5483 // > this are in the previous century, 5484 // string value starting with '+' for current year + value 5485 showStatus: false, // True to show status bar at bottom, false to not show it 5486 statusForDate: this.dateStatus, // Function to provide status text for a date - 5487 // takes date and instance as parameters, returns display text 5488 minDate: null, // The earliest selectable date, or null for no limit 5489 maxDate: null, // The latest selectable date, or null for no limit 5490 duration: 'normal', // Duration of display/closure 5491 beforeShowDay: null, // Function that takes a date and returns an array with 5492 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', 5493 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 5494 beforeShow: null, // Function that takes an input field and 5495 // returns a set of custom settings for the date picker 5496 onSelect: null, // Define a callback function when a date is selected 5497 onChangeMonthYear: null, // Define a callback function when the month or year is changed 5498 onClose: null, // Define a callback function when the datepicker is closed 5499 numberOfMonths: 1, // Number of months to show at a time 5500 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 5501 stepMonths: 1, // Number of months to step back/forward 5502 stepBigMonths: 12, // Number of months to step back/forward for the big links 5503 rangeSelect: false, // Allows for selecting a date range on one date picker 5504 rangeSeparator: ' - ', // Text between two dates in a range 5505 altField: '', // Selector for an alternate field to store selected dates into 5506 altFormat: '', // The date format to use for the alternate field 5507 constrainInput: true // The input is constrained by the current date format 5508 }; 5509 $.extend(this._defaults, this.regional['']); 5510 this.dpDiv = $('<div id="' + this._mainDivId + '" style="display: none;"></div>'); 5511 } 5512 5513 $.extend(Datepicker.prototype, { 5514 /* Class name added to elements to indicate already configured with a date picker. */ 5515 markerClassName: 'hasDatepicker', 5516 5517 /* Debug logging (if enabled). */ 5518 log: function () { 5519 if (this.debug) 5520 console.log.apply('', arguments); 5521 }, 5522 5523 /* Override the default settings for all instances of the date picker. 5524 @param settings object - the new settings to use as defaults (anonymous object) 5525 @return the manager object */ 5526 setDefaults: function(settings) { 5527 extendRemove(this._defaults, settings || {}); 5528 return this; 5529 }, 5530 5531 /* Attach the date picker to a jQuery selection. 5532 @param target element - the target input field or division or span 5533 @param settings object - the new settings to use for this date picker instance (anonymous) */ 5534 _attachDatepicker: function(target, settings) { 5535 // check for settings on the control itself - in namespace 'date:' 5536 var inlineSettings = null; 5537 for (var attrName in this._defaults) { 5538 var attrValue = target.getAttribute('date:' + attrName); 5539 if (attrValue) { 5540 inlineSettings = inlineSettings || {}; 5541 try { 5542 inlineSettings[attrName] = eval(attrValue); 5543 } catch (err) { 5544 inlineSettings[attrName] = attrValue; 5545 } 5546 } 5547 } 5548 var nodeName = target.nodeName.toLowerCase(); 5549 var inline = (nodeName == 'div' || nodeName == 'span'); 5550 if (!target.id) 5551 target.id = 'dp' + (++this.uuid); 5552 var inst = this._newInst($(target), inline); 5553 inst.settings = $.extend({}, settings || {}, inlineSettings || {}); 5554 if (nodeName == 'input') { 5555 this._connectDatepicker(target, inst); 5556 } else if (inline) { 5557 this._inlineDatepicker(target, inst); 5558 } 5559 }, 5560 5561 /* Create a new instance object. */ 5562 _newInst: function(target, inline) { 5563 var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars 5564 return {id: id, input: target, // associated target 5565 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 5566 drawMonth: 0, drawYear: 0, // month being drawn 5567 inline: inline, // is datepicker inline or not 5568 dpDiv: (!inline ? this.dpDiv : // presentation div 5569 $('<div class="' + this._inlineClass + '"></div>'))}; 5570 }, 5571 5572 /* Attach the date picker to an input field. */ 5573 _connectDatepicker: function(target, inst) { 5574 var input = $(target); 5575 if (input.hasClass(this.markerClassName)) 5576 return; 5577 var appendText = this._get(inst, 'appendText'); 5578 var isRTL = this._get(inst, 'isRTL'); 5579 if (appendText) 5580 input[isRTL ? 'before' : 'after']('<span class="' + this._appendClass + '">' + appendText + '</span>'); 5581 var showOn = this._get(inst, 'showOn'); 5582 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field 5583 input.focus(this._showDatepicker); 5584 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked 5585 var buttonText = this._get(inst, 'buttonText'); 5586 var buttonImage = this._get(inst, 'buttonImage'); 5587 var trigger = $(this._get(inst, 'buttonImageOnly') ? 5588 $('<img/>').addClass(this._triggerClass). 5589 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 5590 $('<button type="button"></button>').addClass(this._triggerClass). 5591 html(buttonImage == '' ? buttonText : $('<img/>').attr( 5592 { src:buttonImage, alt:buttonText, title:buttonText }))); 5593 input[isRTL ? 'before' : 'after'](trigger); 5594 trigger.click(function() { 5595 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target) 5596 $.datepicker._hideDatepicker(); 5597 else 5598 $.datepicker._showDatepicker(target); 5599 return false; 5600 }); 5601 } 5602 input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress). 5603 bind("setData.datepicker", function(event, key, value) { 5604 inst.settings[key] = value; 5605 }).bind("getData.datepicker", function(event, key) { 5606 return this._get(inst, key); 5607 }); 5608 $.data(target, PROP_NAME, inst); 5609 }, 5610 5611 /* Attach an inline date picker to a div. */ 5612 _inlineDatepicker: function(target, inst) { 5613 var divSpan = $(target); 5614 if (divSpan.hasClass(this.markerClassName)) 5615 return; 5616 divSpan.addClass(this.markerClassName).append(inst.dpDiv). 5617 bind("setData.datepicker", function(event, key, value){ 5618 inst.settings[key] = value; 5619 }).bind("getData.datepicker", function(event, key){ 5620 return this._get(inst, key); 5621 }); 5622 $.data(target, PROP_NAME, inst); 5623 this._setDate(inst, this._getDefaultDate(inst)); 5624 this._updateDatepicker(inst); 5625 this._updateAlternate(inst); 5626 }, 5627 5628 /* Pop-up the date picker in a "dialog" box. 5629 @param input element - ignored 5630 @param dateText string - the initial date to display (in the current format) 5631 @param onSelect function - the function(dateText) to call when a date is selected 5632 @param settings object - update the dialog date picker instance's settings (anonymous object) 5633 @param pos int[2] - coordinates for the dialog's position within the screen or 5634 event - with x/y coordinates or 5635 leave empty for default (screen centre) 5636 @return the manager object */ 5637 _dialogDatepicker: function(input, dateText, onSelect, settings, pos) { 5638 var inst = this._dialogInst; // internal instance 5639 if (!inst) { 5640 var id = 'dp' + (++this.uuid); 5641 this._dialogInput = $('<input type="text" id="' + id + 5642 '" size="1" style="position: absolute; top: -100px;"/>'); 5643 this._dialogInput.keydown(this._doKeyDown); 5644 $('body').append(this._dialogInput); 5645 inst = this._dialogInst = this._newInst(this._dialogInput, false); 5646 inst.settings = {}; 5647 $.data(this._dialogInput[0], PROP_NAME, inst); 5648 } 5649 extendRemove(inst.settings, settings || {}); 5650 this._dialogInput.val(dateText); 5651 5652 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 5653 if (!this._pos) { 5654 var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; 5655 var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; 5656 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 5657 var scrollY = document.documentElement.scrollTop || document.body.scrollTop; 5658 this._pos = // should use actual width/height below 5659 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 5660 } 5661 5662 // move input on screen for focus, but hidden behind dialog 5663 this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px'); 5664 inst.settings.onSelect = onSelect; 5665 this._inDialog = true; 5666 this.dpDiv.addClass(this._dialogClass); 5667 this._showDatepicker(this._dialogInput[0]); 5668 if ($.blockUI) 5669 $.blockUI(this.dpDiv); 5670 $.data(this._dialogInput[0], PROP_NAME, inst); 5671 return this; 5672 }, 5673 5674 /* Detach a datepicker from its control. 5675 @param target element - the target input field or division or span */ 5676 _destroyDatepicker: function(target) { 5677 var $target = $(target); 5678 if (!$target.hasClass(this.markerClassName)) { 5679 return; 5680 } 5681 var nodeName = target.nodeName.toLowerCase(); 5682 $.removeData(target, PROP_NAME); 5683 if (nodeName == 'input') { 5684 $target.siblings('.' + this._appendClass).remove().end(). 5685 siblings('.' + this._triggerClass).remove().end(). 5686 removeClass(this.markerClassName). 5687 unbind('focus', this._showDatepicker). 5688 unbind('keydown', this._doKeyDown). 5689 unbind('keypress', this._doKeyPress); 5690 } else if (nodeName == 'div' || nodeName == 'span') 5691 $target.removeClass(this.markerClassName).empty(); 5692 }, 5693 5694 /* Enable the date picker to a jQuery selection. 5695 @param target element - the target input field or division or span */ 5696 _enableDatepicker: function(target) { 5697 var $target = $(target); 5698 if (!$target.hasClass(this.markerClassName)) { 5699 return; 5700 } 5701 var nodeName = target.nodeName.toLowerCase(); 5702 if (nodeName == 'input') { 5703 target.disabled = false; 5704 $target.siblings('button.' + this._triggerClass). 5705 each(function() { this.disabled = false; }).end(). 5706 siblings('img.' + this._triggerClass). 5707 css({opacity: '1.0', cursor: ''}); 5708 } 5709 else if (nodeName == 'div' || nodeName == 'span') { 5710 $target.children('.' + this._disableClass).remove(); 5711 } 5712 this._disabledInputs = $.map(this._disabledInputs, 5713 function(value) { return (value == target ? null : value); }); // delete entry 5714 }, 5715 5716 /* Disable the date picker to a jQuery selection. 5717 @param target element - the target input field or division or span */ 5718 _disableDatepicker: function(target) { 5719 var $target = $(target); 5720 if (!$target.hasClass(this.markerClassName)) { 5721 return; 5722 } 5723 var nodeName = target.nodeName.toLowerCase(); 5724 if (nodeName == 'input') { 5725 target.disabled = true; 5726 $target.siblings('button.' + this._triggerClass). 5727 each(function() { this.disabled = true; }).end(). 5728 siblings('img.' + this._triggerClass). 5729 css({opacity: '0.5', cursor: 'default'}); 5730 } 5731 else if (nodeName == 'div' || nodeName == 'span') { 5732 var inline = $target.children('.' + this._inlineClass); 5733 var offset = inline.offset(); 5734 var relOffset = {left: 0, top: 0}; 5735 inline.parents().each(function() { 5736 if ($(this).css('position') == 'relative') { 5737 relOffset = $(this).offset(); 5738 return false; 5739 } 5740 }); 5741 $target.prepend('<div class="' + this._disableClass + '" style="' + 5742 ($.browser.msie ? 'background-color: transparent; ' : '') + 5743 'width: ' + inline.width() + 'px; height: ' + inline.height() + 5744 'px; left: ' + (offset.left - relOffset.left) + 5745 'px; top: ' + (offset.top - relOffset.top) + 'px;"></div>'); 5746 } 5747 this._disabledInputs = $.map(this._disabledInputs, 5748 function(value) { return (value == target ? null : value); }); // delete entry 5749 this._disabledInputs[this._disabledInputs.length] = target; 5750 }, 5751 5752 /* Is the first field in a jQuery collection disabled as a datepicker? 5753 @param target element - the target input field or division or span 5754 @return boolean - true if disabled, false if enabled */ 5755 _isDisabledDatepicker: function(target) { 5756 if (!target) 5757 return false; 5758 for (var i = 0; i < this._disabledInputs.length; i++) { 5759 if (this._disabledInputs[i] == target) 5760 return true; 5761 } 5762 return false; 5763 }, 5764 5765 /* Retrieve the instance data for the target control. 5766 @param target element - the target input field or division or span 5767 @return object - the associated instance data 5768 @throws error if a jQuery problem getting data */ 5769 _getInst: function(target) { 5770 try { 5771 return $.data(target, PROP_NAME); 5772 } 5773 catch (err) { 5774 throw 'Missing instance data for this datepicker'; 5775 } 5776 }, 5777 5778 /* Update the settings for a date picker attached to an input field or division. 5779 @param target element - the target input field or division or span 5780 @param name object - the new settings to update or 5781 string - the name of the setting to change or 5782 @param value any - the new value for the setting (omit if above is an object) */ 5783 _optionDatepicker: function(target, name, value) { 5784 var settings = name || {}; 5785 if (typeof name == 'string') { 5786 settings = {}; 5787 settings[name] = value; 5788 } 5789 var inst = this._getInst(target); 5790 if (inst) { 5791 if (this._curInst == inst) { 5792 this._hideDatepicker(null); 5793 } 5794 extendRemove(inst.settings, settings); 5795 var date = new Date(); 5796 extendRemove(inst, {rangeStart: null, // start of range 5797 endDay: null, endMonth: null, endYear: null, // end of range 5798 selectedDay: date.getDate(), selectedMonth: date.getMonth(), 5799 selectedYear: date.getFullYear(), // starting point 5800 currentDay: date.getDate(), currentMonth: date.getMonth(), 5801 currentYear: date.getFullYear(), // current selection 5802 drawMonth: date.getMonth(), drawYear: date.getFullYear()}); // month being drawn 5803 this._updateDatepicker(inst); 5804 } 5805 }, 5806 5807 // change method deprecated 5808 _changeDatepicker: function(target, name, value) { 5809 this._optionDatepicker(target, name, value); 5810 }, 5811 5812 /* Redraw the date picker attached to an input field or division. 5813 @param target element - the target input field or division or span */ 5814 _refreshDatepicker: function(target) { 5815 var inst = this._getInst(target); 5816 if (inst) { 5817 this._updateDatepicker(inst); 5818 } 5819 }, 5820 5821 /* Set the dates for a jQuery selection. 5822 @param target element - the target input field or division or span 5823 @param date Date - the new date 5824 @param endDate Date - the new end date for a range (optional) */ 5825 _setDateDatepicker: function(target, date, endDate) { 5826 var inst = this._getInst(target); 5827 if (inst) { 5828 this._setDate(inst, date, endDate); 5829 this._updateDatepicker(inst); 5830 this._updateAlternate(inst); 5831 } 5832 }, 5833 5834 /* Get the date(s) for the first entry in a jQuery selection. 5835 @param target element - the target input field or division or span 5836 @return Date - the current date or 5837 Date[2] - the current dates for a range */ 5838 _getDateDatepicker: function(target) { 5839 var inst = this._getInst(target); 5840 if (inst && !inst.inline) 5841 this._setDateFromField(inst); 5842 return (inst ? this._getDate(inst) : null); 5843 }, 5844 5845 /* Handle keystrokes. */ 5846 _doKeyDown: function(event) { 5847 var inst = $.datepicker._getInst(event.target); 5848 var handled = true; 5849 inst._keyEvent = true; 5850 if ($.datepicker._datepickerShowing) 5851 switch (event.keyCode) { 5852 case 9: $.datepicker._hideDatepicker(null, ''); 5853 break; // hide on tab out 5854 case 13: var sel = $('td.' + $.datepicker._dayOverClass + 5855 ', td.' + $.datepicker._currentClass, inst.dpDiv); 5856 if (sel[0]) 5857 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 5858 else 5859 $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration')); 5860 return false; // don't submit the form 5861 break; // select the value on enter 5862 case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration')); 5863 break; // hide on escape 5864 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 5865 -$.datepicker._get(inst, 'stepBigMonths') : 5866 -$.datepicker._get(inst, 'stepMonths')), 'M'); 5867 break; // previous month/year on page up/+ ctrl 5868 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 5869 +$.datepicker._get(inst, 'stepBigMonths') : 5870 +$.datepicker._get(inst, 'stepMonths')), 'M'); 5871 break; // next month/year on page down/+ ctrl 5872 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); 5873 handled = event.ctrlKey || event.metaKey; 5874 break; // clear on ctrl or command +end 5875 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); 5876 handled = event.ctrlKey || event.metaKey; 5877 break; // current on ctrl or command +home 5878 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -1, 'D'); 5879 handled = event.ctrlKey || event.metaKey; 5880 // -1 day on ctrl or command +left 5881 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 5882 -$.datepicker._get(inst, 'stepBigMonths') : 5883 -$.datepicker._get(inst, 'stepMonths')), 'M'); 5884 // next month/year on alt +left on Mac 5885 break; 5886 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); 5887 handled = event.ctrlKey || event.metaKey; 5888 break; // -1 week on ctrl or command +up 5889 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +1, 'D'); 5890 handled = event.ctrlKey || event.metaKey; 5891 // +1 day on ctrl or command +right 5892 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 5893 +$.datepicker._get(inst, 'stepBigMonths') : 5894 +$.datepicker._get(inst, 'stepMonths')), 'M'); 5895 // next month/year on alt +right 5896 break; 5897 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); 5898 handled = event.ctrlKey || event.metaKey; 5899 break; // +1 week on ctrl or command +down 5900 default: handled = false; 5901 } 5902 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home 5903 $.datepicker._showDatepicker(this); 5904 else { 5905 handled = false; 5906 } 5907 if (handled) { 5908 event.preventDefault(); 5909 event.stopPropagation(); 5910 } 5911 }, 5912 5913 /* Filter entered characters - based on date format. */ 5914 _doKeyPress: function(event) { 5915 var inst = $.datepicker._getInst(event.target); 5916 if ($.datepicker._get(inst, 'constrainInput')) { 5917 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); 5918 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); 5919 return event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); 5920 } 5921 }, 5922 5923 /* Pop-up the date picker for a given input field. 5924 @param input element - the input field attached to the date picker or 5925 event - if triggered by focus */ 5926 _showDatepicker: function(input) { 5927 input = input.target || input; 5928 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger 5929 input = $('input', input.parentNode)[0]; 5930 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here 5931 return; 5932 var inst = $.datepicker._getInst(input); 5933 var beforeShow = $.datepicker._get(inst, 'beforeShow'); 5934 extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {})); 5935 $.datepicker._hideDatepicker(null, ''); 5936 $.datepicker._lastInput = input; 5937 $.datepicker._setDateFromField(inst); 5938 if ($.datepicker._inDialog) // hide cursor 5939 input.value = ''; 5940 if (!$.datepicker._pos) { // position below input 5941 $.datepicker._pos = $.datepicker._findPos(input); 5942 $.datepicker._pos[1] += input.offsetHeight; // add the height 5943 } 5944 var isFixed = false; 5945 $(input).parents().each(function() { 5946 isFixed |= $(this).css('position') == 'fixed'; 5947 return !isFixed; 5948 }); 5949 if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled 5950 $.datepicker._pos[0] -= document.documentElement.scrollLeft; 5951 $.datepicker._pos[1] -= document.documentElement.scrollTop; 5952 } 5953 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 5954 $.datepicker._pos = null; 5955 inst.rangeStart = null; 5956 // determine sizing offscreen 5957 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); 5958 $.datepicker._updateDatepicker(inst); 5959 // fix width for dynamic number of date pickers 5960 inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1] * 5961 $('.ui-datepicker', inst.dpDiv[0])[0].offsetWidth); 5962 // and adjust position before showing 5963 offset = $.datepicker._checkOffset(inst, offset, isFixed); 5964 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 5965 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', 5966 left: offset.left + 'px', top: offset.top + 'px'}); 5967 if (!inst.inline) { 5968 var showAnim = $.datepicker._get(inst, 'showAnim') || 'show'; 5969 var duration = $.datepicker._get(inst, 'duration'); 5970 var postProcess = function() { 5971 $.datepicker._datepickerShowing = true; 5972 if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems 5973 $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4, 5974 height: inst.dpDiv.height() + 4}); 5975 }; 5976 if ($.effects && $.effects[showAnim]) 5977 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 5978 else 5979 inst.dpDiv[showAnim](duration, postProcess); 5980 if (duration == '') 5981 postProcess(); 5982 if (inst.input[0].type != 'hidden') 5983 inst.input[0].focus(); 5984 $.datepicker._curInst = inst; 5985 } 5986 }, 5987 5988 /* Generate the date picker content. */ 5989 _updateDatepicker: function(inst) { 5990 var dims = {width: inst.dpDiv.width() + 4, 5991 height: inst.dpDiv.height() + 4}; 5992 inst.dpDiv.empty().append(this._generateHTML(inst)). 5993 find('iframe.ui-datepicker-cover'). 5994 css({width: dims.width, height: dims.height}); 5995 var numMonths = this._getNumberOfMonths(inst); 5996 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + 5997 'Class']('ui-datepicker-multi'); 5998 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + 5999 'Class']('ui-datepicker-rtl'); 6000 if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst) 6001 $(inst.input[0]).focus(); 6002 }, 6003 6004 /* Check positioning to remain on screen. */ 6005 _checkOffset: function(inst, offset, isFixed) { 6006 var pos = inst.input ? this._findPos(inst.input[0]) : null; 6007 var browserWidth = window.innerWidth || (document.documentElement ? 6008 document.documentElement.clientWidth : document.body.clientWidth); 6009 var browserHeight = window.innerHeight || (document.documentElement ? 6010 document.documentElement.clientHeight : document.body.clientHeight); 6011 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 6012 var scrollY = document.documentElement.scrollTop || document.body.scrollTop; 6013 // reposition date picker horizontally if outside the browser window 6014 if (this._get(inst, 'isRTL') || (offset.left + inst.dpDiv.width() - scrollX) > browserWidth) 6015 offset.left = Math.max((isFixed ? 0 : scrollX), 6016 pos[0] + (inst.input ? inst.input.width() : 0) - (isFixed ? scrollX : 0) - inst.dpDiv.width() - 6017 (isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0)); 6018 else 6019 offset.left -= (isFixed ? scrollX : 0); 6020 // reposition date picker vertically if outside the browser window 6021 if ((offset.top + inst.dpDiv.height() - scrollY) > browserHeight) 6022 offset.top = Math.max((isFixed ? 0 : scrollY), 6023 pos[1] - (isFixed ? scrollY : 0) - (this._inDialog ? 0 : inst.dpDiv.height()) - 6024 (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0)); 6025 else 6026 offset.top -= (isFixed ? scrollY : 0); 6027 return offset; 6028 }, 6029 6030 /* Find an object's position on the screen. */ 6031 _findPos: function(obj) { 6032 while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) { 6033 obj = obj.nextSibling; 6034 } 6035 var position = $(obj).offset(); 6036 return [position.left, position.top]; 6037 }, 6038 6039 /* Hide the date picker from view. 6040 @param input element - the input field attached to the date picker 6041 @param duration string - the duration over which to close the date picker */ 6042 _hideDatepicker: function(input, duration) { 6043 var inst = this._curInst; 6044 if (!inst || (input && inst != $.data(input, PROP_NAME))) 6045 return; 6046 var rangeSelect = this._get(inst, 'rangeSelect'); 6047 if (rangeSelect && inst.stayOpen) 6048 this._selectDate('#' + inst.id, this._formatDate(inst, 6049 inst.currentDay, inst.currentMonth, inst.currentYear)); 6050 inst.stayOpen = false; 6051 if (this._datepickerShowing) { 6052 duration = (duration != null ? duration : this._get(inst, 'duration')); 6053 var showAnim = this._get(inst, 'showAnim'); 6054 var postProcess = function() { 6055 $.datepicker._tidyDialog(inst); 6056 }; 6057 if (duration != '' && $.effects && $.effects[showAnim]) 6058 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), 6059 duration, postProcess); 6060 else 6061 inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' : 6062 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess); 6063 if (duration == '') 6064 this._tidyDialog(inst); 6065 var onClose = this._get(inst, 'onClose'); 6066 if (onClose) 6067 onClose.apply((inst.input ? inst.input[0] : null), 6068 [(inst.input ? inst.input.val() : ''), inst]); // trigger custom callback 6069 this._datepickerShowing = false; 6070 this._lastInput = null; 6071 inst.settings.prompt = null; 6072 if (this._inDialog) { 6073 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); 6074 if ($.blockUI) { 6075 $.unblockUI(); 6076 $('body').append(this.dpDiv); 6077 } 6078 } 6079 this._inDialog = false; 6080 } 6081 this._curInst = null; 6082 }, 6083 6084 /* Tidy up after a dialog display. */ 6085 _tidyDialog: function(inst) { 6086 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker'); 6087 $('.' + this._promptClass, inst.dpDiv).remove(); 6088 }, 6089 6090 /* Close date picker if clicked elsewhere. */ 6091 _checkExternalClick: function(event) { 6092 if (!$.datepicker._curInst) 6093 return; 6094 var $target = $(event.target); 6095 if (($target.parents('#' + $.datepicker._mainDivId).length == 0) && 6096 !$target.hasClass($.datepicker.markerClassName) && 6097 !$target.hasClass($.datepicker._triggerClass) && 6098 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) 6099 $.datepicker._hideDatepicker(null, ''); 6100 }, 6101 6102 /* Adjust one of the date sub-fields. */ 6103 _adjustDate: function(id, offset, period) { 6104 var target = $(id); 6105 var inst = this._getInst(target[0]); 6106 this._adjustInstDate(inst, offset, period); 6107 this._updateDatepicker(inst); 6108 }, 6109 6110 /* Action for current link. */ 6111 _gotoToday: function(id) { 6112 var target = $(id); 6113 var inst = this._getInst(target[0]); 6114 if (this._get(inst, 'gotoCurrent') && inst.currentDay) { 6115 inst.selectedDay = inst.currentDay; 6116 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 6117 inst.drawYear = inst.selectedYear = inst.currentYear; 6118 } 6119 else { 6120 var date = new Date(); 6121 inst.selectedDay = date.getDate(); 6122 inst.drawMonth = inst.selectedMonth = date.getMonth(); 6123 inst.drawYear = inst.selectedYear = date.getFullYear(); 6124 } 6125 this._notifyChange(inst); 6126 this._adjustDate(target); 6127 }, 6128 6129 /* Action for selecting a new month/year. */ 6130 _selectMonthYear: function(id, select, period) { 6131 var target = $(id); 6132 var inst = this._getInst(target[0]); 6133 inst._selectingMonthYear = false; 6134 inst['selected' + (period == 'M' ? 'Month' : 'Year')] = 6135 inst['draw' + (period == 'M' ? 'Month' : 'Year')] = 6136 parseInt(select.options[select.selectedIndex].value,10); 6137 this._notifyChange(inst); 6138 this._adjustDate(target); 6139 }, 6140 6141 /* Restore input focus after not changing month/year. */ 6142 _clickMonthYear: function(id) { 6143 var target = $(id); 6144 var inst = this._getInst(target[0]); 6145 if (inst.input && inst._selectingMonthYear && !$.browser.msie) 6146 inst.input[0].focus(); 6147 inst._selectingMonthYear = !inst._selectingMonthYear; 6148 }, 6149 6150 /* Action for changing the first week day. */ 6151 _changeFirstDay: function(id, day) { 6152 var target = $(id); 6153 var inst = this._getInst(target[0]); 6154 inst.settings.firstDay = day; 6155 this._updateDatepicker(inst); 6156 }, 6157 6158 /* Action for selecting a day. */ 6159 _selectDay: function(id, month, year, td) { 6160 if ($(td).hasClass(this._unselectableClass)) 6161 return; 6162 var target = $(id); 6163 var inst = this._getInst(target[0]); 6164 var rangeSelect = this._get(inst, 'rangeSelect'); 6165 if (rangeSelect) { 6166 inst.stayOpen = !inst.stayOpen; 6167 if (inst.stayOpen) { 6168 $('.ui-datepicker td', inst.dpDiv).removeClass(this._currentClass); 6169 $(td).addClass(this._currentClass); 6170 } 6171 } 6172 inst.selectedDay = inst.currentDay = $('a', td).html(); 6173 inst.selectedMonth = inst.currentMonth = month; 6174 inst.selectedYear = inst.currentYear = year; 6175 if (inst.stayOpen) { 6176 inst.endDay = inst.endMonth = inst.endYear = null; 6177 } 6178 else if (rangeSelect) { 6179 inst.endDay = inst.currentDay; 6180 inst.endMonth = inst.currentMonth; 6181 inst.endYear = inst.currentYear; 6182 } 6183 this._selectDate(id, this._formatDate(inst, 6184 inst.currentDay, inst.currentMonth, inst.currentYear)); 6185 if (inst.stayOpen) { 6186 inst.rangeStart = this._daylightSavingAdjust( 6187 new Date(inst.currentYear, inst.currentMonth, inst.currentDay)); 6188 this._updateDatepicker(inst); 6189 } 6190 else if (rangeSelect) { 6191 inst.selectedDay = inst.currentDay = inst.rangeStart.getDate(); 6192 inst.selectedMonth = inst.currentMonth = inst.rangeStart.getMonth(); 6193 inst.selectedYear = inst.currentYear = inst.rangeStart.getFullYear(); 6194 inst.rangeStart = null; 6195 if (inst.inline) 6196 this._updateDatepicker(inst); 6197 } 6198 }, 6199 6200 /* Erase the input field and hide the date picker. */ 6201 _clearDate: function(id) { 6202 var target = $(id); 6203 var inst = this._getInst(target[0]); 6204 if (this._get(inst, 'mandatory')) 6205 return; 6206 inst.stayOpen = false; 6207 inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null; 6208 this._selectDate(target, ''); 6209 }, 6210 6211 /* Update the input field with the selected date. */ 6212 _selectDate: function(id, dateStr) { 6213 var target = $(id); 6214 var inst = this._getInst(target[0]); 6215 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 6216 if (this._get(inst, 'rangeSelect') && dateStr) 6217 dateStr = (inst.rangeStart ? this._formatDate(inst, inst.rangeStart) : 6218 dateStr) + this._get(inst, 'rangeSeparator') + dateStr; 6219 if (inst.input) 6220 inst.input.val(dateStr); 6221 this._updateAlternate(inst); 6222 var onSelect = this._get(inst, 'onSelect'); 6223 if (onSelect) 6224 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 6225 else if (inst.input) 6226 inst.input.trigger('change'); // fire the change event 6227 if (inst.inline) 6228 this._updateDatepicker(inst); 6229 else if (!inst.stayOpen) { 6230 this._hideDatepicker(null, this._get(inst, 'duration')); 6231 this._lastInput = inst.input[0]; 6232 if (typeof(inst.input[0]) != 'object') 6233 inst.input[0].focus(); // restore focus 6234 this._lastInput = null; 6235 } 6236 }, 6237 6238 /* Update any alternate field to synchronise with the main field. */ 6239 _updateAlternate: function(inst) { 6240 var altField = this._get(inst, 'altField'); 6241 if (altField) { // update alternate field too 6242 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); 6243 var date = this._getDate(inst); 6244 dateStr = (isArray(date) ? (!date[0] && !date[1] ? '' : 6245 this.formatDate(altFormat, date[0], this._getFormatConfig(inst)) + 6246 this._get(inst, 'rangeSeparator') + this.formatDate( 6247 altFormat, date[1] || date[0], this._getFormatConfig(inst))) : 6248 this.formatDate(altFormat, date, this._getFormatConfig(inst))); 6249 $(altField).each(function() { $(this).val(dateStr); }); 6250 } 6251 }, 6252 6253 /* Set as beforeShowDay function to prevent selection of weekends. 6254 @param date Date - the date to customise 6255 @return [boolean, string] - is this date selectable?, what is its CSS class? */ 6256 noWeekends: function(date) { 6257 var day = date.getDay(); 6258 return [(day > 0 && day < 6), '']; 6259 }, 6260 6261 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 6262 @param date Date - the date to get the week for 6263 @return number - the number of the week within the year that contains this date */ 6264 iso8601Week: function(date) { 6265 var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()); 6266 var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan 6267 var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7 6268 firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday 6269 if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary 6270 checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year 6271 return $.datepicker.iso8601Week(checkDate); 6272 } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year 6273 firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7; 6274 if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary 6275 return 1; 6276 } 6277 } 6278 return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date 6279 }, 6280 6281 /* Provide status text for a particular date. 6282 @param date the date to get the status for 6283 @param inst the current datepicker instance 6284 @return the status display text for this date */ 6285 dateStatus: function(date, inst) { 6286 return $.datepicker.formatDate($.datepicker._get(inst, 'dateStatus'), 6287 date, $.datepicker._getFormatConfig(inst)); 6288 }, 6289 6290 /* Parse a string value into a date object. 6291 See formatDate below for the possible formats. 6292 6293 @param format string - the expected format of the date 6294 @param value string - the date in the above format 6295 @param settings Object - attributes include: 6296 shortYearCutoff number - the cutoff year for determining the century (optional) 6297 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 6298 dayNames string[7] - names of the days from Sunday (optional) 6299 monthNamesShort string[12] - abbreviated names of the months (optional) 6300 monthNames string[12] - names of the months (optional) 6301 @return Date - the extracted date value or null if value is blank */ 6302 parseDate: function (format, value, settings) { 6303 if (format == null || value == null) 6304 throw 'Invalid arguments'; 6305 value = (typeof value == 'object' ? value.toString() : value + ''); 6306 if (value == '') 6307 return null; 6308 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; 6309 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 6310 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 6311 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 6312 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 6313 var year = -1; 6314 var month = -1; 6315 var day = -1; 6316 var doy = -1; 6317 var literal = false; 6318 // Check whether a format character is doubled 6319 var lookAhead = function(match) { 6320 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 6321 if (matches) 6322 iFormat++; 6323 return matches; 6324 }; 6325 // Extract a number from the string value 6326 var getNumber = function(match) { 6327 lookAhead(match); 6328 var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2))); 6329 var size = origSize; 6330 var num = 0; 6331 while (size > 0 && iValue < value.length && 6332 value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') { 6333 num = num * 10 + parseInt(value.charAt(iValue++),10); 6334 size--; 6335 } 6336 if (size == origSize) 6337 throw 'Missing number at position ' + iValue; 6338 return num; 6339 }; 6340 // Extract a name from the string value and convert to an index 6341 var getName = function(match, shortNames, longNames) { 6342 var names = (lookAhead(match) ? longNames : shortNames); 6343 var size = 0; 6344 for (var j = 0; j < names.length; j++) 6345 size = Math.max(size, names[j].length); 6346 var name = ''; 6347 var iInit = iValue; 6348 while (size > 0 && iValue < value.length) { 6349 name += value.charAt(iValue++); 6350 for (var i = 0; i < names.length; i++) 6351 if (name == names[i]) 6352 return i + 1; 6353 size--; 6354 } 6355 throw 'Unknown name at position ' + iInit; 6356 }; 6357 // Confirm that a literal character matches the string value 6358 var checkLiteral = function() { 6359 if (value.charAt(iValue) != format.charAt(iFormat)) 6360 throw 'Unexpected literal at position ' + iValue; 6361 iValue++; 6362 }; 6363 var iValue = 0; 6364 for (var iFormat = 0; iFormat < format.length; iFormat++) { 6365 if (literal) 6366 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 6367 literal = false; 6368 else 6369 checkLiteral(); 6370 else 6371 switch (format.charAt(iFormat)) { 6372 case 'd': 6373 day = getNumber('d'); 6374 break; 6375 case 'D': 6376 getName('D', dayNamesShort, dayNames); 6377 break; 6378 case 'o': 6379 doy = getNumber('o'); 6380 break; 6381 case 'm': 6382 month = getNumber('m'); 6383 break; 6384 case 'M': 6385 month = getName('M', monthNamesShort, monthNames); 6386 break; 6387 case 'y': 6388 year = getNumber('y'); 6389 break; 6390 case '@': 6391 var date = new Date(getNumber('@')); 6392 year = date.getFullYear(); 6393 month = date.getMonth() + 1; 6394 day = date.getDate(); 6395 break; 6396 case "'": 6397 if (lookAhead("'")) 6398 checkLiteral(); 6399 else 6400 literal = true; 6401 break; 6402 default: 6403 checkLiteral(); 6404 } 6405 } 6406 if (year == -1) 6407 year = new Date().getFullYear(); 6408 else if (year < 100) 6409 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 6410 (year <= shortYearCutoff ? 0 : -100); 6411 if (doy > -1) { 6412 month = 1; 6413 day = doy; 6414 do { 6415 var dim = this._getDaysInMonth(year, month - 1); 6416 if (day <= dim) 6417 break; 6418 month++; 6419 day -= dim; 6420 } while (true); 6421 } 6422 var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 6423 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) 6424 throw 'Invalid date'; // E.g. 31/02/* 6425 return date; 6426 }, 6427 6428 /* Standard date formats. */ 6429 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) 6430 COOKIE: 'D, dd M yy', 6431 ISO_8601: 'yy-mm-dd', 6432 RFC_822: 'D, d M y', 6433 RFC_850: 'DD, dd-M-y', 6434 RFC_1036: 'D, d M y', 6435 RFC_1123: 'D, d M yy', 6436 RFC_2822: 'D, d M yy', 6437 RSS: 'D, d M y', // RFC 822 6438 TIMESTAMP: '@', 6439 W3C: 'yy-mm-dd', // ISO 8601 6440 6441 /* Format a date object into a string value. 6442 The format can be combinations of the following: 6443 d - day of month (no leading zero) 6444 dd - day of month (two digit) 6445 o - day of year (no leading zeros) 6446 oo - day of year (three digit) 6447 D - day name short 6448 DD - day name long 6449 m - month of year (no leading zero) 6450 mm - month of year (two digit) 6451 M - month name short 6452 MM - month name long 6453 y - year (two digit) 6454 yy - year (four digit) 6455 @ - Unix timestamp (ms since 01/01/1970) 6456 '...' - literal text 6457 '' - single quote 6458 6459 @param format string - the desired format of the date 6460 @param date Date - the date value to format 6461 @param settings Object - attributes include: 6462 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 6463 dayNames string[7] - names of the days from Sunday (optional) 6464 monthNamesShort string[12] - abbreviated names of the months (optional) 6465 monthNames string[12] - names of the months (optional) 6466 @return string - the date in the above format */ 6467 formatDate: function (format, date, settings) { 6468 if (!date) 6469 return ''; 6470 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 6471 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 6472 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 6473 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 6474 // Check whether a format character is doubled 6475 var lookAhead = function(match) { 6476 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 6477 if (matches) 6478 iFormat++; 6479 return matches; 6480 }; 6481 // Format a number, with leading zero if necessary 6482 var formatNumber = function(match, value, len) { 6483 var num = '' + value; 6484 if (lookAhead(match)) 6485 while (num.length < len) 6486 num = '0' + num; 6487 return num; 6488 }; 6489 // Format a name, short or long as requested 6490 var formatName = function(match, value, shortNames, longNames) { 6491 return (lookAhead(match) ? longNames[value] : shortNames[value]); 6492 }; 6493 var output = ''; 6494 var literal = false; 6495 if (date) 6496 for (var iFormat = 0; iFormat < format.length; iFormat++) { 6497 if (literal) 6498 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 6499 literal = false; 6500 else 6501 output += format.charAt(iFormat); 6502 else 6503 switch (format.charAt(iFormat)) { 6504 case 'd': 6505 output += formatNumber('d', date.getDate(), 2); 6506 break; 6507 case 'D': 6508 output += formatName('D', date.getDay(), dayNamesShort, dayNames); 6509 break; 6510 case 'o': 6511 var doy = date.getDate(); 6512 for (var m = date.getMonth() - 1; m >= 0; m--) 6513 doy += this._getDaysInMonth(date.getFullYear(), m); 6514 output += formatNumber('o', doy, 3); 6515 break; 6516 case 'm': 6517 output += formatNumber('m', date.getMonth() + 1, 2); 6518 break; 6519 case 'M': 6520 output += formatName('M', date.getMonth(), monthNamesShort, monthNames); 6521 break; 6522 case 'y': 6523 output += (lookAhead('y') ? date.getFullYear() : 6524 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); 6525 break; 6526 case '@': 6527 output += date.getTime(); 6528 break; 6529 case "'": 6530 if (lookAhead("'")) 6531 output += "'"; 6532 else 6533 literal = true; 6534 break; 6535 default: 6536 output += format.charAt(iFormat); 6537 } 6538 } 6539 return output; 6540 }, 6541 6542 /* Extract all possible characters from the date format. */ 6543 _possibleChars: function (format) { 6544 var chars = ''; 6545 var literal = false; 6546 for (var iFormat = 0; iFormat < format.length; iFormat++) 6547 if (literal) 6548 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 6549 literal = false; 6550 else 6551 chars += format.charAt(iFormat); 6552 else 6553 switch (format.charAt(iFormat)) { 6554 case 'd': case 'm': case 'y': case '@': 6555 chars += '0123456789'; 6556 break; 6557 case 'D': case 'M': 6558 return null; // Accept anything 6559 case "'": 6560 if (lookAhead("'")) 6561 chars += "'"; 6562 else 6563 literal = true; 6564 break; 6565 default: 6566 chars += format.charAt(iFormat); 6567 } 6568 return chars; 6569 }, 6570 6571 /* Get a setting value, defaulting if necessary. */ 6572 _get: function(inst, name) { 6573 return inst.settings[name] !== undefined ? 6574 inst.settings[name] : this._defaults[name]; 6575 }, 6576 6577 /* Parse existing date and initialise date picker. */ 6578 _setDateFromField: function(inst) { 6579 var dateFormat = this._get(inst, 'dateFormat'); 6580 var dates = inst.input ? inst.input.val().split(this._get(inst, 'rangeSeparator')) : null; 6581 inst.endDay = inst.endMonth = inst.endYear = null; 6582 var date = defaultDate = this._getDefaultDate(inst); 6583 if (dates.length > 0) { 6584 var settings = this._getFormatConfig(inst); 6585 if (dates.length > 1) { 6586 date = this.parseDate(dateFormat, dates[1], settings) || defaultDate; 6587 inst.endDay = date.getDate(); 6588 inst.endMonth = date.getMonth(); 6589 inst.endYear = date.getFullYear(); 6590 } 6591 try { 6592 date = this.parseDate(dateFormat, dates[0], settings) || defaultDate; 6593 } catch (event) { 6594 this.log(event); 6595 date = defaultDate; 6596 } 6597 } 6598 inst.selectedDay = date.getDate(); 6599 inst.drawMonth = inst.selectedMonth = date.getMonth(); 6600 inst.drawYear = inst.selectedYear = date.getFullYear(); 6601 inst.currentDay = (dates[0] ? date.getDate() : 0); 6602 inst.currentMonth = (dates[0] ? date.getMonth() : 0); 6603 inst.currentYear = (dates[0] ? date.getFullYear() : 0); 6604 this._adjustInstDate(inst); 6605 }, 6606 6607 /* Retrieve the default date shown on opening. */ 6608 _getDefaultDate: function(inst) { 6609 var date = this._determineDate(this._get(inst, 'defaultDate'), new Date()); 6610 var minDate = this._getMinMaxDate(inst, 'min', true); 6611 var maxDate = this._getMinMaxDate(inst, 'max'); 6612 date = (minDate && date < minDate ? minDate : date); 6613 date = (maxDate && date > maxDate ? maxDate : date); 6614 return date; 6615 }, 6616 6617 /* A date may be specified as an exact value or a relative one. */ 6618 _determineDate: function(date, defaultDate) { 6619 var offsetNumeric = function(offset) { 6620 var date = new Date(); 6621 date.setDate(date.getDate() + offset); 6622 return date; 6623 }; 6624 var offsetString = function(offset, getDaysInMonth) { 6625 var date = new Date(); 6626 var year = date.getFullYear(); 6627 var month = date.getMonth(); 6628 var day = date.getDate(); 6629 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; 6630 var matches = pattern.exec(offset); 6631 while (matches) { 6632 switch (matches[2] || 'd') { 6633 case 'd' : case 'D' : 6634 day += parseInt(matches[1],10); break; 6635 case 'w' : case 'W' : 6636 day += parseInt(matches[1],10) * 7; break; 6637 case 'm' : case 'M' : 6638 month += parseInt(matches[1],10); 6639 day = Math.min(day, getDaysInMonth(year, month)); 6640 break; 6641 case 'y': case 'Y' : 6642 year += parseInt(matches[1],10); 6643 day = Math.min(day, getDaysInMonth(year, month)); 6644 break; 6645 } 6646 matches = pattern.exec(offset); 6647 } 6648 return new Date(year, month, day); 6649 }; 6650 date = (date == null ? defaultDate : 6651 (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) : 6652 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date))); 6653 date = (date && date.toString() == 'Invalid Date' ? defaultDate : date); 6654 if (date) { 6655 date.setHours(0); 6656 date.setMinutes(0); 6657 date.setSeconds(0); 6658 date.setMilliseconds(0); 6659 } 6660 return this._daylightSavingAdjust(date); 6661 }, 6662 6663 /* Handle switch to/from daylight saving. 6664 Hours may be non-zero on daylight saving cut-over: 6665 > 12 when midnight changeover, but then cannot generate 6666 midnight datetime, so jump to 1AM, otherwise reset. 6667 @param date (Date) the date to check 6668 @return (Date) the corrected date */ 6669 _daylightSavingAdjust: function(date) { 6670 if (!date) return null; 6671 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 6672 return date; 6673 }, 6674 6675 /* Set the date(s) directly. */ 6676 _setDate: function(inst, date, endDate) { 6677 var clear = !(date); 6678 var origMonth = inst.selectedMonth; 6679 var origYear = inst.selectedYear; 6680 date = this._determineDate(date, new Date()); 6681 inst.selectedDay = inst.currentDay = date.getDate(); 6682 inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth(); 6683 inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear(); 6684 if (this._get(inst, 'rangeSelect')) { 6685 if (endDate) { 6686 endDate = this._determineDate(endDate, null); 6687 inst.endDay = endDate.getDate(); 6688 inst.endMonth = endDate.getMonth(); 6689 inst.endYear = endDate.getFullYear(); 6690 } else { 6691 inst.endDay = inst.currentDay; 6692 inst.endMonth = inst.currentMonth; 6693 inst.endYear = inst.currentYear; 6694 } 6695 } 6696 if (origMonth != inst.selectedMonth || origYear != inst.selectedYear) 6697 this._notifyChange(inst); 6698 this._adjustInstDate(inst); 6699 if (inst.input) 6700 inst.input.val(clear ? '' : this._formatDate(inst) + 6701 (!this._get(inst, 'rangeSelect') ? '' : this._get(inst, 'rangeSeparator') + 6702 this._formatDate(inst, inst.endDay, inst.endMonth, inst.endYear))); 6703 }, 6704 6705 /* Retrieve the date(s) directly. */ 6706 _getDate: function(inst) { 6707 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : 6708 this._daylightSavingAdjust(new Date( 6709 inst.currentYear, inst.currentMonth, inst.currentDay))); 6710 if (this._get(inst, 'rangeSelect')) { 6711 return [inst.rangeStart || startDate, 6712 (!inst.endYear ? inst.rangeStart || startDate : 6713 this._daylightSavingAdjust(new Date(inst.endYear, inst.endMonth, inst.endDay)))]; 6714 } else 6715 return startDate; 6716 }, 6717 6718 /* Generate the HTML for the current state of the date picker. */ 6719 _generateHTML: function(inst) { 6720 var today = new Date(); 6721 today = this._daylightSavingAdjust( 6722 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time 6723 var showStatus = this._get(inst, 'showStatus'); 6724 var initStatus = this._get(inst, 'initStatus') || ' '; 6725 var isRTL = this._get(inst, 'isRTL'); 6726 // build the date picker HTML 6727 var clear = (this._get(inst, 'mandatory') ? '' : 6728 '<div class="ui-datepicker-clear"><a onclick="jQuery.datepicker._clearDate(\'#' + inst.id + '\');"' + 6729 this._addStatus(showStatus, inst.id, this._get(inst, 'clearStatus'), initStatus) + '>' + 6730 this._get(inst, 'clearText') + '</a></div>'); 6731 var controls = '<div class="ui-datepicker-control">' + (isRTL ? '' : clear) + 6732 '<div class="ui-datepicker-close"><a onclick="jQuery.datepicker._hideDatepicker();"' + 6733 this._addStatus(showStatus, inst.id, this._get(inst, 'closeStatus'), initStatus) + '>' + 6734 this._get(inst, 'closeText') + '</a></div>' + (isRTL ? clear : '') + '</div>'; 6735 var prompt = this._get(inst, 'prompt'); 6736 var closeAtTop = this._get(inst, 'closeAtTop'); 6737 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); 6738 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); 6739 var showBigPrevNext = this._get(inst, 'showBigPrevNext'); 6740 var numMonths = this._getNumberOfMonths(inst); 6741 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); 6742 var stepMonths = this._get(inst, 'stepMonths'); 6743 var stepBigMonths = this._get(inst, 'stepBigMonths'); 6744 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); 6745 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 6746 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 6747 var minDate = this._getMinMaxDate(inst, 'min', true); 6748 var maxDate = this._getMinMaxDate(inst, 'max'); 6749 var drawMonth = inst.drawMonth - showCurrentAtPos; 6750 var drawYear = inst.drawYear; 6751 if (drawMonth < 0) { 6752 drawMonth += 12; 6753 drawYear--; 6754 } 6755 if (maxDate) { 6756 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 6757 maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate())); 6758 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 6759 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 6760 drawMonth--; 6761 if (drawMonth < 0) { 6762 drawMonth = 11; 6763 drawYear--; 6764 } 6765 } 6766 } 6767 // controls and links 6768 var prevText = this._get(inst, 'prevText'); 6769 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 6770 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 6771 this._getFormatConfig(inst))); 6772 var prevBigText = (showBigPrevNext ? this._get(inst, 'prevBigText') : ''); 6773 prevBigText = (!navigationAsDateFormat ? prevBigText : this.formatDate(prevBigText, 6774 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepBigMonths, 1)), 6775 this._getFormatConfig(inst))); 6776 var prev = '<div class="ui-datepicker-prev">' + (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 6777 (showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepBigMonths + ', \'M\');"' + 6778 this._addStatus(showStatus, inst.id, this._get(inst, 'prevBigStatus'), initStatus) + '>' + prevBigText + '</a>' : '') + 6779 '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' + 6780 this._addStatus(showStatus, inst.id, this._get(inst, 'prevStatus'), initStatus) + '>' + prevText + '</a>' : 6781 (hideIfNoPrevNext ? '' : (showBigPrevNext ? '<label>' + prevBigText + '</label>' : '') + 6782 '<label>' + prevText + '</label>')) + '</div>'; 6783 var nextText = this._get(inst, 'nextText'); 6784 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 6785 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 6786 this._getFormatConfig(inst))); 6787 var nextBigText = (showBigPrevNext ? this._get(inst, 'nextBigText') : ''); 6788 nextBigText = (!navigationAsDateFormat ? nextBigText : this.formatDate(nextBigText, 6789 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepBigMonths, 1)), 6790 this._getFormatConfig(inst))); 6791 var next = '<div class="ui-datepicker-next">' + (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 6792 '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' + 6793 this._addStatus(showStatus, inst.id, this._get(inst, 'nextStatus'), initStatus) + '>' + nextText + '</a>' + 6794 (showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepBigMonths + ', \'M\');"' + 6795 this._addStatus(showStatus, inst.id, this._get(inst, 'nextBigStatus'), initStatus) + '>' + nextBigText + '</a>' : '') : 6796 (hideIfNoPrevNext ? '' : '<label>' + nextText + '</label>' + 6797 (showBigPrevNext ? '<label>' + nextBigText + '</label>' : ''))) + '</div>'; 6798 var currentText = this._get(inst, 'currentText'); 6799 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); 6800 currentText = (!navigationAsDateFormat ? currentText : 6801 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 6802 var html = (closeAtTop && !inst.inline ? controls : '') + 6803 '<div class="ui-datepicker-links">' + (isRTL ? next : prev) + 6804 (this._isInRange(inst, gotoDate) ? '<div class="ui-datepicker-current">' + 6805 '<a onclick="jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' + 6806 this._addStatus(showStatus, inst.id, this._get(inst, 'currentStatus'), initStatus) + '>' + 6807 currentText + '</a></div>' : '') + (isRTL ? prev : next) + '</div>' + 6808 (prompt ? '<div class="' + this._promptClass + '"><span>' + prompt + '</span></div>' : ''); 6809 var firstDay = parseInt(this._get(inst, 'firstDay')); 6810 firstDay = (isNaN(firstDay) ? 0 : firstDay); 6811 var changeFirstDay = this._get(inst, 'changeFirstDay'); 6812 var dayNames = this._get(inst, 'dayNames'); 6813 var dayNamesShort = this._get(inst, 'dayNamesShort'); 6814 var dayNamesMin = this._get(inst, 'dayNamesMin'); 6815 var monthNames = this._get(inst, 'monthNames'); 6816 var beforeShowDay = this._get(inst, 'beforeShowDay'); 6817 var highlightWeek = this._get(inst, 'highlightWeek'); 6818 var showOtherMonths = this._get(inst, 'showOtherMonths'); 6819 var showWeeks = this._get(inst, 'showWeeks'); 6820 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; 6821 var weekStatus = this._get(inst, 'weekStatus'); 6822 var status = (showStatus ? this._get(inst, 'dayStatus') || initStatus : ''); 6823 var dateStatus = this._get(inst, 'statusForDate') || this.dateStatus; 6824 var endDate = inst.endDay ? this._daylightSavingAdjust( 6825 new Date(inst.endYear, inst.endMonth, inst.endDay)) : currentDate; 6826 var defaultDate = this._getDefaultDate(inst); 6827 for (var row = 0; row < numMonths[0]; row++) 6828 for (var col = 0; col < numMonths[1]; col++) { 6829 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 6830 html += '<div class="ui-datepicker-one-month' + (col == 0 ? ' ui-datepicker-new-row' : '') + '">' + 6831 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 6832 selectedDate, row > 0 || col > 0, showStatus, initStatus, monthNames) + // draw month headers 6833 '<table class="ui-datepicker" cellpadding="0" cellspacing="0"><thead>' + 6834 '<tr class="ui-datepicker-title-row">' + 6835 (showWeeks ? '<td' + this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' + 6836 this._get(inst, 'weekHeader') + '</td>' : ''); 6837 for (var dow = 0; dow < 7; dow++) { // days of the week 6838 var day = (dow + firstDay) % 7; 6839 var dayStatus = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) : 6840 status.replace(/D/, dayNamesShort[day])); 6841 html += '<td' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end-cell"' : '') + '>' + 6842 (!changeFirstDay ? '<span' : 6843 '<a onclick="jQuery.datepicker._changeFirstDay(\'#' + inst.id + '\', ' + day + ');"') + 6844 this._addStatus(showStatus, inst.id, dayStatus, initStatus) + ' title="' + dayNames[day] + '">' + 6845 dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>'; 6846 } 6847 html += '</tr></thead><tbody>'; 6848 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 6849 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) 6850 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 6851 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 6852 var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate 6853 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 6854 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows 6855 html += '<tr class="ui-datepicker-days-row">' + 6856 (showWeeks ? '<td class="ui-datepicker-week-col"' + 6857 this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' + 6858 calculateWeek(printDate) + '</td>' : ''); 6859 for (var dow = 0; dow < 7; dow++) { // create date picker days 6860 var daySettings = (beforeShowDay ? 6861 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); 6862 var otherMonth = (printDate.getMonth() != drawMonth); 6863 var unselectable = otherMonth || !daySettings[0] || 6864 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 6865 html += '<td class="ui-datepicker-days-cell' + 6866 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end-cell' : '') + // highlight weekends 6867 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months 6868 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key 6869 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ? 6870 // or defaultDate is current printedDate and defaultDate is selectedDate 6871 ' ' + $.datepicker._dayOverClass : '') + // highlight selected day 6872 (unselectable ? ' ' + this._unselectableClass : '') + // highlight unselectable days 6873 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates 6874 (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range 6875 ' ' + this._currentClass : '') + // highlight selected day 6876 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) 6877 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title 6878 (unselectable ? (highlightWeek ? ' onmouseover="jQuery(this).parent().addClass(\'' + this._weekOverClass + '\');"' + // highlight selection week 6879 ' onmouseout="jQuery(this).parent().removeClass(\'' + this._weekOverClass + '\');"' : '') : // unhighlight selection week 6880 ' onmouseover="jQuery(this).addClass(\'' + this._dayOverClass + '\')' + // highlight selection 6881 (highlightWeek ? '.parent().addClass(\'' + this._weekOverClass + '\')' : '') + ';' + // highlight selection week 6882 (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' + 6883 inst.id + '\').html(\'' + (dateStatus.apply((inst.input ? inst.input[0] : null), 6884 [printDate, inst]) || initStatus) +'\');') + '"' + 6885 ' onmouseout="jQuery(this).removeClass(\'' + this._dayOverClass + '\')' + // unhighlight selection 6886 (highlightWeek ? '.parent().removeClass(\'' + this._weekOverClass + '\')' : '') + ';' + // unhighlight selection week 6887 (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' + 6888 inst.id + '\').html(\'' + initStatus + '\');') + '" onclick="jQuery.datepicker._selectDay(\'#' + 6889 inst.id + '\',' + drawMonth + ',' + drawYear + ', this);"') + '>' + // actions 6890 (otherMonth ? (showOtherMonths ? printDate.getDate() : ' ') : // display for other months 6891 (unselectable ? printDate.getDate() : '<a>' + printDate.getDate() + '</a>')) + '</td>'; // display for this month 6892 printDate.setDate(printDate.getDate() + 1); 6893 printDate = this._daylightSavingAdjust(printDate); 6894 } 6895 html += '</tr>'; 6896 } 6897 drawMonth++; 6898 if (drawMonth > 11) { 6899 drawMonth = 0; 6900 drawYear++; 6901 } 6902 html += '</tbody></table></div>'; 6903 } 6904 html += (showStatus ? '<div style="clear: both;"></div><div id="ui-datepicker-status-' + inst.id + 6905 '" class="ui-datepicker-status">' + initStatus + '</div>' : '') + 6906 (!closeAtTop && !inst.inline ? controls : '') + 6907 '<div style="clear: both;"></div>' + 6908 ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ? 6909 '<iframe src="javascript:false;" class="ui-datepicker-cover"></iframe>' : ''); 6910 inst._keyEvent = false; 6911 return html; 6912 }, 6913 6914 /* Generate the month and year header. */ 6915 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 6916 selectedDate, secondary, showStatus, initStatus, monthNames) { 6917 minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate); 6918 var changeMonth = this._get(inst, 'changeMonth'); 6919 var changeYear = this._get(inst, 'changeYear'); 6920 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); 6921 var html = '<div class="ui-datepicker-header">'; 6922 var monthHtml = ''; 6923 // month selection 6924 if (secondary || !changeMonth) 6925 monthHtml += monthNames[drawMonth]; 6926 else { 6927 var inMinYear = (minDate && minDate.getFullYear() == drawYear); 6928 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); 6929 monthHtml += '<select class="ui-datepicker-new-month" ' + 6930 'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' + 6931 'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + 6932 this._addStatus(showStatus, inst.id, this._get(inst, 'monthStatus'), initStatus) + '>'; 6933 for (var month = 0; month < 12; month++) { 6934 if ((!inMinYear || month >= minDate.getMonth()) && 6935 (!inMaxYear || month <= maxDate.getMonth())) 6936 monthHtml += '<option value="' + month + '"' + 6937 (month == drawMonth ? ' selected="selected"' : '') + 6938 '>' + monthNames[month] + '</option>'; 6939 } 6940 monthHtml += '</select>'; 6941 } 6942 if (!showMonthAfterYear) 6943 html += monthHtml + (secondary || changeMonth || changeYear ? ' ' : ''); 6944 // year selection 6945 if (secondary || !changeYear) 6946 html += drawYear; 6947 else { 6948 // determine range of years to display 6949 var years = this._get(inst, 'yearRange').split(':'); 6950 var year = 0; 6951 var endYear = 0; 6952 if (years.length != 2) { 6953 year = drawYear - 10; 6954 endYear = drawYear + 10; 6955 } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') { 6956 year = endYear = new Date().getFullYear(); 6957 year += parseInt(years[0], 10); 6958 endYear += parseInt(years[1], 10); 6959 } else { 6960 year = parseInt(years[0], 10); 6961 endYear = parseInt(years[1], 10); 6962 } 6963 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 6964 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 6965 html += '<select class="ui-datepicker-new-year" ' + 6966 'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' + 6967 'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + 6968 this._addStatus(showStatus, inst.id, this._get(inst, 'yearStatus'), initStatus) + '>'; 6969 for (; year <= endYear; year++) { 6970 html += '<option value="' + year + '"' + 6971 (year == drawYear ? ' selected="selected"' : '') + 6972 '>' + year + '</option>'; 6973 } 6974 html += '</select>'; 6975 } 6976 if (showMonthAfterYear) 6977 html += (secondary || changeMonth || changeYear ? ' ' : '') + monthHtml; 6978 html += '</div>'; // Close datepicker_header 6979 return html; 6980 }, 6981 6982 /* Provide code to set and clear the status panel. */ 6983 _addStatus: function(showStatus, id, text, initStatus) { 6984 return (showStatus ? ' onmouseover="jQuery(\'#ui-datepicker-status-' + id + 6985 '\').html(\'' + (text || initStatus) + '\');" ' + 6986 'onmouseout="jQuery(\'#ui-datepicker-status-' + id + 6987 '\').html(\'' + initStatus + '\');"' : ''); 6988 }, 6989 6990 /* Adjust one of the date sub-fields. */ 6991 _adjustInstDate: function(inst, offset, period) { 6992 var year = inst.drawYear + (period == 'Y' ? offset : 0); 6993 var month = inst.drawMonth + (period == 'M' ? offset : 0); 6994 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + 6995 (period == 'D' ? offset : 0); 6996 var date = this._daylightSavingAdjust(new Date(year, month, day)); 6997 // ensure it is within the bounds set 6998 var minDate = this._getMinMaxDate(inst, 'min', true); 6999 var maxDate = this._getMinMaxDate(inst, 'max'); 7000 date = (minDate && date < minDate ? minDate : date); 7001 date = (maxDate && date > maxDate ? maxDate : date); 7002 inst.selectedDay = date.getDate(); 7003 inst.drawMonth = inst.selectedMonth = date.getMonth(); 7004 inst.drawYear = inst.selectedYear = date.getFullYear(); 7005 if (period == 'M' || period == 'Y') 7006 this._notifyChange(inst); 7007 }, 7008 7009 /* Notify change of month/year. */ 7010 _notifyChange: function(inst) { 7011 var onChange = this._get(inst, 'onChangeMonthYear'); 7012 if (onChange) 7013 onChange.apply((inst.input ? inst.input[0] : null), 7014 [inst.selectedYear, inst.selectedMonth + 1, inst]); 7015 }, 7016 7017 /* Determine the number of months to show. */ 7018 _getNumberOfMonths: function(inst) { 7019 var numMonths = this._get(inst, 'numberOfMonths'); 7020 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); 7021 }, 7022 7023 /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */ 7024 _getMinMaxDate: function(inst, minMax, checkRange) { 7025 var date = this._determineDate(this._get(inst, minMax + 'Date'), null); 7026 return (!checkRange || !inst.rangeStart ? date : 7027 (!date || inst.rangeStart > date ? inst.rangeStart : date)); 7028 }, 7029 7030 /* Find the number of days in a given month. */ 7031 _getDaysInMonth: function(year, month) { 7032 return 32 - new Date(year, month, 32).getDate(); 7033 }, 7034 7035 /* Find the day of the week of the first of a month. */ 7036 _getFirstDayOfMonth: function(year, month) { 7037 return new Date(year, month, 1).getDay(); 7038 }, 7039 7040 /* Determines if we should allow a "next/prev" month display change. */ 7041 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 7042 var numMonths = this._getNumberOfMonths(inst); 7043 var date = this._daylightSavingAdjust(new Date( 7044 curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1)); 7045 if (offset < 0) 7046 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 7047 return this._isInRange(inst, date); 7048 }, 7049 7050 /* Is the given date in the accepted range? */ 7051 _isInRange: function(inst, date) { 7052 // during range selection, use minimum of selected date and range start 7053 var newMinDate = (!inst.rangeStart ? null : this._daylightSavingAdjust( 7054 new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay))); 7055 newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate); 7056 var minDate = newMinDate || this._getMinMaxDate(inst, 'min'); 7057 var maxDate = this._getMinMaxDate(inst, 'max'); 7058 return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate)); 7059 }, 7060 7061 /* Provide the configuration settings for formatting/parsing. */ 7062 _getFormatConfig: function(inst) { 7063 var shortYearCutoff = this._get(inst, 'shortYearCutoff'); 7064 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 7065 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 7066 return {shortYearCutoff: shortYearCutoff, 7067 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), 7068 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; 7069 }, 7070 7071 /* Format the given date for display. */ 7072 _formatDate: function(inst, day, month, year) { 7073 if (!day) { 7074 inst.currentDay = inst.selectedDay; 7075 inst.currentMonth = inst.selectedMonth; 7076 inst.currentYear = inst.selectedYear; 7077 } 7078 var date = (day ? (typeof day == 'object' ? day : 7079 this._daylightSavingAdjust(new Date(year, month, day))) : 7080 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 7081 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); 7082 } 7083 }); 7084 7085 /* jQuery extend now ignores nulls! */ 7086 function extendRemove(target, props) { 7087 $.extend(target, props); 7088 for (var name in props) 7089 if (props[name] == null || props[name] == undefined) 7090 target[name] = props[name]; 7091 return target; 7092 }; 7093 7094 /* Determine whether an object is an array. */ 7095 function isArray(a) { 7096 return (a && (($.browser.safari && typeof a == 'object' && a.length) || 7097 (a.constructor && a.constructor.toString().match(/\Array\(\)/)))); 7098 }; 7099 7100 /* Invoke the datepicker functionality. 7101 @param options string - a command, optionally followed by additional parameters or 7102 Object - settings for attaching new datepicker functionality 7103 @return jQuery object */ 7104 $.fn.datepicker = function(options){ 7105 7106 /* Initialise the date picker. */ 7107 if (!$.datepicker.initialized) { 7108 $(document.body).append($.datepicker.dpDiv). 7109 mousedown($.datepicker._checkExternalClick); 7110 $.datepicker.initialized = true; 7111 } 7112 7113 var otherArgs = Array.prototype.slice.call(arguments, 1); 7114 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate')) 7115 return $.datepicker['_' + options + 'Datepicker']. 7116 apply($.datepicker, [this[0]].concat(otherArgs)); 7117 return this.each(function() { 7118 typeof options == 'string' ? 7119 $.datepicker['_' + options + 'Datepicker']. 7120 apply($.datepicker, [this].concat(otherArgs)) : 7121 $.datepicker._attachDatepicker(this, options); 7122 }); 7123 }; 7124 7125 $.datepicker = new Datepicker(); // singleton instance 7126 $.datepicker.initialized = false; 7127 $.datepicker.uuid = new Date().getTime(); 7128 $.datepicker.version = "1.6"; 7129 7130 })(jQuery); 7131 /* 7132 * jQuery UI Dialog 1.6 7133 * 7134 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 7135 * Dual licensed under the MIT (MIT-LICENSE.txt) 7136 * and GPL (GPL-LICENSE.txt) licenses. 7137 * 7138 * http://docs.jquery.com/UI/Dialog 7139 * 7140 * Depends: 7141 * ui.core.js 7142 * ui.draggable.js 7143 * ui.resizable.js 7144 */ 7145 (function($) { 7146 7147 var setDataSwitch = { 7148 dragStart: "start.draggable", 7149 drag: "drag.draggable", 7150 dragStop: "stop.draggable", 7151 maxHeight: "maxHeight.resizable", 7152 minHeight: "minHeight.resizable", 7153 maxWidth: "maxWidth.resizable", 7154 minWidth: "minWidth.resizable", 7155 resizeStart: "start.resizable", 7156 resize: "drag.resizable", 7157 resizeStop: "stop.resizable" 7158 }; 7159 7160 $.widget("ui.dialog", { 7161 7162 _init: function() { 7163 this.originalTitle = this.element.attr('title'); 7164 this.options.title = this.options.title || this.originalTitle; 7165 7166 var self = this, 7167 options = this.options, 7168 7169 uiDialogContent = this.element 7170 .removeAttr('title') 7171 .addClass('ui-dialog-content') 7172 .wrap('<div></div>') 7173 .wrap('<div></div>'), 7174 7175 uiDialogContainer = (this.uiDialogContainer = uiDialogContent.parent()) 7176 .addClass('ui-dialog-container') 7177 .css({ 7178 position: 'relative', 7179 width: '100%', 7180 height: '100%' 7181 }), 7182 7183 uiDialogTitlebar = (this.uiDialogTitlebar = $('<div></div>')) 7184 .addClass('ui-dialog-titlebar') 7185 .mousedown(function() { 7186 self.moveToTop(); 7187 }) 7188 .prependTo(uiDialogContainer), 7189 7190 uiDialogTitlebarClose = $('<a href="#"/>') 7191 .addClass('ui-dialog-titlebar-close') 7192 .attr('role', 'button') 7193 .appendTo(uiDialogTitlebar), 7194 7195 uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>')) 7196 .text(options.closeText) 7197 .appendTo(uiDialogTitlebarClose), 7198 7199 title = options.title || ' ', 7200 titleId = $.ui.dialog.getTitleId(this.element), 7201 uiDialogTitle = $('<span/>') 7202 .addClass('ui-dialog-title') 7203 .attr('id', titleId) 7204 .html(title) 7205 .prependTo(uiDialogTitlebar), 7206 7207 uiDialog = (this.uiDialog = uiDialogContainer.parent()) 7208 .appendTo(document.body) 7209 .hide() 7210 .addClass('ui-dialog') 7211 .addClass(options.dialogClass) 7212 .css({ 7213 position: 'absolute', 7214 width: options.width, 7215 height: options.height, 7216 overflow: 'hidden', 7217 zIndex: options.zIndex 7218 }) 7219 // setting tabIndex makes the div focusable 7220 // setting outline to 0 prevents a border on focus in Mozilla 7221 .attr('tabIndex', -1).css('outline', 0).keydown(function(ev) { 7222 (options.closeOnEscape && ev.keyCode 7223 && ev.keyCode == $.ui.keyCode.ESCAPE && self.close()); 7224 }) 7225 .attr({ 7226 role: 'dialog', 7227 'aria-labelledby': titleId 7228 }) 7229 .mouseup(function() { 7230 self.moveToTop(); 7231 }), 7232 7233 uiDialogButtonPane = (this.uiDialogButtonPane = $('<div></div>')) 7234 .addClass('ui-dialog-buttonpane') 7235 .css({ 7236 position: 'absolute', 7237 bottom: 0 7238 }) 7239 .appendTo(uiDialog), 7240 7241 uiDialogTitlebarClose = $('.ui-dialog-titlebar-close', uiDialogTitlebar) 7242 .hover( 7243 function() { 7244 $(this).addClass('ui-dialog-titlebar-close-hover'); 7245 }, 7246 function() { 7247 $(this).removeClass('ui-dialog-titlebar-close-hover'); 7248 } 7249 ) 7250 .mousedown(function(ev) { 7251 ev.stopPropagation(); 7252 }) 7253 .click(function() { 7254 self.close(); 7255 return false; 7256 }); 7257 7258 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); 7259 7260 (options.draggable && $.fn.draggable && this._makeDraggable()); 7261 (options.resizable && $.fn.resizable && this._makeResizable()); 7262 7263 this._createButtons(options.buttons); 7264 this._isOpen = false; 7265 7266 (options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe()); 7267 (options.autoOpen && this.open()); 7268 }, 7269 7270 destroy: function() { 7271 (this.overlay && this.overlay.destroy()); 7272 this.uiDialog.hide(); 7273 this.element 7274 .unbind('.dialog') 7275 .removeData('dialog') 7276 .removeClass('ui-dialog-content') 7277 .hide().appendTo('body'); 7278 this.uiDialog.remove(); 7279 7280 (this.originalTitle && this.element.attr('title', this.originalTitle)); 7281 }, 7282 7283 close: function() { 7284 if (false === this._trigger('beforeclose', null, { options: this.options })) { 7285 return; 7286 } 7287 7288 (this.overlay && this.overlay.destroy()); 7289 this.uiDialog 7290 .hide(this.options.hide) 7291 .unbind('keypress.ui-dialog'); 7292 7293 this._trigger('close', null, { options: this.options }); 7294 $.ui.dialog.overlay.resize(); 7295 7296 this._isOpen = false; 7297 }, 7298 7299 isOpen: function() { 7300 return this._isOpen; 7301 }, 7302 7303 // the force parameter allows us to move modal dialogs to their correct 7304 // position on open 7305 moveToTop: function(force) { 7306 7307 if ((this.options.modal && !force) 7308 || (!this.options.stack && !this.options.modal)) { 7309 return this._trigger('focus', null, { options: this.options }); 7310 } 7311 7312 var maxZ = this.options.zIndex, options = this.options; 7313 $('.ui-dialog:visible').each(function() { 7314 maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10) || options.zIndex); 7315 }); 7316 (this.overlay && this.overlay.$el.css('z-index', ++maxZ)); 7317 7318 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed. 7319 // http://ui.jquery.com/bugs/ticket/3193 7320 var saveScroll = { scrollTop: this.element.attr('scrollTop'), scrollLeft: this.element.attr('scrollLeft') }; 7321 this.uiDialog.css('z-index', ++maxZ); 7322 this.element.attr(saveScroll); 7323 this._trigger('focus', null, { options: this.options }); 7324 }, 7325 7326 open: function() { 7327 if (this._isOpen) { return; } 7328 7329 this.overlay = this.options.modal ? new $.ui.dialog.overlay(this) : null; 7330 (this.uiDialog.next().length && this.uiDialog.appendTo('body')); 7331 this._position(this.options.position); 7332 this.uiDialog.show(this.options.show); 7333 (this.options.autoResize && this._size()); 7334 this.moveToTop(true); 7335 7336 // prevent tabbing out of modal dialogs 7337 (this.options.modal && this.uiDialog.bind('keypress.ui-dialog', function(event) { 7338 if (event.keyCode != $.ui.keyCode.TAB) { 7339 return; 7340 } 7341 7342 var tabbables = $(':tabbable', this), 7343 first = tabbables.filter(':first')[0], 7344 last = tabbables.filter(':last')[0]; 7345 7346 if (event.target == last && !event.shiftKey) { 7347 setTimeout(function() { 7348 first.focus(); 7349 }, 1); 7350 } else if (event.target == first && event.shiftKey) { 7351 setTimeout(function() { 7352 last.focus(); 7353 }, 1); 7354 } 7355 })); 7356 7357 this.uiDialog.find(':tabbable:first').focus(); 7358 this._trigger('open', null, { options: this.options }); 7359 this._isOpen = true; 7360 }, 7361 7362 _createButtons: function(buttons) { 7363 var self = this, 7364 hasButtons = false, 7365 uiDialogButtonPane = this.uiDialogButtonPane; 7366 7367 // remove any existing buttons 7368 uiDialogButtonPane.empty().hide(); 7369 7370 $.each(buttons, function() { return !(hasButtons = true); }); 7371 if (hasButtons) { 7372 uiDialogButtonPane.show(); 7373 $.each(buttons, function(name, fn) { 7374 $('<button type="button"></button>') 7375 .text(name) 7376 .click(function() { fn.apply(self.element[0], arguments); }) 7377 .appendTo(uiDialogButtonPane); 7378 }); 7379 } 7380 }, 7381 7382 _makeDraggable: function() { 7383 var self = this, 7384 options = this.options; 7385 7386 this.uiDialog.draggable({ 7387 cancel: '.ui-dialog-content', 7388 helper: options.dragHelper, 7389 handle: '.ui-dialog-titlebar', 7390 start: function() { 7391 self.moveToTop(); 7392 (options.dragStart && options.dragStart.apply(self.element[0], arguments)); 7393 }, 7394 drag: function() { 7395 (options.drag && options.drag.apply(self.element[0], arguments)); 7396 }, 7397 stop: function() { 7398 (options.dragStop && options.dragStop.apply(self.element[0], arguments)); 7399 $.ui.dialog.overlay.resize(); 7400 } 7401 }); 7402 }, 7403 7404 _makeResizable: function(handles) { 7405 handles = (handles === undefined ? this.options.resizable : handles); 7406 var self = this, 7407 options = this.options, 7408 resizeHandles = typeof handles == 'string' 7409 ? handles 7410 : 'n,e,s,w,se,sw,ne,nw'; 7411 7412 this.uiDialog.resizable({ 7413 cancel: '.ui-dialog-content', 7414 helper: options.resizeHelper, 7415 maxWidth: options.maxWidth, 7416 maxHeight: options.maxHeight, 7417 minWidth: options.minWidth, 7418 minHeight: options.minHeight, 7419 start: function() { 7420 (options.resizeStart && options.resizeStart.apply(self.element[0], arguments)); 7421 }, 7422 resize: function() { 7423 (options.autoResize && self._size.apply(self)); 7424 (options.resize && options.resize.apply(self.element[0], arguments)); 7425 }, 7426 handles: resizeHandles, 7427 stop: function() { 7428 (options.autoResize && self._size.apply(self)); 7429 (options.resizeStop && options.resizeStop.apply(self.element[0], arguments)); 7430 $.ui.dialog.overlay.resize(); 7431 } 7432 }); 7433 }, 7434 7435 _position: function(pos) { 7436 var wnd = $(window), doc = $(document), 7437 pTop = doc.scrollTop(), pLeft = doc.scrollLeft(), 7438 minTop = pTop; 7439 7440 if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) { 7441 pos = [ 7442 pos == 'right' || pos == 'left' ? pos : 'center', 7443 pos == 'top' || pos == 'bottom' ? pos : 'middle' 7444 ]; 7445 } 7446 if (pos.constructor != Array) { 7447 pos = ['center', 'middle']; 7448 } 7449 if (pos[0].constructor == Number) { 7450 pLeft += pos[0]; 7451 } else { 7452 switch (pos[0]) { 7453 case 'left': 7454 pLeft += 0; 7455 break; 7456 case 'right': 7457 pLeft += wnd.width() - this.uiDialog.outerWidth(); 7458 break; 7459 default: 7460 case 'center': 7461 pLeft += (wnd.width() - this.uiDialog.outerWidth()) / 2; 7462 } 7463 } 7464 if (pos[1].constructor == Number) { 7465 pTop += pos[1]; 7466 } else { 7467 switch (pos[1]) { 7468 case 'top': 7469 pTop += 0; 7470 break; 7471 case 'bottom': 7472 // Opera check fixes #3564, can go away with jQuery 1.3 7473 pTop += ($.browser.opera ? window.innerHeight : wnd.height()) - this.uiDialog.outerHeight(); 7474 break; 7475 default: 7476 case 'middle': 7477 // Opera check fixes #3564, can go away with jQuery 1.3 7478 pTop += (($.browser.opera ? window.innerHeight : wnd.height()) - this.uiDialog.outerHeight()) / 2; 7479 } 7480 } 7481 7482 // prevent the dialog from being too high (make sure the titlebar 7483 // is accessible) 7484 pTop = Math.max(pTop, minTop); 7485 this.uiDialog.css({top: pTop, left: pLeft}); 7486 }, 7487 7488 _setData: function(key, value){ 7489 (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value)); 7490 switch (key) { 7491 case "buttons": 7492 this._createButtons(value); 7493 break; 7494 case "closeText": 7495 this.uiDialogTitlebarCloseText.text(value); 7496 break; 7497 case "draggable": 7498 (value 7499 ? this._makeDraggable() 7500 : this.uiDialog.draggable('destroy')); 7501 break; 7502 case "height": 7503 this.uiDialog.height(value); 7504 break; 7505 case "position": 7506 this._position(value); 7507 break; 7508 case "resizable": 7509 var uiDialog = this.uiDialog, 7510 isResizable = this.uiDialog.is(':data(resizable)'); 7511 7512 // currently resizable, becoming non-resizable 7513 (isResizable && !value && uiDialog.resizable('destroy')); 7514 7515 // currently resizable, changing handles 7516 (isResizable && typeof value == 'string' && 7517 uiDialog.resizable('option', 'handles', value)); 7518 7519 // currently non-resizable, becoming resizable 7520 (isResizable || this._makeResizable(value)); 7521 7522 break; 7523 case "title": 7524 $(".ui-dialog-title", this.uiDialogTitlebar).html(value || ' '); 7525 break; 7526 case "width": 7527 this.uiDialog.width(value); 7528 break; 7529 } 7530 7531 $.widget.prototype._setData.apply(this, arguments); 7532 }, 7533 7534 _size: function() { 7535 var container = this.uiDialogContainer, 7536 titlebar = this.uiDialogTitlebar, 7537 content = this.element, 7538 tbMargin = (parseInt(content.css('margin-top'), 10) || 0) 7539 + (parseInt(content.css('margin-bottom'), 10) || 0), 7540 lrMargin = (parseInt(content.css('margin-left'), 10) || 0) 7541 + (parseInt(content.css('margin-right'), 10) || 0); 7542 content.height(container.height() - titlebar.outerHeight() - tbMargin); 7543 content.width(container.width() - lrMargin); 7544 } 7545 7546 }); 7547 7548 $.extend($.ui.dialog, { 7549 version: "1.6", 7550 defaults: { 7551 autoOpen: true, 7552 autoResize: true, 7553 bgiframe: false, 7554 buttons: {}, 7555 closeOnEscape: true, 7556 closeText: 'close', 7557 draggable: true, 7558 height: 200, 7559 minHeight: 100, 7560 minWidth: 150, 7561 modal: false, 7562 overlay: {}, 7563 position: 'center', 7564 resizable: true, 7565 stack: true, 7566 width: 300, 7567 zIndex: 1000 7568 }, 7569 7570 getter: 'isOpen', 7571 7572 uuid: 0, 7573 7574 getTitleId: function($el) { 7575 return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid); 7576 }, 7577 7578 overlay: function(dialog) { 7579 this.$el = $.ui.dialog.overlay.create(dialog); 7580 } 7581 }); 7582 7583 $.extend($.ui.dialog.overlay, { 7584 instances: [], 7585 events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','), 7586 function(event) { return event + '.dialog-overlay'; }).join(' '), 7587 create: function(dialog) { 7588 if (this.instances.length === 0) { 7589 // prevent use of anchors and inputs 7590 // we use a setTimeout in case the overlay is created from an 7591 // event that we're going to be cancelling (see #2804) 7592 setTimeout(function() { 7593 $('a, :input').bind($.ui.dialog.overlay.events, function() { 7594 // allow use of the element if inside a dialog and 7595 // - there are no modal dialogs 7596 // - there are modal dialogs, but we are in front of the topmost modal 7597 var allow = false; 7598 var $dialog = $(this).parents('.ui-dialog'); 7599 if ($dialog.length) { 7600 var $overlays = $('.ui-dialog-overlay'); 7601 if ($overlays.length) { 7602 var maxZ = parseInt($overlays.css('z-index'), 10); 7603 $overlays.each(function() { 7604 maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10)); 7605 }); 7606 allow = parseInt($dialog.css('z-index'), 10) > maxZ; 7607 } else { 7608 allow = true; 7609 } 7610 } 7611 return allow; 7612 }); 7613 }, 1); 7614 7615 // allow closing by pressing the escape key 7616 $(document).bind('keydown.dialog-overlay', function(event) { 7617 (dialog.options.closeOnEscape && event.keyCode 7618 && event.keyCode == $.ui.keyCode.ESCAPE && dialog.close()); 7619 }); 7620 7621 // handle window resize 7622 $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize); 7623 } 7624 7625 var $el = $('<div></div>').appendTo(document.body) 7626 .addClass('ui-dialog-overlay').css($.extend({ 7627 borderWidth: 0, margin: 0, padding: 0, 7628 position: 'absolute', top: 0, left: 0, 7629 width: this.width(), 7630 height: this.height() 7631 }, dialog.options.overlay)); 7632 7633 (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe()); 7634 7635 this.instances.push($el); 7636 return $el; 7637 }, 7638 7639 destroy: function($el) { 7640 this.instances.splice($.inArray(this.instances, $el), 1); 7641 7642 if (this.instances.length === 0) { 7643 $('a, :input').add([document, window]).unbind('.dialog-overlay'); 7644 } 7645 7646 $el.remove(); 7647 }, 7648 7649 height: function() { 7650 // handle IE 6 7651 if ($.browser.msie && $.browser.version < 7) { 7652 var scrollHeight = Math.max( 7653 document.documentElement.scrollHeight, 7654 document.body.scrollHeight 7655 ); 7656 var offsetHeight = Math.max( 7657 document.documentElement.offsetHeight, 7658 document.body.offsetHeight 7659 ); 7660 7661 if (scrollHeight < offsetHeight) { 7662 return $(window).height() + 'px'; 7663 } else { 7664 return scrollHeight + 'px'; 7665 } 7666 // handle Opera 7667 } else if ($.browser.opera) { 7668 return Math.max( 7669 window.innerHeight, 7670 $(document).height() 7671 ) + 'px'; 7672 // handle "good" browsers 7673 } else { 7674 return $(document).height() + 'px'; 7675 } 7676 }, 7677 7678 width: function() { 7679 // handle IE 6 7680 if ($.browser.msie && $.browser.version < 7) { 7681 var scrollWidth = Math.max( 7682 document.documentElement.scrollWidth, 7683 document.body.scrollWidth 7684 ); 7685 var offsetWidth = Math.max( 7686 document.documentElement.offsetWidth, 7687 document.body.offsetWidth 7688 ); 7689 7690 if (scrollWidth < offsetWidth) { 7691 return $(window).width() + 'px'; 7692 } else { 7693 return scrollWidth + 'px'; 7694 } 7695 // handle Opera 7696 } else if ($.browser.opera) { 7697 return Math.max( 7698 window.innerWidth, 7699 $(document).width() 7700 ) + 'px'; 7701 // handle "good" browsers 7702 } else { 7703 return $(document).width() + 'px'; 7704 } 7705 }, 7706 7707 resize: function() { 7708 /* If the dialog is draggable and the user drags it past the 7709 * right edge of the window, the document becomes wider so we 7710 * need to stretch the overlay. If the user then drags the 7711 * dialog back to the left, the document will become narrower, 7712 * so we need to shrink the overlay to the appropriate size. 7713 * This is handled by shrinking the overlay before setting it 7714 * to the full document size. 7715 */ 7716 var $overlays = $([]); 7717 $.each($.ui.dialog.overlay.instances, function() { 7718 $overlays = $overlays.add(this); 7719 }); 7720 7721 $overlays.css({ 7722 width: 0, 7723 height: 0 7724 }).css({ 7725 width: $.ui.dialog.overlay.width(), 7726 height: $.ui.dialog.overlay.height() 7727 }); 7728 } 7729 }); 7730 7731 $.extend($.ui.dialog.overlay.prototype, { 7732 destroy: function() { 7733 $.ui.dialog.overlay.destroy(this.$el); 7734 } 7735 }); 7736 7737 })(jQuery); 7738 /* 7739 * jQuery UI Slider 1.6 7740 * 7741 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 7742 * Dual licensed under the MIT (MIT-LICENSE.txt) 7743 * and GPL (GPL-LICENSE.txt) licenses. 7744 * 7745 * http://docs.jquery.com/UI/Slider 7746 * 7747 * Depends: 7748 * ui.core.js 7749 */ 7750 (function($) { 7751 7752 $.fn.unwrap = $.fn.unwrap || function(expr) { 7753 return this.each(function(){ 7754 $(this).parents(expr).eq(0).after(this).remove(); 7755 }); 7756 }; 7757 7758 $.widget("ui.slider", { 7759 7760 _init: function() { 7761 7762 var self = this; 7763 this.element.addClass("ui-slider"); 7764 this._initBoundaries(); 7765 7766 // Initialize mouse and key events for interaction 7767 this.handle = $(this.options.handle, this.element); 7768 if (!this.handle.length) { 7769 self.handle = self.generated = $(self.options.handles || [0]).map(function() { 7770 var handle = $("<div/>").addClass("ui-slider-handle").appendTo(self.element); 7771 if (this.id) 7772 handle.attr("id", this.id); 7773 return handle[0]; 7774 }); 7775 } 7776 7777 var handleclass = function(el) { 7778 this.element = $(el); 7779 this.element.data("mouse", this); 7780 this.options = self.options; 7781 7782 this.element.bind("mousedown", function() { 7783 if(self.currentHandle) this.blur(self.currentHandle); 7784 self._focus(this, true); 7785 }); 7786 7787 this._mouseInit(); 7788 }; 7789 7790 $.extend(handleclass.prototype, $.ui.mouse, { 7791 _mouseCapture: function() { return true; }, 7792 _mouseStart: function(event) { return self._start.call(self, event, this.element[0]); }, 7793 _mouseDrag: function(event) { return self._drag.call(self, event, this.element[0]); }, 7794 _mouseStop: function(event) { return self._stop.call(self, event, this.element[0]); }, 7795 trigger: function(event) { this._mouseDown(event); } 7796 }); 7797 7798 $(this.handle) 7799 .each(function() { 7800 new handleclass(this); 7801 }) 7802 .wrap('<a href="#" style="outline:none;border:none;"></a>') 7803 .parent() 7804 .bind('click', function() { return false; }) 7805 .bind('focus', function(event) { self._focus(this.firstChild); }) 7806 .bind('blur', function(event) { self._blur(this.firstChild); }) 7807 .bind('keydown', function(event) { if(!self.options.noKeyboard) return self._keydown(event.keyCode, this.firstChild); }) 7808 ; 7809 7810 // Bind the click to the slider itself 7811 this.element.bind('mousedown.slider', function(event) { 7812 7813 if($(event.target).is('.ui-slider-handle')) return; 7814 7815 //Go to the actual clicked posiion, apply a click 7816 self._click.apply(self, [event]); 7817 7818 //initiate a handle drag, so we can click+drag somewhere 7819 self.currentHandle.data("mouse").trigger(event); 7820 7821 //This is for always triggering the change event 7822 self.firstValue = self.firstValue + 1; 7823 7824 }); 7825 7826 // Move the first handle to the startValue 7827 $.each(this.options.handles || [], function(index, handle) { 7828 self.moveTo(handle.start, index, true); 7829 }); 7830 if (!isNaN(this.options.startValue)) 7831 this.moveTo(this.options.startValue, 0, true); 7832 7833 this.previousHandle = $(this.handle[0]); //set the previous handle to the first to allow clicking before selecting the handle 7834 if(this.handle.length == 2 && this.options.range) this._createRange(); 7835 7836 }, 7837 7838 destroy: function() { 7839 7840 this.element 7841 .removeClass("ui-slider ui-slider-disabled") 7842 .removeData("slider") 7843 .unbind(".slider"); 7844 7845 if(this.handle && this.handle.length) { 7846 this.handle 7847 .unwrap("a"); 7848 this.handle.each(function() { 7849 var mouse = $(this).data("mouse"); 7850 mouse && mouse._mouseDestroy(); 7851 }); 7852 } 7853 7854 this.generated && this.generated.remove(); 7855 7856 }, 7857 7858 _start: function(event, handle) { 7859 7860 var o = this.options; 7861 if(o.disabled) return false; 7862 7863 // Prepare the outer size 7864 this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() }; 7865 7866 // This is a especially ugly fix for strange blur events happening on mousemove events 7867 if (!this.currentHandle) 7868 this._focus(this.previousHandle, true); 7869 7870 this.offset = this.element.offset(); 7871 7872 this.handleOffset = this.currentHandle.offset(); 7873 this.clickOffset = { top: event.pageY - this.handleOffset.top, left: event.pageX - this.handleOffset.left }; 7874 7875 this.firstValue = this.value(); 7876 7877 this._propagate('start', event); 7878 this._drag(event, handle); 7879 return true; 7880 7881 }, 7882 7883 _drag: function(event, handle) { 7884 7885 var o = this.options; 7886 7887 var position = { top: event.pageY - this.offset.top - this.clickOffset.top, left: event.pageX - this.offset.left - this.clickOffset.left}; 7888 if(!this.currentHandle) this._focus(this.previousHandle, true); //This is a especially ugly fix for strange blur events happening on mousemove events 7889 7890 position.left = this._translateLimits(position.left, "x"); 7891 position.top = this._translateLimits(position.top, "y"); 7892 7893 if (o.stepping.x) { 7894 var value = this._convertValue(position.left, "x"); 7895 value = this._round(value / o.stepping.x) * o.stepping.x; 7896 position.left = this._translateValue(value, "x"); 7897 } 7898 if (o.stepping.y) { 7899 var value = this._convertValue(position.top, "y"); 7900 value = this._round(value / o.stepping.y) * o.stepping.y; 7901 position.top = this._translateValue(value, "y"); 7902 } 7903 7904 position.left = this._translateRange(position.left, "x"); 7905 position.top = this._translateRange(position.top, "y"); 7906 7907 if(o.axis != "vertical") this.currentHandle.css({ left: position.left }); 7908 if(o.axis != "horizontal") this.currentHandle.css({ top: position.top }); 7909 7910 //Store the slider's value 7911 this.currentHandle.data("mouse").sliderValue = { 7912 x: this._round(this._convertValue(position.left, "x")) || 0, 7913 y: this._round(this._convertValue(position.top, "y")) || 0 7914 }; 7915 7916 if (this.rangeElement) 7917 this._updateRange(); 7918 this._propagate('slide', event); 7919 return false; 7920 7921 }, 7922 7923 _stop: function(event) { 7924 7925 this._propagate('stop', event); 7926 7927 if (this.firstValue != this.value()) 7928 this._propagate('change', event); 7929 7930 // This is a especially ugly fix for strange blur events happening on mousemove events 7931 this._focus(this.currentHandle, true); 7932 7933 return false; 7934 7935 }, 7936 7937 _round: function(value) { 7938 7939 return this.options.round ? parseInt(value,10) : parseFloat(value); 7940 7941 }, 7942 7943 _setData: function(key, value) { 7944 7945 $.widget.prototype._setData.apply(this, arguments); 7946 7947 if (/min|max|steps/.test(key)) { 7948 this._initBoundaries(); 7949 } 7950 7951 if(key == "range") { 7952 value ? this.handle.length == 2 && this._createRange() : this._removeRange(); 7953 } 7954 7955 }, 7956 7957 _initBoundaries: function() { 7958 7959 var element = this.element[0], o = this.options; 7960 this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() }; 7961 7962 $.extend(o, { 7963 axis: o.axis || (element.offsetWidth < element.offsetHeight ? 'vertical' : 'horizontal'), 7964 max: !isNaN(parseInt(o.max,10)) ? { x: parseInt(o.max, 10), y: parseInt(o.max, 10) } : ({ x: o.max && o.max.x || 100, y: o.max && o.max.y || 100 }), 7965 min: !isNaN(parseInt(o.min,10)) ? { x: parseInt(o.min, 10), y: parseInt(o.min, 10) } : ({ x: o.min && o.min.x || 0, y: o.min && o.min.y || 0 }) 7966 }); 7967 //Prepare the real maxValue 7968 o.realMax = { 7969 x: o.max.x - o.min.x, 7970 y: o.max.y - o.min.y 7971 }; 7972 //Calculate stepping based on steps 7973 o.stepping = { 7974 x: o.stepping && o.stepping.x || parseInt(o.stepping, 10) || (o.steps ? o.realMax.x/(o.steps.x || parseInt(o.steps, 10) || o.realMax.x) : 0), 7975 y: o.stepping && o.stepping.y || parseInt(o.stepping, 10) || (o.steps ? o.realMax.y/(o.steps.y || parseInt(o.steps, 10) || o.realMax.y) : 0) 7976 }; 7977 7978 }, 7979 7980 _keydown: function(keyCode, handle) { 7981 7982 if (this.options.disabled) 7983 return; 7984 7985 var k = keyCode; 7986 if(/(33|34|35|36|37|38|39|40)/.test(k)) { 7987 var o = this.options, xpos, ypos; 7988 if (/(35|36)/.test(k)) { 7989 xpos = (k == 35) ? o.max.x : o.min.x; 7990 ypos = (k == 35) ? o.max.y : o.min.y; 7991 } else { 7992 var oper = /(34|37|40)/.test(k) ? "-=" : "+="; 7993 var step = /(37|38|39|40)/.test(k) ? "_oneStep" : "_pageStep"; 7994 xpos = oper + this[step]("x"); 7995 ypos = oper + this[step]("y"); 7996 } 7997 this.moveTo({ 7998 x: xpos, 7999 y: ypos 8000 }, handle); 8001 return false; 8002 } 8003 return true; 8004 8005 }, 8006 8007 _focus: function(handle,hard) { 8008 8009 this.currentHandle = $(handle).addClass('ui-slider-handle-active'); 8010 8011 if (hard) 8012 this.currentHandle.parent()[0].focus(); 8013 8014 }, 8015 8016 _blur: function(handle) { 8017 8018 $(handle).removeClass('ui-slider-handle-active'); 8019 8020 if(this.currentHandle && this.currentHandle[0] == handle) { 8021 this.previousHandle = this.currentHandle; 8022 this.currentHandle = null; 8023 }; 8024 8025 }, 8026 8027 _click: function(event) { 8028 8029 // This method is only used if: 8030 // - The user didn't click a handle 8031 // - The Slider is not disabled 8032 // - There is a current, or previous selected handle (otherwise we wouldn't know which one to move) 8033 8034 var pointer = [event.pageX, event.pageY]; 8035 8036 var clickedHandle = false; 8037 this.handle.each(function() { 8038 if(this == event.target) 8039 clickedHandle = true; 8040 }); 8041 if (clickedHandle || this.options.disabled || !(this.currentHandle || this.previousHandle)) 8042 return; 8043 8044 // If a previous handle was focussed, focus it again 8045 if (!this.currentHandle && this.previousHandle) 8046 this._focus(this.previousHandle, true); 8047 8048 // propagate only for distance > 0, otherwise propagation is done my drag 8049 this.offset = this.element.offset(); 8050 8051 this.moveTo({ 8052 y: this._convertValue(event.pageY - this.offset.top - this.currentHandle[0].offsetHeight/2, "y"), 8053 x: this._convertValue(event.pageX - this.offset.left - this.currentHandle[0].offsetWidth/2, "x") 8054 }, null, !this.options.distance); 8055 8056 }, 8057 8058 _createRange: function() { 8059 8060 if(this.rangeElement) return; 8061 this.rangeElement = $('<div></div>') 8062 .addClass('ui-slider-range') 8063 .css({ position: 'absolute' }) 8064 .appendTo(this.element); 8065 this._updateRange(); 8066 8067 }, 8068 8069 _removeRange: function() { 8070 8071 this.rangeElement.remove(); 8072 this.rangeElement = null; 8073 8074 }, 8075 8076 _updateRange: function() { 8077 8078 var prop = this.options.axis == "vertical" ? "top" : "left"; 8079 var size = this.options.axis == "vertical" ? "height" : "width"; 8080 8081 this.rangeElement.css(prop, (this._round($(this.handle[0]).css(prop)) || 0) + this._handleSize(0, this.options.axis == "vertical" ? "y" : "x")/2); 8082 this.rangeElement.css(size, (this._round($(this.handle[1]).css(prop)) || 0) - (this._round($(this.handle[0]).css(prop)) || 0)); 8083 8084 }, 8085 8086 _getRange: function() { 8087 8088 return this.rangeElement ? this._convertValue(this._round(this.rangeElement.css(this.options.axis == "vertical" ? "height" : "width")), this.options.axis == "vertical" ? "y" : "x") : null; 8089 8090 }, 8091 8092 _handleIndex: function() { 8093 8094 return this.handle.index(this.currentHandle[0]); 8095 8096 }, 8097 8098 value: function(handle, axis) { 8099 8100 if(this.handle.length == 1) this.currentHandle = this.handle; 8101 if(!axis) axis = this.options.axis == "vertical" ? "y" : "x"; 8102 8103 var curHandle = $(handle != undefined && handle !== null ? this.handle[handle] || handle : this.currentHandle); 8104 8105 if(curHandle.data("mouse").sliderValue) { 8106 return this._round(curHandle.data("mouse").sliderValue[axis]); 8107 } else { 8108 return this._round(((this._round(curHandle.css(axis == "x" ? "left" : "top")) / (this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(handle,axis))) * this.options.realMax[axis]) + this.options.min[axis]); 8109 } 8110 8111 }, 8112 8113 _convertValue: function(value,axis) { 8114 8115 return this.options.min[axis] + (value / (this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis))) * this.options.realMax[axis]; 8116 8117 }, 8118 8119 _translateValue: function(value,axis) { 8120 8121 return ((value - this.options.min[axis]) / this.options.realMax[axis]) * (this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis)); 8122 8123 }, 8124 8125 _translateRange: function(value,axis) { 8126 8127 if (this.rangeElement) { 8128 if (this.currentHandle[0] == this.handle[0] && value >= this._translateValue(this.value(1),axis)) 8129 value = this._translateValue(this.value(1,axis) - this._oneStep(axis), axis); 8130 if (this.currentHandle[0] == this.handle[1] && value <= this._translateValue(this.value(0),axis)) 8131 value = this._translateValue(this.value(0,axis) + this._oneStep(axis), axis); 8132 } 8133 8134 if (this.options.handles) { 8135 var handle = this.options.handles[this._handleIndex()]; 8136 if (value < this._translateValue(handle.min,axis)) { 8137 value = this._translateValue(handle.min,axis); 8138 } else if (value > this._translateValue(handle.max,axis)) { 8139 value = this._translateValue(handle.max,axis); 8140 } 8141 } 8142 8143 return value; 8144 8145 }, 8146 8147 _translateLimits: function(value,axis) { 8148 8149 if (value >= this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis)) 8150 value = this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis); 8151 8152 if (value <= 0) 8153 value = 0; 8154 8155 return value; 8156 8157 }, 8158 8159 _handleSize: function(handle,axis) { 8160 8161 return $(handle != undefined && handle !== null ? this.handle[handle] : this.currentHandle)[0]["offset"+(axis == "x" ? "Width" : "Height")]; 8162 8163 }, 8164 8165 _oneStep: function(axis) { 8166 8167 return this.options.stepping[axis] || 1; 8168 8169 }, 8170 8171 _pageStep: function(axis) { 8172 8173 return /* this.options.paging[axis] ||*/ 10; 8174 8175 }, 8176 8177 moveTo: function(value, handle, noPropagation) { 8178 8179 var o = this.options; 8180 8181 // Prepare the outer size 8182 this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() }; 8183 8184 //If no handle has been passed, no current handle is available and we have multiple handles, return false 8185 if (handle == undefined && !this.currentHandle && this.handle.length != 1) 8186 return false; 8187 8188 //If only one handle is available, use it 8189 if (handle == undefined && !this.currentHandle) 8190 handle = 0; 8191 8192 if (handle != undefined) 8193 this.currentHandle = this.previousHandle = $(this.handle[handle] || handle); 8194 8195 if(value.x !== undefined && value.y !== undefined) { 8196 var x = value.x, y = value.y; 8197 } else { 8198 var x = value, y = value; 8199 } 8200 8201 if(x !== undefined && x.constructor != Number) { 8202 var me = /^\-\=/.test(x), pe = /^\+\=/.test(x); 8203 if(me || pe) { 8204 x = this.value(null, "x") + this._round(x.replace(me ? '=' : '+=', '')); 8205 } else { 8206 x = isNaN(this._round(x)) ? undefined : this._round(x); 8207 } 8208 } 8209 8210 if(y !== undefined && y.constructor != Number) { 8211 var me = /^\-\=/.test(y), pe = /^\+\=/.test(y); 8212 if(me || pe) { 8213 y = this.value(null, "y") + this._round(y.replace(me ? '=' : '+=', '')); 8214 } else { 8215 y = isNaN(this._round(y)) ? undefined : this._round(y); 8216 } 8217 } 8218 8219 if(o.axis != "vertical" && x !== undefined) { 8220 if(o.stepping.x) x = this._round(x / o.stepping.x) * o.stepping.x; 8221 x = this._translateValue(x, "x"); 8222 x = this._translateLimits(x, "x"); 8223 x = this._translateRange(x, "x"); 8224 8225 o.animate ? this.currentHandle.stop().animate({ left: x }, (Math.abs(parseInt(this.currentHandle.css("left"),10) - x)) * (!isNaN(parseInt(o.animate,10)) ? o.animate : 5)) : this.currentHandle.css({ left: x }); 8226 } 8227 8228 if(o.axis != "horizontal" && y !== undefined) { 8229 if(o.stepping.y) y = this._round(y / o.stepping.y) * o.stepping.y; 8230 y = this._translateValue(y, "y"); 8231 y = this._translateLimits(y, "y"); 8232 y = this._translateRange(y, "y"); 8233 o.animate ? this.currentHandle.stop().animate({ top: y }, (Math.abs(parseInt(this.currentHandle.css("top"),10) - y)) * (!isNaN(parseInt(o.animate,10)) ? o.animate : 5)) : this.currentHandle.css({ top: y }); 8234 } 8235 8236 if (this.rangeElement) 8237 this._updateRange(); 8238 8239 //Store the slider's value 8240 this.currentHandle.data("mouse").sliderValue = { 8241 x: this._round(this._convertValue(x, "x")) || 0, 8242 y: this._round(this._convertValue(y, "y")) || 0 8243 }; 8244 8245 if (!noPropagation) { 8246 this._propagate('start', null); 8247 this._propagate("slide", null); 8248 this._propagate('stop', null); 8249 this._propagate('change', null); 8250 } 8251 8252 }, 8253 8254 _propagate: function(n, event) { 8255 8256 $.ui.plugin.call(this, n, [event, this.ui()]); 8257 this.element.triggerHandler(n == "slide" ? n : "slide"+n, [event, this.ui()], this.options[n]); 8258 8259 }, 8260 8261 plugins: {}, 8262 8263 ui: function(event) { 8264 return { 8265 options: this.options, 8266 handle: this.currentHandle, 8267 value: this.options.axis != "both" || !this.options.axis ? 8268 this._round(this.value(null, this.options.axis == "vertical" ? "y" : "x")) : 8269 { 8270 x: this._round(this.value(null, "x")), 8271 y: this._round(this.value(null, "y")) 8272 }, 8273 range: this._getRange() 8274 }; 8275 } 8276 8277 }); 8278 8279 $.extend($.ui.slider, { 8280 getter: "value", 8281 version: "1.6", 8282 defaults: { 8283 animate: false, 8284 distance: 1, 8285 handle: ".ui-slider-handle", 8286 round: true 8287 } 8288 }); 8289 8290 })(jQuery); 8291 /* 8292 * jQuery UI Tabs 1.6 8293 * 8294 * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about) 8295 * Dual licensed under the MIT (MIT-LICENSE.txt) 8296 * and GPL (GPL-LICENSE.txt) licenses. 8297 * 8298 * http://docs.jquery.com/UI/Tabs 8299 * 8300 * Depends: 8301 * ui.core.js 8302 */ 8303 (function($) { 8304 8305 $.widget("ui.tabs", { 8306 8307 _init: function() { 8308 // create tabs 8309 this._tabify(true); 8310 }, 8311 8312 destroy: function() { 8313 var o = this.options; 8314 this.element.unbind('.tabs') 8315 .removeClass(o.navClass).removeData('tabs'); 8316 this.$tabs.each(function() { 8317 var href = $.data(this, 'href.tabs'); 8318 if (href) 8319 this.href = href; 8320 var $this = $(this).unbind('.tabs'); 8321 $.each(['href', 'load', 'cache'], function(i, prefix) { 8322 $this.removeData(prefix + '.tabs'); 8323 }); 8324 }); 8325 this.$lis.add(this.$panels).each(function() { 8326 if ($.data(this, 'destroy.tabs')) 8327 $(this).remove(); 8328 else 8329 $(this).removeClass([o.selectedClass, o.deselectableClass, 8330 o.disabledClass, o.panelClass, o.hideClass].join(' ')); 8331 }); 8332 if (o.cookie) 8333 this._cookie(null, o.cookie); 8334 }, 8335 8336 _setData: function(key, value) { 8337 if ((/^selected/).test(key)) 8338 this.select(value); 8339 else { 8340 this.options[key] = value; 8341 this._tabify(); 8342 } 8343 }, 8344 8345 length: function() { 8346 return this.$tabs.length; 8347 }, 8348 8349 _tabId: function(a) { 8350 return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') 8351 || this.options.idPrefix + $.data(a); 8352 }, 8353 8354 _sanitizeSelector: function(hash) { 8355 return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":" 8356 }, 8357 8358 _cookie: function() { 8359 var cookie = this.cookie || (this.cookie = 'ui-tabs-' + $.data(this.element[0])); 8360 return $.cookie.apply(null, [cookie].concat($.makeArray(arguments))); 8361 }, 8362 8363 _tabify: function(init) { 8364 8365 this.$lis = $('li:has(a[href])', this.element); 8366 this.$tabs = this.$lis.map(function() { return $('a', this)[0]; }); 8367 this.$panels = $([]); 8368 8369 var self = this, o = this.options; 8370 8371 this.$tabs.each(function(i, a) { 8372 // inline tab 8373 if (a.hash && a.hash.replace('#', '')) // Safari 2 reports '#' for an empty hash 8374 self.$panels = self.$panels.add(self._sanitizeSelector(a.hash)); 8375 // remote tab 8376 else if ($(a).attr('href') != '#') { // prevent loading the page itself if href is just "#" 8377 $.data(a, 'href.tabs', a.href); // required for restore on destroy 8378 $.data(a, 'load.tabs', a.href); // mutable 8379 var id = self._tabId(a); 8380 a.href = '#' + id; 8381 var $panel = $('#' + id); 8382 if (!$panel.length) { 8383 $panel = $(o.panelTemplate).attr('id', id).addClass(o.panelClass) 8384 .insertAfter(self.$panels[i - 1] || self.element); 8385 $panel.data('destroy.tabs', true); 8386 } 8387 self.$panels = self.$panels.add($panel); 8388 } 8389 // invalid tab href 8390 else 8391 o.disabled.push(i + 1); 8392 }); 8393 8394 // initialization from scratch 8395 if (init) { 8396 8397 // attach necessary classes for styling if not present 8398 this.element.addClass(o.navClass); 8399 this.$panels.addClass(o.panelClass); 8400 8401 // Selected tab 8402 // use "selected" option or try to retrieve: 8403 // 1. from fragment identifier in url 8404 // 2. from cookie 8405 // 3. from selected class attribute on <li> 8406 if (o.selected === undefined) { 8407 if (location.hash) { 8408 this.$tabs.each(function(i, a) { 8409 if (a.hash == location.hash) { 8410 o.selected = i; 8411 return false; // break 8412 } 8413 }); 8414 } 8415 else if (o.cookie) { 8416 var index = parseInt(self._cookie(), 10); 8417 if (index && self.$tabs[index]) o.selected = index; 8418 } 8419 else if (self.$lis.filter('.' + o.selectedClass).length) 8420 o.selected = self.$lis.index( self.$lis.filter('.' + o.selectedClass)[0] ); 8421 } 8422 o.selected = o.selected === null || o.selected !== undefined ? o.selected : 0; // first tab selected by default 8423 8424 // Take disabling tabs via class attribute from HTML 8425 // into account and update option properly. 8426 // A selected tab cannot become disabled. 8427 o.disabled = $.unique(o.disabled.concat( 8428 $.map(this.$lis.filter('.' + o.disabledClass), 8429 function(n, i) { return self.$lis.index(n); } ) 8430 )).sort(); 8431 if ($.inArray(o.selected, o.disabled) != -1) 8432 o.disabled.splice($.inArray(o.selected, o.disabled), 1); 8433 8434 // highlight selected tab 8435 this.$panels.addClass(o.hideClass); 8436 this.$lis.removeClass(o.selectedClass); 8437 if (o.selected !== null) { 8438 this.$panels.eq(o.selected).removeClass(o.hideClass); 8439 var classes = [o.selectedClass]; 8440 if (o.deselectable) classes.push(o.deselectableClass); 8441 this.$lis.eq(o.selected).addClass(classes.join(' ')); 8442 8443 // seems to be expected behavior that the show callback is fired 8444 var onShow = function() { 8445 self._trigger('show', null, 8446 self.ui(self.$tabs[o.selected], self.$panels[o.selected])); 8447 }; 8448 8449 // load if remote tab 8450 if ($.data(this.$tabs[o.selected], 'load.tabs')) 8451 this.load(o.selected, onShow); 8452 // just trigger show event 8453 else onShow(); 8454 } 8455 8456 // clean up to avoid memory leaks in certain versions of IE 6 8457 $(window).bind('unload', function() { 8458 self.$tabs.unbind('.tabs'); 8459 self.$lis = self.$tabs = self.$panels = null; 8460 }); 8461 8462 } 8463 // update selected after add/remove 8464 else 8465 o.selected = this.$lis.index( this.$lis.filter('.' + o.selectedClass)[0] ); 8466 8467 // set or update cookie after init and add/remove respectively 8468 if (o.cookie) this._cookie(o.selected, o.cookie); 8469 8470 // disable tabs 8471 for (var i = 0, li; li = this.$lis[i]; i++) 8472 $(li)[$.inArray(i, o.disabled) != -1 && !$(li).hasClass(o.selectedClass) ? 'addClass' : 'removeClass'](o.disabledClass); 8473 8474 // reset cache if switching from cached to not cached 8475 if (o.cache === false) this.$tabs.removeData('cache.tabs'); 8476 8477 // set up animations 8478 var hideFx, showFx; 8479 if (o.fx) { 8480 if (o.fx.constructor == Array) { 8481 hideFx = o.fx[0]; 8482 showFx = o.fx[1]; 8483 } 8484 else hideFx = showFx = o.fx; 8485 } 8486 8487 // Reset certain styles left over from animation 8488 // and prevent IE's ClearType bug... 8489 function resetStyle($el, fx) { 8490 $el.css({ display: '' }); 8491 if ($.browser.msie && fx.opacity) $el[0].style.removeAttribute('filter'); 8492 } 8493 8494 // Show a tab... 8495 var showTab = showFx ? 8496 function(clicked, $show) { 8497 $show.animate(showFx, showFx.duration || 'normal', function() { 8498 $show.removeClass(o.hideClass); 8499 resetStyle($show, showFx); 8500 self._trigger('show', null, self.ui(clicked, $show[0])); 8501 }); 8502 } : 8503 function(clicked, $show) { 8504 $show.removeClass(o.hideClass); 8505 self._trigger('show', null, self.ui(clicked, $show[0])); 8506 }; 8507 8508 // Hide a tab, $show is optional... 8509 var hideTab = hideFx ? 8510 function(clicked, $hide, $show) { 8511 $hide.animate(hideFx, hideFx.duration || 'normal', function() { 8512 $hide.addClass(o.hideClass); 8513 resetStyle($hide, hideFx); 8514 if ($show) showTab(clicked, $show, $hide); 8515 }); 8516 } : 8517 function(clicked, $hide, $show) { 8518 $hide.addClass(o.hideClass); 8519 if ($show) showTab(clicked, $show); 8520 }; 8521 8522 // Switch a tab... 8523 function switchTab(clicked, $li, $hide, $show) { 8524 var classes = [o.selectedClass]; 8525 if (o.deselectable) classes.push(o.deselectableClass); 8526 $li.addClass(classes.join(' ')).siblings().removeClass(classes.join(' ')); 8527 hideTab(clicked, $hide, $show); 8528 } 8529 8530 // attach tab event handler, unbind to avoid duplicates from former tabifying... 8531 this.$tabs.unbind('.tabs').bind(o.event + '.tabs', function() { 8532 8533 //var trueClick = event.clientX; // add to history only if true click occured, not a triggered click 8534 var $li = $(this).parents('li:eq(0)'), 8535 $hide = self.$panels.filter(':visible'), 8536 $show = $(self._sanitizeSelector(this.hash)); 8537 8538 // If tab is already selected and not deselectable or tab disabled or 8539 // or is already loading or click callback returns false stop here. 8540 // Check if click handler returns false last so that it is not executed 8541 // for a disabled or loading tab! 8542 if (($li.hasClass(o.selectedClass) && !o.deselectable) 8543 || $li.hasClass(o.disabledClass) 8544 || $(this).hasClass(o.loadingClass) 8545 || self._trigger('select', null, self.ui(this, $show[0])) === false 8546 ) { 8547 this.blur(); 8548 return false; 8549 } 8550 8551 o.selected = self.$tabs.index(this); 8552 8553 // if tab may be closed 8554 if (o.deselectable) { 8555 if ($li.hasClass(o.selectedClass)) { 8556 self.options.selected = null; 8557 $li.removeClass([o.selectedClass, o.deselectableClass].join(' ')); 8558 self.$panels.stop(); 8559 hideTab(this, $hide); 8560 this.blur(); 8561 return false; 8562 } else if (!$hide.length) { 8563 self.$panels.stop(); 8564 var a = this; 8565 self.load(self.$tabs.index(this), function() { 8566 $li.addClass([o.selectedClass, o.deselectableClass].join(' ')); 8567 showTab(a, $show); 8568 }); 8569 this.blur(); 8570 return false; 8571 } 8572 } 8573 8574 if (o.cookie) self._cookie(o.selected, o.cookie); 8575 8576 // stop possibly running animations 8577 self.$panels.stop(); 8578 8579 // show new tab 8580 if ($show.length) { 8581 var a = this; 8582 self.load(self.$tabs.index(this), $hide.length ? 8583 function() { 8584 switchTab(a, $li, $hide, $show); 8585 } : 8586 function() { 8587 $li.addClass(o.selectedClass); 8588 showTab(a, $show); 8589 } 8590 ); 8591 } else 8592 throw 'jQuery UI Tabs: Mismatching fragment identifier.'; 8593 8594 // Prevent IE from keeping other link focussed when using the back button 8595 // and remove dotted border from clicked link. This is controlled via CSS 8596 // in modern browsers; blur() removes focus from address bar in Firefox 8597 // which can become a usability and annoying problem with tabs('rotate'). 8598 if ($.browser.msie) this.blur(); 8599 8600 return false; 8601 8602 }); 8603 8604 // disable click if event is configured to something else 8605 if (o.event != 'click') this.$tabs.bind('click.tabs', function(){return false;}); 8606 8607 }, 8608 8609 add: function(url, label, index) { 8610 if (index == undefined) 8611 index = this.$tabs.length; // append by default 8612 8613 var o = this.options; 8614 var $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label)); 8615 $li.data('destroy.tabs', true); 8616 8617 var id = url.indexOf('#') == 0 ? url.replace('#', '') : this._tabId( $('a:first-child', $li)[0] ); 8618 8619 // try to find an existing element before creating a new one 8620 var $panel = $('#' + id); 8621 if (!$panel.length) { 8622 $panel = $(o.panelTemplate).attr('id', id) 8623 .addClass(o.hideClass) 8624 .data('destroy.tabs', true); 8625 } 8626 $panel.addClass(o.panelClass); 8627 if (index >= this.$lis.length) { 8628 $li.appendTo(this.element); 8629 $panel.appendTo(this.element[0].parentNode); 8630 } else { 8631 $li.insertBefore(this.$lis[index]); 8632 $panel.insertBefore(this.$panels[index]); 8633 } 8634 8635 o.disabled = $.map(o.disabled, 8636 function(n, i) { return n >= index ? ++n : n }); 8637 8638 this._tabify(); 8639 8640 if (this.$tabs.length == 1) { 8641 $li.addClass(o.selectedClass); 8642 $panel.removeClass(o.hideClass); 8643 var href = $.data(this.$tabs[0], 'load.tabs'); 8644 if (href) 8645 this.load(index, href); 8646 } 8647 8648 // callback 8649 this._trigger('add', null, this.ui(this.$tabs[index], this.$panels[index])); 8650 }, 8651 8652 remove: function(index) { 8653 var o = this.options, $li = this.$lis.eq(index).remove(), 8654 $panel = this.$panels.eq(index).remove(); 8655 8656 // If selected tab was removed focus tab to the right or 8657 // in case the last tab was removed the tab to the left. 8658 if ($li.hasClass(o.selectedClass) && this.$tabs.length > 1) 8659 this.select(index + (index + 1 < this.$tabs.length ? 1 : -1)); 8660 8661 o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }), 8662 function(n, i) { return n >= index ? --n : n }); 8663 8664 this._tabify(); 8665 8666 // callback 8667 this._trigger('remove', null, this.ui($li.find('a')[0], $panel[0])); 8668 }, 8669 8670 enable: function(index) { 8671 var o = this.options; 8672 if ($.inArray(index, o.disabled) == -1) 8673 return; 8674 8675 var $li = this.$lis.eq(index).removeClass(o.disabledClass); 8676 if ($.browser.safari) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2... 8677 $li.css('display', 'inline-block'); 8678 setTimeout(function() { 8679 $li.css('display', 'block'); 8680 }, 0); 8681 } 8682 8683 o.disabled = $.grep(o.disabled, function(n, i) { return n != index; }); 8684 8685 // callback 8686 this._trigger('enable', null, this.ui(this.$tabs[index], this.$panels[index])); 8687 }, 8688 8689 disable: function(index) { 8690 var self = this, o = this.options; 8691 if (index != o.selected) { // cannot disable already selected tab 8692 this.$lis.eq(index).addClass(o.disabledClass); 8693 8694 o.disabled.push(index); 8695 o.disabled.sort(); 8696 8697 // callback 8698 this._trigger('disable', null, this.ui(this.$tabs[index], this.$panels[index])); 8699 } 8700 }, 8701 8702 select: function(index) { 8703 // TODO make null as argument work 8704 if (typeof index == 'string') 8705 index = this.$tabs.index( this.$tabs.filter('[href$=' + index + ']')[0] ); 8706 this.$tabs.eq(index).trigger(this.options.event + '.tabs'); 8707 }, 8708 8709 load: function(index, callback) { // callback is for internal usage only 8710 8711 var self = this, o = this.options, $a = this.$tabs.eq(index), a = $a[0], 8712 bypassCache = callback == undefined || callback === false, url = $a.data('load.tabs'); 8713 8714 callback = callback || function() {}; 8715 8716 // no remote or from cache - just finish with callback 8717 if (!url || !bypassCache && $.data(a, 'cache.tabs')) { 8718 callback(); 8719 return; 8720 } 8721 8722 // load remote from here on 8723 8724 var inner = function(parent) { 8725 var $parent = $(parent), $inner = $parent.find('*:last'); 8726 return $inner.length && $inner.is(':not(img)') && $inner || $parent; 8727 }; 8728 var cleanup = function() { 8729 self.$tabs.filter('.' + o.loadingClass).removeClass(o.loadingClass) 8730 .each(function() { 8731 if (o.spinner) 8732 inner(this).parent().html(inner(this).data('label.tabs')); 8733 }); 8734 self.xhr = null; 8735 }; 8736 8737 if (o.spinner) { 8738 var label = inner(a).html(); 8739 inner(a).wrapInner('<em></em>') 8740 .find('em').data('label.tabs', label).html(o.spinner); 8741 } 8742 8743 var ajaxOptions = $.extend({}, o.ajaxOptions, { 8744 url: url, 8745 success: function(r, s) { 8746 $(self._sanitizeSelector(a.hash)).html(r); 8747 cleanup(); 8748 8749 if (o.cache) 8750 $.data(a, 'cache.tabs', true); // if loaded once do not load them again 8751 8752 // callbacks 8753 self._trigger('load', null, self.ui(self.$tabs[index], self.$panels[index])); 8754 try { 8755 o.ajaxOptions.success(r, s); 8756 } 8757 catch (event) {} 8758 8759 // This callback is required because the switch has to take 8760 // place after loading has completed. Call last in order to 8761 // fire load before show callback... 8762 callback(); 8763 } 8764 }); 8765 if (this.xhr) { 8766 // terminate pending requests from other tabs and restore tab label 8767 this.xhr.abort(); 8768 cleanup(); 8769 } 8770 $a.addClass(o.loadingClass); 8771 self.xhr = $.ajax(ajaxOptions); 8772 }, 8773 8774 url: function(index, url) { 8775 this.$tabs.eq(index).removeData('cache.tabs').data('load.tabs', url); 8776 }, 8777 8778 ui: function(tab, panel) { 8779 return { 8780 options: this.options, 8781 tab: tab, 8782 panel: panel, 8783 index: this.$tabs.index(tab) 8784 }; 8785 } 8786 8787 }); 8788 8789 $.extend($.ui.tabs, { 8790 version: '1.6', 8791 getter: 'length', 8792 defaults: { 8793 ajaxOptions: null, 8794 cache: false, 8795 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } 8796 deselectable: false, 8797 deselectableClass: 'ui-tabs-deselectable', 8798 disabled: [], 8799 disabledClass: 'ui-tabs-disabled', 8800 event: 'click', 8801 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } 8802 hideClass: 'ui-tabs-hide', 8803 idPrefix: 'ui-tabs-', 8804 loadingClass: 'ui-tabs-loading', 8805 navClass: 'ui-tabs-nav', 8806 panelClass: 'ui-tabs-panel', 8807 panelTemplate: '<div></div>', 8808 selectedClass: 'ui-tabs-selected', 8809 spinner: 'Loading…', 8810 tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>' 8811 } 8812 }); 8813 8814 /* 8815 * Tabs Extensions 8816 */ 8817 8818 /* 8819 * Rotate 8820 */ 8821 $.extend($.ui.tabs.prototype, { 8822 rotation: null, 8823 rotate: function(ms, continuing) { 8824 8825 continuing = continuing || false; 8826 8827 var self = this, t = this.options.selected; 8828 8829 function start() { 8830 self.rotation = setInterval(function() { 8831 t = ++t < self.$tabs.length ? t : 0; 8832 self.select(t); 8833 }, ms); 8834 } 8835 8836 function stop(event) { 8837 if (!event || event.clientX) { // only in case of a true click 8838 clearInterval(self.rotation); 8839 } 8840 } 8841 8842 // start interval 8843 if (ms) { 8844 start(); 8845 if (!continuing) 8846 this.$tabs.bind(this.options.event + '.tabs', stop); 8847 else 8848 this.$tabs.bind(this.options.event + '.tabs', function() { 8849 stop(); 8850 t = self.options.selected; 8851 start(); 8852 }); 8853 } 8854 // stop interval 8855 else { 8856 stop(); 8857 this.$tabs.unbind(this.options.event + '.tabs', stop); 8858 } 8859 } 8860 }); 8861 8862 })(jQuery);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |