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