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