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