1/*! jQuery UI - v1.9.2 - 2012-11-23 2* http://jqueryui.com 3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js 4* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ 5 6(function ($, undefined) { 7 8 var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11 // prevent duplicate loading 12 // this is only a problem because we proxy existing functions 13 // and we don't want to double proxy them 14 $.ui = $.ui || {}; 15 if ($.ui.version) { 16 return; 17 } 18 19 $.extend($.ui, { 20 version: "1.9.2", 21 22 keyCode: { 23 BACKSPACE: 8, 24 COMMA: 188, 25 DELETE: 46, 26 DOWN: 40, 27 END: 35, 28 ENTER: 13, 29 ESCAPE: 27, 30 HOME: 36, 31 LEFT: 37, 32 NUMPAD_ADD: 107, 33 NUMPAD_DECIMAL: 110, 34 NUMPAD_DIVIDE: 111, 35 NUMPAD_ENTER: 108, 36 NUMPAD_MULTIPLY: 106, 37 NUMPAD_SUBTRACT: 109, 38 PAGE_DOWN: 34, 39 PAGE_UP: 33, 40 PERIOD: 190, 41 RIGHT: 39, 42 SPACE: 32, 43 TAB: 9, 44 UP: 38 45 } 46 }); 47 48 // plugins 49 $.fn.extend({ 50 _focus: $.fn.focus, 51 focus: function (delay, fn) { 52 return typeof delay === "number" ? 53 this.each(function () { 54 var elem = this; 55 setTimeout(function () { 56 $(elem).focus(); 57 if (fn) { 58 fn.call(elem); 59 } 60 }, delay); 61 }) : 62 this._focus.apply(this, arguments); 63 }, 64 65 scrollParent: function () { 66 var scrollParent; 67 if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { 68 scrollParent = this.parents().filter(function () { 69 return (/(relative|absolute|fixed)/).test($.css(this, 'position')) && (/(auto|scroll)/).test($.css(this, 'overflow') + $.css(this, 'overflow-y') + $.css(this, 'overflow-x')); 70 }).eq(0); 71 } else { 72 scrollParent = this.parents().filter(function () { 73 return (/(auto|scroll)/).test($.css(this, 'overflow') + $.css(this, 'overflow-y') + $.css(this, 'overflow-x')); 74 }).eq(0); 75 } 76 77 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; 78 }, 79 80 zIndex: function (zIndex) { 81 if (zIndex !== undefined) { 82 return this.css("zIndex", zIndex); 83 } 84 85 if (this.length) { 86 var elem = $(this[0]), position, value; 87 while (elem.length && elem[0] !== document) { 88 // Ignore z-index if position is set to a value where z-index is ignored by the browser 89 // This makes behavior of this function consistent across browsers 90 // WebKit always returns auto if the element is positioned 91 position = elem.css("position"); 92 if (position === "absolute" || position === "relative" || position === "fixed") { 93 // IE returns 0 when zIndex is not specified 94 // other browsers return a string 95 // we ignore the case of nested elements with an explicit value of 0 96 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 97 value = parseInt(elem.css("zIndex"), 10); 98 if (!isNaN(value) && value !== 0) { 99 return value; 100 } 101 } 102 elem = elem.parent(); 103 } 104 } 105 106 return 0; 107 }, 108 109 uniqueId: function () { 110 return this.each(function () { 111 if (!this.id) { 112 this.id = "ui-id-" + (++uuid); 113 } 114 }); 115 }, 116 117 removeUniqueId: function () { 118 return this.each(function () {
vendor: 11,295 bytes, lines 119-431
119 if (runiqueId.test(this.id)) { 120 $(this).removeAttr("id"); 121 } 122 }); 123 } 124 }); 125 126 // selectors 127 function focusable(element, isTabIndexNotNaN) { 128 var map, mapName, img, 129 nodeName = element.nodeName.toLowerCase(); 130 if ("area" === nodeName) { 131 map = element.parentNode; 132 mapName = map.name; 133 if (!element.href || !mapName || map.nodeName.toLowerCase() !== "map") { 134 return false; 135 } 136 img = $("img[usemap=#" + mapName + "]")[0]; 137 return !!img && visible(img); 138 } 139 return (/input|select|textarea|button|object/.test(nodeName) ? 140 !element.disabled : 141 "a" === nodeName ? 142 element.href || isTabIndexNotNaN : 143 isTabIndexNotNaN) && 144 // the element and all of its ancestors must be visible 145 visible(element); 146 } 147 148 function visible(element) { 149 return $.expr.filters.visible(element) && 150 !$(element).parents().andSelf().filter(function () { 151 return $.css(this, "visibility") === "hidden"; 152 }).length; 153 } 154 155 $.extend($.expr[":"], { 156 data: $.expr.createPseudo ? 157 $.expr.createPseudo(function (dataName) { 158 return function (elem) { 159 return !!$.data(elem, dataName); 160 }; 161 }) : 162 // support: jQuery <1.8 163 function (elem, i, match) { 164 return !!$.data(elem, match[3]); 165 }, 166 167 focusable: function (element) { 168 return focusable(element, !isNaN($.attr(element, "tabindex"))); 169 }, 170 171 tabbable: function (element) { 172 var tabIndex = $.attr(element, "tabindex"), 173 isTabIndexNaN = isNaN(tabIndex); 174 return (isTabIndexNaN || tabIndex >= 0) && focusable(element, !isTabIndexNaN); 175 } 176 }); 177 178 // support 179 $(function () { 180 var body = document.body, 181 div = body.appendChild(div = document.createElement("div")); 182 183 // access offsetHeight before setting the style to prevent a layout bug 184 // in IE 9 which causes the element to continue to take up space even 185 // after it is removed from the DOM (#8026) 186 div.offsetHeight; 187 188 $.extend(div.style, { 189 minHeight: "100px", 190 height: "auto", 191 padding: 0, 192 borderWidth: 0 193 }); 194 195 $.support.minHeight = div.offsetHeight === 100; 196 $.support.selectstart = "onselectstart" in div; 197 198 // set display to none to avoid a layout bug in IE 199 // http://dev.jquery.com/ticket/4014 200 body.removeChild(div).style.display = "none"; 201 }); 202 203 // support: jQuery <1.8 204 if (!$("<a>").outerWidth(1).jquery) { 205 $.each(["Width", "Height"], function (i, name) { 206 var side = name === "Width" ? ["Left", "Right"] : ["Top", "Bottom"], 207 type = name.toLowerCase(), 208 orig = { 209 innerWidth: $.fn.innerWidth, 210 innerHeight: $.fn.innerHeight, 211 outerWidth: $.fn.outerWidth, 212 outerHeight: $.fn.outerHeight 213 }; 214 215 function reduce(elem, size, border, margin) { 216 $.each(side, function () { 217 size -= parseFloat($.css(elem, "padding" + this)) || 0; 218 if (border) { 219 size -= parseFloat($.css(elem, "border" + this + "Width")) || 0; 220 } 221 if (margin) { 222 size -= parseFloat($.css(elem, "margin" + this)) || 0; 223 } 224 }); 225 return size; 226 } 227 228 $.fn["inner" + name] = function (size) { 229 if (size === undefined) { 230 return orig["inner" + name].call(this); 231 } 232 233 return this.each(function () { 234 $(this).css(type, reduce(this, size) + "px"); 235 }); 236 }; 237 238 $.fn["outer" + name] = function (size, margin) { 239 if (typeof size !== "number") { 240 return orig["outer" + name].call(this, size); 241 } 242 243 return this.each(function () { 244 $(this).css(type, reduce(this, size, true, margin) + "px"); 245 }); 246 }; 247 }); 248 } 249 250 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 251 if ($("<a>").data("a-b", "a").removeData("a-b").data("a-b")) { 252 $.fn.removeData = (function (removeData) { 253 return function (key) { 254 if (arguments.length) { 255 return removeData.call(this, $.camelCase(key)); 256 } else { 257 return removeData.call(this); 258 } 259 }; 260 })($.fn.removeData); 261 } 262 263 264 265 266 267 // deprecated 268 269 (function () { 270 var uaMatch = /msie ([\w.]+)/.exec(navigator.userAgent.toLowerCase()) || []; 271 $.ui.ie = uaMatch.length ? true : false; 272 $.ui.ie6 = parseFloat(uaMatch[1], 10) === 6; 273 })(); 274 275 $.fn.extend({ 276 disableSelection: function () { 277 return this.bind(($.support.selectstart ? "selectstart" : "mousedown") + 278 ".ui-disableSelection", function (event) { 279 event.preventDefault(); 280 }); 281 }, 282 283 enableSelection: function () { 284 return this.unbind(".ui-disableSelection"); 285 } 286 }); 287 288 $.extend($.ui, { 289 // $.ui.plugin is deprecated. Use the proxy pattern instead. 290 plugin: { 291 add: function (module, option, set) { 292 var i, 293 proto = $.ui[module].prototype; 294 for (i in set) { 295 proto.plugins[i] = proto.plugins[i] || []; 296 proto.plugins[i].push([option, set[i]]); 297 } 298 }, 299 call: function (instance, name, args) { 300 var i, 301 set = instance.plugins[name]; 302 if (!set || !instance.element[0].parentNode || instance.element[0].parentNode.nodeType === 11) { 303 return; 304 } 305 306 for (i = 0; i < set.length; i++) { 307 if (instance.options[set[i][0]]) { 308 set[i][1].apply(instance.element, args); 309 } 310 } 311 } 312 }, 313 314 contains: $.contains, 315 316 // only used by resizable 317 hasScroll: function (el, a) { 318 319 //If overflow is hidden, the element might have extra content, but the user wants to hide it 320 if ($(el).css("overflow") === "hidden") { 321 return false; 322 } 323 324 var scroll = (a && a === "left") ? "scrollLeft" : "scrollTop", 325 has = false; 326 327 if (el[scroll] > 0) { 328 return true; 329 } 330 331 // TODO: determine which cases actually cause this to happen 332 // if the element doesn't have the scroll set, see if it's possible to 333 // set the scroll 334 el[scroll] = 1; 335 has = (el[scroll] > 0); 336 el[scroll] = 0; 337 return has; 338 }, 339 340 // these are odd functions, fix the API or move into individual plugins 341 isOverAxis: function (x, reference, size) { 342 //Determines when x coordinate is over "b" element axis 343 return (x > reference) && (x < (reference + size)); 344 }, 345 isOver: function (y, x, top, left, height, width) { 346 //Determines when x, y coordinates is over "b" element 347 return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width); 348 } 349 }); 350 351})(jQuery); 352 353(function ($, undefined) { 354 355 var uuid = 0, 356 slice = Array.prototype.slice, 357 _cleanData = $.cleanData; 358 $.cleanData = function (elems) { 359 for (var i = 0, elem; (elem = elems[i]) != null; i++) { 360 try { 361 $(elem).triggerHandler("remove"); 362 // http://bugs.jquery.com/ticket/8235 363 } catch (e) { } 364 } 365 _cleanData(elems); 366 }; 367 368 $.widget = function (name, base, prototype) { 369 var fullName, existingConstructor, constructor, basePrototype, 370 namespace = name.split(".")[0]; 371 372 name = name.split(".")[1]; 373 fullName = namespace + "-" + name; 374 375 if (!prototype) { 376 prototype = base; 377 base = $.Widget; 378 } 379 380 // create selector for plugin 381 $.expr[":"][fullName.toLowerCase()] = function (elem) { 382 return !!$.data(elem, fullName); 383 }; 384 385 $[namespace] = $[namespace] || {}; 386 existingConstructor = $[namespace][name]; 387 constructor = $[namespace][name] = function (options, element) { 388 // allow instantiation without "new" keyword 389 if (!this._createWidget) { 390 return new constructor(options, element); 391 } 392 393 // allow instantiation without initializing for simple inheritance 394 // must use "new" keyword (the code above always passes args) 395 if (arguments.length) { 396 this._createWidget(options, element); 397 } 398 }; 399 // extend with the existing constructor to carry over any static properties 400 $.extend(constructor, existingConstructor, { 401 version: prototype.version, 402 // copy the object used to create the prototype in case we need to 403 // redefine the widget later 404 _proto: $.extend({}, prototype), 405 // track widgets that inherit from this widget in case this widget is 406 // redefined after a widget inherits from it 407 _childConstructors: [] 408 }); 409 410 basePrototype = new base(); 411 // we need to make the options hash a property directly on the new instance 412 // otherwise we'll modify the options hash on the prototype that we're 413 // inheriting from 414 basePrototype.options = $.widget.extend({}, basePrototype.options); 415 $.each(prototype, function (prop, value) { 416 if ($.isFunction(value)) { 417 prototype[prop] = (function () { 418 var _super = function () { 419 return base.prototype[prop].apply(this, arguments); 420 }, 421 _superApply = function (args) { 422 return base.prototype[prop].apply(this, args); 423 }; 424 return function () { 425 var __super = this._super, 426 __superApply = this._superApply, 427 returnValue; 428 429 this._super = _super; 430 this._superApply = _superApply; 431
vendor: 17,069 bytes, lines 432-861
432 returnValue = value.apply(this, arguments); 433 434 this._super = __super; 435 this._superApply = __superApply; 436 437 return returnValue; 438 }; 439 })(); 440 } 441 }); 442 constructor.prototype = $.widget.extend(basePrototype, { 443 // TODO: remove support for widgetEventPrefix 444 // always use the name + a colon as the prefix, e.g., draggable:start 445 // don't prefix for widgets that aren't DOM-based 446 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 447 }, prototype, { 448 constructor: constructor, 449 namespace: namespace, 450 widgetName: name, 451 // TODO remove widgetBaseClass, see #8155 452 widgetBaseClass: fullName, 453 widgetFullName: fullName 454 }); 455 456 // If this widget is being redefined then we need to find all widgets that 457 // are inheriting from it and redefine all of them so that they inherit from 458 // the new version of this widget. We're essentially trying to replace one 459 // level in the prototype chain. 460 if (existingConstructor) { 461 $.each(existingConstructor._childConstructors, function (i, child) { 462 var childPrototype = child.prototype; 463 464 // redefine the child widget using the same prototype that was 465 // originally used, but inherit from the new version of the base 466 $.widget(childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto); 467 }); 468 // remove the list of existing child constructors from the old constructor 469 // so the old child constructors can be garbage collected 470 delete existingConstructor._childConstructors; 471 } else { 472 base._childConstructors.push(constructor); 473 } 474 475 $.widget.bridge(name, constructor); 476 }; 477 478 $.widget.extend = function (target) { 479 var input = slice.call(arguments, 1), 480 inputIndex = 0, 481 inputLength = input.length, 482 key, 483 value; 484 for (; inputIndex < inputLength; inputIndex++) { 485 for (key in input[inputIndex]) { 486 value = input[inputIndex][key]; 487 if (input[inputIndex].hasOwnProperty(key) && value !== undefined) { 488 // Clone objects 489 if ($.isPlainObject(value)) { 490 target[key] = $.isPlainObject(target[key]) ? 491 $.widget.extend({}, target[key], value) : 492 // Don't extend strings, arrays, etc. with objects 493 $.widget.extend({}, value); 494 // Copy everything else by reference 495 } else { 496 target[key] = value; 497 } 498 } 499 } 500 } 501 return target; 502 }; 503 504 $.widget.bridge = function (name, object) { 505 var fullName = object.prototype.widgetFullName || name; 506 $.fn[name] = function (options) { 507 var isMethodCall = typeof options === "string", 508 args = slice.call(arguments, 1), 509 returnValue = this; 510 511 // allow multiple hashes to be passed on init 512 options = !isMethodCall && args.length ? 513 $.widget.extend.apply(null, [options].concat(args)) : 514 options; 515 516 if (isMethodCall) { 517 this.each(function () { 518 var methodValue, 519 instance = $.data(this, fullName); 520 if (!instance) { 521 return $.error("cannot call methods on " + name + " prior to initialization; " + 522 "attempted to call method '" + options + "'"); 523 } 524 if (!$.isFunction(instance[options]) || options.charAt(0) === "_") { 525 return $.error("no such method '" + options + "' for " + name + " widget instance"); 526 } 527 methodValue = instance[options].apply(instance, args); 528 if (methodValue !== instance && methodValue !== undefined) { 529 returnValue = methodValue && methodValue.jquery ? 530 returnValue.pushStack(methodValue.get()) : 531 methodValue; 532 return false; 533 } 534 }); 535 } else { 536 this.each(function () { 537 var instance = $.data(this, fullName); 538 if (instance) { 539 instance.option(options || {})._init(); 540 } else { 541 $.data(this, fullName, new object(options, this)); 542 } 543 }); 544 } 545 546 return returnValue; 547 }; 548 }; 549 550 $.Widget = function ( /* options, element */) { }; 551 $.Widget._childConstructors = []; 552 553 $.Widget.prototype = { 554 widgetName: "widget", 555 widgetEventPrefix: "", 556 defaultElement: "<div>", 557 options: { 558 disabled: false, 559 560 // callbacks 561 create: null 562 }, 563 _createWidget: function (options, element) { 564 element = $(element || this.defaultElement || this)[0]; 565 this.element = $(element); 566 this.uuid = uuid++; 567 this.eventNamespace = "." + this.widgetName + this.uuid; 568 this.options = $.widget.extend({}, 569 this.options, 570 this._getCreateOptions(), 571 options); 572 573 this.bindings = $(); 574 this.hoverable = $(); 575 this.focusable = $(); 576 577 if (element !== this) { 578 // 1.9 BC for #7810 579 // TODO remove dual storage 580 $.data(element, this.widgetName, this); 581 $.data(element, this.widgetFullName, this); 582 this._on(true, this.element, { 583 remove: function (event) { 584 if (event.target === element) { 585 this.destroy(); 586 } 587 } 588 }); 589 this.document = $(element.style ? 590 // element within the document 591 element.ownerDocument : 592 // element is window or document 593 element.document || element); 594 this.window = $(this.document[0].defaultView || this.document[0].parentWindow); 595 } 596 597 this._create(); 598 this._trigger("create", null, this._getCreateEventData()); 599 this._init(); 600 }, 601 _getCreateOptions: $.noop, 602 _getCreateEventData: $.noop, 603 _create: $.noop, 604 _init: $.noop, 605 606 destroy: function () { 607 this._destroy(); 608 // we can probably remove the unbind calls in 2.0 609 // all event bindings should go through this._on() 610 this.element 611 .unbind(this.eventNamespace) 612 // 1.9 BC for #7810 613 // TODO remove dual storage 614 .removeData(this.widgetName) 615 .removeData(this.widgetFullName) 616 // support: jquery <1.6.3 617 // http://bugs.jquery.com/ticket/9413 618 .removeData($.camelCase(this.widgetFullName)); 619 this.widget() 620 .unbind(this.eventNamespace) 621 .removeAttr("aria-disabled") 622 .removeClass( 623 this.widgetFullName + "-disabled " + 624 "ui-state-disabled"); 625 626 // clean up events and states 627 this.bindings.unbind(this.eventNamespace); 628 this.hoverable.removeClass("ui-state-hover"); 629 this.focusable.removeClass("ui-state-focus"); 630 }, 631 _destroy: $.noop, 632 633 widget: function () { 634 return this.element; 635 }, 636 637 option: function (key, value) { 638 var options = key, 639 parts, 640 curOption, 641 i; 642 643 if (arguments.length === 0) { 644 // don't return a reference to the internal hash 645 return $.widget.extend({}, this.options); 646 } 647 648 if (typeof key === "string") { 649 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 650 options = {}; 651 parts = key.split("."); 652 key = parts.shift(); 653 if (parts.length) { 654 curOption = options[key] = $.widget.extend({}, this.options[key]); 655 for (i = 0; i < parts.length - 1; i++) { 656 curOption[parts[i]] = curOption[parts[i]] || {}; 657 curOption = curOption[parts[i]]; 658 } 659 key = parts.pop(); 660 if (value === undefined) { 661 return curOption[key] === undefined ? null : curOption[key]; 662 } 663 curOption[key] = value; 664 } else { 665 if (value === undefined) { 666 return this.options[key] === undefined ? null : this.options[key]; 667 } 668 options[key] = value; 669 } 670 } 671 672 this._setOptions(options); 673 674 return this; 675 }, 676 _setOptions: function (options) { 677 var key; 678 679 for (key in options) { 680 this._setOption(key, options[key]); 681 } 682 683 return this; 684 }, 685 _setOption: function (key, value) { 686 this.options[key] = value; 687 688 if (key === "disabled") { 689 this.widget() 690 .toggleClass(this.widgetFullName + "-disabled ui-state-disabled", !!value) 691 .attr("aria-disabled", value); 692 this.hoverable.removeClass("ui-state-hover"); 693 this.focusable.removeClass("ui-state-focus"); 694 } 695 696 return this; 697 }, 698 699 enable: function () { 700 return this._setOption("disabled", false); 701 }, 702 disable: function () { 703 return this._setOption("disabled", true); 704 }, 705 706 _on: function (suppressDisabledCheck, element, handlers) { 707 var delegateElement, 708 instance = this; 709 710 // no suppressDisabledCheck flag, shuffle arguments 711 if (typeof suppressDisabledCheck !== "boolean") { 712 handlers = element; 713 element = suppressDisabledCheck; 714 suppressDisabledCheck = false; 715 } 716 717 // no element argument, shuffle and use this.element 718 if (!handlers) { 719 handlers = element; 720 element = this.element; 721 delegateElement = this.widget(); 722 } else { 723 // accept selectors, DOM elements 724 element = delegateElement = $(element); 725 this.bindings = this.bindings.add(element); 726 } 727 728 $.each(handlers, function (event, handler) { 729 function handlerProxy() { 730 // allow widgets to customize the disabled handling 731 // - disabled as an array instead of boolean 732 // - disabled class as method for disabling individual parts 733 if (!suppressDisabledCheck && 734 (instance.options.disabled === true || 735 $(this).hasClass("ui-state-disabled"))) { 736 return; 737 } 738 return (typeof handler === "string" ? instance[handler] : handler) 739 .apply(instance, arguments); 740 } 741 742 // copy the guid so direct unbinding works 743 if (typeof handler !== "string") { 744 handlerProxy.guid = handler.guid = 745 handler.guid || handlerProxy.guid || $.guid++; 746 } 747 748 var match = event.match(/^(\w+)\s*(.*)$/), 749 eventName = match[1] + instance.eventNamespace, 750 selector = match[2]; 751 if (selector) { 752 delegateElement.delegate(selector, eventName, handlerProxy); 753 } else { 754 element.bind(eventName, handlerProxy); 755 } 756 }); 757 }, 758 759 _off: function (element, eventName) { 760 eventName = (eventName || "").split(" ").join(this.eventNamespace + " ") + this.eventNamespace; 761 element.unbind(eventName).undelegate(eventName); 762 }, 763 764 _delay: function (handler, delay) { 765 function handlerProxy() { 766 return (typeof handler === "string" ? instance[handler] : handler) 767 .apply(instance, arguments); 768 } 769 var instance = this; 770 return setTimeout(handlerProxy, delay || 0); 771 }, 772 773 _hoverable: function (element) { 774 this.hoverable = this.hoverable.add(element); 775 this._on(element, { 776 mouseenter: function (event) { 777 $(event.currentTarget).addClass("ui-state-hover"); 778 }, 779 mouseleave: function (event) { 780 $(event.currentTarget).removeClass("ui-state-hover"); 781 } 782 }); 783 }, 784 785 _focusable: function (element) { 786 this.focusable = this.focusable.add(element); 787 this._on(element, { 788 focusin: function (event) { 789 $(event.currentTarget).addClass("ui-state-focus"); 790 }, 791 focusout: function (event) { 792 $(event.currentTarget).removeClass("ui-state-focus"); 793 } 794 }); 795 }, 796 797 _trigger: function (type, event, data) { 798 var prop, orig, 799 callback = this.options[type]; 800 801 data = data || {}; 802 event = $.Event(event); 803 event.type = (type === this.widgetEventPrefix ? 804 type : 805 this.widgetEventPrefix + type).toLowerCase(); 806 // the original event may come from any element 807 // so we need to reset the target on the new event 808 event.target = this.element[0]; 809 810 // copy original event properties over to the new event 811 orig = event.originalEvent; 812 if (orig) { 813 for (prop in orig) { 814 if (!(prop in event)) { 815 event[prop] = orig[prop]; 816 } 817 } 818 } 819 820 this.element.trigger(event, data); 821 return !($.isFunction(callback) && 822 callback.apply(this.element[0], [event].concat(data)) === false || 823 event.isDefaultPrevented()); 824 } 825 }; 826 827 $.each({ show: "fadeIn", hide: "fadeOut" }, function (method, defaultEffect) { 828 $.Widget.prototype["_" + method] = function (element, options, callback) { 829 if (typeof options === "string") { 830 options = { effect: options }; 831 } 832 var hasOptions, 833 effectName = !options ? 834 method : 835 options === true || typeof options === "number" ? 836 defaultEffect : 837 options.effect || defaultEffect; 838 options = options || {}; 839 if (typeof options === "number") { 840 options = { duration: options }; 841 } 842 hasOptions = !$.isEmptyObject(options); 843 options.complete = callback; 844 if (options.delay) { 845 element.delay(options.delay); 846 } 847 if (hasOptions && $.effects && ($.effects.effect[effectName] || $.uiBackCompat !== false && $.effects[effectName])) { 848 element[method](options); 849 } else if (effectName !== method && element[effectName]) { 850 element[effectName](options.duration, options.easing, callback); 851 } else { 852 element.queue(function (next) { 853 $(this)[method](); 854 if (callback) { 855 callback.call(element[0]); 856 } 857 next(); 858 }); 859 } 860 }; 861 });
vendor: 10,603 bytes, lines 862-1154
862 863 // DEPRECATED 864 if ($.uiBackCompat !== false) { 865 $.Widget.prototype._getCreateOptions = function () { 866 return $.metadata && $.metadata.get(this.element[0])[this.widgetName]; 867 }; 868 } 869 870})(jQuery); 871 872(function ($, undefined) { 873 874 var mouseHandled = false; 875 $(document).mouseup(function (e) { 876 mouseHandled = false; 877 }); 878 879 $.widget("ui.mouse", { 880 version: "1.9.2", 881 options: { 882 cancel: 'input,textarea,button,select,option', 883 distance: 1, 884 delay: 0 885 }, 886 _mouseInit: function () { 887 var that = this; 888 889 this.element 890 .bind('mousedown.' + this.widgetName, function (event) { 891 return that._mouseDown(event); 892 }) 893 .bind('click.' + this.widgetName, function (event) { 894 if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) { 895 $.removeData(event.target, that.widgetName + '.preventClickEvent'); 896 event.stopImmediatePropagation(); 897 return false; 898 } 899 }); 900 901 this.started = false; 902 }, 903 904 // TODO: make sure destroying one instance of mouse doesn't mess with 905 // other instances of mouse 906 _mouseDestroy: function () { 907 this.element.unbind('.' + this.widgetName); 908 if (this._mouseMoveDelegate) { 909 $(document) 910 .unbind('mousemove.' + this.widgetName, this._mouseMoveDelegate) 911 .unbind('mouseup.' + this.widgetName, this._mouseUpDelegate); 912 } 913 }, 914 915 _mouseDown: function (event) { 916 // don't let more than one widget handle mouseStart 917 if (mouseHandled) { return; } 918 919 // we may have missed mouseup (out of window) 920 (this._mouseStarted && this._mouseUp(event)); 921 922 this._mouseDownEvent = event; 923 924 var that = this, 925 btnIsLeft = (event.which === 1), 926 // event.target.nodeName works around a bug in IE 8 with 927 // disabled inputs (#7620) 928 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 929 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 930 return true; 931 } 932 933 this.mouseDelayMet = !this.options.delay; 934 if (!this.mouseDelayMet) { 935 this._mouseDelayTimer = setTimeout(function () { 936 that.mouseDelayMet = true; 937 }, this.options.delay); 938 } 939 940 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 941 this._mouseStarted = (this._mouseStart(event) !== false); 942 if (!this._mouseStarted) { 943 event.preventDefault(); 944 return true; 945 } 946 } 947 948 // Click event may never have fired (Gecko & Opera) 949 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) { 950 $.removeData(event.target, this.widgetName + '.preventClickEvent'); 951 } 952 953 // these delegates are required to keep context 954 this._mouseMoveDelegate = function (event) { 955 return that._mouseMove(event); 956 }; 957 this._mouseUpDelegate = function (event) { 958 return that._mouseUp(event); 959 }; 960 $(document) 961 .bind('mousemove.' + this.widgetName, this._mouseMoveDelegate) 962 .bind('mouseup.' + this.widgetName, this._mouseUpDelegate); 963 964 event.preventDefault(); 965 966 mouseHandled = true; 967 return true; 968 }, 969 970 _mouseMove: function (event) { 971 // IE mouseup check - mouseup happened when mouse was out of window 972 if ($.ui.ie && !(document.documentMode >= 9) && !event.button) { 973 return this._mouseUp(event); 974 } 975 976 if (this._mouseStarted) { 977 this._mouseDrag(event); 978 return event.preventDefault(); 979 } 980 981 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 982 this._mouseStarted = 983 (this._mouseStart(this._mouseDownEvent, event) !== false); 984 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 985 } 986 987 return !this._mouseStarted; 988 }, 989 990 _mouseUp: function (event) { 991 $(document) 992 .unbind('mousemove.' + this.widgetName, this._mouseMoveDelegate) 993 .unbind('mouseup.' + this.widgetName, this._mouseUpDelegate); 994 995 if (this._mouseStarted) { 996 this._mouseStarted = false; 997 998 if (event.target === this._mouseDownEvent.target) { 999 $.data(event.target, this.widgetName + '.preventClickEvent', true); 1000 } 1001 1002 this._mouseStop(event); 1003 } 1004 1005 return false; 1006 }, 1007 1008 _mouseDistanceMet: function (event) { 1009 return (Math.max( 1010 Math.abs(this._mouseDownEvent.pageX - event.pageX), 1011 Math.abs(this._mouseDownEvent.pageY - event.pageY) 1012 ) >= this.options.distance 1013 ); 1014 }, 1015 1016 _mouseDelayMet: function (event) { 1017 return this.mouseDelayMet; 1018 }, 1019 1020 // These are placeholder methods, to be overriden by extending plugin 1021 _mouseStart: function (event) { }, 1022 _mouseDrag: function (event) { }, 1023 _mouseStop: function (event) { }, 1024 _mouseCapture: function (event) { return true; } 1025 }); 1026 1027})(jQuery); 1028 1029(function ($, undefined) { 1030 1031 $.widget("ui.draggable", $.ui.mouse, { 1032 version: "1.9.2", 1033 widgetEventPrefix: "drag", 1034 options: { 1035 addClasses: true, 1036 appendTo: "parent", 1037 axis: false, 1038 connectToSortable: false, 1039 containment: false, 1040 cursor: "auto", 1041 cursorAt: false, 1042 grid: false, 1043 handle: false, 1044 helper: "original", 1045 iframeFix: false, 1046 opacity: false, 1047 refreshPositions: false, 1048 revert: false, 1049 revertDuration: 500, 1050 scope: "default", 1051 scroll: true, 1052 scrollSensitivity: 20, 1053 scrollSpeed: 20, 1054 snap: false, 1055 snapMode: "both", 1056 snapTolerance: 20, 1057 stack: false, 1058 zIndex: false 1059 }, 1060 _create: function () { 1061 1062 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) 1063 this.element[0].style.position = 'relative'; 1064 1065 (this.options.addClasses && this.element.addClass("ui-draggable")); 1066 (this.options.disabled && this.element.addClass("ui-draggable-disabled")); 1067 1068 this._mouseInit(); 1069 1070 }, 1071 1072 _destroy: function () { 1073 this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"); 1074 this._mouseDestroy(); 1075 }, 1076 1077 _mouseCapture: function (event) { 1078 1079 var o = this.options; 1080 1081 // among others, prevent a drag on a resizable-handle 1082 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) 1083 return false; 1084 1085 //Quit if we're not on a valid handle 1086 this.handle = this._getHandle(event); 1087 if (!this.handle) 1088 return false; 1089 1090 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function () { 1091 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>') 1092 .css({ 1093 width: this.offsetWidth + "px", height: this.offsetHeight + "px", 1094 position: "absolute", opacity: "0.001", zIndex: 1000 1095 }) 1096 .css($(this).offset()) 1097 .appendTo("body"); 1098 }); 1099 1100 return true; 1101 1102 }, 1103 1104 _mouseStart: function (event) { 1105 1106 var o = this.options; 1107 1108 //Create and append the visible helper 1109 this.helper = this._createHelper(event); 1110 1111 this.helper.addClass("ui-draggable-dragging"); 1112 1113 //Cache the helper size 1114 this._cacheHelperProportions(); 1115 1116 //If ddmanager is used for droppables, set the global draggable 1117 if ($.ui.ddmanager) 1118 $.ui.ddmanager.current = this; 1119 1120 /* 1121 * - Position generation - 1122 * This block generates everything position related - it's the core of draggables. 1123 */ 1124 1125 //Cache the margins of the original element 1126 this._cacheMargins(); 1127 1128 //Store the helper's css position 1129 this.cssPosition = this.helper.css("position"); 1130 this.scrollParent = this.helper.scrollParent(); 1131 1132 //The element's absolute position on the page minus margins 1133 this.offset = this.positionAbs = this.element.offset(); 1134 this.offset = { 1135 top: this.offset.top - this.margins.top, 1136 left: this.offset.left - this.margins.left 1137 }; 1138 1139 $.extend(this.offset, { 1140 click: { //Where the click happened, relative to the element 1141 left: event.pageX - this.offset.left, 1142 top: event.pageY - this.offset.top 1143 }, 1144 parent: this._getParentOffset(), 1145 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1146 }); 1147 1148 //Generate the original position 1149 this.originalPosition = this.position = this._generatePosition(event); 1150 this.originalPageX = event.pageX; 1151 this.originalPageY = event.pageY; 1152 1153 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 1154 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1155 1156 //Set a containment if given in the options 1157 if (o.containment) 1158 this._setContainment(); 1159 1160 //Trigger event + callbacks 1161 if (this._trigger("start", event) === false) { 1162 this._clear(); 1163 return false; 1164 } 1165 1166 //Recache the helper size 1167 this._cacheHelperProportions(); 1168 1169 //Prepare the droppable offsets 1170 if ($.ui.ddmanager && !o.dropBehaviour) 1171 $.ui.ddmanager.prepareOffsets(this, event); 1172 1173 1174 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1175 1176 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1177 if ($.ui.ddmanager) $.ui.ddmanager.dragStart(this, event); 1178 1179 return true; 1180 }, 1181 1182 _mouseDrag: function (event, noPropagation) { 1183 1184 //Compute the helpers position 1185 this.position = this._generatePosition(event); 1186 this.positionAbs = this._convertPositionTo("absolute"); 1187 1188 //Call plugins and callbacks and use the resulting position if something is returned 1189 if (!noPropagation) { 1190 var ui = this._uiHash(); 1191 if (this._trigger('drag', event, ui) === false) { 1192 this._mouseUp({}); 1193 return false; 1194 } 1195 this.position = ui.position; 1196 } 1197 1198 if (!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left + 'px'; 1199 if (!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top + 'px'; 1200 if ($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 1201 1202 return false; 1203 }, 1204 1205 _mouseStop: function (event) { 1206 1207 //If we are using droppables, inform the manager about the drop 1208 var dropped = false; 1209 if ($.ui.ddmanager && !this.options.dropBehaviour) 1210 dropped = $.ui.ddmanager.drop(this, event); 1211 1212 //if a drop comes from outside (a sortable) 1213 if (this.dropped) { 1214 dropped = this.dropped; 1215 this.dropped = false; 1216 } 1217 1218 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1219 var element = this.element[0], elementInDom = false; 1220 while (element && (element = element.parentNode)) { 1221 if (element == document) { 1222 elementInDom = true; 1223 } 1224 } 1225 if (!elementInDom && this.options.helper === "original") 1226 return false; 1227 1228 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))) { 1229 var that = this; 1230 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function () { 1231 if (that._trigger("stop", event) !== false) { 1232 that._clear(); 1233 } 1234 }); 1235 } else { 1236 if (this._trigger("stop", event) !== false) { 1237 this._clear(); 1238 } 1239 } 1240 1241 return false; 1242 }, 1243 1244 _mouseUp: function (event) { 1245 //Remove frame helpers 1246 $("div.ui-draggable-iframeFix").each(function () { 1247 this.parentNode.removeChild(this); 1248 }); 1249 1250 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1251 if ($.ui.ddmanager) $.ui.ddmanager.dragStop(this, event); 1252 1253 return $.ui.mouse.prototype._mouseUp.call(this, event); 1254 }, 1255 1256 cancel: function () { 1257 1258 if (this.helper.is(".ui-draggable-dragging")) { 1259 this._mouseUp({}); 1260 } else { 1261 this._clear(); 1262 } 1263 1264 return this; 1265 1266 }, 1267 1268 _getHandle: function (event) { 1269 1270 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; 1271 $(this.options.handle, this.element) 1272 .find("*") 1273 .andSelf() 1274 .each(function () { 1275 if (this == event.target) handle = true; 1276 }); 1277 1278 return handle; 1279 1280 }, 1281 1282 _createHelper: function (event) { 1283 1284 var o = this.options; 1285 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); 1286 1287 if (!helper.parents('body').length) 1288 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); 1289 1290 if (helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) 1291 helper.css("position", "absolute"); 1292 1293 return helper; 1294 1295 }, 1296 1297 _adjustOffsetFromHelper: function (obj) { 1298 if (typeof obj == 'string') { 1299 obj = obj.split(' '); 1300 } 1301 if ($.isArray(obj)) { 1302 obj = { left: +obj[0], top: +obj[1] || 0 }; 1303 } 1304 if ('left' in obj) { 1305 this.offset.click.left = obj.left + this.margins.left; 1306 } 1307 if ('right' in obj) { 1308 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1309 } 1310 if ('top' in obj) { 1311 this.offset.click.top = obj.top + this.margins.top; 1312 } 1313 if ('bottom' in obj) { 1314 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1315 } 1316 }, 1317 1318 _getParentOffset: function () { 1319 1320 //Get the offsetParent and cache its position 1321 this.offsetParent = this.helper.offsetParent(); 1322 var po = this.offsetParent.offset(); 1323 1324 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1325 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1326 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1327 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1328 if (this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1329 po.left += this.scrollParent.scrollLeft(); 1330 po.top += this.scrollParent.scrollTop(); 1331 } 1332 1333 if ((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 1334 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 1335 po = { top: 0, left: 0 }; 1336 1337 return { 1338 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), 1339 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) 1340 }; 1341 1342 }, 1343 1344 _getRelativeOffset: function () { 1345 1346 if (this.cssPosition == "relative") { 1347 var p = this.element.position(); 1348 return { 1349 top: p.top - (parseInt(this.helper.css("top"), 10) || 0) + this.scrollParent.scrollTop(), 1350 left: p.left - (parseInt(this.helper.css("left"), 10) || 0) + this.scrollParent.scrollLeft() 1351 }; 1352 } else { 1353 return { top: 0, left: 0 }; 1354 } 1355 1356 }, 1357 1358 _cacheMargins: function () { 1359 this.margins = { 1360 left: (parseInt(this.element.css("marginLeft"), 10) || 0), 1361 top: (parseInt(this.element.css("marginTop"), 10) || 0), 1362 right: (parseInt(this.element.css("marginRight"), 10) || 0), 1363 bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) 1364 }; 1365 }, 1366 1367 _cacheHelperProportions: function () { 1368 this.helperProportions = { 1369 width: this.helper.outerWidth(), 1370 height: this.helper.outerHeight() 1371 }; 1372 }, 1373 1374 _setContainment: function () { 1375 1376 var o = this.options; 1377 if (o.containment == 'parent') o.containment = this.helper[0].parentNode; 1378 if (o.containment == 'document' || o.containment == 'window') this.containment = [ 1379 o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1380 o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1381 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 1382 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 1383 ]; 1384 1385 if (!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { 1386 var c = $(o.containment); 1387 var ce = c[0]; if (!ce) return; 1388 var co = c.offset(); 1389 var over = ($(ce).css("overflow") != 'hidden'); 1390 1391 this.containment = [ 1392 (parseInt($(ce).css("borderLeftWidth"), 10) || 0) + (parseInt($(ce).css("paddingLeft"), 10) || 0), 1393 (parseInt($(ce).css("borderTopWidth"), 10) || 0) + (parseInt($(ce).css("paddingTop"), 10) || 0), 1394 (over ? Math.max(ce.scrollWidth, ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"), 10) || 0) - (parseInt($(ce).css("paddingRight"), 10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right, 1395 (over ? Math.max(ce.scrollHeight, ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"), 10) || 0) - (parseInt($(ce).css("paddingBottom"), 10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom 1396 ]; 1397 this.relative_container = c; 1398 1399 } else if (o.containment.constructor == Array) {
1400 this.containment = o.containment; 1401 } 1402 1403 }, 1404 1405 _convertPositionTo: function (d, pos) { 1406 1407 if (!pos) pos = this.position; 1408 var mod = d == "absolute" ? 1 : -1; 1409 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 1410 1411 return { 1412 top: ( 1413 pos.top // The absolute mouse position 1414 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 1415 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 1416 - ((this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : (scrollIsRootNode ? 0 : scroll.scrollTop())) * mod) 1417 ), 1418 left: ( 1419 pos.left // The absolute mouse position 1420 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 1421 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 1422 - ((this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft()) * mod) 1423 ) 1424 }; 1425 1426 }, 1427 1428 _generatePosition: function (event) { 1429 1430 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 1431 var pageX = event.pageX; 1432 var pageY = event.pageY; 1433 1434 /* 1435 * - Position constraining - 1436 * Constrain the position to a mix of grid, containment. 1437 */ 1438 1439 if (this.originalPosition) { //If we are not dragging yet, we won't check for options 1440 var containment; 1441 if (this.containment) { 1442 if (this.relative_container) { 1443 var co = this.relative_container.offset(); 1444 containment = [this.containment[0] + co.left, 1445 this.containment[1] + co.top, 1446 this.containment[2] + co.left, 1447 this.containment[3] + co.top]; 1448 } 1449 else { 1450 containment = this.containment; 1451 } 1452 1453 if (event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; 1454 if (event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; 1455 if (event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; 1456 if (event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; 1457 } 1458 1459 if (o.grid) { 1460 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1461 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1462 pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; 1463 1464 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1465 pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; 1466 } 1467 1468 } 1469 1470 return { 1471 top: ( 1472 pageY // The absolute mouse position 1473 - this.offset.click.top // Click offset (relative to the element) 1474 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 1475 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 1476 + ((this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : (scrollIsRootNode ? 0 : scroll.scrollTop()))) 1477 ), 1478 left: ( 1479 pageX // The absolute mouse position 1480 - this.offset.click.left // Click offset (relative to the element) 1481 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 1482 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 1483 + ((this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft())) 1484 ) 1485 }; 1486 1487 }, 1488 1489 _clear: function () { 1490 this.helper.removeClass("ui-draggable-dragging"); 1491 if (this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); 1492 //if($.ui.ddmanager) $.ui.ddmanager.current = null; 1493 this.helper = null; 1494 this.cancelHelperRemoval = false; 1495 }, 1496 1497 // From now on bulk stuff - mainly helpers 1498 1499 _trigger: function (type, event, ui) { 1500 ui = ui || this._uiHash(); 1501 $.ui.plugin.call(this, type, [event, ui]); 1502 if (type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins 1503 return $.Widget.prototype._trigger.call(this, type, event, ui); 1504 }, 1505 1506 plugins: {}, 1507 1508 _uiHash: function (event) { 1509 return { 1510 helper: this.helper, 1511 position: this.position, 1512 originalPosition: this.originalPosition, 1513 offset: this.positionAbs 1514 }; 1515 } 1516 1517 });
1518 1519 $.ui.plugin.add("draggable", "connectToSortable", { 1520 start: function (event, ui) { 1521 1522 var inst = $(this).data("draggable"), o = inst.options, 1523 uiSortable = $.extend({}, ui, { item: inst.element }); 1524 inst.sortables = []; 1525 $(o.connectToSortable).each(function () { 1526 var sortable = $.data(this, 'sortable'); 1527 if (sortable && !sortable.options.disabled) { 1528 inst.sortables.push({ 1529 instance: sortable, 1530 shouldRevert: sortable.options.revert 1531 }); 1532 sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). 1533 sortable._trigger("activate", event, uiSortable); 1534 } 1535 }); 1536 1537 }, 1538 stop: function (event, ui) { 1539 1540 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 1541 var inst = $(this).data("draggable"), 1542 uiSortable = $.extend({}, ui, { item: inst.element }); 1543 1544 $.each(inst.sortables, function () { 1545 if (this.instance.isOver) { 1546 1547 this.instance.isOver = 0; 1548 1549 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 1550 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 1551 1552 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' 1553 if (this.shouldRevert) this.instance.options.revert = true; 1554 1555 //Trigger the stop of the sortable 1556 this.instance._mouseStop(event); 1557 1558 this.instance.options.helper = this.instance.options._helper; 1559 1560 //If the helper has been the original item, restore properties in the sortable 1561 if (inst.options.helper == 'original') 1562 this.instance.currentItem.css({ top: 'auto', left: 'auto' }); 1563 1564 } else { 1565 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 1566 this.instance._trigger("deactivate", event, uiSortable); 1567 } 1568 1569 }); 1570 1571 }, 1572 drag: function (event, ui) { 1573 1574 var inst = $(this).data("draggable"), that = this; 1575 1576 var checkPos = function (o) { 1577 var dyClick = this.offset.click.top, dxClick = this.offset.click.left; 1578 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; 1579 var itemHeight = o.height, itemWidth = o.width; 1580 var itemTop = o.top, itemLeft = o.left; 1581 1582 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); 1583 }; 1584 1585 $.each(inst.sortables, function (i) { 1586 1587 var innermostIntersecting = false; 1588 var thisSortable = this; 1589 //Copy over some variables to allow calling the sortable's native _intersectsWith 1590 this.instance.positionAbs = inst.positionAbs; 1591 this.instance.helperProportions = inst.helperProportions; 1592 this.instance.offset.click = inst.offset.click; 1593 1594 if (this.instance._intersectsWith(this.instance.containerCache)) { 1595 innermostIntersecting = true; 1596 $.each(inst.sortables, function () { 1597 this.instance.positionAbs = inst.positionAbs; 1598 this.instance.helperProportions = inst.helperProportions; 1599 this.instance.offset.click = inst.offset.click; 1600 if (this != thisSortable 1601 && this.instance._intersectsWith(this.instance.containerCache) 1602 && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0])) 1603 innermostIntersecting = false; 1604 return innermostIntersecting; 1605 }); 1606 } 1607 1608 1609 if (innermostIntersecting) { 1610 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 1611 if (!this.instance.isOver) { 1612 1613 this.instance.isOver = 1; 1614 //Now we fake the start of dragging for the sortable instance, 1615 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 1616 //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) 1617 this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); 1618 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 1619 this.instance.options.helper = function () { return ui.helper[0]; }; 1620 1621 event.target = this.instance.currentItem[0]; 1622 this.instance._mouseCapture(event, true); 1623 this.instance._mouseStart(event, true, true); 1624
1625 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 1626 this.instance.offset.click.top = inst.offset.click.top; 1627 this.instance.offset.click.left = inst.offset.click.left; 1628 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 1629 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 1630 1631 inst._trigger("toSortable", event); 1632 inst.dropped = this.instance.element; //draggable revert needs that 1633 //hack so receive/update callbacks work (mostly) 1634 inst.currentItem = inst.element; 1635 this.instance.fromOutside = inst; 1636 1637 } 1638 1639 //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 1640 if (this.instance.currentItem) this.instance._mouseDrag(event); 1641 1642 } else { 1643 1644 //If it doesn't intersect with the sortable, and it intersected before, 1645 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 1646 if (this.instance.isOver) { 1647 1648 this.instance.isOver = 0; 1649 this.instance.cancelHelperRemoval = true; 1650 1651 //Prevent reverting on this forced stop 1652 this.instance.options.revert = false; 1653 1654 // The out event needs to be triggered independently 1655 this.instance._trigger('out', event, this.instance._uiHash(this.instance)); 1656 1657 this.instance._mouseStop(event, true); 1658 this.instance.options.helper = this.instance.options._helper; 1659 1660 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 1661 this.instance.currentItem.remove(); 1662 if (this.instance.placeholder) this.instance.placeholder.remove(); 1663 1664 inst._trigger("fromSortable", event); 1665 inst.dropped = false; //draggable revert needs that 1666 } 1667 1668 }; 1669 1670 }); 1671 1672 } 1673 }); 1674 1675 $.ui.plugin.add("draggable", "cursor", { 1676 start: function (event, ui) { 1677 var t = $('body'), o = $(this).data('draggable').options; 1678 if (t.css("cursor")) o._cursor = t.css("cursor"); 1679 t.css("cursor", o.cursor); 1680 }, 1681 stop: function (event, ui) { 1682 var o = $(this).data('draggable').options; 1683 if (o._cursor) $('body').css("cursor", o._cursor); 1684 } 1685 }); 1686 1687 $.ui.plugin.add("draggable", "opacity", { 1688 start: function (event, ui) { 1689 var t = $(ui.helper), o = $(this).data('draggable').options; 1690 if (t.css("opacity")) o._opacity = t.css("opacity"); 1691 t.css('opacity', o.opacity); 1692 }, 1693 stop: function (event, ui) { 1694 var o = $(this).data('draggable').options; 1695 if (o._opacity) $(ui.helper).css('opacity', o._opacity); 1696 } 1697 }); 1698 1699 $.ui.plugin.add("draggable", "scroll", { 1700 start: function (event, ui) { 1701 var i = $(this).data("draggable"); 1702 if (i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); 1703 }, 1704 drag: function (event, ui) { 1705 1706 var i = $(this).data("draggable"), o = i.options, scrolled = false; 1707 1708 if (i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { 1709 1710 if (!o.axis || o.axis != 'x') { 1711 if ((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 1712 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 1713 else if (event.pageY - i.overflowOffset.top < o.scrollSensitivity) 1714 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 1715 } 1716 1717 if (!o.axis || o.axis != 'y') { 1718 if ((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 1719 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 1720 else if (event.pageX - i.overflowOffset.left < o.scrollSensitivity) 1721 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 1722 } 1723 1724 } else { 1725 1726 if (!o.axis || o.axis != 'x') { 1727 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) 1728 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 1729 else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 1730 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 1731 } 1732 1733 if (!o.axis || o.axis != 'y') { 1734 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 1735 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 1736 else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 1737 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 1738 } 1739 1740 } 1741 1742 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 1743 $.ui.ddmanager.prepareOffsets(i, event); 1744 1745 } 1746 });
1747 1748 $.ui.plugin.add("draggable", "snap", { 1749 start: function (event, ui) { 1750 1751 var i = $(this).data("draggable"), o = i.options; 1752 i.snapElements = []; 1753 1754 $(o.snap.constructor != String ? (o.snap.items || ':data(draggable)') : o.snap).each(function () { 1755 var $t = $(this); var $o = $t.offset(); 1756 if (this != i.element[0]) i.snapElements.push({ 1757 item: this, 1758 width: $t.outerWidth(), height: $t.outerHeight(), 1759 top: $o.top, left: $o.left 1760 }); 1761 }); 1762 1763 }, 1764 drag: function (event, ui) { 1765 1766 var inst = $(this).data("draggable"), o = inst.options; 1767 var d = o.snapTolerance; 1768 1769 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 1770 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 1771 1772 for (var i = inst.snapElements.length - 1; i >= 0; i--) { 1773 1774 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, 1775 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; 1776 1777 //Yes, I know, this is insane ;) 1778 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))) { 1779 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 }))); 1780 inst.snapElements[i].snapping = false; 1781 continue; 1782 } 1783 1784 if (o.snapMode != 'inner') { 1785 var ts = Math.abs(t - y2) <= d; 1786 var bs = Math.abs(b - y1) <= d; 1787 var ls = Math.abs(l - x2) <= d; 1788 var rs = Math.abs(r - x1) <= d; 1789 if (ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1790 if (bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 1791 if (ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 1792 if (rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 1793 } 1794 1795 var first = (ts || bs || ls || rs); 1796 1797 if (o.snapMode != 'outer') { 1798 var ts = Math.abs(t - y1) <= d; 1799 var bs = Math.abs(b - y2) <= d; 1800 var ls = Math.abs(l - x1) <= d; 1801 var rs = Math.abs(r - x2) <= d; 1802 if (ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 1803 if (bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1804 if (ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 1805 if (rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 1806 } 1807 1808 if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) 1809 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1810 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 1811 1812 }; 1813 1814 } 1815 }); 1816 1817 $.ui.plugin.add("draggable", "stack", { 1818 start: function (event, ui) { 1819 1820 var o = $(this).data("draggable").options; 1821 1822 var group = $.makeArray($(o.stack)).sort(function (a, b) { 1823 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0); 1824 }); 1825 if (!group.length) { return; } 1826 1827 var min = parseInt(group[0].style.zIndex) || 0; 1828 $(group).each(function (i) { 1829 this.style.zIndex = min + i; 1830 }); 1831 1832 this[0].style.zIndex = min + group.length; 1833 1834 } 1835 });
1836 1837 $.ui.plugin.add("draggable", "zIndex", { 1838 start: function (event, ui) { 1839 var t = $(ui.helper), o = $(this).data("draggable").options; 1840 if (t.css("zIndex")) o._zIndex = t.css("zIndex"); 1841 t.css('zIndex', o.zIndex); 1842 }, 1843 stop: function (event, ui) { 1844 var o = $(this).data("draggable").options; 1845 if (o._zIndex) $(ui.helper).css('zIndex', o._zIndex); 1846 } 1847 }); 1848 1849})(jQuery); 1850 1851(function ($, undefined) { 1852 1853 $.widget("ui.droppable", { 1854 version: "1.9.2", 1855 widgetEventPrefix: "drop", 1856 options: { 1857 accept: '*', 1858 activeClass: false, 1859 addClasses: true, 1860 greedy: false, 1861 hoverClass: false, 1862 scope: 'default', 1863 tolerance: 'intersect' 1864 }, 1865 _create: function () { 1866 1867 var o = this.options, accept = o.accept; 1868 this.isover = 0; this.isout = 1; 1869 1870 this.accept = $.isFunction(accept) ? accept : function (d) { 1871 return d.is(accept); 1872 }; 1873 1874 //Store the droppable's proportions 1875 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 1876 1877 // Add the reference and positions to the manager 1878 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 1879 $.ui.ddmanager.droppables[o.scope].push(this); 1880 1881 (o.addClasses && this.element.addClass("ui-droppable")); 1882 1883 }, 1884 1885 _destroy: function () { 1886 var drop = $.ui.ddmanager.droppables[this.options.scope]; 1887 for (var i = 0; i < drop.length; i++) 1888 if (drop[i] == this) 1889 drop.splice(i, 1); 1890 1891 this.element.removeClass("ui-droppable ui-droppable-disabled"); 1892 }, 1893 1894 _setOption: function (key, value) { 1895 1896 if (key == 'accept') { 1897 this.accept = $.isFunction(value) ? value : function (d) { 1898 return d.is(value); 1899 }; 1900 } 1901 $.Widget.prototype._setOption.apply(this, arguments); 1902 }, 1903 1904 _activate: function (event) { 1905 var draggable = $.ui.ddmanager.current; 1906 if (this.options.activeClass) this.element.addClass(this.options.activeClass); 1907 (draggable && this._trigger('activate', event, this.ui(draggable))); 1908 }, 1909 1910 _deactivate: function (event) { 1911 var draggable = $.ui.ddmanager.current; 1912 if (this.options.activeClass) this.element.removeClass(this.options.activeClass); 1913 (draggable && this._trigger('deactivate', event, this.ui(draggable))); 1914 }, 1915 1916 _over: function (event) { 1917 1918 var draggable = $.ui.ddmanager.current; 1919 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 1920 1921 if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element))) { 1922 if (this.options.hoverClass) this.element.addClass(this.options.hoverClass); 1923 this._trigger('over', event, this.ui(draggable)); 1924 } 1925 1926 }, 1927 1928 _out: function (event) { 1929 1930 var draggable = $.ui.ddmanager.current; 1931 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 1932 1933 if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element))) { 1934 if (this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 1935 this._trigger('out', event, this.ui(draggable)); 1936 } 1937 1938 }, 1939 1940 _drop: function (event, custom) { 1941 1942 var draggable = custom || $.ui.ddmanager.current; 1943 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element 1944 1945 var childrenIntersection = false; 1946 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function () { 1947 var inst = $.data(this, 'droppable'); 1948 if ( 1949 inst.options.greedy 1950 && !inst.options.disabled
1951 && inst.options.scope == draggable.options.scope 1952 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) 1953 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 1954 ) { childrenIntersection = true; return false; } 1955 }); 1956 if (childrenIntersection) return false; 1957 1958 if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element))) { 1959 if (this.options.activeClass) this.element.removeClass(this.options.activeClass); 1960 if (this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 1961 this._trigger('drop', event, this.ui(draggable)); 1962 return this.element; 1963 } 1964 1965 return false; 1966 1967 }, 1968 1969 ui: function (c) { 1970 return { 1971 draggable: (c.currentItem || c.element), 1972 helper: c.helper, 1973 position: c.position, 1974 offset: c.positionAbs 1975 }; 1976 } 1977 1978 }); 1979 1980 $.ui.intersect = function (draggable, droppable, toleranceMode) { 1981 1982 if (!droppable.offset) return false; 1983 1984 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 1985 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; 1986 var l = droppable.offset.left, r = l + droppable.proportions.width, 1987 t = droppable.offset.top, b = t + droppable.proportions.height; 1988 1989 switch (toleranceMode) { 1990 case 'fit': 1991 return (l <= x1 && x2 <= r 1992 && t <= y1 && y2 <= b); 1993 break; 1994 case 'intersect': 1995 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half 1996 && x2 - (draggable.helperProportions.width / 2) < r // Left Half 1997 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half 1998 && y2 - (draggable.helperProportions.height / 2) < b); // Top Half 1999 break; 2000 case 'pointer': 2001 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), 2002 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), 2003 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); 2004 return isOver; 2005 break; 2006 case 'touch': 2007 return ( 2008 (y1 >= t && y1 <= b) || // Top edge touching 2009 (y2 >= t && y2 <= b) || // Bottom edge touching 2010 (y1 < t && y2 > b) // Surrounded vertically 2011 ) && ( 2012 (x1 >= l && x1 <= r) || // Left edge touching 2013 (x2 >= l && x2 <= r) || // Right edge touching 2014 (x1 < l && x2 > r) // Surrounded horizontally 2015 ); 2016 break; 2017 default: 2018 return false; 2019 break; 2020 } 2021 2022 }; 2023 2024 /* 2025 This manager tracks offsets of draggables and droppables 2026 */ 2027 $.ui.ddmanager = { 2028 current: null, 2029 droppables: { 'default': [] }, 2030 prepareOffsets: function (t, event) { 2031 2032 var m = $.ui.ddmanager.droppables[t.options.scope] || []; 2033 var type = event ? event.type : null; // workaround for #2317 2034 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); 2035 2036 droppablesLoop: for (var i = 0; i < m.length; i++) { 2037 2038 if (m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0], (t.currentItem || t.element)))) continue; //No disabled and non-accepted 2039 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 2040 m[i].visible = m[i].element.css("display") != "none"; if (!m[i].visible) continue; //If the element is not visible, continue 2041 2042 if (type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables 2043 2044 m[i].offset = m[i].element.offset(); 2045 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2046 2047 } 2048 2049 }, 2050 drop: function (draggable, event) { 2051 2052 var dropped = false;
vendor: 7,226 bytes, lines 2053-2206
2053 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function () { 2054 2055 if (!this.options) return; 2056 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) 2057 dropped = this._drop.call(this, event) || dropped; 2058 2059 if (!this.options.disabled && this.visible && this.accept.call(this.element[0], (draggable.currentItem || draggable.element))) { 2060 this.isout = 1; this.isover = 0; 2061 this._deactivate.call(this, event); 2062 } 2063 2064 }); 2065 return dropped; 2066 2067 }, 2068 dragStart: function (draggable, event) { 2069 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2070 draggable.element.parentsUntil("body").bind("scroll.droppable", function () { 2071 if (!draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); 2072 }); 2073 }, 2074 drag: function (draggable, event) { 2075 2076 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2077 if (draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); 2078 2079 //Run through all droppables and check their positions based on specific tolerance options 2080 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function () { 2081 2082 if (this.options.disabled || this.greedyChild || !this.visible) return; 2083 var intersects = $.ui.intersect(draggable, this, this.options.tolerance); 2084 2085 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); 2086 if (!c) return; 2087 2088 var parentInstance; 2089 if (this.options.greedy) { 2090 // find droppable parents with same scope 2091 var scope = this.options.scope; 2092 var parent = this.element.parents(':data(droppable)').filter(function () { 2093 return $.data(this, 'droppable').options.scope === scope; 2094 }); 2095 2096 if (parent.length) { 2097 parentInstance = $.data(parent[0], 'droppable'); 2098 parentInstance.greedyChild = (c == 'isover' ? 1 : 0); 2099 } 2100 } 2101 2102 // we just moved into a greedy child 2103 if (parentInstance && c == 'isover') { 2104 parentInstance['isover'] = 0; 2105 parentInstance['isout'] = 1; 2106 parentInstance._out.call(parentInstance, event); 2107 } 2108 2109 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; 2110 this[c == "isover" ? "_over" : "_out"].call(this, event); 2111 2112 // we just moved out of a greedy child 2113 if (parentInstance && c == 'isout') { 2114 parentInstance['isout'] = 0; 2115 parentInstance['isover'] = 1; 2116 parentInstance._over.call(parentInstance, event); 2117 } 2118 }); 2119 2120 }, 2121 dragStop: function (draggable, event) { 2122 draggable.element.parentsUntil("body").unbind("scroll.droppable"); 2123 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2124 if (!draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); 2125 } 2126 }; 2127 2128})(jQuery); 2129 2130(function ($, undefined) { 2131 2132 $.widget("ui.resizable", $.ui.mouse, { 2133 version: "1.9.2", 2134 widgetEventPrefix: "resize", 2135 options: { 2136 alsoResize: false, 2137 animate: false, 2138 animateDuration: "slow", 2139 animateEasing: "swing", 2140 aspectRatio: false, 2141 autoHide: false, 2142 containment: false, 2143 ghost: false, 2144 grid: false, 2145 handles: "e,s,se", 2146 helper: false, 2147 maxHeight: null, 2148 maxWidth: null, 2149 minHeight: 10, 2150 minWidth: 10, 2151 zIndex: 1000 2152 }, 2153 _create: function () { 2154 2155 var that = this, o = this.options; 2156 this.element.addClass("ui-resizable"); 2157 2158 $.extend(this, { 2159 _aspectRatio: !!(o.aspectRatio), 2160 aspectRatio: o.aspectRatio, 2161 originalElement: this.element, 2162 _proportionallyResizeElements: [], 2163 _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null 2164 }); 2165 2166 //Wrap the element if it cannot hold child nodes 2167 if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2168 2169 //Create a wrapper element and set the wrapper to the new current internal element 2170 this.element.wrap( 2171 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({ 2172 position: this.element.css('position'), 2173 width: this.element.outerWidth(), 2174 height: this.element.outerHeight(), 2175 top: this.element.css('top'), 2176 left: this.element.css('left') 2177 }) 2178 ); 2179 2180 //Overwrite the original this.element 2181 this.element = this.element.parent().data( 2182 "resizable", this.element.data('resizable') 2183 ); 2184 2185 this.elementIsWrapper = true; 2186 2187 //Move margins to the wrapper 2188 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2189 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0 }); 2190 2191 //Prevent Safari textarea resize 2192 this.originalResizeStyle = this.originalElement.css('resize'); 2193 this.originalElement.css('resize', 'none'); 2194 2195 //Push the actual element to our proportionallyResize internal array 2196 this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); 2197 2198 // avoid IE jump (hard set the margin) 2199 this.originalElement.css({ margin: this.originalElement.css('margin') }); 2200 2201 // fix handlers offset 2202 this._proportionallyResize(); 2203 2204 } 2205 2206 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' });
2207 if (this.handles.constructor == String) { 2208 2209 if (this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; 2210 var n = this.handles.split(","); this.handles = {}; 2211 2212 for (var i = 0; i < n.length; i++) { 2213 2214 var handle = $.trim(n[i]), hname = 'ui-resizable-' + handle; 2215 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); 2216 2217 // Apply zIndex to all handles - see #7960 2218 axis.css({ zIndex: o.zIndex }); 2219 2220 //TODO : What's going on here? 2221 if ('se' == handle) { 2222 axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); 2223 }; 2224 2225 //Insert into internal handles object and append to element 2226 this.handles[handle] = '.ui-resizable-' + handle; 2227 this.element.append(axis); 2228 } 2229 2230 } 2231 2232 this._renderAxis = function (target) { 2233 2234 target = target || this.element; 2235 2236 for (var i in this.handles) { 2237 2238 if (this.handles[i].constructor == String) 2239 this.handles[i] = $(this.handles[i], this.element).show(); 2240 2241 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2242 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2243 2244 var axis = $(this.handles[i], this.element), padWrapper = 0; 2245 2246 //Checking the correct pad and border 2247 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2248 2249 //The padding type i have to apply... 2250 var padPos = ['padding', 2251 /ne|nw|n/.test(i) ? 'Top' : 2252 /se|sw|s/.test(i) ? 'Bottom' : 2253 /^e$/.test(i) ? 'Right' : 'Left'].join(""); 2254 2255 target.css(padPos, padWrapper); 2256 2257 this._proportionallyResize(); 2258 2259 } 2260 2261 //TODO: What's that good for? There's not anything to be executed left 2262 if (!$(this.handles[i]).length) 2263 continue; 2264 2265 } 2266 }; 2267 2268 //TODO: make renderAxis a prototype function 2269 this._renderAxis(this.element); 2270 2271 this._handles = $('.ui-resizable-handle', this.element) 2272 .disableSelection(); 2273
2274 //Matching axis name 2275 this._handles.mouseover(function () { 2276 if (!that.resizing) { 2277 if (this.className) 2278 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2279 //Axis, default = se 2280 that.axis = axis && axis[1] ? axis[1] : 'se'; 2281 } 2282 }); 2283 2284 //If we want to auto hide the elements 2285 if (o.autoHide) { 2286 this._handles.hide(); 2287 $(this.element) 2288 .addClass("ui-resizable-autohide") 2289 .mouseenter(function () { 2290 if (o.disabled) return; 2291 $(this).removeClass("ui-resizable-autohide"); 2292 that._handles.show(); 2293 }) 2294 .mouseleave(function () { 2295 if (o.disabled) return; 2296 if (!that.resizing) { 2297 $(this).addClass("ui-resizable-autohide"); 2298 that._handles.hide(); 2299 } 2300 }); 2301 } 2302 2303 //Initialize the mouse interaction 2304 this._mouseInit(); 2305 2306 }, 2307 2308 _destroy: function () { 2309 2310 this._mouseDestroy(); 2311 2312 var _destroy = function (exp) { 2313 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2314 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); 2315 }; 2316 2317 //TODO: Unwrap at same DOM position 2318 if (this.elementIsWrapper) { 2319 _destroy(this.element); 2320 var wrapper = this.element; 2321 this.originalElement.css({ 2322 position: wrapper.css('position'), 2323 width: wrapper.outerWidth(), 2324 height: wrapper.outerHeight(), 2325 top: wrapper.css('top'), 2326 left: wrapper.css('left') 2327 }).insertAfter(wrapper); 2328 wrapper.remove(); 2329 } 2330 2331 this.originalElement.css('resize', this.originalResizeStyle); 2332 _destroy(this.originalElement); 2333 2334 return this; 2335 }, 2336 2337 _mouseCapture: function (event) { 2338 var handle = false; 2339 for (var i in this.handles) { 2340 if ($(this.handles[i])[0] == event.target) { 2341 handle = true; 2342 } 2343 } 2344 2345 return !this.options.disabled && handle; 2346 }, 2347 2348 _mouseStart: function (event) { 2349 2350 var o = this.options, iniPos = this.element.position(), el = this.element; 2351 2352 this.resizing = true; 2353 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; 2354 2355 // bugfix for http://dev.jquery.com/ticket/1749 2356 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { 2357 el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); 2358 } 2359 2360 this._renderProxy(); 2361 2362 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); 2363 2364 if (o.containment) { 2365 curleft += $(o.containment).scrollLeft() || 0; 2366 curtop += $(o.containment).scrollTop() || 0; 2367 } 2368 2369 //Store needed variables 2370 this.offset = this.helper.offset(); 2371 this.position = { left: curleft, top: curtop }; 2372 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2373 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2374 this.originalPosition = { left: curleft, top: curtop }; 2375 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 2376 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2377 2378 //Aspect Ratio 2379 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 2380 2381 var cursor = $('.ui-resizable-' + this.axis).css('cursor'); 2382 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); 2383 2384 el.addClass("ui-resizable-resizing"); 2385 this._propagate("start", event); 2386 return true; 2387 }, 2388 2389 _mouseDrag: function (event) { 2390 2391 //Increase performance, avoid regex 2392 var el = this.helper, o = this.options, props = {}, 2393 that = this, smp = this.originalMousePosition, a = this.axis; 2394 2395 var dx = (event.pageX - smp.left) || 0, dy = (event.pageY - smp.top) || 0; 2396 var trigger = this._change[a]; 2397 if (!trigger) return false; 2398 2399 // Calculate the attrs that will be change 2400 var data = trigger.apply(this, [event, dx, dy]); 2401 2402 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 2403 this._updateVirtualBoundaries(event.shiftKey); 2404 if (this._aspectRatio || event.shiftKey) 2405 data = this._updateRatio(data, event); 2406 2407 data = this._respectSize(data, event); 2408 2409 // plugins callbacks need to be called first 2410 this._propagate("resize", event); 2411 2412 el.css({ 2413 top: this.position.top + "px", left: this.position.left + "px", 2414 width: this.size.width + "px", height: this.size.height + "px" 2415 }); 2416 2417 if (!this._helper && this._proportionallyResizeElements.length) 2418 this._proportionallyResize(); 2419 2420 this._updateCache(data); 2421 2422 // calling the user callback at the end 2423 this._trigger('resize', event, this.ui()); 2424 2425 return false; 2426 }, 2427 2428 _mouseStop: function (event) { 2429 2430 this.resizing = false; 2431 var o = this.options, that = this; 2432 2433 if (this._helper) { 2434 var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2435 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2436 soffsetw = ista ? 0 : that.sizeDiff.width; 2437 2438 var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }, 2439 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 2440 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 2441 2442 if (!o.animate) 2443 this.element.css($.extend(s, { top: top, left: left })); 2444 2445 that.helper.height(that.size.height); 2446 that.helper.width(that.size.width); 2447
2448 if (this._helper && !o.animate) this._proportionallyResize(); 2449 } 2450 2451 $('body').css('cursor', 'auto'); 2452 2453 this.element.removeClass("ui-resizable-resizing"); 2454 2455 this._propagate("stop", event); 2456 2457 if (this._helper) this.helper.remove(); 2458 return false; 2459 2460 }, 2461 2462 _updateVirtualBoundaries: function (forceAspectRatio) { 2463 var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; 2464 2465 b = { 2466 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 2467 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 2468 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 2469 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 2470 }; 2471 2472 if (this._aspectRatio || forceAspectRatio) { 2473 // We want to create an enclosing box whose aspect ration is the requested one 2474 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 2475 pMinWidth = b.minHeight * this.aspectRatio; 2476 pMinHeight = b.minWidth / this.aspectRatio; 2477 pMaxWidth = b.maxHeight * this.aspectRatio; 2478 pMaxHeight = b.maxWidth / this.aspectRatio; 2479 2480 if (pMinWidth > b.minWidth) b.minWidth = pMinWidth; 2481 if (pMinHeight > b.minHeight) b.minHeight = pMinHeight; 2482 if (pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; 2483 if (pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; 2484 } 2485 this._vBoundaries = b; 2486 }, 2487 2488 _updateCache: function (data) { 2489 var o = this.options; 2490 this.offset = this.helper.offset(); 2491 if (isNumber(data.left)) this.position.left = data.left; 2492 if (isNumber(data.top)) this.position.top = data.top; 2493 if (isNumber(data.height)) this.size.height = data.height; 2494 if (isNumber(data.width)) this.size.width = data.width; 2495 }, 2496 2497 _updateRatio: function (data, event) { 2498 2499 var o = this.options, cpos = this.position, csize = this.size, a = this.axis; 2500 2501 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); 2502 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); 2503 2504 if (a == 'sw') { 2505 data.left = cpos.left + (csize.width - data.width); 2506 data.top = null; 2507 } 2508 if (a == 'nw') { 2509 data.top = cpos.top + (csize.height - data.height); 2510 data.left = cpos.left + (csize.width - data.width); 2511 } 2512 2513 return data; 2514 }, 2515 2516 _respectSize: function (data, event) { 2517 2518 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, 2519 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 2520 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); 2521 2522 if (isminw) data.width = o.minWidth; 2523 if (isminh) data.height = o.minHeight; 2524 if (ismaxw) data.width = o.maxWidth; 2525 if (ismaxh) data.height = o.maxHeight; 2526 2527 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; 2528 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 2529 2530 if (isminw && cw) data.left = dw - o.minWidth; 2531 if (ismaxw && cw) data.left = dw - o.maxWidth; 2532 if (isminh && ch) data.top = dh - o.minHeight; 2533 if (ismaxh && ch) data.top = dh - o.maxHeight; 2534 2535 // fixing jump error on top/left - bug #2330 2536 var isNotwh = !data.width && !data.height; 2537 if (isNotwh && !data.left && data.top) data.top = null; 2538 else if (isNotwh && !data.top && data.left) data.left = null; 2539 2540 return data; 2541 }, 2542 2543 _proportionallyResize: function () { 2544 2545 var o = this.options; 2546 if (!this._proportionallyResizeElements.length) return; 2547 var element = this.helper || this.element; 2548 2549 for (var i = 0; i < this._proportionallyResizeElements.length; i++) { 2550 2551 var prel = this._proportionallyResizeElements[i]; 2552 2553 if (!this.borderDif) { 2554 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], 2555 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; 2556 2557 this.borderDif = $.map(b, function (v, i) { 2558 var border = parseInt(v, 10) || 0, padding = parseInt(p[i], 10) || 0; 2559 return border + padding; 2560 }); 2561 } 2562 2563 prel.css({ 2564 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 2565 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 2566 }); 2567 2568 }; 2569 2570 }, 2571 2572 _renderProxy: function () { 2573 2574 var el = this.element, o = this.options; 2575 this.elementOffset = el.offset(); 2576 2577 if (this._helper) { 2578 2579 this.helper = this.helper || $('<div style="overflow:hidden;"></div>'); 2580 2581 // fix ie6 offset TODO: This seems broken 2582 var ie6offset = ($.ui.ie6 ? 1 : 0), 2583 pxyoffset = ($.ui.ie6 ? 2 : -1); 2584 2585 this.helper.addClass(this._helper).css({ 2586 width: this.element.outerWidth() + pxyoffset, 2587 height: this.element.outerHeight() + pxyoffset, 2588 position: 'absolute', 2589 left: this.elementOffset.left - ie6offset + 'px', 2590 top: this.elementOffset.top - ie6offset + 'px', 2591 zIndex: ++o.zIndex //TODO: Don't modify option 2592 }); 2593 2594 this.helper 2595 .appendTo("body") 2596 .disableSelection(); 2597 2598 } else { 2599 this.helper = this.element; 2600 } 2601 2602 }, 2603 2604 _change: { 2605 e: function (event, dx, dy) { 2606 return { width: this.originalSize.width + dx }; 2607 }, 2608 w: function (event, dx, dy) { 2609 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 2610 return { left: sp.left + dx, width: cs.width - dx }; 2611 }, 2612 n: function (event, dx, dy) { 2613 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 2614 return { top: sp.top + dy, height: cs.height - dy }; 2615 }, 2616 s: function (event, dx, dy) { 2617 return { height: this.originalSize.height + dy }; 2618 }, 2619 se: function (event, dx, dy) { 2620 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2621 }, 2622 sw: function (event, dx, dy) { 2623 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2624 }, 2625 ne: function (event, dx, dy) { 2626 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2627 }, 2628 nw: function (event, dx, dy) { 2629 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2630 } 2631 }, 2632 2633 _propagate: function (n, event) { 2634 $.ui.plugin.call(this, n, [event, this.ui()]); 2635 (n != "resize" && this._trigger(n, event, this.ui())); 2636 }, 2637 2638 plugins: {}, 2639 2640 ui: function () { 2641 return { 2642 originalElement: this.originalElement, 2643 element: this.element, 2644 helper: this.helper, 2645 position: this.position, 2646 size: this.size, 2647 originalSize: this.originalSize, 2648 originalPosition: this.originalPosition 2649 }; 2650 } 2651 2652 });
vendor: 4,320 bytes, lines 2653-2753
2653 2654 /* 2655 * Resizable Extensions 2656 */ 2657 2658 $.ui.plugin.add("resizable", "alsoResize", { 2659 2660 start: function (event, ui) { 2661 var that = $(this).data("resizable"), o = that.options; 2662 2663 var _store = function (exp) { 2664 $(exp).each(function () { 2665 var el = $(this); 2666 el.data("resizable-alsoresize", { 2667 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 2668 left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10) 2669 }); 2670 }); 2671 }; 2672 2673 if (typeof (o.alsoResize) == 'object' && !o.alsoResize.parentNode) { 2674 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 2675 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 2676 } else { 2677 _store(o.alsoResize); 2678 } 2679 }, 2680 2681 resize: function (event, ui) { 2682 var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition; 2683 2684 var delta = { 2685 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 2686 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 2687 }, 2688 2689 _alsoResize = function (exp, c) { 2690 $(exp).each(function () { 2691 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 2692 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; 2693 2694 $.each(css, function (i, prop) { 2695 var sum = (start[prop] || 0) + (delta[prop] || 0); 2696 if (sum && sum >= 0) 2697 style[prop] = sum || null; 2698 }); 2699 2700 el.css(style); 2701 }); 2702 }; 2703 2704 if (typeof (o.alsoResize) == 'object' && !o.alsoResize.nodeType) { 2705 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 2706 } else { 2707 _alsoResize(o.alsoResize); 2708 } 2709 }, 2710 2711 stop: function (event, ui) { 2712 $(this).removeData("resizable-alsoresize"); 2713 } 2714 }); 2715 2716 $.ui.plugin.add("resizable", "animate", { 2717 2718 stop: function (event, ui) { 2719 var that = $(this).data("resizable"), o = that.options; 2720 2721 var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2722 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2723 soffsetw = ista ? 0 : that.sizeDiff.width; 2724 2725 var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 2726 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 2727 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 2728 2729 that.element.animate( 2730 $.extend(style, top && left ? { top: top, left: left } : {}), { 2731 duration: o.animateDuration, 2732 easing: o.animateEasing, 2733 step: function () { 2734 2735 var data = { 2736 width: parseInt(that.element.css('width'), 10), 2737 height: parseInt(that.element.css('height'), 10), 2738 top: parseInt(that.element.css('top'), 10), 2739 left: parseInt(that.element.css('left'), 10) 2740 }; 2741 2742 if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); 2743 2744 // propagating resize, and updating values for each animation step 2745 that._updateCache(data); 2746 that._propagate("resize", event); 2747 2748 } 2749 } 2750 ); 2751 } 2752 2753 });
2754 2755 $.ui.plugin.add("resizable", "containment", { 2756 2757 start: function (event, ui) { 2758 var that = $(this).data("resizable"), o = that.options, el = that.element; 2759 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 2760 if (!ce) return; 2761 2762 that.containerElement = $(ce); 2763 2764 if (/document/.test(oc) || oc == document) { 2765 that.containerOffset = { left: 0, top: 0 }; 2766 that.containerPosition = { left: 0, top: 0 }; 2767 2768 that.parentData = { 2769 element: $(document), left: 0, top: 0, 2770 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 2771 }; 2772 } 2773 2774 // i'm a node, so compute top, left, right, bottom 2775 else { 2776 var element = $(ce), p = []; 2777 $(["Top", "Right", "Left", "Bottom"]).each(function (i, name) { p[i] = num(element.css("padding" + name)); }); 2778 2779 that.containerOffset = element.offset(); 2780 that.containerPosition = element.position(); 2781 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 2782 2783 var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width, 2784 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 2785 2786 that.parentData = { 2787 element: ce, left: co.left, top: co.top, width: width, height: height 2788 }; 2789 } 2790 }, 2791 2792 resize: function (event, ui) { 2793 var that = $(this).data("resizable"), o = that.options, 2794 ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position, 2795 pRatio = that._aspectRatio || event.shiftKey, cop = { top: 0, left: 0 }, ce = that.containerElement; 2796 2797 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; 2798 2799 if (cp.left < (that._helper ? co.left : 0)) { 2800 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 2801 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 2802 that.position.left = o.helper ? co.left : 0; 2803 } 2804 2805 if (cp.top < (that._helper ? co.top : 0)) { 2806 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 2807 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 2808 that.position.top = that._helper ? co.top : 0; 2809 } 2810 2811 that.offset.left = that.parentData.left + that.position.left; 2812 that.offset.top = that.parentData.top + that.position.top; 2813 2814 var woset = Math.abs((that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width), 2815 hoset = Math.abs((that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height); 2816 2817 var isParent = that.containerElement.get(0) == that.element.parent().get(0), 2818 isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position')); 2819 2820 if (isParent && isOffsetRelative) woset -= that.parentData.left; 2821 2822 if (woset + that.size.width >= that.parentData.width) { 2823 that.size.width = that.parentData.width - woset; 2824 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 2825 } 2826 2827 if (hoset + that.size.height >= that.parentData.height) { 2828 that.size.height = that.parentData.height - hoset; 2829 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 2830 } 2831 }, 2832 2833 stop: function (event, ui) { 2834 var that = $(this).data("resizable"), o = that.options, cp = that.position, 2835 co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement; 2836 2837 var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height; 2838
2839 if (that._helper && !o.animate && (/relative/).test(ce.css('position'))) 2840 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 2841 2842 if (that._helper && !o.animate && (/static/).test(ce.css('position'))) 2843 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 2844 2845 } 2846 }); 2847 2848 $.ui.plugin.add("resizable", "ghost", { 2849 2850 start: function (event, ui) { 2851 2852 var that = $(this).data("resizable"), o = that.options, cs = that.size; 2853 2854 that.ghost = that.originalElement.clone(); 2855 that.ghost 2856 .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 2857 .addClass('ui-resizable-ghost') 2858 .addClass(typeof o.ghost == 'string' ? o.ghost : ''); 2859 2860 that.ghost.appendTo(that.helper); 2861 2862 }, 2863 2864 resize: function (event, ui) { 2865 var that = $(this).data("resizable"), o = that.options; 2866 if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width }); 2867 }, 2868 2869 stop: function (event, ui) { 2870 var that = $(this).data("resizable"), o = that.options; 2871 if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0)); 2872 } 2873 2874 }); 2875 2876 $.ui.plugin.add("resizable", "grid", { 2877 2878 resize: function (event, ui) { 2879 var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey; 2880 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; 2881 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); 2882 2883 if (/^(se|s|e)$/.test(a)) { 2884 that.size.width = os.width + ox; 2885 that.size.height = os.height + oy; 2886 } 2887 else if (/^(ne)$/.test(a)) { 2888 that.size.width = os.width + ox; 2889 that.size.height = os.height + oy; 2890 that.position.top = op.top - oy; 2891 } 2892 else if (/^(sw)$/.test(a)) { 2893 that.size.width = os.width + ox; 2894 that.size.height = os.height + oy; 2895 that.position.left = op.left - ox; 2896 } 2897 else { 2898 that.size.width = os.width + ox; 2899 that.size.height = os.height + oy; 2900 that.position.top = op.top - oy; 2901 that.position.left = op.left - ox; 2902 } 2903 } 2904 2905 }); 2906 2907 var num = function (v) { 2908 return parseInt(v, 10) || 0; 2909 }; 2910 2911 var isNumber = function (value) { 2912 return !isNaN(parseInt(value, 10)); 2913 }; 2914 2915})(jQuery); 2916 2917(function ($, undefined) { 2918 2919 $.widget("ui.selectable", $.ui.mouse, { 2920 version: "1.9.2", 2921 options: { 2922 appendTo: 'body', 2923 autoRefresh: true, 2924 distance: 0, 2925 filter: '*', 2926 tolerance: 'touch' 2927 }, 2928 _create: function () { 2929 var that = this; 2930 2931 this.element.addClass("ui-selectable"); 2932 2933 this.dragged = false; 2934 2935 // cache selectee children based on filter 2936 var selectees; 2937 this.refresh = function () { 2938 selectees = $(that.options.filter, that.element[0]); 2939 selectees.addClass("ui-selectee"); 2940 selectees.each(function () { 2941 var $this = $(this); 2942 var pos = $this.offset(); 2943 $.data(this, "selectable-item", { 2944 element: this, 2945 $element: $this, 2946 left: pos.left, 2947 top: pos.top, 2948 right: pos.left + $this.outerWidth(), 2949 bottom: pos.top + $this.outerHeight(), 2950 startselected: false, 2951 selected: $this.hasClass('ui-selected'), 2952 selecting: $this.hasClass('ui-selecting'), 2953 unselecting: $this.hasClass('ui-unselecting') 2954 }); 2955 }); 2956 }; 2957 this.refresh();
vendor: 8,271 bytes, lines 2958-3160
2958 2959 this.selectees = selectees.addClass("ui-selectee"); 2960 2961 this._mouseInit(); 2962 2963 this.helper = $("<div class='ui-selectable-helper'></div>"); 2964 }, 2965 2966 _destroy: function () { 2967 this.selectees 2968 .removeClass("ui-selectee") 2969 .removeData("selectable-item"); 2970 this.element 2971 .removeClass("ui-selectable ui-selectable-disabled"); 2972 this._mouseDestroy(); 2973 }, 2974 2975 _mouseStart: function (event) { 2976 var that = this; 2977 2978 this.opos = [event.pageX, event.pageY]; 2979 2980 if (this.options.disabled) 2981 return; 2982 2983 var options = this.options; 2984 2985 this.selectees = $(options.filter, this.element[0]); 2986 2987 this._trigger("start", event); 2988 2989 $(options.appendTo).append(this.helper); 2990 // position helper (lasso) 2991 this.helper.css({ 2992 "left": event.clientX, 2993 "top": event.clientY, 2994 "width": 0, 2995 "height": 0 2996 }); 2997 2998 if (options.autoRefresh) { 2999 this.refresh(); 3000 } 3001 3002 this.selectees.filter('.ui-selected').each(function () { 3003 var selectee = $.data(this, "selectable-item"); 3004 selectee.startselected = true; 3005 if (!event.metaKey && !event.ctrlKey) { 3006 selectee.$element.removeClass('ui-selected'); 3007 selectee.selected = false; 3008 selectee.$element.addClass('ui-unselecting'); 3009 selectee.unselecting = true; 3010 // selectable UNSELECTING callback 3011 that._trigger("unselecting", event, { 3012 unselecting: selectee.element 3013 }); 3014 } 3015 }); 3016 3017 $(event.target).parents().andSelf().each(function () { 3018 var selectee = $.data(this, "selectable-item"); 3019 if (selectee) { 3020 var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected'); 3021 selectee.$element 3022 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3023 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3024 selectee.unselecting = !doSelect; 3025 selectee.selecting = doSelect; 3026 selectee.selected = doSelect; 3027 // selectable (UN)SELECTING callback 3028 if (doSelect) { 3029 that._trigger("selecting", event, { 3030 selecting: selectee.element 3031 }); 3032 } else { 3033 that._trigger("unselecting", event, { 3034 unselecting: selectee.element 3035 }); 3036 } 3037 return false; 3038 } 3039 }); 3040 3041 }, 3042 3043 _mouseDrag: function (event) { 3044 var that = this; 3045 this.dragged = true; 3046 3047 if (this.options.disabled) 3048 return; 3049 3050 var options = this.options; 3051 3052 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; 3053 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } 3054 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } 3055 this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 }); 3056 3057 this.selectees.each(function () { 3058 var selectee = $.data(this, "selectable-item"); 3059 //prevent helper from being selected if appendTo: selectable 3060 if (!selectee || selectee.element == that.element[0]) 3061 return; 3062 var hit = false; 3063 if (options.tolerance == 'touch') { 3064 hit = (!(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1)); 3065 } else if (options.tolerance == 'fit') { 3066 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3067 } 3068 3069 if (hit) { 3070 // SELECT 3071 if (selectee.selected) { 3072 selectee.$element.removeClass('ui-selected'); 3073 selectee.selected = false; 3074 } 3075 if (selectee.unselecting) { 3076 selectee.$element.removeClass('ui-unselecting'); 3077 selectee.unselecting = false; 3078 } 3079 if (!selectee.selecting) { 3080 selectee.$element.addClass('ui-selecting'); 3081 selectee.selecting = true; 3082 // selectable SELECTING callback 3083 that._trigger("selecting", event, { 3084 selecting: selectee.element 3085 }); 3086 } 3087 } else { 3088 // UNSELECT 3089 if (selectee.selecting) { 3090 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3091 selectee.$element.removeClass('ui-selecting'); 3092 selectee.selecting = false; 3093 selectee.$element.addClass('ui-selected'); 3094 selectee.selected = true; 3095 } else { 3096 selectee.$element.removeClass('ui-selecting'); 3097 selectee.selecting = false; 3098 if (selectee.startselected) { 3099 selectee.$element.addClass('ui-unselecting'); 3100 selectee.unselecting = true; 3101 } 3102 // selectable UNSELECTING callback 3103 that._trigger("unselecting", event, { 3104 unselecting: selectee.element 3105 }); 3106 } 3107 } 3108 if (selectee.selected) { 3109 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3110 selectee.$element.removeClass('ui-selected'); 3111 selectee.selected = false; 3112 3113 selectee.$element.addClass('ui-unselecting'); 3114 selectee.unselecting = true; 3115 // selectable UNSELECTING callback 3116 that._trigger("unselecting", event, { 3117 unselecting: selectee.element 3118 }); 3119 } 3120 } 3121 } 3122 }); 3123 3124 return false; 3125 }, 3126 3127 _mouseStop: function (event) { 3128 var that = this; 3129 3130 this.dragged = false; 3131 3132 var options = this.options; 3133 3134 $('.ui-unselecting', this.element[0]).each(function () { 3135 var selectee = $.data(this, "selectable-item"); 3136 selectee.$element.removeClass('ui-unselecting'); 3137 selectee.unselecting = false; 3138 selectee.startselected = false; 3139 that._trigger("unselected", event, { 3140 unselected: selectee.element 3141 }); 3142 }); 3143 $('.ui-selecting', this.element[0]).each(function () { 3144 var selectee = $.data(this, "selectable-item"); 3145 selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); 3146 selectee.selecting = false; 3147 selectee.selected = true; 3148 selectee.startselected = true; 3149 that._trigger("selected", event, { 3150 selected: selectee.element 3151 }); 3152 }); 3153 this._trigger("stop", event); 3154 3155 this.helper.remove(); 3156 3157 return false; 3158 } 3159 3160 });
3161 3162})(jQuery); 3163 3164(function ($, undefined) { 3165 3166 $.widget("ui.sortable", $.ui.mouse, { 3167 version: "1.9.2", 3168 widgetEventPrefix: "sort", 3169 ready: false, 3170 options: { 3171 appendTo: "parent", 3172 axis: false, 3173 connectWith: false, 3174 containment: false, 3175 cursor: 'auto', 3176 cursorAt: false, 3177 dropOnEmpty: true, 3178 forcePlaceholderSize: false, 3179 forceHelperSize: false, 3180 grid: false, 3181 handle: false, 3182 helper: "original", 3183 items: '> *', 3184 opacity: false, 3185 placeholder: false, 3186 revert: false, 3187 scroll: true, 3188 scrollSensitivity: 20, 3189 scrollSpeed: 20, 3190 scope: "default", 3191 tolerance: "intersect", 3192 zIndex: 1000 3193 }, 3194 _create: function () { 3195 3196 var o = this.options; 3197 this.containerCache = {}; 3198 this.element.addClass("ui-sortable"); 3199 3200 //Get the items 3201 this.refresh(); 3202 3203 //Let's determine if the items are being displayed horizontally 3204 this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false; 3205 3206 //Let's determine the parent's offset 3207 this.offset = this.element.offset(); 3208 3209 //Initialize mouse events for interaction 3210 this._mouseInit(); 3211 3212 //We're ready to go 3213 this.ready = true 3214 3215 }, 3216 3217 _destroy: function () { 3218 this.element 3219 .removeClass("ui-sortable ui-sortable-disabled"); 3220 this._mouseDestroy(); 3221 3222 for (var i = this.items.length - 1; i >= 0; i--) 3223 this.items[i].item.removeData(this.widgetName + "-item"); 3224 3225 return this; 3226 }, 3227 3228 _setOption: function (key, value) { 3229 if (key === "disabled") { 3230 this.options[key] = value; 3231 3232 this.widget().toggleClass("ui-sortable-disabled", !!value); 3233 } else { 3234 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 3235 $.Widget.prototype._setOption.apply(this, arguments); 3236 } 3237 }, 3238 3239 _mouseCapture: function (event, overrideHandle) { 3240 var that = this; 3241 3242 if (this.reverting) { 3243 return false; 3244 } 3245 3246 if (this.options.disabled || this.options.type == 'static') return false; 3247 3248 //We have to refresh the items data once first 3249 this._refreshItems(event); 3250 3251 //Find out if the clicked node (or one of its parents) is a actual item in this.items 3252 var currentItem = null, nodes = $(event.target).parents().each(function () { 3253 if ($.data(this, that.widgetName + '-item') == that) { 3254 currentItem = $(this); 3255 return false; 3256 } 3257 }); 3258 if ($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target); 3259 3260 if (!currentItem) return false; 3261 if (this.options.handle && !overrideHandle) { 3262 var validHandle = false; 3263 3264 $(this.options.handle, currentItem).find("*").andSelf().each(function () { if (this == event.target) validHandle = true; }); 3265 if (!validHandle) return false; 3266 } 3267 3268 this.currentItem = currentItem; 3269 this._removeCurrentsFromItems(); 3270 return true; 3271 3272 }, 3273 3274 _mouseStart: function (event, overrideHandle, noActivation) { 3275 3276 var o = this.options; 3277 this.currentContainer = this; 3278 3279 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 3280 this.refreshPositions(); 3281 3282 //Create and append the visible helper 3283 this.helper = this._createHelper(event); 3284 3285 //Cache the helper size 3286 this._cacheHelperProportions(); 3287 3288 /* 3289 * - Position generation - 3290 * This block generates everything position related - it's the core of draggables. 3291 */ 3292 3293 //Cache the margins of the original element 3294 this._cacheMargins(); 3295 3296 //Get the next scrolling parent 3297 this.scrollParent = this.helper.scrollParent(); 3298 3299 //The element's absolute position on the page minus margins 3300 this.offset = this.currentItem.offset(); 3301 this.offset = { 3302 top: this.offset.top - this.margins.top, 3303 left: this.offset.left - this.margins.left 3304 }; 3305 3306 $.extend(this.offset, { 3307 click: { //Where the click happened, relative to the element 3308 left: event.pageX - this.offset.left, 3309 top: event.pageY - this.offset.top 3310 }, 3311 parent: this._getParentOffset(), 3312 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3313 }); 3314 3315 // Only after we got the offset, we can change the helper's position to absolute 3316 // TODO: Still need to figure out a way to make relative sorting possible 3317 this.helper.css("position", "absolute"); 3318 this.cssPosition = this.helper.css("position"); 3319 3320 //Generate the original position 3321 this.originalPosition = this._generatePosition(event); 3322 this.originalPageX = event.pageX; 3323 this.originalPageY = event.pageY; 3324 3325 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 3326 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3327 3328 //Cache the former DOM position 3329 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 3330 3331 //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 3332 if (this.helper[0] != this.currentItem[0]) { 3333 this.currentItem.hide(); 3334 } 3335 3336 //Create the placeholder 3337 this._createPlaceholder(); 3338 3339 //Set a containment if given in the options 3340 if (o.containment) 3341 this._setContainment(); 3342 3343 if (o.cursor) { // cursor option 3344 if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor"); 3345 $('body').css("cursor", o.cursor); 3346 } 3347 3348 if (o.opacity) { // opacity option 3349 if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity"); 3350 this.helper.css("opacity", o.opacity); 3351 } 3352 3353 if (o.zIndex) { // zIndex option 3354 if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex"); 3355 this.helper.css("zIndex", o.zIndex); 3356 } 3357 3358 //Prepare scrolling 3359 if (this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') 3360 this.overflowOffset = this.scrollParent.offset(); 3361 3362 //Call callbacks 3363 this._trigger("start", event, this._uiHash()); 3364 3365 //Recache the helper size 3366 if (!this._preserveHelperProportions) 3367 this._cacheHelperProportions(); 3368 3369 3370 //Post 'activate' events to possible containers 3371 if (!noActivation) { 3372 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); } 3373 } 3374 3375 //Prepare possible droppables 3376 if ($.ui.ddmanager) 3377 $.ui.ddmanager.current = this; 3378 3379 if ($.ui.ddmanager && !o.dropBehaviour) 3380 $.ui.ddmanager.prepareOffsets(this, event); 3381 3382 this.dragging = true; 3383 3384 this.helper.addClass("ui-sortable-helper"); 3385 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3386 return true; 3387 3388 }, 3389 3390 _mouseDrag: function (event) { 3391 3392 //Compute the helpers position 3393 this.position = this._generatePosition(event); 3394 this.positionAbs = this._convertPositionTo("absolute"); 3395 3396 if (!this.lastPositionAbs) { 3397 this.lastPositionAbs = this.positionAbs; 3398 } 3399 3400 //Do scrolling 3401 if (this.options.scroll) { 3402 var o = this.options, scrolled = false; 3403 if (this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { 3404 3405 if ((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 3406 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 3407 else if (event.pageY - this.overflowOffset.top < o.scrollSensitivity) 3408 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 3409 3410 if ((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 3411 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 3412 else if (event.pageX - this.overflowOffset.left < o.scrollSensitivity) 3413 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 3414 3415 } else { 3416 3417 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) 3418 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3419 else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 3420 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3421 3422 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 3423 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3424 else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 3425 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3426 3427 } 3428 3429 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 3430 $.ui.ddmanager.prepareOffsets(this, event); 3431 } 3432 3433 //Regenerate the absolute position used for position checks 3434 this.positionAbs = this._convertPositionTo("absolute"); 3435 3436 //Set the helper position 3437 if (!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left + 'px'; 3438 if (!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top + 'px'; 3439 3440 //Rearrange 3441 for (var i = this.items.length - 1; i >= 0; i--) { 3442 3443 //Cache variables and intersection, continue if no intersection 3444 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); 3445 if (!intersection) continue; 3446 3447 // Only put the placeholder inside the current Container, skip all 3448 // items form other containers. This works because when moving 3449 // an item from one container to another the 3450 // currentContainer is switched before the placeholder is moved. 3451 //
3452 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 3453 // beetween the outer and inner container. 3454 if (item.instance !== this.currentContainer) continue; 3455 3456 if (itemElement != this.currentItem[0] //cannot intersect with itself 3457 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before 3458 && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked 3459 && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true) 3460 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container 3461 ) { 3462 3463 this.direction = intersection == 1 ? "down" : "up"; 3464 3465 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { 3466 this._rearrange(event, item); 3467 } else { 3468 break; 3469 } 3470 3471 this._trigger("change", event, this._uiHash()); 3472 break; 3473 } 3474 } 3475 3476 //Post events to containers 3477 this._contactContainers(event); 3478 3479 //Interconnect with droppables 3480 if ($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 3481 3482 //Call callbacks 3483 this._trigger('sort', event, this._uiHash()); 3484 3485 this.lastPositionAbs = this.positionAbs; 3486 return false; 3487 3488 }, 3489 3490 _mouseStop: function (event, noPropagation) { 3491 3492 if (!event) return; 3493 3494 //If we are using droppables, inform the manager about the drop 3495 if ($.ui.ddmanager && !this.options.dropBehaviour) 3496 $.ui.ddmanager.drop(this, event); 3497 3498 if (this.options.revert) { 3499 var that = this; 3500 var cur = this.placeholder.offset(); 3501 3502 this.reverting = true; 3503 3504 $(this.helper).animate({ 3505 left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), 3506 top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) 3507 }, parseInt(this.options.revert, 10) || 500, function () { 3508 that._clear(event); 3509 }); 3510 } else { 3511 this._clear(event, noPropagation); 3512 } 3513 3514 return false; 3515 3516 }, 3517 3518 cancel: function () { 3519 3520 if (this.dragging) { 3521 3522 this._mouseUp({ target: null }); 3523 3524 if (this.options.helper == "original") 3525 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 3526 else 3527 this.currentItem.show(); 3528 3529 //Post deactivating events to containers 3530 for (var i = this.containers.length - 1; i >= 0; i--) { 3531 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 3532 if (this.containers[i].containerCache.over) { 3533 this.containers[i]._trigger("out", null, this._uiHash(this)); 3534 this.containers[i].containerCache.over = 0; 3535 } 3536 } 3537 3538 } 3539 3540 if (this.placeholder) { 3541 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 3542 if (this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 3543 if (this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); 3544 3545 $.extend(this, { 3546 helper: null, 3547 dragging: false, 3548 reverting: false, 3549 _noFinalSort: null 3550 }); 3551 3552 if (this.domPosition.prev) { 3553 $(this.domPosition.prev).after(this.currentItem); 3554 } else { 3555 $(this.domPosition.parent).prepend(this.currentItem); 3556 } 3557 } 3558 3559 return this; 3560 3561 }, 3562 3563 serialize: function (o) { 3564 3565 var items = this._getItemsAsjQuery(o && o.connected); 3566 var str = []; o = o || {}; 3567 3568 $(items).each(function () { 3569 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); 3570 if (res) str.push((o.key || res[1] + '[]') + '=' + (o.key && o.expression ? res[1] : res[2])); 3571 }); 3572 3573 if (!str.length && o.key) { 3574 str.push(o.key + '='); 3575 } 3576 3577 return str.join('&'); 3578 3579 }, 3580 3581 toArray: function (o) { 3582 3583 var items = this._getItemsAsjQuery(o && o.connected); 3584 var ret = []; o = o || {}; 3585
3586 items.each(function () { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); 3587 return ret; 3588 3589 }, 3590 3591 /* Be careful with the following core functions */ 3592 _intersectsWith: function (item) { 3593 3594 var x1 = this.positionAbs.left, 3595 x2 = x1 + this.helperProportions.width, 3596 y1 = this.positionAbs.top, 3597 y2 = y1 + this.helperProportions.height; 3598 3599 var l = item.left, 3600 r = l + item.width, 3601 t = item.top, 3602 b = t + item.height; 3603 3604 var dyClick = this.offset.click.top, 3605 dxClick = this.offset.click.left; 3606 3607 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 3608 3609 if (this.options.tolerance == "pointer" 3610 || this.options.forcePointerForContainers 3611 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) 3612 ) { 3613 return isOverElement; 3614 } else { 3615 3616 return (l < x1 + (this.helperProportions.width / 2) // Right Half 3617 && x2 - (this.helperProportions.width / 2) < r // Left Half 3618 && t < y1 + (this.helperProportions.height / 2) // Bottom Half 3619 && y2 - (this.helperProportions.height / 2) < b); // Top Half 3620 3621 } 3622 }, 3623 3624 _intersectsWithPointer: function (item) { 3625 3626 var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 3627 isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 3628 isOverElement = isOverElementHeight && isOverElementWidth, 3629 verticalDirection = this._getDragVerticalDirection(), 3630 horizontalDirection = this._getDragHorizontalDirection(); 3631 3632 if (!isOverElement) 3633 return false; 3634 3635 return this.floating ? 3636 (((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1) 3637 : (verticalDirection && (verticalDirection == "down" ? 2 : 1)); 3638 3639 }, 3640 3641 _intersectsWithSides: function (item) { 3642 3643 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height / 2), item.height), 3644 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width / 2), item.width), 3645 verticalDirection = this._getDragVerticalDirection(), 3646 horizontalDirection = this._getDragHorizontalDirection(); 3647 3648 if (this.floating && horizontalDirection) { 3649 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); 3650 } else { 3651 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); 3652 } 3653 3654 }, 3655 3656 _getDragVerticalDirection: function () { 3657 var delta = this.positionAbs.top - this.lastPositionAbs.top; 3658 return delta != 0 && (delta > 0 ? "down" : "up"); 3659 }, 3660 3661 _getDragHorizontalDirection: function () { 3662 var delta = this.positionAbs.left - this.lastPositionAbs.left; 3663 return delta != 0 && (delta > 0 ? "right" : "left"); 3664 }, 3665 3666 refresh: function (event) { 3667 this._refreshItems(event); 3668 this.refreshPositions(); 3669 return this; 3670 }, 3671 3672 _connectWith: function () { 3673 var options = this.options; 3674 return options.connectWith.constructor == String 3675 ? [options.connectWith] 3676 : options.connectWith; 3677 }, 3678 3679 _getItemsAsjQuery: function (connected) { 3680 3681 var items = []; 3682 var queries = []; 3683 var connectWith = this._connectWith(); 3684 3685 if (connectWith && connected) { 3686 for (var i = connectWith.length - 1; i >= 0; i--) { 3687 var cur = $(connectWith[i]); 3688 for (var j = cur.length - 1; j >= 0; j--) { 3689 var inst = $.data(cur[j], this.widgetName); 3690 if (inst && inst != this && !inst.options.disabled) { 3691 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]); 3692 } 3693 }; 3694 }; 3695 } 3696 3697 queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]); 3698 3699 for (var i = queries.length - 1; i >= 0; i--) { 3700 queries[i][0].each(function () { 3701 items.push(this); 3702 }); 3703 }; 3704 3705 return $(items); 3706 3707 }, 3708 3709 _removeCurrentsFromItems: function () { 3710 3711 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 3712 3713 this.items = $.grep(this.items, function (item) { 3714 for (var j = 0; j < list.length; j++) { 3715 if (list[j] == item.item[0]) 3716 return false; 3717 }; 3718 return true; 3719 }); 3720 3721 }, 3722 3723 _refreshItems: function (event) { 3724 3725 this.items = []; 3726 this.containers = [this]; 3727 var items = this.items; 3728 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; 3729 var connectWith = this._connectWith(); 3730 3731 if (connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 3732 for (var i = connectWith.length - 1; i >= 0; i--) { 3733 var cur = $(connectWith[i]); 3734 for (var j = cur.length - 1; j >= 0; j--) { 3735 var inst = $.data(cur[j], this.widgetName); 3736 if (inst && inst != this && !inst.options.disabled) { 3737 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 3738 this.containers.push(inst); 3739 } 3740 }; 3741 }; 3742 } 3743 3744 for (var i = queries.length - 1; i >= 0; i--) { 3745 var targetData = queries[i][1]; 3746 var _queries = queries[i][0]; 3747 3748 for (var j = 0, queriesLength = _queries.length; j < queriesLength; j++) { 3749 var item = $(_queries[j]); 3750 3751 item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager) 3752 3753 items.push({ 3754 item: item, 3755 instance: targetData, 3756 width: 0, height: 0, 3757 left: 0, top: 0 3758 }); 3759 }; 3760 }; 3761 3762 }, 3763 3764 refreshPositions: function (fast) { 3765 3766 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 3767 if (this.offsetParent && this.helper) { 3768 this.offset.parent = this._getParentOffset(); 3769 } 3770 3771 for (var i = this.items.length - 1; i >= 0; i--) { 3772 var item = this.items[i]; 3773 3774 //We ignore calculating positions of all connected containers when we're not over them 3775 if (item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) 3776 continue; 3777 3778 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 3779 3780 if (!fast) { 3781 item.width = t.outerWidth(); 3782 item.height = t.outerHeight(); 3783 } 3784 3785 var p = t.offset(); 3786 item.left = p.left; 3787 item.top = p.top; 3788 }; 3789 3790 if (this.options.custom && this.options.custom.refreshContainers
3790) { 3791 this.options.custom.refreshContainers.call(this); 3792 } else { 3793 for (var i = this.containers.length - 1; i >= 0; i--) { 3794 var p = this.containers[i].element.offset(); 3795 this.containers[i].containerCache.left = p.left; 3796 this.containers[i].containerCache.top = p.top; 3797 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 3798 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 3799 }; 3800 } 3801 3802 return this; 3803 }, 3804 3805 _createPlaceholder: function (that) { 3806 that = that || this; 3807 var o = that.options; 3808 3809 if (!o.placeholder || o.placeholder.constructor == String) { 3810 var className = o.placeholder; 3811 o.placeholder = { 3812 element: function () { 3813 3814 var el = $(document.createElement(that.currentItem[0].nodeName)) 3815 .addClass(className || that.currentItem[0].className + " ui-sortable-placeholder") 3816 .removeClass("ui-sortable-helper")[0]; 3817 3818 if (!className) 3819 el.style.visibility = "hidden"; 3820 3821 return el; 3822 }, 3823 update: function (container, p) { 3824 3825 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 3826 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 3827 if (className && !o.forcePlaceholderSize) return; 3828 3829 //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 3830 if (!p.height()) { p.height(that.currentItem.innerHe
3830ight() - parseInt(that.currentItem.css('paddingTop') || 0, 10) - parseInt(that.currentItem.css('paddingBottom') || 0, 10)); }; 3831 if (!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft') || 0, 10) - parseInt(that.currentItem.css('paddingRight') || 0, 10)); }; 3832 } 3833 }; 3834 } 3835 3836 //Create the placeholder 3837 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 3838 3839 //Append it after the actual current item 3840 that.currentItem.after(that.placeholder); 3841 3842 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 3843 o.placeholder.update(that, that.placeholder); 3844 3845 }, 3846 3847 _contactContainers: function (event) { 3848 3849 // get innermost container that intersects with item 3850 var innermostContainer = null, innermostIndex = null; 3851 3852 3853 for (var i = this.containers.length - 1; i >= 0; i--) { 3854 3855 // never consider a container that's located within the item itself 3856 if ($.contains(this.currentItem[0], this.containers[i].element[0])) 3857 continue; 3858 3859 if (this._intersectsWith(this.containers[i].containerCache)) { 3860 3861 // if we've already found a container and it's more "inner" than this, then continue 3862 if (innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) 3863 continue; 3864 3865 innermostContainer = this.containers[i]; 3866 innermostIndex = i; 3867 3868 } else { 3869 // container doesn't intersect. trigger "out" event if necessary 3870 if (this.containers[i].containerCache.over) { 3871 this.containers[i]._trigger("out", event, this._uiHash(this)); 3872 this.containers[i].containerCache.over = 0; 3873 } 3874 } 3875 3876 } 3877 3878 // if no intersecting containers found, return 3879 if (!innermostContainer) return; 3880 3881 // move the item into the container if it's not there already 3882 if (this.containers.length === 1) { 3883 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 3884 this.containers[innermostIndex].containerCache.over = 1; 3885 } else { 3886 3887 //When entering a new container, we will find the item with the least distance and append our item near it 3888 var dist = 10000; var itemWithLeastDistance = null; 3889 var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top'; 3890 var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height'; 3891 var base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 3892 for (var j = this.items.length - 1; j >= 0; j--) { 3893 if (!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 3894 if (this.items[j].item[0] == this.currentItem[0]) continue; 3895 var cur = this.items[j].item.offset()[posProperty]; 3896 var nearBottom = false; 3897 if (Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)) { 3898 nearBottom = true; 3899 cur += this.items[j][sizeProperty]; 3900 } 3901 3902 if (Math.abs(cur - base) < dist) { 3903 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 3904 this.direction = nearBottom ? "up" : "down"; 3905 } 3906 } 3907 3908 if (!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 3909 return; 3910 3911 this.currentContainer = this.containers[innermostIndex]; 3912 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 3913 this._trigger("change", event, this._uiHash()); 3914 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 3915 3916 //Update the placeholder 3917 this.options.placeholder.update(this.currentContainer, this.placeholder); 3918 3919 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 3920 this.containers[innermostIndex].containerCache.over = 1; 3921 } 3922 3923 3924 }, 3925 3926 _createHelper: function (event) { 3927 3928 var o = this.options; 3929 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); 3930 3931 if (!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already 3932 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 3933 3934 if (helper[0] == this.currentItem[0]) 3935 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
3935: this.currentItem.css("left") }; 3936 3937 if (helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); 3938 if (helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); 3939 3940 return helper; 3941 3942 }, 3943 3944 _adjustOffsetFromHelper: function (obj) { 3945 if (typeof obj == 'string') { 3946 obj = obj.split(' '); 3947 } 3948 if ($.isArray(obj)) { 3949 obj = { left: +obj[0], top: +obj[1] || 0 }; 3950 } 3951 if ('left' in obj) { 3952 this.offset.click.left = obj.left + this.margins.left; 3953 } 3954 if ('right' in obj) { 3955 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 3956 } 3957 if ('top' in obj) { 3958 this.offset.click.top = obj.top + this.margins.top; 3959 } 3960 if ('bottom' in obj) { 3961 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 3962 } 3963 }, 3964 3965 _getParentOffset: function () { 3966 3967 3968 //Get the offsetParent and cache its position 3969 this.offsetParent = this.helper.offsetParent(); 3970 var po = this.offsetParent.offset(); 3971 3972 // This is a special case where we need to modify a offset calculated on start, since the following happened: 3973 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 3974 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 3975 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 3976 if (this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 3977 po.left += this.scrollParent.scrollLeft(); 3978 po.top += this.scrollParent.scrollTop(); 3979 } 3980 3981 if ((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 3982 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 3983 po = { top: 0, left: 0 }; 3984 3985 return { 3986 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), 3987 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) 3988 }; 3989 3990 }, 3991 3992 _getRelativeOffset: function () { 3993 3994 if (this.cssPosition == "relative") { 3995 var p = this.currentItem.position(); 3996 return { 3997 top: p.top - (parseInt(this.helper.css("top"), 10) || 0) + this.scrollParent.scrollTop(), 3998 left: p.left - (parseInt(this.helper.css("left"), 10) || 0) + this.scrollParent.scrollLeft() 3999 }; 4000 } else { 4001 return { top: 0, left: 0 }; 4002 } 4003 4004 }, 4005 4006 _cacheMargins: function () { 4007 this.margins = { 4008 left: (parseInt(this.currentItem.css("marginLeft"), 10) || 0), 4009 top: (parseInt(this.currentItem.css("marginTop"), 10) || 0) 4010 }; 4011 }, 4012 4013 _cacheHelperProportions: function () { 4014 this.helperProportions = { 4015 width: this.helper.outerWidth(), 4016 height: this.helper.outerHeight() 4017 }; 4018 }, 4019 4020 _setContainment: function () { 4021 4022 var o = this.options; 4023 if (o.containment == 'parent') o.containment = this.helper[0].parentNode; 4024 if (o.containment == 'document' || o.containment == 'window') this.containment = [ 4025 0 - this.offset.relative.left - this.offset.parent.left, 4026 0 - this.offset.relative.top - this.offset.parent.top, 4027 $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 4028 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4029 ]; 4030 4031 if (!(/^(document|window|parent)$/).test(o.containment)) { 4032 var ce = $(o.containment)[0]; 4033 var co = $(o.containment).offset(); 4034 var over = ($(ce).css("overflow") != 'hidden'); 4035 4036 this.containment = [ 4037 co.left + (parseInt($(ce).css("borderLeftWidth"), 10) || 0) + (parseInt($(ce).css("paddingLeft"), 10) || 0) - this.margins.left, 4038 co.top + (parseInt($(ce).css("borderTopWidth"), 10) || 0) + (parseInt($(ce).css("paddingTop"), 10) || 0) - this.margins.top, 4039 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, 4040 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 4041 ]; 4042 } 4043 4044 }, 4045 4046 _convertPositionTo: function (d, pos) { 4047 4048 if (!pos) pos = this.position; 4049 var mod = d == "absolute" ? 1 : -1; 4050 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 4051 4052 return { 4053 top: ( 4054 pos.top // The absolute mouse position 4055 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4056 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 4057 - ((this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : (scrollIsRootNode ? 0 : scroll.scrollTop())) * mod) 4058 ), 4059 left: ( 4060 pos.left // The absolute mouse position 4061 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4062 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 4063 - ((this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft()) * mod) 4064 ) 4065 }; 4066 4067 }, 4068 4069 _generatePosition: function (event) { 4070 4071 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 4072 4073 // This is another very weird special case that only happens for relative elements: 4074 // 1. If the css position is relative 4075 // 2. and the scroll parent is the document or similar to the offset parent 4076 // we have to refresh the relative offset during the scroll so there are no jumps 4077 if (this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { 4078 this.offset.relative = this._getRelativeOffset(); 4079 } 4080 4081 var pageX = event.pageX; 4082 var pageY = event.pageY; 4083 4084 /* 4085 * - Position constraining - 4086 * Constrain the position to a mix of grid, containment. 4087 */ 4088 4089 if (this.originalPosition) { //If we are not dragging yet, we won't check for options 4090 4091 if (this.containment) { 4092 if (event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; 4093 if (event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; 4094 if (event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; 4095 if (event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; 4096 } 4097 4098 if (o.grid) { 4099 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 4100 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; 4101 4102 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 4103 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; 4104 } 4105 4106 } 4107 4108 return { 4109 top: ( 4110 pageY // The absolute mouse position 4111 - this.offset.click.top // Click offset (relative to the element) 4112 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 4113 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 4114 + ((this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : (scrollIsRootNode ? 0 : scroll.scrollTop()))) 4115 ), 4116 left: ( 4117 pageX // The absolute mouse position 4118 - this.offset.click.left // Click offset (relative to the element) 4119 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 4120 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 4121 + ((this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft())) 4122 ) 4123 }; 4124 4125 }, 4126 4127 _rearrange: function (event, i, a, hardRefresh) { 4128 4129 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)); 4130 4131 //Various things done here to improve the performance: 4132 // 1. we create a setTimeout, that calls refreshPositions 4133 // 2. on the instance, we have a counter variable, that get's higher after every append 4134 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 4135 // 4. this lets only the last addition to the timeout stack through 4136 this.counter = this.counter ? ++this.counter : 1; 4137 var counter = this.counter; 4138 4139 this._delay(function () { 4140 if (counter == this.counter) this.refreshPositions(!h
4140ardRefresh); //Precompute after each DOM insertion, NOT on mousemove 4141 }); 4142 4143 }, 4144 4145 _clear: function (event, noPropagation) { 4146 4147 this.reverting = false; 4148 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 4149 // everything else normalized again 4150 var delayedTriggers = []; 4151 4152 // We first have to update the dom position of the actual currentItem 4153 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 4154 if (!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); 4155 this._noFinalSort = null; 4156 4157 if (this.helper[0] == this.currentItem[0]) { 4158 for (var i in this._storedCSS) { 4159 if (this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; 4160 } 4161 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4162 } else { 4163 this.currentItem.show(); 4164 } 4165 4166 if (this.fromOutside && !noPropagation) delayedTriggers.push(function (event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 4167 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 4168 4169 // Check if the items Container has Changed and trigger appropriate 4170 // events. 4171 if (this !== this.currentContainer) { 4172 if (!noPropagation) { 4173 delayedTriggers.push(function (event) { this._trigger("remove", event, this._uiHash()); }); 4174 delayedTriggers.push((function (c) { return function (event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4175 delayedTriggers.push((function (c) { return function (event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4176 } 4177 } 4178 4179 4180 //Post events to containers 4181 for (var i = this.containers.length - 1; i >= 0; i--) { 4182 if (!noPropagation) delayedTriggers.push((function (c) { return function (event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4183 if (this.containers[i].containerCache.over) { 4184 delayedTriggers.push((function (c) { return function (event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4185 this.containers[i].containerCache.over = 0; 4186 } 4187 } 4188 4189 //Do what was originally in plugins 4190 if (this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor 4191 if (this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity 4192 if (this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index 4193 4194 this.dragging = false; 4195 if (this.cancelHelperRemoval) { 4196 if (!noPropagation) { 4197 this._trigger("beforeStop", event, this._uiHash()); 4198 for (var i = 0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 4199 this._trigger("stop", event, this._uiHash()); 4200 } 4201 4202 this.fromOutside = false; 4203 return false; 4204 } 4205 4206 if (!noPropagation) this._trigger("beforeStop", event, this._uiHash()); 4207 4208 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4209 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4210 4211 if (this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; 4212 4213 if (!noPropagation) { 4214 for (var i = 0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 4215 this._trigger("stop", event, this._uiHash()); 4216 } 4217 4218 this.fromOutside = false; 4219 return true; 4220 4221 }, 4222 4223 _trigger: function () { 4224 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 4225 this.cancel(); 4226 } 4227 }, 4228 4229 _uiHash: function (_inst) { 4230 var inst = _inst || this; 4231 return { 4232 helper: inst.helper, 4233 placeholder: inst.placeholder || $([]), 4234 position: inst.position, 4235 originalPosition: inst.originalPosition, 4236 offset: inst.positionAbs, 4237 item: inst.currentItem, 4238 sender: _inst ? _inst.element : null 4239 }; 4240 } 4241 4242 });
vendor: 66,951 bytes, lines 4243-6039
4243 4244})(jQuery); 4245 4246; (jQuery.effects || (function ($, undefined) { 4247 4248 var backCompat = $.uiBackCompat !== false, 4249 // prefix used for storing data on .data() 4250 dataSpace = "ui-effects-"; 4251 4252 $.effects = { 4253 effect: {} 4254 }; 4255 4256 /*! 4257 * jQuery Color Animations v2.0.0 4258 * http://jquery.com/ 4259 * 4260 * Copyright 2012 jQuery Foundation and other contributors 4261 * Released under the MIT license. 4262 * http://jquery.org/license 4263 * 4264 * Date: Mon Aug 13 13:41:02 2012 -0500 4265 */ 4266 (function (jQuery, undefined) { 4267 4268 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "), 4269 4270 // plusequals test for += 100 -= 100 4271 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 4272 // a set of RE's that can match strings and generate color tuples. 4273 stringParsers = [{ 4274 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 4275 parse: function (execResult) { 4276 return [ 4277 execResult[1], 4278 execResult[2], 4279 execResult[3], 4280 execResult[4] 4281 ]; 4282 } 4283 }, { 4284 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 4285 parse: function (execResult) { 4286 return [ 4287 execResult[1] * 2.55, 4288 execResult[2] * 2.55, 4289 execResult[3] * 2.55, 4290 execResult[4] 4291 ]; 4292 } 4293 }, { 4294 // this regex ignores A-F because it's compared against an already lowercased string 4295 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 4296 parse: function (execResult) { 4297 return [ 4298 parseInt(execResult[1], 16), 4299 parseInt(execResult[2], 16), 4300 parseInt(execResult[3], 16) 4301 ]; 4302 } 4303 }, { 4304 // this regex ignores A-F because it's compared against an already lowercased string 4305 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 4306 parse: function (execResult) { 4307 return [ 4308 parseInt(execResult[1] + execResult[1], 16), 4309 parseInt(execResult[2] + execResult[2], 16), 4310 parseInt(execResult[3] + execResult[3], 16) 4311 ]; 4312 } 4313 }, { 4314 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 4315 space: "hsla", 4316 parse: function (execResult) { 4317 return [ 4318 execResult[1], 4319 execResult[2] / 100, 4320 execResult[3] / 100, 4321 execResult[4] 4322 ]; 4323 } 4324 }], 4325 4326 // jQuery.Color( ) 4327 color = jQuery.Color = function (color, green, blue, alpha) { 4328 return new jQuery.Color.fn.parse(color, green, blue, alpha); 4329 }, 4330 spaces = { 4331 rgba: { 4332 props: { 4333 red: { 4334 idx: 0, 4335 type: "byte" 4336 }, 4337 green: { 4338 idx: 1, 4339 type: "byte" 4340 }, 4341 blue: { 4342 idx: 2, 4343 type: "byte" 4344 } 4345 } 4346 }, 4347 4348 hsla: { 4349 props: { 4350 hue: { 4351 idx: 0, 4352 type: "degrees" 4353 }, 4354 saturation: { 4355 idx: 1, 4356 type: "percent" 4357 }, 4358 lightness: { 4359 idx: 2, 4360 type: "percent" 4361 } 4362 } 4363 } 4364 }, 4365 propTypes = { 4366 "byte": { 4367 floor: true, 4368 max: 255 4369 }, 4370 "percent": { 4371 max: 1 4372 }, 4373 "degrees": { 4374 mod: 360, 4375 floor: true 4376 } 4377 }, 4378 support = color.support = {}, 4379 4380 // element for support tests 4381 supportElem = jQuery("<p>")[0], 4382 4383 // colors = jQuery.Color.names 4384 colors, 4385 4386 // local aliases of functions called often 4387 each = jQuery.each; 4388 4389 // determine rgba support immediately 4390 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 4391 support.rgba = supportElem.style.backgroundColor.indexOf("rgba") > -1; 4392 4393 // define cache name and alpha properties 4394 // for rgba and hsla spaces 4395 each(spaces, function (spaceName, space) { 4396 space.cache = "_" + spaceName; 4397 space.props.alpha = { 4398 idx: 3, 4399 type: "percent", 4400 def: 1 4401 }; 4402 }); 4403 4404 function clamp(value, prop, allowEmpty) { 4405 var type = propTypes[prop.type] || {}; 4406 4407 if (value == null) { 4408 return (allowEmpty || !prop.def) ? null : prop.def; 4409 } 4410 4411 // ~~ is an short way of doing floor for positive numbers 4412 value = type.floor ? ~~value : parseFloat(value); 4413 4414 // IE will pass in empty strings as value for alpha, 4415 // which will hit this case 4416 if (isNaN(value)) { 4417 return prop.def; 4418 } 4419 4420 if (type.mod) { 4421 // we add mod before modding to make sure that negatives values 4422 // get converted properly: -10 -> 350 4423 return (value + type.mod) % type.mod; 4424 } 4425 4426 // for now all property types without mod have min and max 4427 return 0 > value ? 0 : type.max < value ? type.max : value; 4428 } 4429 4430 function stringParse(string) { 4431 var inst = color(), 4432 rgba = inst._rgba = []; 4433 4434 string = string.toLowerCase(); 4435 4436 each(stringParsers, function (i, parser) { 4437 var parsed, 4438 match = parser.re.exec(string), 4439 values = match && parser.parse(match), 4440 spaceName = parser.space || "rgba"; 4441 4442 if (values) { 4443 parsed = inst[spaceName](values); 4444 4445 // if this was an rgba parse the assignment might happen twice 4446 // oh well.... 4447 inst[spaces[spaceName].cache] = parsed[spaces[spaceName].cache]; 4448 rgba = inst._rgba = parsed._rgba; 4449 4450 // exit each( stringParsers ) here because we matched 4451 return false; 4452 } 4453 }); 4454 4455 // Found a stringParser that handled it 4456 if (rgba.length) { 4457 4458 // if this came from a parsed string, force "transparent" when alpha is 0 4459 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 4460 if (rgba.join() === "0,0,0,0") { 4461 jQuery.extend(rgba, colors.transparent); 4462 } 4463 return inst; 4464 } 4465 4466 // named colors 4467 return colors[string]; 4468 } 4469 4470 color.fn = jQuery.extend(color.prototype, { 4471 parse: function (red, green, blue, alpha) { 4472 if (red === undefined) { 4473 this._rgba = [null, null, null, null]; 4474 return this; 4475 } 4476 if (red.jquery || red.nodeType) { 4477 red = jQuery(red).css(green); 4478 green = undefined; 4479 } 4480 4481 var inst = this, 4482 type = jQuery.type(red), 4483 rgba = this._rgba = []; 4484 4485 // more than 1 argument specified - assume ( red, green, blue, alpha ) 4486 if (green !== undefined) { 4487 red = [red, green, blue, alpha]; 4488 type = "array"; 4489 } 4490 4491 if (type === "string") { 4492 return this.parse(stringParse(red) || colors._default); 4493 } 4494 4495 if (type === "array") { 4496 each(spaces.rgba.props, function (key, prop) { 4497 rgba[prop.idx] = clamp(red[prop.idx], prop); 4498 }); 4499 return this; 4500 } 4501 4502 if (type === "object") { 4503 if (red instanceof color) { 4504 each(spaces, function (spaceName, space) { 4505 if (red[space.cache]) { 4506 inst[space.cache] = red[space.cache].slice(); 4507 } 4508 }); 4509 } else { 4510 each(spaces, function (spaceName, space) { 4511 var cache = space.cache; 4512 each(space.props, function (key, prop) { 4513 4514 // if the cache doesn't exist, and we know how to convert 4515 if (!inst[cache] && space.to) { 4516 4517 // if the value was null, we don't need to copy it 4518 // if the key was alpha, we don't need to copy it either 4519 if (key === "alpha" || red[key] == null) { 4520 return; 4521 } 4522 inst[cache] = space.to(inst._rgba); 4523 } 4524 4525 // this is the only case where we allow nulls for ALL properties. 4526 // call clamp with alwaysAllowEmpty 4527 inst[cache][prop.idx] = clamp(red[key], prop, true); 4528 }); 4529 4530 // everything defined but alpha? 4531 if (inst[cache] && $.inArray(null, inst[cache].slice(0, 3)) < 0) { 4532 // use the default of 1 4533 inst[cache][3] = 1; 4534 if (space.from) { 4535 inst._rgba = space.from(inst[cache]); 4536 } 4537 } 4538 }); 4539 } 4540 return this; 4541 } 4542 }, 4543 is: function (compare) { 4544 var is = color(compare), 4545 same = true, 4546 inst = this; 4547 4548 each(spaces, function (_, space) { 4549 var localCache, 4550 isCache = is[space.cache]; 4551 if (isCache) { 4552 localCache = inst[space.cache] || space.to && space.to(inst._rgba) || []; 4553 each(space.props, function (_, prop) { 4554 if (isCache[prop.idx] != null) { 4555 same = (isCache[prop.idx] === localCache[prop.idx]); 4556 return same; 4557 } 4558 }); 4559 } 4560 return same; 4561 }); 4562 return same; 4563 }, 4564 _space: function () { 4565 var used = [], 4566 inst = this; 4567 each(spaces, function (spaceName, space) { 4568 if (inst[space.cache]) { 4569 used.push(spaceName); 4570 } 4571 }); 4572 return used.pop(); 4573 }, 4574 transition: function (other, distance) { 4575 var end = color(other), 4576 spaceName = end._space(), 4577 space = spaces[spaceName], 4578 startColor = this.alpha() === 0 ? color("transparent") : this, 4579 start = startColor[space.cache] || space.to(startColor._rgba), 4580 result = start.slice(); 4581 4582 end = end[space.cache]; 4583 each(space.props, function (key, prop) { 4584 var index = prop.idx, 4585 startValue = start[index], 4586 endValue = end[index], 4587 type = propTypes[prop.type] || {}; 4588 4589 // if null, don't override start value 4590 if (endValue === null) { 4591 return; 4592 } 4593 // if null - use end 4594 if (startValue === null) { 4595 result[index] = endValue; 4596 } else { 4597 if (type.mod) { 4598 if (endValue - startValue > type.mod / 2) { 4599 startValue += type.mod; 4600 } else if (startValue - endValue > type.mod / 2) { 4601 startValue -= type.mod; 4602 } 4603 } 4604 result[index] = clamp((endValue - startValue) * distance + startValue, prop); 4605 } 4606 }); 4607 return this[spaceName](result); 4608 }, 4609 blend: function (opaque) { 4610 // if we are already opaque - return ourself 4611 if (this._rgba[3] === 1) { 4612 return this; 4613 } 4614 4615 var rgb = this._rgba.slice(), 4616 a = rgb.pop(), 4617 blend = color(opaque)._rgba; 4618 4619 return color(jQuery.map(rgb, function (v, i) { 4620 return (1 - a) * blend[i] + a * v; 4621 })); 4622 }, 4623 toRgbaString: function () { 4624 var prefix = "rgba(", 4625 rgba = jQuery.map(this._rgba, function (v, i) { 4626 return v == null ? (i > 2 ? 1 : 0) : v; 4627 }); 4628 4629 if (rgba[3] === 1) { 4630 rgba.pop(); 4631 prefix = "rgb("; 4632 } 4633 4634 return prefix + rgba.join() + ")"; 4635 }, 4636 toHslaString: function () { 4637 var prefix = "hsla(", 4638 hsla = jQuery.map(this.hsla(), function (v, i) { 4639 if (v == null) { 4640 v = i > 2 ? 1 : 0; 4641 } 4642 4643 // catch 1 and 2 4644 if (i && i < 3) { 4645 v = Math.round(v * 100) + "%"; 4646 } 4647 return v; 4648 }); 4649 4650 if (hsla[3] === 1) { 4651 hsla.pop(); 4652 prefix = "hsl("; 4653 } 4654 return prefix + hsla.join() + ")"; 4655 }, 4656 toHexString: function (includeAlpha) { 4657 var rgba = this._rgba.slice(), 4658 alpha = rgba.pop(); 4659 4660 if (includeAlpha) { 4661 rgba.push(~~(alpha * 255)); 4662 } 4663 4664 return "#" + jQuery.map(rgba, function (v) { 4665 4666 // default to 0 when nulls exist 4667 v = (v || 0).toString(16); 4668 return v.length === 1 ? "0" + v : v; 4669 }).join(""); 4670 }, 4671 toString: function () { 4672 return this._rgba[3] === 0 ? "transparent" : this.toRgbaString(); 4673 } 4674 }); 4675 color.fn.parse.prototype = color.fn; 4676 4677 // hsla conversions adapted from: 4678 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 4679 4680 function hue2rgb(p, q, h) { 4681 h = (h + 1) % 1; 4682 if (h * 6 < 1) { 4683 return p + (q - p) * h * 6; 4684 } 4685 if (h * 2 < 1) { 4686 return q; 4687 } 4688 if (h * 3 < 2) { 4689 return p + (q - p) * ((2 / 3) - h) * 6; 4690 } 4691 return p; 4692 } 4693 4694 spaces.hsla.to = function (rgba) { 4695 if (rgba[0] == null || rgba[1] == null || rgba[2] == null) { 4696 return [null, null, null, rgba[3]]; 4697 } 4698 var r = rgba[0] / 255, 4699 g = rgba[1] / 255, 4700 b = rgba[2] / 255, 4701 a = rgba[3], 4702 max = Math.max(r, g, b), 4703 min = Math.min(r, g, b), 4704 diff = max - min, 4705 add = max + min, 4706 l = add * 0.5, 4707 h, s; 4708 4709 if (min === max) { 4710 h = 0; 4711 } else if (r === max) { 4712 h = (60 * (g - b) / diff) + 360; 4713 } else if (g === max) { 4714 h = (60 * (b - r) / diff) + 120; 4715 } else { 4716 h = (60 * (r - g) / diff) + 240; 4717 } 4718 4719 if (l === 0 || l === 1) { 4720 s = l; 4721 } else if (l <= 0.5) { 4722 s = diff / add; 4723 } else { 4724 s = diff / (2 - add); 4725 } 4726 return [Math.round(h) % 360, s, l, a == null ? 1 : a]; 4727 }; 4728 4729 spaces.hsla.from = function (hsla) { 4730 if (hsla[0] == null || hsla[1] == null || hsla[2] == null) { 4731 return [null, null, null, hsla[3]]; 4732 } 4733 var h = hsla[0] / 360, 4734 s = hsla[1], 4735 l = hsla[2], 4736 a = hsla[3], 4737 q = l <= 0.5 ? l * (1 + s) : l + s - l * s, 4738 p = 2 * l - q; 4739 4740 return [ 4741 Math.round(hue2rgb(p, q, h + (1 / 3)) * 255), 4742 Math.round(hue2rgb(p, q, h) * 255), 4743 Math.round(hue2rgb(p, q, h - (1 / 3)) * 255), 4744 a 4745 ]; 4746 }; 4747 4748 4749 each(spaces, function (spaceName, space) { 4750 var props = space.props, 4751 cache = space.cache, 4752 to = space.to, 4753 from = space.from; 4754 4755 // makes rgba() and hsla() 4756 color.fn[spaceName] = function (value) { 4757 4758 // generate a cache for this space if it doesn't exist 4759 if (to && !this[cache]) { 4760 this[cache] = to(this._rgba); 4761 } 4762 if (value === undefined) { 4763 return this[cache].slice(); 4764 } 4765 4766 var ret, 4767 type = jQuery.type(value), 4768 arr = (type === "array" || type === "object") ? value : arguments, 4769 local = this[cache].slice(); 4770 4771 each(props, function (key, prop) { 4772 var val = arr[type === "object" ? key : prop.idx]; 4773 if (val == null) { 4774 val = local[prop.idx]; 4775 } 4776 local[prop.idx] = clamp(val, prop); 4777 }); 4778 4779 if (from) { 4780 ret = color(from(local)); 4781 ret[cache] = local; 4782 return ret; 4783 } else { 4784 return color(local); 4785 } 4786 }; 4787 4788 // makes red() green() blue() alpha() hue() saturation() lightness() 4789 each(props, function (key, prop) { 4790 // alpha is included in more than one space 4791 if (color.fn[key]) { 4792 return; 4793 } 4794 color.fn[key] = function (value) { 4795 var vtype = jQuery.type(value), 4796 fn = (key === "alpha" ? (this._hsla ? "hsla" : "rgba") : spaceName), 4797 local = this[fn](), 4798 cur = local[prop.idx], 4799 match; 4800 4801 if (vtype === "undefined") { 4802 return cur; 4803 } 4804 4805 if (vtype === "function") { 4806 value = value.call(this, cur); 4807 vtype = jQuery.type(value); 4808 } 4809 if (value == null && prop.empty) { 4810 return this; 4811 } 4812 if (vtype === "string") { 4813 match = rplusequals.exec(value); 4814 if (match) { 4815 value = cur + parseFloat(match[2]) * (match[1] === "+" ? 1 : -1); 4816 } 4817 } 4818 local[prop.idx] = value; 4819 return this[fn](local); 4820 }; 4821 }); 4822 }); 4823 4824 // add .fx.step functions 4825 each(stepHooks, function (i, hook) { 4826 jQuery.cssHooks[hook] = { 4827 set: function (elem, value) { 4828 var parsed, curElem, 4829 backgroundColor = ""; 4830 4831 if (jQuery.type(value) !== "string" || (parsed = stringParse(value))) { 4832 value = color(parsed || value); 4833 if (!support.rgba && value._rgba[3] !== 1) { 4834 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 4835 while ( 4836 (backgroundColor === "" || backgroundColor === "transparent") && 4837 curElem && curElem.style 4838 ) { 4839 try { 4840 backgroundColor = jQuery.css(curElem, "backgroundColor"); 4841 curElem = curElem.parentNode; 4842 } catch (e) { 4843 } 4844 } 4845 4846 value = value.blend(backgroundColor && backgroundColor !== "transparent" ? 4847 backgroundColor : 4848 "_default"); 4849 } 4850 4851 value = value.toRgbaString(); 4852 } 4853 try { 4854 elem.style[hook] = value; 4855 } catch (error) { 4856 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 4857 } 4858 } 4859 }; 4860 jQuery.fx.step[hook] = function (fx) { 4861 if (!fx.colorInit) { 4862 fx.start = color(fx.elem, hook); 4863 fx.end = color(fx.end); 4864 fx.colorInit = true; 4865 } 4866 jQuery.cssHooks[hook].set(fx.elem, fx.start.transition(fx.end, fx.pos)); 4867 }; 4868 }); 4869 4870 jQuery.cssHooks.borderColor = { 4871 expand: function (value) { 4872 var expanded = {}; 4873 4874 each(["Top", "Right", "Bottom", "Left"], function (i, part) { 4875 expanded["border" + part + "Color"] = value; 4876 }); 4877 return expanded; 4878 } 4879 }; 4880 4881 // Basic color names only. 4882 // Usage of any of the other color names requires adding yourself or including 4883 // jquery.color.svg-names.js. 4884 colors = jQuery.Color.names = { 4885 // 4.1. Basic color keywords 4886 aqua: "#00ffff", 4887 black: "#000000", 4888 blue: "#0000ff", 4889 fuchsia: "#ff00ff", 4890 gray: "#808080", 4891 green: "#008000", 4892 lime: "#00ff00", 4893 maroon: "#800000", 4894 navy: "#000080", 4895 olive: "#808000", 4896 purple: "#800080", 4897 red: "#ff0000", 4898 silver: "#c0c0c0", 4899 teal: "#008080", 4900 white: "#ffffff", 4901 yellow: "#ffff00", 4902 4903 // 4.2.3. "transparent" color keyword 4904 transparent: [null, null, null, 0], 4905 4906 _default: "#ffffff" 4907 }; 4908 4909 })(jQuery); 4910 4911 4912 4913 /******************************************************************************/ 4914 /****************************** CLASS ANIMATIONS ******************************/ 4915 /******************************************************************************/ 4916 (function () { 4917 4918 var classAnimationActions = ["add", "remove", "toggle"], 4919 shorthandStyles = { 4920 border: 1, 4921 borderBottom: 1, 4922 borderColor: 1, 4923 borderLeft: 1, 4924 borderRight: 1, 4925 borderTop: 1, 4926 borderWidth: 1, 4927 margin: 1, 4928 padding: 1 4929 }; 4930 4931 $.each(["borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle"], function (_, prop) { 4932 $.fx.step[prop] = function (fx) { 4933 if (fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr) { 4934 jQuery.style(fx.elem, prop, fx.end); 4935 fx.setAttr = true; 4936 } 4937 }; 4938 }); 4939 4940 function getElementStyles() { 4941 var style = this.ownerDocument.defaultView ? 4942 this.ownerDocument.defaultView.getComputedStyle(this, null) : 4943 this.currentStyle, 4944 newStyle = {}, 4945 key, 4946 len; 4947 4948 // webkit enumerates style porperties 4949 if (style && style.length && style[0] && style[style[0]]) { 4950 len = style.length; 4951 while (len--) { 4952 key = style[len]; 4953 if (typeof style[key] === "string") { 4954 newStyle[$.camelCase(key)] = style[key]; 4955 } 4956 } 4957 } else { 4958 for (key in style) { 4959 if (typeof style[key] === "string") { 4960 newStyle[key] = style[key]; 4961 } 4962 } 4963 } 4964 4965 return newStyle; 4966 } 4967 4968 4969 function styleDifference(oldStyle, newStyle) { 4970 var diff = {}, 4971 name, value; 4972 4973 for (name in newStyle) { 4974 value = newStyle[name]; 4975 if (oldStyle[name] !== value) { 4976 if (!shorthandStyles[name]) { 4977 if ($.fx.step[name] || !isNaN(parseFloat(value))) { 4978 diff[name] = value; 4979 } 4980 } 4981 } 4982 } 4983 4984 return diff; 4985 } 4986 4987 $.effects.animateClass = function (value, duration, easing, callback) { 4988 var o = $.speed(duration, easing, callback); 4989 4990 return this.queue(function () { 4991 var animated = $(this), 4992 baseClass = animated.attr("class") || "", 4993 applyClassChange, 4994 allAnimations = o.children ? animated.find("*").andSelf() : animated; 4995 4996 // map the animated objects to store the original styles. 4997 allAnimations = allAnimations.map(function () { 4998 var el = $(this); 4999 return { 5000 el: el, 5001 start: getElementStyles.call(this) 5002 }; 5003 }); 5004 5005 // apply class change 5006 applyClassChange = function () { 5007 $.each(classAnimationActions, function (i, action) { 5008 if (value[action]) { 5009 animated[action + "Class"](value[action]); 5010 } 5011 }); 5012 }; 5013 applyClassChange(); 5014 5015 // map all animated objects again - calculate new styles and diff 5016 allAnimations = allAnimations.map(function () { 5017 this.end = getElementStyles.call(this.el[0]); 5018 this.diff = styleDifference(this.start, this.end); 5019 return this; 5020 }); 5021 5022 // apply original class 5023 animated.attr("class", baseClass); 5024 5025 // map all animated objects again - this time collecting a promise 5026 allAnimations = allAnimations.map(function () { 5027 var styleInfo = this, 5028 dfd = $.Deferred(), 5029 opts = jQuery.extend({}, o, { 5030 queue: false, 5031 complete: function () { 5032 dfd.resolve(styleInfo); 5033 } 5034 }); 5035 5036 this.el.animate(this.diff, opts); 5037 return dfd.promise(); 5038 }); 5039 5040 // once all animations have completed: 5041 $.when.apply($, allAnimations.get()).done(function () { 5042 5043 // set the final class 5044 applyClassChange(); 5045 5046 // for each animated element, 5047 // clear all css properties that were animated 5048 $.each(arguments, function () { 5049 var el = this.el; 5050 $.each(this.diff, function (key) { 5051 el.css(key, ''); 5052 }); 5053 }); 5054 5055 // this is guarnteed to be there if you use jQuery.speed() 5056 // it also handles dequeuing the next anim... 5057 o.complete.call(animated[0]); 5058 }); 5059 }); 5060 }; 5061 5062 $.fn.extend({ 5063 _addClass: $.fn.addClass, 5064 addClass: function (classNames, speed, easing, callback) { 5065 return speed ? 5066 $.effects.animateClass.call(this, 5067 { add: classNames }, speed, easing, callback) : 5068 this._addClass(classNames); 5069 }, 5070 5071 _removeClass: $.fn.removeClass, 5072 removeClass: function (classNames, speed, easing, callback) { 5073 return speed ? 5074 $.effects.animateClass.call(this, 5075 { remove: classNames }, speed, easing, callback) : 5076 this._removeClass(classNames); 5077 }, 5078 5079 _toggleClass: $.fn.toggleClass, 5080 toggleClass: function (classNames, force, speed, easing, callback) { 5081 if (typeof force === "boolean" || force === undefined) { 5082 if (!speed) { 5083 // without speed parameter 5084 return this._toggleClass(classNames, force); 5085 } else { 5086 return $.effects.animateClass.call(this, 5087 (force ? { add: classNames } : { remove: classNames }), 5088 speed, easing, callback); 5089 } 5090 } else { 5091 // without force parameter 5092 return $.effects.animateClass.call(this, 5093 { toggle: classNames }, force, speed, easing); 5094 } 5095 }, 5096 5097 switchClass: function (remove, add, speed, easing, callback) { 5098 return $.effects.animateClass.call(this, { 5099 add: add, 5100 remove: remove 5101 }, speed, easing, callback); 5102 } 5103 }); 5104 5105 })(); 5106 5107 /******************************************************************************/ 5108 /*********************************** EFFECTS **********************************/ 5109 /******************************************************************************/ 5110 5111 (function () { 5112 5113 $.extend($.effects, { 5114 version: "1.9.2", 5115 5116 // Saves a set of properties in a data storage 5117 save: function (element, set) { 5118 for (var i = 0; i < set.length; i++) { 5119 if (set[i] !== null) { 5120 element.data(dataSpace + set[i], element[0].style[set[i]]); 5121 } 5122 } 5123 }, 5124 5125 // Restores a set of previously saved properties from a data storage 5126 restore: function (element, set) { 5127 var val, i; 5128 for (i = 0; i < set.length; i++) { 5129 if (set[i] !== null) { 5130 val = element.data(dataSpace + set[i]); 5131 // support: jQuery 1.6.2 5132 // http://bugs.jquery.com/ticket/9917 5133 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 5134 // We can't differentiate between "" and 0 here, so we just assume 5135 // empty string since it's likely to be a more common value... 5136 if (val === undefined) { 5137 val = ""; 5138 } 5139 element.css(set[i], val); 5140 } 5141 } 5142 }, 5143 5144 setMode: function (el, mode) { 5145 if (mode === "toggle") { 5146 mode = el.is(":hidden") ? "show" : "hide"; 5147 } 5148 return mode; 5149 }, 5150 5151 // Translates a [top,left] array into a baseline value 5152 // this should be a little more flexible in the future to handle a string & hash 5153 getBaseline: function (origin, original) { 5154 var y, x; 5155 switch (origin[0]) { 5156 case "top": y = 0; break; 5157 case "middle": y = 0.5; break; 5158 case "bottom": y = 1; break; 5159 default: y = origin[0] / original.height; 5160 } 5161 switch (origin[1]) { 5162 case "left": x = 0; break; 5163 case "center": x = 0.5; break; 5164 case "right": x = 1; break; 5165 default: x = origin[1] / original.width; 5166 } 5167 return { 5168 x: x, 5169 y: y 5170 }; 5171 }, 5172 5173 // Wraps the element around a wrapper that copies position properties 5174 createWrapper: function (element) { 5175 5176 // if the element is already wrapped, return it 5177 if (element.parent().is(".ui-effects-wrapper")) { 5178 return element.parent(); 5179 } 5180 5181 // wrap the element 5182 var props = { 5183 width: element.outerWidth(true), 5184 height: element.outerHeight(true), 5185 "float": element.css("float") 5186 }, 5187 wrapper = $("<div></div>") 5188 .addClass("ui-effects-wrapper") 5189 .css({ 5190 fontSize: "100%", 5191 background: "transparent", 5192 border: "none", 5193 margin: 0, 5194 padding: 0 5195 }), 5196 // Store the size in case width/height are defined in % - Fixes #5245 5197 size = { 5198 width: element.width(), 5199 height: element.height() 5200 }, 5201 active = document.activeElement; 5202 5203 // support: Firefox 5204 // Firefox incorrectly exposes anonymous content 5205 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 5206 try { 5207 active.id; 5208 } catch (e) { 5209 active = document.body; 5210 } 5211 5212 element.wrap(wrapper); 5213 5214 // Fixes #7595 - Elements lose focus when wrapped. 5215 if (element[0] === active || $.contains(element[0], active)) { 5216 $(active).focus(); 5217 } 5218 5219 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 5220 5221 // transfer positioning properties to the wrapper 5222 if (element.css("position") === "static") { 5223 wrapper.css({ position: "relative" }); 5224 element.css({ position: "relative" }); 5225 } else { 5226 $.extend(props, { 5227 position: element.css("position"), 5228 zIndex: element.css("z-index") 5229 }); 5230 $.each(["top", "left", "bottom", "right"], function (i, pos) { 5231 props[pos] = element.css(pos); 5232 if (isNaN(parseInt(props[pos], 10))) { 5233 props[pos] = "auto"; 5234 } 5235 }); 5236 element.css({ 5237 position: "relative", 5238 top: 0, 5239 left: 0, 5240 right: "auto", 5241 bottom: "auto" 5242 }); 5243 } 5244 element.css(size); 5245 5246 return wrapper.css(props).show(); 5247 }, 5248 5249 removeWrapper: function (element) { 5250 var active = document.activeElement; 5251 5252 if (element.parent().is(".ui-effects-wrapper")) { 5253 element.parent().replaceWith(element); 5254 5255 // Fixes #7595 - Elements lose focus when wrapped. 5256 if (element[0] === active || $.contains(element[0], active)) { 5257 $(active).focus(); 5258 } 5259 } 5260 5261 5262 return element; 5263 }, 5264 5265 setTransition: function (element, list, factor, value) { 5266 value = value || {}; 5267 $.each(list, function (i, x) { 5268 var unit = element.cssUnit(x); 5269 if (unit[0] > 0) { 5270 value[x] = unit[0] * factor + unit[1]; 5271 } 5272 }); 5273 return value; 5274 } 5275 }); 5276 5277 // return an effect options object for the given parameters: 5278 function _normalizeArguments(effect, options, speed, callback) { 5279 5280 // allow passing all options as the first parameter 5281 if ($.isPlainObject(effect)) { 5282 options = effect; 5283 effect = effect.effect; 5284 } 5285 5286 // convert to an object 5287 effect = { effect: effect }; 5288 5289 // catch (effect, null, ...) 5290 if (options == null) { 5291 options = {}; 5292 } 5293 5294 // catch (effect, callback) 5295 if ($.isFunction(options)) { 5296 callback = options; 5297 speed = null; 5298 options = {}; 5299 } 5300 5301 // catch (effect, speed, ?) 5302 if (typeof options === "number" || $.fx.speeds[options]) { 5303 callback = speed; 5304 speed = options; 5305 options = {}; 5306 } 5307 5308 // catch (effect, options, callback) 5309 if ($.isFunction(speed)) { 5310 callback = speed; 5311 speed = null; 5312 } 5313 5314 // add options to effect 5315 if (options) { 5316 $.extend(effect, options); 5317 } 5318 5319 speed = speed || options.duration; 5320 effect.duration = $.fx.off ? 0 : 5321 typeof speed === "number" ? speed : 5322 speed in $.fx.speeds ? $.fx.speeds[speed] : 5323 $.fx.speeds._default; 5324 5325 effect.complete = callback || options.complete; 5326 5327 return effect; 5328 } 5329 5330 function standardSpeed(speed) { 5331 // valid standard speeds 5332 if (!speed || typeof speed === "number" || $.fx.speeds[speed]) { 5333 return true; 5334 } 5335 5336 // invalid strings - treat as "normal" speed 5337 if (typeof speed === "string" && !$.effects.effect[speed]) { 5338 // TODO: remove in 2.0 (#7115) 5339 if (backCompat && $.effects[speed]) { 5340 return false; 5341 } 5342 return true; 5343 } 5344 5345 return false; 5346 } 5347 5348 $.fn.extend({ 5349 effect: function ( /* effect, options, speed, callback */) { 5350 var args = _normalizeArguments.apply(this, arguments), 5351 mode = args.mode, 5352 queue = args.queue, 5353 effectMethod = $.effects.effect[args.effect], 5354 5355 // DEPRECATED: remove in 2.0 (#7115) 5356 oldEffectMethod = !effectMethod && backCompat && $.effects[args.effect]; 5357 5358 if ($.fx.off || !(effectMethod || oldEffectMethod)) { 5359 // delegate to the original method (e.g., .show()) if possible 5360 if (mode) { 5361 return this[mode](args.duration, args.complete); 5362 } else { 5363 return this.each(function () { 5364 if (args.complete) { 5365 args.complete.call(this); 5366 } 5367 }); 5368 } 5369 } 5370 5371 function run(next) { 5372 var elem = $(this), 5373 complete = args.complete, 5374 mode = args.mode; 5375 5376 function done() { 5377 if ($.isFunction(complete)) { 5378 complete.call(elem[0]); 5379 } 5380 if ($.isFunction(next)) { 5381 next(); 5382 } 5383 } 5384 5385 // if the element is hiddden and mode is hide, 5386 // or element is visible and mode is show 5387 if (elem.is(":hidden") ? mode === "hide" : mode === "show") { 5388 done(); 5389 } else { 5390 effectMethod.call(elem[0], args, done); 5391 } 5392 } 5393 5394 // TODO: remove this check in 2.0, effectMethod will always be true 5395 if (effectMethod) { 5396 return queue === false ? this.each(run) : this.queue(queue || "fx", run); 5397 } else { 5398 // DEPRECATED: remove in 2.0 (#7115) 5399 return oldEffectMethod.call(this, { 5400 options: args, 5401 duration: args.duration, 5402 callback: args.complete, 5403 mode: args.mode 5404 }); 5405 } 5406 }, 5407 5408 _show: $.fn.show, 5409 show: function (speed) { 5410 if (standardSpeed(speed)) { 5411 return this._show.apply(this, arguments); 5412 } else { 5413 var args = _normalizeArguments.apply(this, arguments); 5414 args.mode = "show"; 5415 return this.effect.call(this, args); 5416 } 5417 }, 5418 5419 _hide: $.fn.hide, 5420 hide: function (speed) { 5421 if (standardSpeed(speed)) { 5422 return this._hide.apply(this, arguments); 5423 } else { 5424 var args = _normalizeArguments.apply(this, arguments); 5425 args.mode = "hide"; 5426 return this.effect.call(this, args); 5427 } 5428 }, 5429 5430 // jQuery core overloads toggle and creates _toggle 5431 __toggle: $.fn.toggle, 5432 toggle: function (speed) { 5433 if (standardSpeed(speed) || typeof speed === "boolean" || $.isFunction(speed)) { 5434 return this.__toggle.apply(this, arguments); 5435 } else { 5436 var args = _normalizeArguments.apply(this, arguments); 5437 args.mode = "toggle"; 5438 return this.effect.call(this, args); 5439 } 5440 }, 5441 5442 // helper functions 5443 cssUnit: function (key) { 5444 var style = this.css(key), 5445 val = []; 5446 5447 $.each(["em", "px", "%", "pt"], function (i, unit) { 5448 if (style.indexOf(unit) > 0) { 5449 val = [parseFloat(style), unit]; 5450 } 5451 }); 5452 return val; 5453 } 5454 }); 5455 5456 })(); 5457 5458 /******************************************************************************/ 5459 /*********************************** EASING ***********************************/ 5460 /******************************************************************************/ 5461 5462 (function () { 5463 5464 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 5465 5466 var baseEasings = {}; 5467 5468 $.each(["Quad", "Cubic", "Quart", "Quint", "Expo"], function (i, name) { 5469 baseEasings[name] = function (p) { 5470 return Math.pow(p, i + 2); 5471 }; 5472 }); 5473 5474 $.extend(baseEasings, { 5475 Sine: function (p) { 5476 return 1 - Math.cos(p * Math.PI / 2); 5477 }, 5478 Circ: function (p) { 5479 return 1 - Math.sqrt(1 - p * p); 5480 }, 5481 Elastic: function (p) { 5482 return p === 0 || p === 1 ? p : 5483 -Math.pow(2, 8 * (p - 1)) * Math.sin(((p - 1) * 80 - 7.5) * Math.PI / 15); 5484 }, 5485 Back: function (p) { 5486 return p * p * (3 * p - 2); 5487 }, 5488 Bounce: function (p) { 5489 var pow2, 5490 bounce = 4; 5491 5492 while (p < ((pow2 = Math.pow(2, --bounce)) - 1) / 11) { } 5493 return 1 / Math.pow(4, 3 - bounce) - 7.5625 * Math.pow((pow2 * 3 - 2) / 22 - p, 2); 5494 } 5495 }); 5496 5497 $.each(baseEasings, function (name, easeIn) { 5498 $.easing["easeIn" + name] = easeIn; 5499 $.easing["easeOut" + name] = function (p) { 5500 return 1 - easeIn(1 - p); 5501 }; 5502 $.easing["easeInOut" + name] = function (p) { 5503 return p < 0.5 ? 5504 easeIn(p * 2) / 2 : 5505 1 - easeIn(p * -2 + 2) / 2; 5506 }; 5507 }); 5508 5509 })(); 5510 5511})(jQuery)); 5512 5513(function ($, undefined) { 5514 5515 var uid = 0, 5516 hideProps = {}, 5517 showProps = {}; 5518 5519 hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 5520 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 5521 showProps.height = showProps.paddingTop = showProps.paddingBottom = 5522 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 5523 5524 $.widget("ui.accordion", { 5525 version: "1.9.2", 5526 options: { 5527 active: 0, 5528 animate: {}, 5529 collapsible: false, 5530 event: "click", 5531 header: "> li > :first-child,> :not(li):even", 5532 heightStyle: "auto", 5533 icons: { 5534 activeHeader: "ui-icon-triangle-1-s", 5535 header: "ui-icon-triangle-1-e" 5536 }, 5537 5538 // callbacks 5539 activate: null, 5540 beforeActivate: null 5541 }, 5542 5543 _create: function () { 5544 var accordionId = this.accordionId = "ui-accordion-" + 5545 (this.element.attr("id") || ++uid), 5546 options = this.options; 5547 5548 this.prevShow = this.prevHide = $(); 5549 this.element.addClass("ui-accordion ui-widget ui-helper-reset"); 5550 5551 this.headers = this.element.find(options.header) 5552 .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"); 5553 this._hoverable(this.headers); 5554 this._focusable(this.headers); 5555 5556 this.headers.next() 5557 .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom") 5558 .hide(); 5559 5560 // don't allow collapsible: false and active: false / null 5561 if (!options.collapsible && (options.active === false || options.active == null)) { 5562 options.active = 0; 5563 } 5564 // handle negative values 5565 if (options.active < 0) { 5566 options.active += this.headers.length; 5567 } 5568 this.active = this._findActive(options.active) 5569 .addClass("ui-accordion-header-active ui-state-active") 5570 .toggleClass("ui-corner-all ui-corner-top"); 5571 this.active.next() 5572 .addClass("ui-accordion-content-active") 5573 .show(); 5574 5575 this._createIcons(); 5576 this.refresh(); 5577 5578 // ARIA 5579 this.element.attr("role", "tablist"); 5580 5581 this.headers 5582 .attr("role", "tab") 5583 .each(function (i) { 5584 var header = $(this), 5585 headerId = header.attr("id"), 5586 panel = header.next(), 5587 panelId = panel.attr("id"); 5588 if (!headerId) { 5589 headerId = accordionId + "-header-" + i; 5590 header.attr("id", headerId); 5591 } 5592 if (!panelId) { 5593 panelId = accordionId + "-panel-" + i; 5594 panel.attr("id", panelId); 5595 } 5596 header.attr("aria-controls", panelId); 5597 panel.attr("aria-labelledby", headerId); 5598 }) 5599 .next() 5600 .attr("role", "tabpanel"); 5601 5602 this.headers 5603 .not(this.active) 5604 .attr({ 5605 "aria-selected": "false", 5606 tabIndex: -1 5607 }) 5608 .next() 5609 .attr({ 5610 "aria-expanded": "false", 5611 "aria-hidden": "true" 5612 }) 5613 .hide(); 5614 5615 // make sure at least one header is in the tab order 5616 if (!this.active.length) { 5617 this.headers.eq(0).attr("tabIndex", 0); 5618 } else { 5619 this.active.attr({ 5620 "aria-selected": "true", 5621 tabIndex: 0 5622 }) 5623 .next() 5624 .attr({ 5625 "aria-expanded": "true", 5626 "aria-hidden": "false" 5627 }); 5628 } 5629 5630 this._on(this.headers, { keydown: "_keydown" }); 5631 this._on(this.headers.next(), { keydown: "_panelKeyDown" }); 5632 this._setupEvents(options.event); 5633 }, 5634 5635 _getCreateEventData: function () { 5636 return { 5637 header: this.active, 5638 content: !this.active.length ? $() : this.active.next() 5639 }; 5640 }, 5641 5642 _createIcons: function () { 5643 var icons = this.options.icons; 5644 if (icons) { 5645 $("<span>") 5646 .addClass("ui-accordion-header-icon ui-icon " + icons.header) 5647 .prependTo(this.headers); 5648 this.active.children(".ui-accordion-header-icon") 5649 .removeClass(icons.header) 5650 .addClass(icons.activeHeader); 5651 this.headers.addClass("ui-accordion-icons"); 5652 } 5653 }, 5654 5655 _destroyIcons: function () { 5656 this.headers 5657 .removeClass("ui-accordion-icons") 5658 .children(".ui-accordion-header-icon") 5659 .remove(); 5660 }, 5661 5662 _destroy: function () { 5663 var contents; 5664 5665 // clean up main element 5666 this.element 5667 .removeClass("ui-accordion ui-widget ui-helper-reset") 5668 .removeAttr("role"); 5669 5670 // clean up headers 5671 this.headers 5672 .removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top") 5673 .removeAttr("role") 5674 .removeAttr("aria-selected") 5675 .removeAttr("aria-controls") 5676 .removeAttr("tabIndex") 5677 .each(function () { 5678 if (/^ui-accordion/.test(this.id)) { 5679 this.removeAttribute("id"); 5680 } 5681 }); 5682 this._destroyIcons(); 5683 5684 // clean up content panels 5685 contents = this.headers.next() 5686 .css("display", "") 5687 .removeAttr("role") 5688 .removeAttr("aria-expanded") 5689 .removeAttr("aria-hidden") 5690 .removeAttr("aria-labelledby") 5691 .removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled") 5692 .each(function () { 5693 if (/^ui-accordion/.test(this.id)) { 5694 this.removeAttribute("id"); 5695 } 5696 }); 5697 if (this.options.heightStyle !== "content") { 5698 contents.css("height", ""); 5699 } 5700 }, 5701 5702 _setOption: function (key, value) { 5703 if (key === "active") { 5704 // _activate() will handle invalid values and update this.options 5705 this._activate(value); 5706 return; 5707 } 5708 5709 if (key === "event") { 5710 if (this.options.event) { 5711 this._off(this.headers, this.options.event); 5712 } 5713 this._setupEvents(value); 5714 } 5715 5716 this._super(key, value); 5717 5718 // setting collapsible: false while collapsed; open first panel 5719 if (key === "collapsible" && !value && this.options.active === false) { 5720 this._activate(0); 5721 } 5722 5723 if (key === "icons") { 5724 this._destroyIcons(); 5725 if (value) { 5726 this._createIcons(); 5727 } 5728 } 5729 5730 // #5332 - opacity doesn't cascade to positioned elements in IE 5731 // so we need to add the disabled class to the headers and panels 5732 if (key === "disabled") { 5733 this.headers.add(this.headers.next()) 5734 .toggleClass("ui-state-disabled", !!value); 5735 } 5736 }, 5737 5738 _keydown: function (event) { 5739 if (event.altKey || event.ctrlKey) { 5740 return; 5741 } 5742 5743 var keyCode = $.ui.keyCode, 5744 length = this.headers.length, 5745 currentIndex = this.headers.index(event.target), 5746 toFocus = false; 5747 5748 switch (event.keyCode) { 5749 case keyCode.RIGHT: 5750 case keyCode.DOWN: 5751 toFocus = this.headers[(currentIndex + 1) % length]; 5752 break; 5753 case keyCode.LEFT: 5754 case keyCode.UP: 5755 toFocus = this.headers[(currentIndex - 1 + length) % length]; 5756 break; 5757 case keyCode.SPACE: 5758 case keyCode.ENTER: 5759 this._eventHandler(event); 5760 break; 5761 case keyCode.HOME: 5762 toFocus = this.headers[0]; 5763 break; 5764 case keyCode.END: 5765 toFocus = this.headers[length - 1]; 5766 break; 5767 } 5768 5769 if (toFocus) { 5770 $(event.target).attr("tabIndex", -1); 5771 $(toFocus).attr("tabIndex", 0); 5772 toFocus.focus(); 5773 event.preventDefault(); 5774 } 5775 }, 5776 5777 _panelKeyDown: function (event) { 5778 if (event.keyCode === $.ui.keyCode.UP && event.ctrlKey) { 5779 $(event.currentTarget).prev().focus(); 5780 } 5781 }, 5782 5783 refresh: function () { 5784 var maxHeight, overflow, 5785 heightStyle = this.options.heightStyle, 5786 parent = this.element.parent(); 5787 5788 5789 if (heightStyle === "fill") { 5790 // IE 6 treats height like minHeight, so we need to turn off overflow 5791 // in order to get a reliable height 5792 // we use the minHeight support test because we assume that only 5793 // browsers that don't support minHeight will treat height as minHeight 5794 if (!$.support.minHeight) { 5795 overflow = parent.css("overflow"); 5796 parent.css("overflow", "hidden"); 5797 } 5798 maxHeight = parent.height(); 5799 this.element.siblings(":visible").each(function () { 5800 var elem = $(this), 5801 position = elem.css("position"); 5802 5803 if (position === "absolute" || position === "fixed") { 5804 return; 5805 } 5806 maxHeight -= elem.outerHeight(true); 5807 }); 5808 if (overflow) { 5809 parent.css("overflow", overflow); 5810 } 5811 5812 this.headers.each(function () { 5813 maxHeight -= $(this).outerHeight(true); 5814 }); 5815 5816 this.headers.next() 5817 .each(function () { 5818 $(this).height(Math.max(0, maxHeight - 5819 $(this).innerHeight() + $(this).height())); 5820 }) 5821 .css("overflow", "auto"); 5822 } else if (heightStyle === "auto") { 5823 maxHeight = 0; 5824 this.headers.next() 5825 .each(function () { 5826 maxHeight = Math.max(maxHeight, $(this).css("height", "").height()); 5827 }) 5828 .height(maxHeight); 5829 } 5830 }, 5831 5832 _activate: function (index) { 5833 var active = this._findActive(index)[0]; 5834 5835 // trying to activate the already active panel 5836 if (active === this.active[0]) { 5837 return; 5838 } 5839 5840 // trying to collapse, simulate a click on the currently active header 5841 active = active || this.active[0]; 5842 5843 this._eventHandler({ 5844 target: active, 5845 currentTarget: active, 5846 preventDefault: $.noop 5847 }); 5848 }, 5849 5850 _findActive: function (selector) { 5851 return typeof selector === "number" ? this.headers.eq(selector) : $(); 5852 }, 5853 5854 _setupEvents: function (event) { 5855 var events = {}; 5856 if (!event) { 5857 return; 5858 } 5859 $.each(event.split(" "), function (index, eventName) { 5860 events[eventName] = "_eventHandler"; 5861 }); 5862 this._on(this.headers, events); 5863 }, 5864 5865 _eventHandler: function (event) { 5866 var options = this.options, 5867 active = this.active, 5868 clicked = $(event.currentTarget), 5869 clickedIsActive = clicked[0] === active[0], 5870 collapsing = clickedIsActive && options.collapsible, 5871 toShow = collapsing ? $() : clicked.next(), 5872 toHide = active.next(), 5873 eventData = { 5874 oldHeader: active, 5875 oldPanel: toHide, 5876 newHeader: collapsing ? $() : clicked, 5877 newPanel: toShow 5878 }; 5879 5880 event.preventDefault(); 5881 5882 if ( 5883 // click on active header, but not collapsible 5884 (clickedIsActive && !options.collapsible) || 5885 // allow canceling activation 5886 (this._trigger("beforeActivate", event, eventData) === false)) { 5887 return; 5888 } 5889 5890 options.active = collapsing ? false : this.headers.index(clicked); 5891 5892 // when the call to ._toggle() comes after the class changes 5893 // it causes a very odd bug in IE 8 (see #6720) 5894 this.active = clickedIsActive ? $() : clicked; 5895 this._toggle(eventData); 5896 5897 // switch classes 5898 // corner classes on the previously active header stay after the animation 5899 active.removeClass("ui-accordion-header-active ui-state-active"); 5900 if (options.icons) { 5901 active.children(".ui-accordion-header-icon") 5902 .removeClass(options.icons.activeHeader) 5903 .addClass(options.icons.header); 5904 } 5905 5906 if (!clickedIsActive) { 5907 clicked 5908 .removeClass("ui-corner-all") 5909 .addClass("ui-accordion-header-active ui-state-active ui-corner-top"); 5910 if (options.icons) { 5911 clicked.children(".ui-accordion-header-icon") 5912 .removeClass(options.icons.header) 5913 .addClass(options.icons.activeHeader); 5914 } 5915 5916 clicked 5917 .next() 5918 .addClass("ui-accordion-content-active"); 5919 } 5920 }, 5921 5922 _toggle: function (data) { 5923 var toShow = data.newPanel, 5924 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 5925 5926 // handle activating a panel during the animation for another activation 5927 this.prevShow.add(this.prevHide).stop(true, true); 5928 this.prevShow = toShow; 5929 this.prevHide = toHide; 5930 5931 if (this.options.animate) { 5932 this._animate(toShow, toHide, data); 5933 } else { 5934 toHide.hide(); 5935 toShow.show(); 5936 this._toggleComplete(data); 5937 } 5938 5939 toHide.attr({ 5940 "aria-expanded": "false", 5941 "aria-hidden": "true" 5942 }); 5943 toHide.prev().attr("aria-selected", "false"); 5944 // if we're switching panels, remove the old header from the tab order 5945 // if we're opening from collapsed state, remove the previous header from the tab order 5946 // if we're collapsing, then keep the collapsing header in the tab order 5947 if (toShow.length && toHide.length) { 5948 toHide.prev().attr("tabIndex", -1); 5949 } else if (toShow.length) { 5950 this.headers.filter(function () { 5951 return $(this).attr("tabIndex") === 0; 5952 }) 5953 .attr("tabIndex", -1); 5954 } 5955 5956 toShow 5957 .attr({ 5958 "aria-expanded": "true", 5959 "aria-hidden": "false" 5960 }) 5961 .prev() 5962 .attr({ 5963 "aria-selected": "true", 5964 tabIndex: 0 5965 }); 5966 }, 5967 5968 _animate: function (toShow, toHide, data) { 5969 var total, easing, duration, 5970 that = this, 5971 adjust = 0, 5972 down = toShow.length && 5973 (!toHide.length || (toShow.index() < toHide.index())), 5974 animate = this.options.animate || {}, 5975 options = down && animate.down || animate, 5976 complete = function () { 5977 that._toggleComplete(data); 5978 }; 5979 5980 if (typeof options === "number") { 5981 duration = options; 5982 } 5983 if (typeof options === "string") { 5984 easing = options; 5985 } 5986 // fall back from options to animation in case of partial down settings 5987 easing = easing || options.easing || animate.easing; 5988 duration = duration || options.duration || animate.duration; 5989 5990 if (!toHide.length) { 5991 return toShow.animate(showProps, duration, easing, complete); 5992 } 5993 if (!toShow.length) { 5994 return toHide.animate(hideProps, duration, easing, complete); 5995 } 5996 5997 total = toShow.show().outerHeight(); 5998 toHide.animate(hideProps, { 5999 duration: duration, 6000 easing: easing, 6001 step: function (now, fx) { 6002 fx.now = Math.round(now); 6003 } 6004 }); 6005 toShow 6006 .hide() 6007 .animate(showProps, { 6008 duration: duration, 6009 easing: easing, 6010 complete: complete, 6011 step: function (now, fx) { 6012 fx.now = Math.round(now); 6013 if (fx.prop !== "height") { 6014 adjust += fx.now; 6015 } else if (that.options.heightStyle !== "content") { 6016 fx.now = Math.round(total - toHide.outerHeight() - adjust); 6017 adjust = 0; 6018 } 6019 } 6020 }); 6021 }, 6022 6023 _toggleComplete: function (data) { 6024 var toHide = data.oldPanel; 6025 6026 toHide 6027 .removeClass("ui-accordion-content-active") 6028 .prev() 6029 .removeClass("ui-corner-top") 6030 .addClass("ui-corner-all"); 6031 6032 // Work around for rendering bug in IE (#5421) 6033 if (toHide.length) { 6034 toHide.parent()[0].className = toHide.parent()[0].className; 6035 } 6036 6037 this._trigger("activate", null, data); 6038 } 6039 });
6040 6041 6042 6043 // DEPRECATED 6044 if ($.uiBackCompat !== false) { 6045 // navigation options 6046 (function ($, prototype) { 6047 $.extend(prototype.options, { 6048 navigation: false, 6049 navigationFilter: function () { 6050 return this.href.toLowerCase() === location.href.toLowerCase(); 6051 } 6052 }); 6053 6054 var _create = prototype._create; 6055 prototype._create = function () { 6056 if (this.options.navigation) { 6057 var that = this, 6058 headers = this.element.find(this.options.header), 6059 content = headers.next(), 6060 current = headers.add(content) 6061 .find("a") 6062 .filter(this.options.navigationFilter) 6063 [0]; 6064 if (current) { 6065 headers.add(content).each(function (index) { 6066 if ($.contains(this, current)) { 6067 that.options.active = Math.floor(index / 2); 6068 return false; 6069 } 6070 }); 6071 } 6072 } 6073 _create.call(this); 6074 }; 6075 }(jQuery, jQuery.ui.accordion.prototype)); 6076 6077 // height options 6078 (function ($, prototype) { 6079 $.extend(prototype.options, { 6080 heightStyle: null, // remove default so we fall back to old values 6081 autoHeight: true, // use heightStyle: "auto" 6082 clearStyle: false, // use heightStyle: "content" 6083 fillSpace: false // use heightStyle: "fill" 6084 }); 6085 6086 var _create = prototype._create, 6087 _setOption = prototype._setOption; 6088 6089 $.extend(prototype, { 6090 _create: function () { 6091 this.options.heightStyle = this.options.heightStyle || 6092 this._mergeHeightStyle(); 6093 6094 _create.call(this); 6095 }, 6096 6097 _setOption: function (key) { 6098 if (key === "autoHeight" || key === "clearStyle" || key === "fillSpace") { 6099 this.options.heightStyle = this._mergeHeightStyle(); 6100 } 6101 _setOption.apply(this, arguments); 6102 }, 6103 6104 _mergeHeightStyle: function () { 6105 var options = this.options; 6106 6107 if (options.fillSpace) { 6108 return "fill"; 6109 } 6110 6111 if (options.clearStyle) { 6112 return "content"; 6113 } 6114 6115 if (options.autoHeight) { 6116 return "auto"; 6117 } 6118 } 6119 }); 6120 }(jQuery, jQuery.ui.accordion.prototype)); 6121 6122 // icon options 6123 (function ($, prototype) { 6124 $.extend(prototype.options.icons, { 6125 activeHeader: null, // remove default so we fall back to old values 6126 headerSelected: "ui-icon-triangle-1-s" 6127 }); 6128 6129 var _createIcons = prototype._createIcons; 6130 prototype._createIcons = function () { 6131 if (this.options.icons) { 6132 this.options.icons.activeHeader = this.options.icons.activeHeader || 6133 this.options.icons.headerSelected; 6134 } 6135 _createIcons.call(this); 6136 }; 6137 }(jQuery, jQuery.ui.accordion.prototype)); 6138 6139 // expanded active option, activate method 6140 (function ($, prototype) { 6141 prototype.activate = prototype._activate; 6142 6143 var _findActive = prototype._findActive; 6144 prototype._findActive = function (index) { 6145 if (index === -1) { 6146 index = false; 6147 } 6148 if (index && typeof index !== "number") { 6149 index = this.headers.index(this.headers.filter(index)); 6150 if (index === -1) { 6151 index = false; 6152 } 6153 } 6154 return _findActive.call(this, index); 6155 }; 6156 }(jQuery, jQuery.ui.accordion.prototype)); 6157 6158 // resize method 6159 jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh; 6160 6161 // change events 6162 (function ($, prototype) { 6163 $.extend(prototype.options, { 6164 change: null, 6165 changestart: null 6166 }); 6167 6168 var _trigger = prototype._trigger; 6169 prototype._trigger = function (type, event, data) { 6170 var ret = _trigger.apply(this, arguments); 6171 if (!ret) { 6172 return false; 6173 } 6174 6175 if (type === "beforeActivate") { 6176 ret = _trigger.call(this, "changestart", event, { 6177 oldHeader: data.oldHeader, 6178 oldContent: data.oldPanel, 6179 newHeader: data.newHeader, 6180 newContent: data.newPanel 6181 }); 6182 } else if (type === "activate") { 6183 ret = _trigger.call(this, "change", event, { 6184 oldHeader: data.oldHeader, 6185 oldContent: data.oldPanel, 6186 newHeader: data.newHeader, 6187 newContent: data.newPanel 6188 }); 6189 } 6190 return ret; 6191 }; 6192 }(jQuery, jQuery.ui.accordion.prototype)); 6193
vendor: 7,743 bytes, lines 6194-6380
6194 // animated option 6195 // NOTE: this only provides support for "slide", "bounceslide", and easings 6196 // not the full $.ui.accordion.animations API 6197 (function ($, prototype) { 6198 $.extend(prototype.options, { 6199 animate: null, 6200 animated: "slide" 6201 }); 6202 6203 var _create = prototype._create; 6204 prototype._create = function () { 6205 var options = this.options; 6206 if (options.animate === null) { 6207 if (!options.animated) { 6208 options.animate = false; 6209 } else if (options.animated === "slide") { 6210 options.animate = 300; 6211 } else if (options.animated === "bounceslide") { 6212 options.animate = { 6213 duration: 200, 6214 down: { 6215 easing: "easeOutBounce", 6216 duration: 1000 6217 } 6218 }; 6219 } else { 6220 options.animate = options.animated; 6221 } 6222 } 6223 6224 _create.call(this); 6225 }; 6226 }(jQuery, jQuery.ui.accordion.prototype)); 6227 } 6228 6229})(jQuery); 6230 6231(function ($, undefined) { 6232 6233 // used to prevent race conditions with remote data sources 6234 var requestIndex = 0; 6235 6236 $.widget("ui.autocomplete", { 6237 version: "1.9.2", 6238 defaultElement: "<input>", 6239 options: { 6240 appendTo: "body", 6241 autoFocus: false, 6242 delay: 300, 6243 minLength: 1, 6244 position: { 6245 my: "left top", 6246 at: "left bottom", 6247 collision: "none" 6248 }, 6249 source: null, 6250 6251 // callbacks 6252 change: null, 6253 close: null, 6254 focus: null, 6255 open: null, 6256 response: null, 6257 search: null, 6258 select: null 6259 }, 6260 6261 pending: 0, 6262 6263 _create: function () { 6264 // Some browsers only repeat keydown events, not keypress events, 6265 // so we use the suppressKeyPress flag to determine if we've already 6266 // handled the keydown event. #7269 6267 // Unfortunately the code for & in keypress is the same as the up arrow, 6268 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 6269 // events when we know the keydown event was used to modify the 6270 // search term. #7799 6271 var suppressKeyPress, suppressKeyPressRepeat, suppressInput; 6272 6273 this.isMultiLine = this._isMultiLine(); 6274 this.valueMethod = this.element[this.element.is("input,textarea") ? "val" : "text"]; 6275 this.isNewMenu = true; 6276 6277 this.element 6278 .addClass("ui-autocomplete-input") 6279 .attr("autocomplete", "off"); 6280 6281 this._on(this.element, { 6282 keydown: function (event) { 6283 if (this.element.prop("readOnly")) { 6284 suppressKeyPress = true; 6285 suppressInput = true; 6286 suppressKeyPressRepeat = true; 6287 return; 6288 } 6289 6290 suppressKeyPress = false; 6291 suppressInput = false; 6292 suppressKeyPressRepeat = false; 6293 var keyCode = $.ui.keyCode; 6294 switch (event.keyCode) { 6295 case keyCode.PAGE_UP: 6296 suppressKeyPress = true; 6297 this._move("previousPage", event); 6298 break; 6299 case keyCode.PAGE_DOWN: 6300 suppressKeyPress = true; 6301 this._move("nextPage", event); 6302 break; 6303 case keyCode.UP: 6304 suppressKeyPress = true; 6305 this._keyEvent("previous", event); 6306 break; 6307 case keyCode.DOWN: 6308 suppressKeyPress = true; 6309 this._keyEvent("next", event); 6310 break; 6311 case keyCode.ENTER: 6312 case keyCode.NUMPAD_ENTER: 6313 // when menu is open and has focus 6314 if (this.menu.active) { 6315 // #6055 - Opera still allows the keypress to occur 6316 // which causes forms to submit 6317 suppressKeyPress = true; 6318 event.preventDefault(); 6319 this.menu.select(event); 6320 } 6321 break; 6322 case keyCode.TAB: 6323 if (this.menu.active) { 6324 this.menu.select(event); 6325 } 6326 break; 6327 case keyCode.ESCAPE: 6328 if (this.menu.element.is(":visible")) { 6329 this._value(this.term); 6330 this.close(event); 6331 // Different browsers have different default behavior for escape 6332 // Single press can mean undo or clear 6333 // Double press in IE means clear the whole form 6334 event.preventDefault(); 6335 } 6336 break; 6337 default: 6338 suppressKeyPressRepeat = true; 6339 // search timeout should be triggered before the input value is changed 6340 this._searchTimeout(event); 6341 break; 6342 } 6343 }, 6344 keypress: function (event) { 6345 if (suppressKeyPress) { 6346 suppressKeyPress = false; 6347 event.preventDefault(); 6348 return; 6349 } 6350 if (suppressKeyPressRepeat) { 6351 return; 6352 } 6353 6354 // replicate some key handlers to allow them to repeat in Firefox and Opera 6355 var keyCode = $.ui.keyCode; 6356 switch (event.keyCode) { 6357 case keyCode.PAGE_UP: 6358 this._move("previousPage", event); 6359 break; 6360 case keyCode.PAGE_DOWN: 6361 this._move("nextPage", event); 6362 break; 6363 case keyCode.UP: 6364 this._keyEvent("previous", event); 6365 break; 6366 case keyCode.DOWN: 6367 this._keyEvent("next", event); 6368 break; 6369 } 6370 }, 6371 input: function (event) { 6372 if (suppressInput) { 6373 suppressInput = false; 6374 event.preventDefault(); 6375 return; 6376 } 6377 this._searchTimeout(event); 6378 }, 6379 focus: function () { 6380 this.selectedItem = null;
vendor: 4,795 bytes, lines 6381-6476
6381 this.previous = this._value(); 6382 }, 6383 blur: function (event) { 6384 if (this.cancelBlur) { 6385 delete this.cancelBlur; 6386 return; 6387 } 6388 6389 clearTimeout(this.searching); 6390 this.close(event); 6391 this._change(event); 6392 } 6393 }); 6394 6395 this._initSource(); 6396 this.menu = $("<ul>") 6397 .addClass("ui-autocomplete") 6398 .appendTo(this.document.find(this.options.appendTo || "body")[0]) 6399 .menu({ 6400 // custom key handling for now 6401 input: $(), 6402 // disable ARIA support, the live region takes care of that 6403 role: null 6404 }) 6405 .zIndex(this.element.zIndex() + 1) 6406 .hide() 6407 .data("menu"); 6408 6409 this._on(this.menu.element, { 6410 mousedown: function (event) { 6411 // prevent moving focus out of the text field 6412 event.preventDefault(); 6413 6414 // IE doesn't prevent moving focus even with event.preventDefault() 6415 // so we set a flag to know when we should ignore the blur event 6416 this.cancelBlur = true; 6417 this._delay(function () { 6418 delete this.cancelBlur; 6419 }); 6420 6421 // clicking on the scrollbar causes focus to shift to the body 6422 // but we can't detect a mouseup or a click immediately afterward 6423 // so we have to track the next mousedown and close the menu if 6424 // the user clicks somewhere outside of the autocomplete 6425 var menuElement = this.menu.element[0]; 6426 if (!$(event.target).closest(".ui-menu-item").length) { 6427 this._delay(function () { 6428 var that = this; 6429 this.document.one("mousedown", function (event) { 6430 if (event.target !== that.element[0] && 6431 event.target !== menuElement && 6432 !$.contains(menuElement, event.target)) { 6433 that.close(); 6434 } 6435 }); 6436 }); 6437 } 6438 }, 6439 menufocus: function (event, ui) { 6440 // #7024 - Prevent accidental activation of menu items in Firefox 6441 if (this.isNewMenu) { 6442 this.isNewMenu = false; 6443 if (event.originalEvent && /^mouse/.test(event.originalEvent.type)) { 6444 this.menu.blur(); 6445 6446 this.document.one("mousemove", function () { 6447 $(event.target).trigger(event.originalEvent); 6448 }); 6449 6450 return; 6451 } 6452 } 6453 6454 // back compat for _renderItem using item.autocomplete, via #7810 6455 // TODO remove the fallback, see #8156 6456 var item = ui.item.data("ui-autocomplete-item") || ui.item.data("item.autocomplete"); 6457 if (false !== this._trigger("focus", event, { item: item })) { 6458 // use value to match what will end up in the input, if it was a key event 6459 if (event.originalEvent && /^key/.test(event.originalEvent.type)) { 6460 this._value(item.value); 6461 } 6462 } else { 6463 // Normally the input is populated with the item's value as the 6464 // menu is navigated, causing screen readers to notice a change and 6465 // announce the item. Since the focus event was canceled, this doesn't 6466 // happen, so we update the live region so that screen readers can 6467 // still notice the change and announce it. 6468 this.liveRegion.text(item.value); 6469 } 6470 }, 6471 menuselect: function (event, ui) { 6472 // back compat for _renderItem using item.autocomplete, via #7810 6473 // TODO remove the fallback, see #8156 6474 var item = ui.item.data("ui-autocomplete-item") || ui.item.data("item.autocomplete"), 6475 previous = this.previous; 6476
vendor: 4,632 bytes, lines 6477-6593
6477 // only trigger when focus was lost (click on menu) 6478 if (this.element[0] !== this.document[0].activeElement) { 6479 this.element.focus(); 6480 this.previous = previous; 6481 // #6109 - IE triggers two focus events and the second 6482 // is asynchronous, so we need to reset the previous 6483 // term synchronously and asynchronously :-( 6484 this._delay(function () { 6485 this.previous = previous; 6486 this.selectedItem = item; 6487 }); 6488 } 6489 6490 if (false !== this._trigger("select", event, { item: item })) { 6491 this._value(item.value); 6492 } 6493 // reset the term after the select event 6494 // this allows custom select handling to work properly 6495 this.term = this._value(); 6496 6497 this.close(event); 6498 this.selectedItem = item; 6499 } 6500 }); 6501 6502 this.liveRegion = $("<span>", { 6503 role: "status", 6504 "aria-live": "polite" 6505 }) 6506 .addClass("ui-helper-hidden-accessible") 6507 .insertAfter(this.element); 6508 6509 if ($.fn.bgiframe) { 6510 this.menu.element.bgiframe(); 6511 } 6512 6513 // turning off autocomplete prevents the browser from remembering the 6514 // value when navigating through history, so we re-enable autocomplete 6515 // if the page is unloaded before the widget is destroyed. #7790 6516 this._on(this.window, { 6517 beforeunload: function () { 6518 this.element.removeAttr("autocomplete"); 6519 } 6520 }); 6521 }, 6522 6523 _destroy: function () { 6524 clearTimeout(this.searching); 6525 this.element 6526 .removeClass("ui-autocomplete-input") 6527 .removeAttr("autocomplete"); 6528 this.menu.element.remove(); 6529 this.liveRegion.remove(); 6530 }, 6531 6532 _setOption: function (key, value) { 6533 this._super(key, value); 6534 if (key === "source") { 6535 this._initSource(); 6536 } 6537 if (key === "appendTo") { 6538 this.menu.element.appendTo(this.document.find(value || "body")[0]); 6539 } 6540 if (key === "disabled" && value && this.xhr) { 6541 this.xhr.abort(); 6542 } 6543 }, 6544 6545 _isMultiLine: function () { 6546 // Textareas are always multi-line 6547 if (this.element.is("textarea")) { 6548 return true; 6549 } 6550 // Inputs are always single-line, even if inside a contentEditable element 6551 // IE also treats inputs as contentEditable 6552 if (this.element.is("input")) { 6553 return false; 6554 } 6555 // All other element types are determined by whether or not they're contentEditable 6556 return this.element.prop("isContentEditable"); 6557 }, 6558 6559 _initSource: function () { 6560 var array, url, 6561 that = this; 6562 if ($.isArray(this.options.source)) { 6563 array = this.options.source; 6564 this.source = function (request, response) { 6565 response($.ui.autocomplete.filter(array, request.term)); 6566 }; 6567 } else if (typeof this.options.source === "string") { 6568 url = this.options.source; 6569 this.source = function (request, response) { 6570 if (that.xhr) { 6571 that.xhr.abort(); 6572 } 6573 that.xhr = $.ajax({ 6574 url: url, 6575 data: request, 6576 dataType: "json", 6577 success: function (data) { 6578 response(data); 6579 }, 6580 error: function () { 6581 response([]); 6582 } 6583 }); 6584 }; 6585 } else { 6586 this.source = this.options.source; 6587 } 6588 }, 6589 6590 _searchTimeout: function (event) { 6591 clearTimeout(this.searching); 6592 this.searching = this._delay(function () { 6593 // only search if the value has changed
vendor: 5,755 bytes, lines 6594-6771
6594 if (this.term !== this._value()) { 6595 this.selectedItem = null; 6596 this.search(null, event); 6597 } 6598 }, this.options.delay); 6599 }, 6600 6601 search: function (value, event) { 6602 value = value != null ? value : this._value(); 6603 6604 // always save the actual value, not the one passed as an argument 6605 this.term = this._value(); 6606 6607 if (value.length < this.options.minLength) { 6608 return this.close(event); 6609 } 6610 6611 if (this._trigger("search", event) === false) { 6612 return; 6613 } 6614 6615 return this._search(value); 6616 }, 6617 6618 _search: function (value) { 6619 this.pending++; 6620 this.element.addClass("ui-autocomplete-loading"); 6621 this.cancelSearch = false; 6622 6623 this.source({ term: value }, this._response()); 6624 }, 6625 6626 _response: function () { 6627 var that = this, 6628 index = ++requestIndex; 6629 6630 return function (content) { 6631 if (index === requestIndex) { 6632 that.__response(content); 6633 } 6634 6635 that.pending--; 6636 if (!that.pending) { 6637 that.element.removeClass("ui-autocomplete-loading"); 6638 } 6639 }; 6640 }, 6641 6642 __response: function (content) { 6643 if (content) { 6644 content = this._normalize(content); 6645 } 6646 this._trigger("response", null, { content: content }); 6647 if (!this.options.disabled && content && content.length && !this.cancelSearch) { 6648 this._suggest(content); 6649 this._trigger("open"); 6650 } else { 6651 // use ._close() instead of .close() so we don't cancel future searches 6652 this._close(); 6653 } 6654 }, 6655 6656 close: function (event) { 6657 this.cancelSearch = true; 6658 this._close(event); 6659 }, 6660 6661 _close: function (event) { 6662 if (this.menu.element.is(":visible")) { 6663 this.menu.element.hide(); 6664 this.menu.blur(); 6665 this.isNewMenu = true; 6666 this._trigger("close", event); 6667 } 6668 }, 6669 6670 _change: function (event) { 6671 if (this.previous !== this._value()) { 6672 this._trigger("change", event, { item: this.selectedItem }); 6673 } 6674 }, 6675 6676 _normalize: function (items) { 6677 // assume all items have the right format when the first item is complete 6678 if (items.length && items[0].label && items[0].value) { 6679 return items; 6680 } 6681 return $.map(items, function (item) { 6682 if (typeof item === "string") { 6683 return { 6684 label: item, 6685 value: item 6686 }; 6687 } 6688 return $.extend({ 6689 label: item.label || item.value, 6690 value: item.value || item.label 6691 }, item); 6692 }); 6693 }, 6694 6695 _suggest: function (items) { 6696 var ul = this.menu.element 6697 .empty() 6698 .zIndex(this.element.zIndex() + 1); 6699 this._renderMenu(ul, items); 6700 this.menu.refresh(); 6701 6702 // size and position menu 6703 ul.show(); 6704 this._resizeMenu(); 6705 ul.position($.extend({ 6706 of: this.element 6707 }, this.options.position)); 6708 6709 if (this.options.autoFocus) { 6710 this.menu.next(); 6711 } 6712 }, 6713 6714 _resizeMenu: function () { 6715 var ul = this.menu.element; 6716 ul.outerWidth(Math.max( 6717 // Firefox wraps long text (possibly a rounding bug) 6718 // so we add 1px to avoid the wrapping (#7513) 6719 ul.width("").outerWidth() + 1, 6720 this.element.outerWidth() 6721 )); 6722 }, 6723 6724 _renderMenu: function (ul, items) { 6725 var that = this; 6726 $.each(items, function (index, item) { 6727 that._renderItemData(ul, item); 6728 }); 6729 }, 6730 6731 _renderItemData: function (ul, item) { 6732 return this._renderItem(ul, item).data("ui-autocomplete-item", item); 6733 }, 6734 6735 _renderItem: function (ul, item) { 6736 return $("<li>") 6737 .append($("<a>").text(item.label)) 6738 .appendTo(ul); 6739 }, 6740 6741 _move: function (direction, event) { 6742 if (!this.menu.element.is(":visible")) { 6743 this.search(null, event); 6744 return; 6745 } 6746 if (this.menu.isFirstItem() && /^previous/.test(direction) || 6747 this.menu.isLastItem() && /^next/.test(direction)) { 6748 this._value(this.term); 6749 this.menu.blur(); 6750 return; 6751 } 6752 this.menu[direction](event); 6753 }, 6754 6755 widget: function () { 6756 return this.menu.element; 6757 }, 6758 6759 _value: function () { 6760 return this.valueMethod.apply(this.element, arguments); 6761 }, 6762 6763 _keyEvent: function (keyEvent, event) { 6764 if (!this.isMultiLine || this.menu.element.is(":visible")) { 6765 this._move(keyEvent, event); 6766 6767 // prevents moving cursor to beginning/end of the text field in some browsers 6768 event.preventDefault(); 6769 } 6770 } 6771 });
vendor: 14,920 bytes, lines 6772-7134
6772 6773 $.extend($.ui.autocomplete, { 6774 escapeRegex: function (value) { 6775 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 6776 }, 6777 filter: function (array, term) { 6778 var matcher = new RegExp($.ui.autocomplete.escapeRegex(term), "i"); 6779 return $.grep(array, function (value) { 6780 return matcher.test(value.label || value.value || value); 6781 }); 6782 } 6783 }); 6784 6785 6786 // live region extension, adding a `messages` option 6787 // NOTE: This is an experimental API. We are still investigating 6788 // a full solution for string manipulation and internationalization. 6789 $.widget("ui.autocomplete", $.ui.autocomplete, { 6790 options: { 6791 messages: { 6792 noResults: "No search results.", 6793 results: function (amount) { 6794 return amount + (amount > 1 ? " results are" : " result is") + 6795 " available, use up and down arrow keys to navigate."; 6796 } 6797 } 6798 }, 6799 6800 __response: function (content) { 6801 var message; 6802 this._superApply(arguments); 6803 if (this.options.disabled || this.cancelSearch) { 6804 return; 6805 } 6806 if (content && content.length) { 6807 message = this.options.messages.results(content.length); 6808 } else { 6809 message = this.options.messages.noResults; 6810 } 6811 this.liveRegion.text(message); 6812 } 6813 }); 6814 6815 6816}(jQuery)); 6817 6818(function ($, undefined) { 6819 6820 var lastActive, startXPos, startYPos, clickDragged, 6821 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 6822 stateClasses = "ui-state-hover ui-state-active ", 6823 typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", 6824 formResetHandler = function () { 6825 var buttons = $(this).find(":ui-button"); 6826 setTimeout(function () { 6827 buttons.button("refresh"); 6828 }, 1); 6829 }, 6830 radioGroup = function (radio) { 6831 var name = radio.name, 6832 form = radio.form, 6833 radios = $([]); 6834 if (name) { 6835 if (form) { 6836 radios = $(form).find("[name='" + name + "']"); 6837 } else { 6838 radios = $("[name='" + name + "']", radio.ownerDocument) 6839 .filter(function () { 6840 return !this.form; 6841 }); 6842 } 6843 } 6844 return radios; 6845 }; 6846 6847 $.widget("ui.button", { 6848 version: "1.9.2", 6849 defaultElement: "<button>", 6850 options: { 6851 disabled: null, 6852 text: true, 6853 label: null, 6854 icons: { 6855 primary: null, 6856 secondary: null 6857 } 6858 }, 6859 _create: function () { 6860 this.element.closest("form") 6861 .unbind("reset" + this.eventNamespace) 6862 .bind("reset" + this.eventNamespace, formResetHandler); 6863 6864 if (typeof this.options.disabled !== "boolean") { 6865 this.options.disabled = !!this.element.prop("disabled"); 6866 } else { 6867 this.element.prop("disabled", this.options.disabled); 6868 } 6869 6870 this._determineButtonType(); 6871 this.hasTitle = !!this.buttonElement.attr("title"); 6872 6873 var that = this, 6874 options = this.options, 6875 toggleButton = this.type === "checkbox" || this.type === "radio", 6876 activeClass = !toggleButton ? "ui-state-active" : "", 6877 focusClass = "ui-state-focus"; 6878 6879 if (options.label === null) { 6880 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 6881 } 6882 6883 this._hoverable(this.buttonElement); 6884 6885 this.buttonElement 6886 .addClass(baseClasses) 6887 .attr("role", "button") 6888 .bind("mouseenter" + this.eventNamespace, function () { 6889 if (options.disabled) { 6890 return; 6891 } 6892 if (this === lastActive) { 6893 $(this).addClass("ui-state-active"); 6894 } 6895 }) 6896 .bind("mouseleave" + this.eventNamespace, function () { 6897 if (options.disabled) { 6898 return; 6899 } 6900 $(this).removeClass(activeClass); 6901 }) 6902 .bind("click" + this.eventNamespace, function (event) { 6903 if (options.disabled) { 6904 event.preventDefault(); 6905 event.stopImmediatePropagation(); 6906 } 6907 }); 6908 6909 this.element 6910 .bind("focus" + this.eventNamespace, function () { 6911 // no need to check disabled, focus won't be triggered anyway 6912 that.buttonElement.addClass(focusClass); 6913 }) 6914 .bind("blur" + this.eventNamespace, function () { 6915 that.buttonElement.removeClass(focusClass); 6916 }); 6917 6918 if (toggleButton) { 6919 this.element.bind("change" + this.eventNamespace, function () { 6920 if (clickDragged) { 6921 return; 6922 } 6923 that.refresh(); 6924 }); 6925 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 6926 // prevents issue where button state changes but checkbox/radio checked state 6927 // does not in Firefox (see ticket #6970) 6928 this.buttonElement 6929 .bind("mousedown" + this.eventNamespace, function (event) { 6930 if (options.disabled) { 6931 return; 6932 } 6933 clickDragged = false; 6934 startXPos = event.pageX; 6935 startYPos = event.pageY; 6936 }) 6937 .bind("mouseup" + this.eventNamespace, function (event) { 6938 if (options.disabled) { 6939 return; 6940 } 6941 if (startXPos !== event.pageX || startYPos !== event.pageY) { 6942 clickDragged = true; 6943 } 6944 }); 6945 } 6946 6947 if (this.type === "checkbox") { 6948 this.buttonElement.bind("click" + this.eventNamespace, function () { 6949 if (options.disabled || clickDragged) { 6950 return false; 6951 } 6952 $(this).toggleClass("ui-state-active"); 6953 that.buttonElement.attr("aria-pressed", that.element[0].checked); 6954 }); 6955 } else if (this.type === "radio") { 6956 this.buttonElement.bind("click" + this.eventNamespace, function () { 6957 if (options.disabled || clickDragged) { 6958 return false; 6959 } 6960 $(this).addClass("ui-state-active"); 6961 that.buttonElement.attr("aria-pressed", "true"); 6962 6963 var radio = that.element[0]; 6964 radioGroup(radio) 6965 .not(radio) 6966 .map(function () { 6967 return $(this).button("widget")[0]; 6968 }) 6969 .removeClass("ui-state-active") 6970 .attr("aria-pressed", "false"); 6971 }); 6972 } else { 6973 this.buttonElement 6974 .bind("mousedown" + this.eventNamespace, function () { 6975 if (options.disabled) { 6976 return false; 6977 } 6978 $(this).addClass("ui-state-active"); 6979 lastActive = this; 6980 that.document.one("mouseup", function () { 6981 lastActive = null; 6982 }); 6983 }) 6984 .bind("mouseup" + this.eventNamespace, function () { 6985 if (options.disabled) { 6986 return false; 6987 } 6988 $(this).removeClass("ui-state-active"); 6989 }) 6990 .bind("keydown" + this.eventNamespace, function (event) { 6991 if (options.disabled) { 6992 return false; 6993 } 6994 if (event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER) { 6995 $(this).addClass("ui-state-active"); 6996 } 6997 }) 6998 .bind("keyup" + this.eventNamespace, function () { 6999 $(this).removeClass("ui-state-active"); 7000 }); 7001 7002 if (this.buttonElement.is("a")) { 7003 this.buttonElement.keyup(function (event) { 7004 if (event.keyCode === $.ui.keyCode.SPACE) { 7005 // TODO pass through original event correctly (just as 2nd argument doesn't work) 7006 $(this).click(); 7007 } 7008 }); 7009 } 7010 } 7011 7012 // TODO: pull out $.Widget's handling for the disabled option into 7013 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 7014 // be overridden by individual plugins 7015 this._setOption("disabled", options.disabled); 7016 this._resetButton(); 7017 }, 7018 7019 _determineButtonType: function () { 7020 var ancestor, labelSelector, checked; 7021 7022 if (this.element.is("[type=checkbox]")) { 7023 this.type = "checkbox"; 7024 } else if (this.element.is("[type=radio]")) { 7025 this.type = "radio"; 7026 } else if (this.element.is("input")) { 7027 this.type = "input"; 7028 } else { 7029 this.type = "button"; 7030 } 7031 7032 if (this.type === "checkbox" || this.type === "radio") { 7033 // we don't search against the document in case the element 7034 // is disconnected from the DOM 7035 ancestor = this.element.parents().last(); 7036 labelSelector = "label[for='" + this.element.attr("id") + "']"; 7037 this.buttonElement = ancestor.find(labelSelector); 7038 if (!this.buttonElement.length) { 7039 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 7040 this.buttonElement = ancestor.filter(labelSelector); 7041 if (!this.buttonElement.length) { 7042 this.buttonElement = ancestor.find(labelSelector); 7043 } 7044 } 7045 this.element.addClass("ui-helper-hidden-accessible"); 7046 7047 checked = this.element.is(":checked"); 7048 if (checked) { 7049 this.buttonElement.addClass("ui-state-active"); 7050 } 7051 this.buttonElement.prop("aria-pressed", checked); 7052 } else { 7053 this.buttonElement = this.element; 7054 } 7055 }, 7056 7057 widget: function () { 7058 return this.buttonElement; 7059 }, 7060 7061 _destroy: function () { 7062 this.element 7063 .removeClass("ui-helper-hidden-accessible"); 7064 this.buttonElement 7065 .removeClass(baseClasses + " " + stateClasses + " " + typeClasses) 7066 .removeAttr("role") 7067 .removeAttr("aria-pressed") 7068 .html(this.buttonElement.find(".ui-button-text").html()); 7069 7070 if (!this.hasTitle) { 7071 this.buttonElement.removeAttr("title"); 7072 } 7073 }, 7074 7075 _setOption: function (key, value) { 7076 this._super(key, value); 7077 if (key === "disabled") { 7078 if (value) { 7079 this.element.prop("disabled", true); 7080 } else { 7081 this.element.prop("disabled", false); 7082 } 7083 return; 7084 } 7085 this._resetButton(); 7086 }, 7087 7088 refresh: function () { 7089 //See #8237 & #8828 7090 var isDisabled = this.element.is("input, button") ? this.element.is(":disabled") : this.element.hasClass("ui-button-disabled"); 7091 7092 if (isDisabled !== this.options.disabled) { 7093 this._setOption("disabled", isDisabled); 7094 } 7095 if (this.type === "radio") { 7096 radioGroup(this.element[0]).each(function () { 7097 if ($(this).is(":checked")) { 7098 $(this).button("widget") 7099 .addClass("ui-state-active") 7100 .attr("aria-pressed", "true"); 7101 } else { 7102 $(this).button("widget") 7103 .removeClass("ui-state-active") 7104 .attr("aria-pressed", "false"); 7105 } 7106 }); 7107 } else if (this.type === "checkbox") { 7108 if (this.element.is(":checked")) { 7109 this.buttonElement 7110 .addClass("ui-state-active") 7111 .attr("aria-pressed", "true"); 7112 } else { 7113 this.buttonElement 7114 .removeClass("ui-state-active") 7115 .attr("aria-pressed", "false"); 7116 } 7117 } 7118 }, 7119 7120 _resetButton: function () { 7121 if (this.type === "input") { 7122 if (this.options.label) { 7123 this.element.val(this.options.label); 7124 } 7125 return; 7126 } 7127 var buttonElement = this.buttonElement.removeClass(typeClasses), 7128 buttonText = $("<span></span>", this.document[0]) 7129 .addClass("ui-button-text") 7130 .html(this.options.label) 7131 .appendTo(buttonElement.empty()) 7132 .text(), 7133 icons = this.options.icons, 7134 multipleIcons = icons.primary && icons.secondary,
vendor: 6,732 bytes, lines 7135-7273
7135 buttonClasses = []; 7136 7137 if (icons.primary || icons.secondary) { 7138 if (this.options.text) { 7139 buttonClasses.push("ui-button-text-icon" + (multipleIcons ? "s" : (icons.primary ? "-primary" : "-secondary"))); 7140 } 7141 7142 if (icons.primary) { 7143 buttonElement.prepend("<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>"); 7144 } 7145 7146 if (icons.secondary) { 7147 buttonElement.append("<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>"); 7148 } 7149 7150 if (!this.options.text) { 7151 buttonClasses.push(multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only"); 7152 7153 if (!this.hasTitle) { 7154 buttonElement.attr("title", $.trim(buttonText)); 7155 } 7156 } 7157 } else { 7158 buttonClasses.push("ui-button-text-only"); 7159 } 7160 buttonElement.addClass(buttonClasses.join(" ")); 7161 } 7162 }); 7163 7164 $.widget("ui.buttonset", { 7165 version: "1.9.2", 7166 options: { 7167 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)" 7168 }, 7169 7170 _create: function () { 7171 this.element.addClass("ui-buttonset"); 7172 }, 7173 7174 _init: function () { 7175 this.refresh(); 7176 }, 7177 7178 _setOption: function (key, value) { 7179 if (key === "disabled") { 7180 this.buttons.button("option", key, value); 7181 } 7182 7183 this._super(key, value); 7184 }, 7185 7186 refresh: function () { 7187 var rtl = this.element.css("direction") === "rtl"; 7188 7189 this.buttons = this.element.find(this.options.items) 7190 .filter(":ui-button") 7191 .button("refresh") 7192 .end() 7193 .not(":ui-button") 7194 .button() 7195 .end() 7196 .map(function () { 7197 return $(this).button("widget")[0]; 7198 }) 7199 .removeClass("ui-corner-all ui-corner-left ui-corner-right") 7200 .filter(":first") 7201 .addClass(rtl ? "ui-corner-right" : "ui-corner-left") 7202 .end() 7203 .filter(":last") 7204 .addClass(rtl ? "ui-corner-left" : "ui-corner-right") 7205 .end() 7206 .end(); 7207 }, 7208 7209 _destroy: function () { 7210 this.element.removeClass("ui-buttonset"); 7211 this.buttons 7212 .map(function () { 7213 return $(this).button("widget")[0]; 7214 }) 7215 .removeClass("ui-corner-left ui-corner-right") 7216 .end() 7217 .button("destroy"); 7218 } 7219 }); 7220 7221}(jQuery)); 7222 7223(function ($, undefined) { 7224 7225 $.extend($.ui, { datepicker: { version: "1.9.2" } }); 7226 7227 var PROP_NAME = 'datepicker'; 7228 var dpuuid = new Date().getTime(); 7229 var instActive; 7230 7231 /* Date picker manager. 7232 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7233 Settings for (groups of) date pickers are maintained in an instance object, 7234 allowing multiple different settings on the same page. */ 7235 7236 function Datepicker() { 7237 this.debug = false; // Change this to true to start debugging 7238 this._curInst = null; // The current instance in use 7239 this._keyEvent = false; // If the last event was a key event 7240 this._disabledInputs = []; // List of date picker inputs that have been disabled 7241 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7242 this._inDialog = false; // True if showing within a "dialog", false if not 7243 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division 7244 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class 7245 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class 7246 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class 7247 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class 7248 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class 7249 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class 7250 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class 7251 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class 7252 this.regional = []; // Available regional settings, indexed by language code 7253 this.regional[''] = { // Default regional settings 7254 closeText: 'Done', // Display text for close link 7255 prevText: 'Prev', // Display text for previous month link 7256 nextText: 'Next', // Display text for next month link 7257 currentText: 'Today', // Display text for current month link 7258 monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 7259 'July', 'August', 'September', 'October', 'November', 'December'], // Names of months for drop-down and formatting 7260 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting 7261 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting 7262 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting 7263 dayNamesMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], // Column headings for days starting at Sunday 7264 weekHeader: 'Wk', // Column header for week of the year 7265 dateFormat: 'mm/dd/yy', // See format options on parseDate 7266 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7267 isRTL: false, // True if right-to-left language, false if left-to-right 7268 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7269 yearSuffix: '' // Additional text to append to the year in the month headers 7270 }; 7271 this._defaults = { // Global defaults for all the date picker instances 7272 showOn: 'focus', // 'focus' for popup on focus, 7273 // 'button' for trigger button, or 'both' for either
7274 showAnim: 'fadeIn', // Name of jQuery animation for popup 7275 showOptions: {}, // Options for enhanced animations 7276 defaultDate: null, // Used when field is blank: actual date, 7277 // +/-number for offset from today, null for today 7278 appendText: '', // Display text following the input box, e.g. showing the format 7279 buttonText: '...', // Text for trigger button 7280 buttonImage: '', // URL for trigger button image 7281 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7282 hideIfNoPrevNext: false, // True to hide next/previous month links 7283 // if not applicable, false to just disable them 7284 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7285 gotoCurrent: false, // True if today link goes back to current selection instead 7286 changeMonth: false, // True if month can be selected directly, false if only prev/next 7287 changeYear: false, // True if year can be selected directly, false if only prev/next 7288 yearRange: 'c-10:c+10', // Range of years to display in drop-down, 7289 // either relative to today's year (-nn:+nn), relative to currently displayed year 7290 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7291 showOtherMonths: false, // True to show dates in other months, false to leave blank 7292 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7293 showWeek: false, // True to show week of the year, false to not show it 7294 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7295 // takes a Date and returns the number of the week for it 7296 shortYearCutoff: '+10', // Short year values < this are in the current century, 7297 // > this are in the previous century, 7298 // string value starting with '+' for current year + value 7299 minDate: null, // The earliest selectable date, or null for no limit 7300 maxDate: null, // The latest selectable date, or null for no limit 7301 duration: 'fast', // Duration of display/closure 7302 beforeShowDay: null, // Function that takes a date and returns an array with 7303 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', 7304 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7305 beforeShow: null, // Function that takes an input field and 7306 // returns a set of custom settings for the date picker 7307 onSelect: null, // Define a callback function when a date is selected 7308 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7309 onClose: null, // Define a callback function when the datepicker is closed 7310 numberOfMonths: 1, // Number of months to show at a time 7311 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7312 stepMonths: 1, // Number of months to step back/forward 7313 stepBigMonths: 12, // Number of months to step back/forward for the big links 7314 altField: '', // Selector for an alternate field to store selected dates into 7315 altFormat: '', // The date format to use for the alternate field 7316 constrainInput: true, // The input is constrained by the current date format 7317 showButtonPanel: false, // True to show button panel, false to not show it 7318 autoSize: false, // True to size the input for the date format, false to leave as is 7319 disabled: false // The initial disabled state 7320 }; 7321 $.extend(this._defaults, this.regional['']); 7322 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')); 7323 } 7324 7325 $.extend(Datepicker.prototype, { 7326 /* Class name added to elements to indicate already configured with a date picker. */ 7327 markerClassName: 'hasDatepicker', 7328 7329 //Keep track of the maximum number of rows displayed (see #7043) 7330 maxRows: 4, 7331 7332 /* Debug logging (if enabled). */ 7333 log: function () { 7334 if (this.debug) 7335 console.log.apply('', arguments); 7336 }, 7337 7338 // TODO rename to "widget" when switching to widget factory 7339 _widgetDatepicker: function () { 7340 return this.dpDiv; 7341 }, 7342 7343 /* Override the default settings for all instances of the date picker. 7344 @param settings object - the new settings to use as defaults (anonymous object) 7345 @return the manager object */ 7346 setDefaults: function (settings) { 7347 extendRemove(this._defaults, settings || {}); 7348 return this; 7349 }, 7350 7351 /* Attach the date picker to a jQuery selection. 7352 @param target element - the target input field or division or span 7353 @param settings object - the new settings to use for this date picker instance (anonymous) */ 7354 _attachDatepicker: function (target, settings) { 7355 // check for settings on the control itself - in namespace 'date:' 7356 var inlineSettings = null; 7357 for (var attrName in this._defaults) { 7358 var attrValue = target.getAttribute('date:' + attrName); 7359 if (attrValue) { 7360 inlineSettings = inlineSettings || {}; 7361 try { 7362 inlineSettings[attrName] = eval(attrValue); 7363 } catch (err) { 7364 inlineSettings[attrName] = attrValue; 7365 } 7366 } 7367 } 7368 var nodeName = target.nodeName.toLowerCase(); 7369 var inline = (nodeName == 'div' || nodeName == 'span'); 7370 if (!target.id) { 7371 this.uuid += 1; 7372 target.id = 'dp' + this.uuid; 7373 } 7374 var inst = this._newInst($(target), inline); 7375 inst.settings = $.extend({}, settings || {}, inlineSettings || {}); 7376 if (nodeName == 'input') { 7377 this._connectDatepicker(target, inst); 7378 } else if (inline) { 7379 this._inlineDatepicker(target, inst); 7380 } 7381 }, 7382 7383 /* Create a new instance object. */ 7384 _newInst: function (target, inline) { 7385 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars 7386 return { 7387 id: id, input: target, // associated target 7388 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 7389 drawMonth: 0, drawYear: 0, // month being drawn 7390 inline: inline, // is datepicker inline or not 7391 dpDiv: (!inline ? this.dpDiv : // presentation div 7392 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))) 7393 }; 7394 }, 7395 7396 /* Attach the date picker to an input field. */ 7397 _connectDatepicker: function (target, inst) { 7398 var input = $(target);
7399 inst.append = $([]); 7400 inst.trigger = $([]); 7401 if (input.hasClass(this.markerClassName)) 7402 return; 7403 this._attachments(input, inst); 7404 input.addClass(this.markerClassName).keydown(this._doKeyDown). 7405 keypress(this._doKeyPress).keyup(this._doKeyUp). 7406 bind("setData.datepicker", function (event, key, value) { 7407 inst.settings[key] = value; 7408 }).bind("getData.datepicker", function (event, key) { 7409 return this._get(inst, key); 7410 }); 7411 this._autoSize(inst); 7412 $.data(target, PROP_NAME, inst); 7413 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 7414 if (inst.settings.disabled) { 7415 this._disableDatepicker(target); 7416 } 7417 }, 7418 7419 /* Make attachments based on settings. */ 7420 _attachments: function (input, inst) { 7421 var appendText = this._get(inst, 'appendText'); 7422 var isRTL = this._get(inst, 'isRTL'); 7423 if (inst.append)
7424 inst.append.remove(); 7425 if (appendText) { 7426 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>'); 7427 input[isRTL ? 'before' : 'after'](inst.append); 7428 } 7429 input.unbind('focus', this._showDatepicker); 7430 if (inst.trigger) 7431 inst.trigger.remove(); 7432 var showOn = this._get(inst, 'showOn'); 7433 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field 7434 input.focus(this._showDatepicker); 7435 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked 7436 var buttonText = this._get(inst, 'buttonText'); 7437 var buttonImage = this._get(inst, 'buttonImage'); 7438 inst.trigger = $(this._get(inst, 'buttonImageOnly') ? 7439 $('<img/>').addClass(this._triggerClass). 7440 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 7441 $('<button type="button"></button>').addClass(this._triggerClass). 7442 html(buttonImage == '' ? buttonText : $('<img/>').attr( 7443 { src: buttonImage, alt: buttonText, title: buttonText }))); 7444 input[isRTL ? 'before' : 'after'](inst.trigger); 7445 inst.trigger.click(function () { 7446 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) 7447 $.datepicker._hideDatepicker(); 7448 else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) { 7449 $.datepicker._hideDatepicker(); 7450 $.datepicker._showDatepicker(input[0]); 7451 } else 7452 $.datepicker._showDatepicker(input[0]); 7453 return false; 7454 }); 7455 } 7456 }, 7457 7458 /* Apply the maximum length for the date format. */ 7459 _autoSize: function (inst) { 7460 if (this._get(inst, 'autoSize') && !inst.inline) { 7461 var date = new Date(2009, 12 - 1, 20); // Ensure double digits 7462 var dateFormat = this._get(inst, 'dateFormat'); 7463 if (dateFormat.match(/[DM]/)) { 7464 var findMax = function (names) { 7465 var max = 0; 7466 var maxI = 0; 7467 for (var i = 0; i < names.length; i++) { 7468 if (names[i].length > max) { 7469 max = names[i].length; 7470 maxI = i; 7471 } 7472 } 7473 return maxI; 7474 }; 7475 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7476 'monthNames' : 'monthNamesShort')))); 7477 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7478 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay()); 7479 } 7480 inst.input.attr('size', this._formatDate(inst, date).length); 7481 } 7482 }, 7483 7484 /* Attach an inline date picker to a div. */ 7485 _inlineDatepicker: function (target, inst) { 7486 var divSpan = $(target); 7487 if (divSpan.hasClass(this.markerClassName)) 7488 return; 7489 divSpan.addClass(this.markerClassName).append(inst.dpDiv). 7490 bind("setData.datepicker", function (event, key, value) { 7491 inst.settings[key] = value; 7492 }).bind("getData.datepicker", function (event, key) { 7493 return this._get(inst, key); 7494 }); 7495 $.data(target, PROP_NAME, inst); 7496 this._setDate(inst, this._getDefaultDate(inst), true); 7497 this._updateDatepicker(inst); 7498 this._updateAlternate(inst); 7499 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7500 if (inst.settings.disabled) { 7501 this._disableDatepicker(target); 7502 } 7503 // Set display:block in place of inst.dpDiv.show() which w
vendor: 3,457 bytes, lines 7503-7566
7503on't work on disconnected elements 7504 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7505 inst.dpDiv.css("display", "block"); 7506 }, 7507 7508 /* Pop-up the date picker in a "dialog" box. 7509 @param input element - ignored 7510 @param date string or Date - the initial date to display 7511 @param onSelect function - the function to call when a date is selected 7512 @param settings object - update the dialog date picker instance's settings (anonymous object) 7513 @param pos int[2] - coordinates for the dialog's position within the screen or 7514 event - with x/y coordinates or 7515 leave empty for default (screen centre) 7516 @return the manager object */ 7517 _dialogDatepicker: function (input, date, onSelect, settings, pos) { 7518 var inst = this._dialogInst; // internal instance 7519 if (!inst) { 7520 this.uuid += 1; 7521 var id = 'dp' + this.uuid; 7522 this._dialogInput = $('<input type="text" id="' + id + 7523 '" style="position: absolute; top: -100px; width: 0px;"/>'); 7524 this._dialogInput.keydown(this._doKeyDown); 7525 $('body').append(this._dialogInput); 7526 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7527 inst.settings = {}; 7528 $.data(this._dialogInput[0], PROP_NAME, inst); 7529 } 7530 extendRemove(inst.settings, settings || {}); 7531 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date); 7532 this._dialogInput.val(date); 7533 7534 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7535 if (!this._pos) { 7536 var browserWidth = document.documentElement.clientWidth; 7537 var browserHeight = document.documentElement.clientHeight; 7538 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7539 var scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7540 this._pos = // should use actual width/height below 7541 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7542 } 7543 7544 // move input on screen for focus, but hidden behind dialog 7545 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px'); 7546 inst.settings.onSelect = onSelect; 7547 this._inDialog = true; 7548 this.dpDiv.addClass(this._dialogClass); 7549 this._showDatepicker(this._dialogInput[0]); 7550 if ($.blockUI) 7551 $.blockUI(this.dpDiv); 7552 $.data(this._dialogInput[0], PROP_NAME, inst); 7553 return this; 7554 }, 7555 7556 /* Detach a datepicker from its control. 7557 @param target element - the target input field or division or span */ 7558 _destroyDatepicker: function (target) { 7559 var $target = $(target); 7560 var inst = $.data(target, PROP_NAME); 7561 if (!$target.hasClass(this.markerClassName)) { 7562 return; 7563 } 7564 var nodeName = target.nodeName.toLowerCase(); 7565 $.removeData(target, PROP_NAME); 7566 if (nodeName == 'input') {
7567 inst.append.remove(); 7568 inst.trigger.remove(); 7569 $target.removeClass(this.markerClassName). 7570 unbind('focus', this._showDatepicker). 7571 unbind('keydown', this._doKeyDown). 7572 unbind('keypress', this._doKeyPress). 7573 unbind('keyup', this._doKeyUp); 7574 } else if (nodeName == 'div' || nodeName == 'span') 7575 $target.removeClass(this.markerClassName).empty(); 7576 }, 7577 7578 /* Enable the date picker to a jQuery selection. 7579 @param target element - the target input field or division or span */ 7580 _enableDatepicker: function (target) { 7581 var $target = $(target); 7582 var inst = $.data(target, PROP_NAME); 7583 if (!$target.hasClass(this.markerClassName)) { 7584 return; 7585 } 7586 var nodeName = target.nodeName.toLowerCase(); 7587 if (nodeName == 'input') { 7588 target.disabled = false; 7589 inst.trigger.filter('button'). 7590 each(function () { this.disabled = false; }).end(). 7591 filter('img').css({ opacity: '1.0', cursor: '' }); 7592 } 7593 else if (nodeName == 'div' || nodeName == 'span') { 7594 var inline = $target.children('.' + this._inlineClass); 7595 inline.children().removeClass('ui-state-disabled'); 7596 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7597 prop("disabled", false); 7598 } 7599 this._disabledInputs = $.map(this._disabledInputs, 7600 function (value) { return (value == target ? null : value); }); // delete entry 7601 }, 7602 7603 /* Disable the date picker to a jQuery selection. 7604 @param target element - the target input field or division or span */ 7605 _disableDatepicker: function (target) { 7606 var $target = $(target); 7607 var inst = $.data(target, PROP_NAME); 7608 if (!$target.hasClass(this.markerClassName)) { 7609 return; 7610 } 7611 var nodeName = target.nodeName.toLowerCase(); 7612 if (nodeName == 'input') { 7613 target.disabled = true; 7614 inst.trigger.filter('button'). 7615 each(function () { this.disabled = true; }).end(). 7616 filter('img').css({ opacity: '0.5', cursor: 'default' }); 7617 } 7618 else if (nodeName == 'div' || nodeName == 'span') { 7619 var inline = $target.children('.' + this._inlineClass); 7620 inline.children().addClass('ui-state-disabled'); 7621 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7622 prop("disabled", true); 7623 } 7624 this._disabledInputs = $.map(this._disabledInputs, 7625 function (value) { return (value == target ? null : value); }); // delete entry 7626 this._disabledInputs[this._disabledInputs.length] = target; 7627 }, 7628 7629 /* Is the first field in a jQuery collection disabled as a datepicker? 7630 @param target element - the target input field or division or span 7631 @return boolean - true if disabled, false if enabled */ 7632 _isDisabledDatepicker: function (target) { 7633 if (!target) { 7634 return false; 7635 } 7636 for (var i = 0; i < this._disabledInputs.length; i++) { 7637 if (this._disabledInputs[i] == target) 7638 return true; 7639 } 7640 return false; 7641 }, 7642 7643 /* Retrieve the instance data for the target control. 7644 @param target element - the target input field or division or span 7645 @return object - the associated instance data 7646 @throws error if a jQuery problem getting data */ 7647 _getInst: function (target) { 7648 try { 7649 return $.data(target, PROP_NAME); 7650 } 7651 catch (err) { 7652 throw 'Missing instance data for this datepicker'; 7653 } 7654 }, 7655
7656 /* Update or retrieve the settings for a date picker attached to an input field or division. 7657 @param target element - the target input field or division or span 7658 @param name object - the new settings to update or 7659 string - the name of the setting to change or retrieve, 7660 when retrieving also 'all' for all instance settings or 7661 'defaults' for all global defaults 7662 @param value any - the new value for the setting 7663 (omit if above is an object or to retrieve a value) */ 7664 _optionDatepicker: function (target, name, value) { 7665 var inst = this._getInst(target); 7666 if (arguments.length == 2 && typeof name == 'string') { 7667 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) : 7668 (inst ? (name == 'all' ? $.extend({}, inst.settings) : 7669 this._get(inst, name)) : null)); 7670 } 7671 var settings = name || {}; 7672 if (typeof name == 'string') { 7673 settings = {}; 7674 settings[name] = value; 7675 } 7676 if (inst) { 7677 if (this._curInst == inst) { 7678 this._hideDatepicker(); 7679 } 7680 var date = this._getDateDatepicker(target, true); 7681 var minDate = this._getMinMaxDate(inst, 'min'); 7682 var maxDate = this._getMinMaxDate(inst, 'max'); 7683 extendRemove(inst.settings, settings); 7684 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 7685 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined) 7686 inst.settings.minDate = this._formatDate(inst, minDate); 7687 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined) 7688 inst.settings.maxDate = this._formatDate(inst, maxDate); 7689 this._attachments($(target), inst); 7690 this._autoSize(inst); 7691 this._setDate(inst, date); 7692 this._updateAlternate(inst); 7693 this._updateDatepicker(inst); 7694 } 7695 }, 7696 7697 // change method deprecated 7698 _changeDatepicker: function (target, name, value) { 7699 this._optionDatepicker(target, name, value); 7700 }, 7701 7702 /* Redraw the date picker attached to an input field or division. 7703 @param target element - the target input field or division or span */ 7704 _refreshDatepicker: function (target) { 7705 var inst = this._getInst(target); 7706 if (inst) { 7707 this._updateDatepicker(inst); 7708 } 7709 }, 7710 7711 /* Set the dates for a jQuery selection. 7712 @param target element - the target input field or division or span 7713 @param date Date - the new date */ 7714 _setDateDatepicker: function (target, date) { 7715 var inst = this._getInst(target); 7716 if (inst) { 7717 this._setDate(inst, date); 7718 this._updateDatepicker(inst); 7719 this._updateAlternate(inst); 7720 } 7721 }, 7722 7723 /* Get the date(s) for the first entry in a jQuery selection. 7724 @param target element - the target input field or division or span 7725 @param noDefault boolean - true if no default date is to be used 7726 @return Date - the current date */ 7727 _getDateDatepicker: function (target, noDefault) { 7728 var inst = this._getInst(target); 7729 if (inst && !inst.inline) 7730 this._setDateFromField(inst, noDefault); 7731 return (inst ? this._getDate(inst) : null); 7732 }, 7733 7734 /* Handle keystrokes. */ 7735 _doKeyDown: function (event) { 7736 var inst = $.datepicker._getInst(event.target); 7737 var handled = true; 7738 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); 7739 inst._keyEvent = true; 7740 if ($.datepicker._datepickerShowing) 7741 switch (event.keyCode) { 7742 case 9: $.datepicker._hideDatepicker(); 7743 handled = false; 7744 break; // hide on tab out 7745 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 7746 $.datepicker._currentClass + ')', inst.dpDiv); 7747 if (sel[0]) 7748 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 7749 var onSelect = $.datepicker._get(inst, 'onSelect'); 7750 if (onSelect) { 7751 var dateStr = $.datepicker._formatDate(inst); 7752 7753 // trigger custom callback 7754 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 7755 } 7756 else 7757 $.datepicker._hideDatepicker(); 7758 return false; // don't submit the form 7759 break; // select the value on enter 7760 case 27: $.datepicker._hideDatepicker(); 7761 break; // hide on escape 7762 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7763 -$.datepicker._get(inst, 'stepBigMonths') : 7764 -$.datepicker._get(inst, 'stepMonths')), 'M'); 7765 break; // previous month/year on page up/+ ctrl 7766 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7767 +$.datepicker._get(inst, 'stepBigMonths') : 7768 +$.datepicker._get(inst, 'stepMonths')), 'M'); 7769 break; // next month/year on page down/+ ctrl 7770 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); 7771 handled = event.ctrlKey || event.metaKey; 7772 break; // clear on ctrl or command +end 7773 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); 7774 handled = event.ctrlKey || event.metaKey; 7775 break; // current on ctrl or command +home 7776 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); 7777 handled = event.ctrlKey || event.metaKey; 7778 // -1 day on ctrl or command +left 7779 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7780 -$.datepicker._get(inst, 'stepBigMonths') : 7781 -$.datepicker._get(inst, 'stepMonths')), 'M'); 7782 // next month/year on alt +left on Mac 7783 break; 7784 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); 7785 handled = event.ctrlKey || event.metaKey; 7786 break; // -1 week on ctrl or command +up 7787 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); 7788 handled = event.ctrlKey || event.metaKey; 7789 // +1 day on ctrl or command +right 7790 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7791 +$.datepicker._get(inst, 'stepBigMonths') : 7792 +$.datepicker._get(inst, 'stepMonths')), 'M'); 7793 // next month/year on alt +right 7794 break; 7795 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); 7796 handled = event.ctrlKey || event.metaKey; 7797 break; // +1 week on ctrl or command +down 7798 default: handled = false; 7799 } 7800 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home 7801 $.datepicker._showDatepicker(this); 7802 else { 7803 handled = false; 7804 } 7805 if (handled) { 7806 event.preventDefault(); 7807 event.stopPropagation(); 7808 } 7809 }, 7810 7811 /* Filter entered characters - based on date format. */ 7812 _doKeyPress: function (event) { 7813 var inst = $.datepicker._getInst(event.target); 7814 if ($.datepicker._get(inst, 'constrainInput')) { 7815 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
7816 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); 7817 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); 7818 } 7819 }, 7820 7821 /* Synchronise manual entry and field/alternate field. */ 7822 _doKeyUp: function (event) { 7823 var inst = $.datepicker._getInst(event.target); 7824 if (inst.input.val() != inst.lastVal) { 7825 try { 7826 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 7827 (inst.input ? inst.input.val() : null), 7828 $.datepicker._getFormatConfig(inst)); 7829 if (date) { // only if valid 7830 $.datepicker._setDateFromField(inst); 7831 $.datepicker._updateAlternate(inst); 7832 $.datepicker._updateDatepicker(inst); 7833 } 7834 } 7835 catch (err) { 7836 $.datepicker.log(err); 7837 } 7838 } 7839 return true; 7840 }, 7841 7842 /* Pop-up the date picker for a given input field. 7843 If false returned from beforeShow event handler do not show. 7844 @param input element - the input field attached to the date picker or 7845 event - if triggered by focus */ 7846 _showDatepicker: function (input) { 7847 input = input.target || input; 7848 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger 7849 input = $('input', input.parentNode)[0]; 7850 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here 7851 return; 7852 var inst = $.datepicker._getInst(input); 7853 if ($.datepicker._curInst && $.datepicker._curInst != inst) { 7854 $.datepicker._curInst.dpDiv.stop(true, true); 7855 if (inst && $.datepicker._datepickerShowing) { 7856 $.datepicker._hideDatepicker($.datepicker._curInst.input[0]); 7857 } 7858 } 7859 var beforeShow = $.datepicker._get(inst, 'beforeShow'); 7860 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 7861 if (beforeShowSettings === false) { 7862 //false 7863 return; 7864 } 7865 extendRemove(inst.settings, beforeShowSettings); 7866 inst.lastVal = null; 7867 $.datepicker._lastInput = input; 7868 $.datepicker._setDateFromField(inst); 7869 if ($.datepicker._inDialog) // hide cursor 7870 input.value = ''; 7871 if (!$.datepicker._pos) { // position below input 7872 $.datepicker._pos = $.datepicker._findPos(input); 7873 $.datepicker._pos[1] += input.offsetHeight; // add the height 7874 } 7875 var isFixed = false; 7876 $(input).parents().each(function () { 7877 isFixed |= $(this).css('position') == 'fixed'; 7878 return !isFixed; 7879 }); 7880 var offset = { left: $.datepicker._pos[0], top: $.datepicker._pos[1] }; 7881 $.datepicker._pos = null; 7882 //to avoid flashes on Firefox 7883 inst.dpDiv.empty(); 7884 // determine sizing offscreen 7885 inst.dpDiv.css({ position: 'absolute', display: 'block', top: '-1000px' }); 7886 $.datepicker._updateDatepicker(inst); 7887 // fix width for dynamic number of date pickers 7888 // and adjust position before showing 7889 offset = $.datepicker._checkOffset(inst, offset, isFixed); 7890 inst.dpDiv.css({ 7891 position: ($.datepicker._inDialog && $.blockUI ? 7892 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', 7893 left: offset.left + 'px', top: offset.top + 'px' 7894 }); 7895 if (!inst.inline) { 7896 var showAnim = $.datepicker._get(inst, 'showAnim'); 7897 var duration = $.datepicker._get(inst, 'duration'); 7898 var postProcess = function () {
7899 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 7900 if (!!cover.length) { 7901 var borders = $.datepicker._getBorders(inst.dpDiv); 7902 cover.css({ 7903 left: -borders[0], top: -borders[1], 7904 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight() 7905 }); 7906 } 7907 }; 7908 inst.dpDiv.zIndex($(input).zIndex() + 1); 7909 $.datepicker._datepickerShowing = true; 7910 7911 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 7912 if ($.effects && ($.effects.effect[showAnim] || $.effects[showAnim])) 7913 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 7914 else 7915 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess); 7916 if (!showAnim || !duration) 7917 postProcess(); 7918 if (inst.input.is(':visible') && !inst.input.is(':disabled')) 7919 inst.input.focus(); 7920 $.datepicker._curInst = inst; 7921 } 7922 }, 7923 7924 /* Generate the date picker content. */ 7925 _updateDatepicker: function (inst) { 7926 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 7927 var borders = $.datepicker._getBorders(inst.dpDiv); 7928 instActive = inst; // for delegate hover events 7929 inst.dpDiv.empty().append(this._generateHTML(inst)); 7930 this._attachHandlers(inst); 7931 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 7932 if (!!cover.length) { //avoid call to outerXXXX() when not in IE6 7933 cover.css({ left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight() }) 7934 } 7935 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover(); 7936 var numMonths = this._getNumberOfMonths(inst); 7937 var cols = numMonths[1]; 7938 var width = 17; 7939 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); 7940 if (cols > 1) 7941 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); 7942 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + 7943 'Class']('ui-datepicker-multi'); 7944 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + 7945 'Class']('ui-datepicker-rtl'); 7946 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 7947 // #6694 - don't focus the input if it's already focused 7948 // this breaks the change event in IE 7949 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement) 7950 inst.input.focus(); 7951 // deffered render of the years select (to avoid flashes on Firefox) 7952 if (inst.yearshtml) { 7953 var origyearshtml = inst.yearshtml; 7954 setTimeout(function () { 7955 //assure that inst.yearshtml didn't change. 7956 if (origyearshtml === inst.yearshtml && inst.yearshtml) { 7957 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); 7958 } 7959 origyearshtml = inst.yearshtml = null; 7960 }, 0); 7961 } 7962 }, 7963 7964 /* Retrieve the size of left and top borders for an element. 7965 @param elem (jQuery object) the element of interest 7966 @return (number[2]) the left and top borders */ 7967 _getBorders: function (elem) { 7968 var convert = function (value) { 7969 return { thin: 1, medium: 2, thick: 3 }[value] || value; 7970 }; 7971 return [parseFloat(convert(elem.css('border-left-width'))), 7972 parseFloat(convert(elem.css('border-top-width')))]; 7973 }, 7974 7975 /* Check positioning to remain on screen. */ 7976 _checkOffset: function (inst, offset, isFixed) { 7977 var dpWidth = inst.dpDiv.outerWidth(); 7978 var dpHeight = inst.dpDiv.outerHeight();
7979 var inputWidth = inst.input ? inst.input.outerWidth() : 0; 7980 var inputHeight = inst.input ? inst.input.outerHeight() : 0; 7981 var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()); 7982 var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 7983 7984 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); 7985 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; 7986 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 7987 7988 // now check if datepicker is showing outside window viewport - move to a better place if so. 7989 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 7990 Math.abs(offset.left + dpWidth - viewWidth) : 0); 7991 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 7992 Math.abs(dpHeight + inputHeight) : 0); 7993 7994 return offset; 7995 }, 7996 7997 /* Find an object's position on the screen. */ 7998 _findPos: function (obj) { 7999 var inst = this._getInst(obj); 8000 var isRTL = this._get(inst, 'isRTL'); 8001 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) { 8002 obj = obj[isRTL ? 'previousSibling' : 'nextSibling']; 8003 } 8004 var position = $(obj).offset(); 8005 return [position.left, position.top]; 8006 }, 8007 8008 /* Hide the date picker from view. 8009 @param input element - the input field attached to the date picker */ 8010 _hideDatepicker: function (input) { 8011 var inst = this._curInst; 8012 if (!inst || (input && inst != $.data(input, PROP_NAME))) 8013 return; 8014 if (this._datepickerShowing) { 8015 var showAnim = this._get(inst, 'showAnim'); 8016 var duration = this._get(inst, 'duration'); 8017 var postProcess = function () { 8018 $.datepicker._tidyDialog(inst); 8019 }; 8020 8021 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8022 if ($.effects && ($.effects.effect[showAnim] || $.effects[showAnim])) 8023 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 8024 else 8025 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' : 8026 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); 8027 if (!showAnim) 8028 postProcess(); 8029 this._datepickerShowing = false; 8030 var onClose = this._get(inst, 'onClose'); 8031 if (onClose) 8032 onClose.apply((inst.input ? inst.input[0] : null), 8033 [(inst.input ? inst.input.val() : ''), inst]); 8034 this._lastInput = null; 8035 if (this._inDialog) { 8036 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); 8037 if ($.blockUI) { 8038 $.unblockUI(); 8039 $('body').append(this.dpDiv); 8040 } 8041 } 8042 this._inDialog = false; 8043 } 8044 }, 8045 8046 /* Tidy up after a dialog display. */ 8047 _tidyDialog: function (inst) { 8048 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); 8049 }, 8050 8051 /* Close date picker if clicked elsewhere. */ 8052 _checkExternalClick: function (event) { 8053 if (!$.datepicker._curInst) 8054 return; 8055 8056 var $target = $(event.target), 8057 inst = $.datepicker._getInst($target[0]); 8058 8059 if ((($target[0].id != $.datepicker._mainDivId && 8060 $target.parents('#' + $.datepicker._mainDivId).length == 0 && 8061 !$target.hasClass($.datepicker.markerClassName) && 8062 !$target.closest("." + $.datepicker._triggerClass).length && 8063 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))) || 8064 ($target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst)) 8065 $.datepicker._hideDatepicker(); 8066 }, 8067 8068 /* Adjust one of the date sub-fields. */ 8069 _adjustDate: function (id, offset, period) { 8070 var target = $(id); 8071 var inst = this._getInst(target[0]); 8072 if (this._isDisabledDatepicker(target[0])) { 8073 return; 8074 } 8075 this._adjustInstDate(inst, offset + 8076 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning 8077 period); 8078 this._updateDatepicker(inst); 8079 }, 8080 8081 /* Action for current link. */ 8082 _gotoToday: function (id) { 8083 var target = $(id); 8084 var inst = this._getInst(target[0]); 8085 if (this._get(inst, 'gotoCurrent') && inst.currentDay) { 8086 inst.selectedDay = inst.currentDay; 8087 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8088 inst.drawYear = inst.selectedYear = inst.currentYear; 8089 } 8090 else { 8091 var date = new Date(); 8092 inst.selectedDay = date.getDate(); 8093 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8094 inst.drawYear = inst.selectedYear = date.getFullYear(); 8095 } 8096 this._notifyChange(inst); 8097 this._adjustDate(target); 8098 }, 8099 8100 /* Action for selecting a new month/year. */
8101 _selectMonthYear: function (id, select, period) { 8102 var target = $(id); 8103 var inst = this._getInst(target[0]); 8104 inst['selected' + (period == 'M' ? 'Month' : 'Year')] = 8105 inst['draw' + (period == 'M' ? 'Month' : 'Year')] = 8106 parseInt(select.options[select.selectedIndex].value, 10); 8107 this._notifyChange(inst); 8108 this._adjustDate(target); 8109 }, 8110 8111 /* Action for selecting a day. */ 8112 _selectDay: function (id, month, year, td) { 8113 var target = $(id); 8114 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8115 return; 8116 } 8117 var inst = this._getInst(target[0]); 8118 inst.selectedDay = inst.currentDay = $('a', td).html(); 8119 inst.selectedMonth = inst.currentMonth = month; 8120 inst.selectedYear = inst.currentYear = year; 8121 this._selectDate(id, this._formatDate(inst, 8122 inst.currentDay, inst.currentMonth, inst.currentYear)); 8123 }, 8124 8125 /* Erase the input field and hide the date picker. */ 8126 _clearDate: function (id) { 8127 var target = $(id); 8128 var inst = this._getInst(target[0]); 8129 this._selectDate(target, ''); 8130 }, 8131 8132 /* Update the input field with the selected date. */ 8133 _selectDate: function (id, dateStr) { 8134 var target = $(id); 8135 var inst = this._getInst(target[0]); 8136 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 8137 if (inst.input) 8138 inst.input.val(dateStr); 8139 this._updateAlternate(inst); 8140 var onSelect = this._get(inst, 'onSelect'); 8141 if (onSelect) 8142 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 8143 else if (inst.input) 8144 inst.input.trigger('change'); // fire the change event 8145 if (inst.inline) 8146 this._updateDatepicker(inst); 8147 else { 8148 this._hideDatepicker(); 8149 this._lastInput = inst.input[0]; 8150 if (typeof (inst.input[0]) != 'object') 8151 inst.input.focus(); // restore focus 8152 this._lastInput = null; 8153 } 8154 }, 8155 8156 /* Update any alternate field to synchronise with the main field. */ 8157 _updateAlternate: function (inst) { 8158 var altField = this._get(inst, 'altField'); 8159 if (altField) { // update alternate field too 8160 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); 8161 var date = this._getDate(inst); 8162 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 8163 $(altField).each(function () { $(this).val(dateStr); }); 8164 } 8165 }, 8166 8167 /* Set as beforeShowDay function to prevent selection of weekends. 8168 @param date Date - the date to customise 8169 @return [boolean, string] - is this date selectable?, what is its CSS class? */ 8170 noWeekends: function (date) { 8171 var day = date.getDay(); 8172 return [(day > 0 && day < 6), '']; 8173 }, 8174 8175 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8176 @param date Date - the date to get the week for 8177 @return number - the number of the week within the year that contains this date */ 8178 iso8601Week: function (date) { 8179 var checkDate = new Date(date.getTime()); 8180 // Find Thursday of this week starting on Monday 8181 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 8182 var time = checkDate.getTime(); 8183 checkDate.setMonth(0); // Compare with Jan 1 8184 checkDate.setDate(1); 8185 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 8186 }, 8187 8188 /* Parse a string value into a date object. 8189 See formatDate below for the possible formats. 8190
8191 @param format string - the expected format of the date 8192 @param value string - the date in the above format 8193 @param settings Object - attributes include: 8194 shortYearCutoff number - the cutoff year for determining the century (optional) 8195 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8196 dayNames string[7] - names of the days from Sunday (optional) 8197 monthNamesShort string[12] - abbreviated names of the months (optional) 8198 monthNames string[12] - names of the months (optional) 8199 @return Date - the extracted date value or null if value is blank */ 8200 parseDate: function (format, value, settings) { 8201 if (format == null || value == null) 8202 throw 'Invalid arguments'; 8203 value = (typeof value == 'object' ? value.toString() : value + ''); 8204 if (value == '') 8205 return null; 8206 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; 8207 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 8208 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 8209 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 8210 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 8211 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 8212 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 8213 var year = -1; 8214 var month = -1; 8215 var day = -1; 8216 var doy = -1; 8217 var literal = false; 8218 // Check whether a format character is doubled 8219 var lookAhead = function (match) { 8220 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 8221 if (matches) 8222 iFormat++; 8223 return matches; 8224 }; 8225 // Extract a number from the string value 8226 var getNumber = function (match) { 8227 var isDoubled = lookAhead(match); 8228 var size = (match == '@' ? 14 : (match == '!' ? 20 : 8229 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2)))); 8230 var digits = new RegExp('^\\d{1,' + size + '}'); 8231 var num = value.substring(iValue).match(digits); 8232 if (!num) 8233 throw 'Missing number at position ' + iValue; 8234 iValue += num[0].length; 8235 return parseInt(num[0], 10); 8236 }; 8237 // Extract a name from the string value and convert to an index 8238 var getName = function (match, shortNames, longNames) { 8239 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 8240 return [[k, v]]; 8241 }).sort(function (a, b) { 8242 return -(a[1].length - b[1].length); 8243 }); 8244 var index = -1; 8245 $.each(names, function (i, pair) { 8246 var name = pair[1]; 8247 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { 8248 index = pair[0]; 8249 iValue += name.length; 8250 return false; 8251 } 8252 }); 8253 if (index != -1) 8254 return index + 1; 8255 else 8256 throw 'Unknown name at position ' + iValue; 8257 }; 8258 // Confirm that a literal character matches the string value 8259 var checkLiteral = function () { 8260 if (value.charAt(iValue) != format.charAt(iFormat)) 8261 throw 'Unexpected literal at position ' + iValue; 8262 iValue++; 8263 }; 8264 var iValue = 0; 8265 for (var iFormat = 0; iFormat < format.length; iFormat++) { 8266 if (literal) 8267 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 8268 literal = false; 8269 else 8270 checkLiteral(); 8271 else 8272 switch (format.charAt(iFormat)) { 8273 case 'd': 8274 day = getNumber('d'); 8275 break; 8276 case 'D': 8277 getName('D', dayNamesShort, dayNames); 8278 break; 8279 case 'o': 8280 doy = getNumber('o'); 8281 break; 8282 case 'm':
8283 month = getNumber('m'); 8284 break; 8285 case 'M': 8286 month = getName('M', monthNamesShort, monthNames); 8287 break; 8288 case 'y': 8289 year = getNumber('y'); 8290 break; 8291 case '@': 8292 var date = new Date(getNumber('@')); 8293 year = date.getFullYear(); 8294 month = date.getMonth() + 1; 8295 day = date.getDate(); 8296 break; 8297 case '!': 8298 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); 8299 year = date.getFullYear(); 8300 month = date.getMonth() + 1; 8301 day = date.getDate(); 8302 break; 8303 case "'": 8304 if (lookAhead("'")) 8305 checkLiteral(); 8306 else 8307 literal = true; 8308 break; 8309 default: 8310 checkLiteral(); 8311 } 8312 } 8313 if (iValue < value.length) { 8314 var extra = value.substr(iValue); 8315 if (!/^\s+/.test(extra)) { 8316 throw "Extra/unparsed characters found in date: " + extra; 8317 } 8318 } 8319 if (year == -1) 8320 year = new Date().getFullYear(); 8321 else if (year < 100) 8322 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8323 (year <= shortYearCutoff ? 0 : -100); 8324 if (doy > -1) { 8325 month = 1; 8326 day = doy; 8327 do { 8328 var dim = this._getDaysInMonth(year, month - 1); 8329 if (day <= dim) 8330 break; 8331 month++; 8332 day -= dim; 8333 } while (true); 8334 } 8335 var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 8336 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) 8337 throw 'Invalid date'; // E.g. 31/02/00 8338 return date; 8339 }, 8340 8341 /* Standard date formats. */ 8342 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) 8343 COOKIE: 'D, dd M yy', 8344 ISO_8601: 'yy-mm-dd', 8345 RFC_822: 'D, d M y', 8346 RFC_850: 'DD, dd-M-y', 8347 RFC_1036: 'D, d M y', 8348 RFC_1123: 'D, d M yy', 8349 RFC_2822: 'D, d M yy', 8350 RSS: 'D, d M y', // RFC 822 8351 TICKS: '!', 8352 TIMESTAMP: '@', 8353 W3C: 'yy-mm-dd', // ISO 8601 8354 8355 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8356 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8357 8358 /* Format a date object into a string value. 8359 The format can be combinations of the following: 8360 d - day of month (no leading zero) 8361 dd - day of month (two digit) 8362 o - day of year (no leading zeros) 8363 oo - day of year (three digit) 8364 D - day name short 8365 DD - day name long 8366 m - month of year (no leading zero) 8367 mm - month of year (two digit) 8368 M - month name short 8369 MM - month name long 8370 y - year (two digit) 8371 yy - year (four digit) 8372 @ - Unix timestamp (ms since 01/01/1970) 8373 ! - Windows ticks (100ns since 01/01/0001) 8374 '...' - literal text 8375 '' - single quote 8376 8377 @param format string - the desired format of the date 8378 @param date Date - the date value to format 8379 @param settings Object - attributes include: 8380 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8381 dayNames string[7] - names of the days from Sunday (optional) 8382 monthNamesShort string[12] - abbreviated names of the months (optional) 8383 monthNames string[12] - names of the months (optional) 8384 @return string - the date in the above format */ 8385 formatDate: function (format, date, settings) { 8386 if (!date) 8387 return ''; 8388 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 8389 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 8390 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 8391 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 8392 // Check whether a format character is doubled 8393 var lookAhead = function (match) { 8394 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 8395 if (matches) 8396 iFormat++; 8397 return matches; 8398 }; 8399 // Format a number, with leading zero if necessary 8400 var formatNumber = function (match, value, len) { 8401 var num = '' + value; 8402 if (lookAhead(match)) 8403 while (num.length < len) 8404 num = '0' + num; 8405 return num; 8406 }; 8407 // Format a name, short or long as requested 8408 var formatName = function (match, value, shortNames, longNames) { 8409 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8410 }; 8411 var output = ''; 8412 var literal = false; 8413 if (date) 8414 for (var iFormat = 0; iFormat < format.length; iFormat++) { 8415 if (literal) 8416 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 8417 literal = false; 8418 else 8419 output += format.charAt(iFormat); 8420 else 8421 switch (format.charAt(iFormat)) { 8422 case 'd': 8423 output += formatNumber('d', date.getDate(), 2); 8424 break; 8425 case 'D': 8426 output += formatName('D', date.getDay(), dayNamesShort, dayNames); 8427 break; 8428 case 'o': 8429 output += formatNumber('o', 8430 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8431 break; 8432 case 'm': 8433 output += formatNumber('m', date.getMonth() + 1, 2); 8434 break; 8435 case 'M': 8436 output += formatName('M', date.getMonth(), monthNamesShort, monthNames); 8437 break; 8438 case 'y': 8439 output += (lookAhead('y') ? date.getFullYear() : 8440 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); 8441 break; 8442 case '@': 8443 output += date.getTime(); 8444 break; 8445 case '!': 8446 output += date.getTime() * 10000 + this._ticksTo1970; 8447 break; 8448 case "'": 8449 if (lookAhead("'")) 8450 output += "'"; 8451 else 8452 literal = true; 8453 break; 8454 default: 8455 output += format.charAt(iFormat); 8456 } 8457 } 8458 return output; 8459 }, 8460 8461 /* Extract all possible characters from the date format. */ 8462 _possibleChars: function (format) { 8463 var chars = ''; 8464 var literal = false; 8465 // Check whether a format character is doubled 8466 var lookAhead = function (match) { 8467 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 8468 if (matches) 8469 iFormat++; 8470 return matches; 8471 }; 8472 for (var iFormat = 0; iFormat < format.length; iFormat++) 8473 if (literal) 8474 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 8475 literal = false; 8476 else 8477 chars += format.charAt(iFormat); 8478 else 8479 switch (format.charAt(iFormat)) { 8480 case 'd': case 'm': case 'y': case '@': 8481 chars += '0123456789'; 8482 break; 8483 case 'D': case 'M': 8484 return null; // Accept anything
8485 case "'": 8486 if (lookAhead("'")) 8487 chars += "'"; 8488 else 8489 literal = true; 8490 break; 8491 default: 8492 chars += format.charAt(iFormat); 8493 } 8494 return chars; 8495 }, 8496 8497 /* Get a setting value, defaulting if necessary. */ 8498 _get: function (inst, name) { 8499 return inst.settings[name] !== undefined ? 8500 inst.settings[name] : this._defaults[name]; 8501 }, 8502 8503 /* Parse existing date and initialise date picker. */ 8504 _setDateFromField: function (inst, noDefault) { 8505 if (inst.input.val() == inst.lastVal) { 8506 return; 8507 } 8508 var dateFormat = this._get(inst, 'dateFormat'); 8509 var dates = inst.lastVal = inst.input ? inst.input.val() : null; 8510 var date, defaultDate; 8511 date = defaultDate = this._getDefaultDate(inst); 8512 var settings = this._getFormatConfig(inst); 8513 try { 8514 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 8515 } catch (event) { 8516 this.log(event); 8517 dates = (noDefault ? '' : dates); 8518 } 8519 inst.selectedDay = date.getDate(); 8520 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8521 inst.drawYear = inst.selectedYear = date.getFullYear(); 8522 inst.currentDay = (dates ? date.getDate() : 0); 8523 inst.currentMonth = (dates ? date.getMonth() : 0); 8524 inst.currentYear = (dates ? date.getFullYear() : 0); 8525 this._adjustInstDate(inst); 8526 }, 8527 8528 /* Retrieve the default date shown on opening. */ 8529 _getDefaultDate: function (inst) { 8530 return this._restrictMinMax(inst, 8531 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date())); 8532 }, 8533 8534 /* A date may be specified as an exact value or a relative one. */ 8535 _determineDate: function (inst, date, defaultDate) { 8536 var offsetNumeric = function (offset) { 8537 var date = new Date(); 8538 date.setDate(date.getDate() + offset); 8539 return date; 8540 }; 8541 var offsetString = function (offset) { 8542 try { 8543 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 8544 offset, $.datepicker._getFormatConfig(inst)); 8545 } 8546 catch (e) { 8547 // Ignore 8548 } 8549 var date = (offset.toLowerCase().match(/^c/) ? 8550 $.datepicker._getDate(inst) : null) || new Date(); 8551 var year = date.getFullYear(); 8552 var month = date.getMonth(); 8553 var day = date.getDate(); 8554 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; 8555 var matches = pattern.exec(offset); 8556 while (matches) { 8557 switch (matches[2] || 'd') { 8558 case 'd': case 'D': 8559 day += parseInt(matches[1], 10); break; 8560 case 'w': case 'W': 8561 day += parseInt(matches[1], 10) * 7; break; 8562 case 'm': case 'M': 8563 month += parseInt(matches[1], 10); 8564 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8565 break; 8566 case 'y': case 'Y': 8567 year += parseInt(matches[1], 10); 8568 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8569 break; 8570 } 8571 matches = pattern.exec(offset); 8572 } 8573 return new Date(year, month, day); 8574 }; 8575 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) : 8576 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 8577 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate); 8578 if (newDate) { 8579 newDate.setHours(0); 8580 newDate.setMinutes(0); 8581 newDate.setSeconds(0); 8582 newDate.setMilliseconds(0); 8583 } 8584 return this._daylightSavingAdjust(newDate); 8585 }, 8586 8587 /* Handle switch to/from daylight saving. 8588 Hours may be non-zero on daylight saving cut-over: 8589 > 12 when midnight changeover, but then cannot generate 8590 midnight datetime, so jump to 1AM, otherwise reset.
8591 @param date (Date) the date to check 8592 @return (Date) the corrected date */ 8593 _daylightSavingAdjust: function (date) { 8594 if (!date) return null; 8595 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 8596 return date; 8597 }, 8598 8599 /* Set the date(s) directly. */ 8600 _setDate: function (inst, date, noChange) { 8601 var clear = !date; 8602 var origMonth = inst.selectedMonth; 8603 var origYear = inst.selectedYear; 8604 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 8605 inst.selectedDay = inst.currentDay = newDate.getDate(); 8606 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 8607 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 8608 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) 8609 this._notifyChange(inst); 8610 this._adjustInstDate(inst); 8611 if (inst.input) { 8612 inst.input.val(clear ? '' : this._formatDate(inst)); 8613 } 8614 }, 8615 8616 /* Retrieve the date(s) directly. */ 8617 _getDate: function (inst) { 8618 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : 8619 this._daylightSavingAdjust(new Date( 8620 inst.currentYear, inst.currentMonth, inst.currentDay))); 8621 return startDate; 8622 }, 8623 8624 /* Attach the onxxx handlers. These are declared statically so 8625 * they work with static code transformers like Caja. 8626 */ 8627 _attachHandlers: function (inst) { 8628 var stepMonths = this._get(inst, 'stepMonths'); 8629 var id = '#' + inst.id.replace(/\\\\/g, "\\"); 8630 inst.dpDiv.find('[data-handler]').map(function () { 8631 var handler = { 8632 prev: function () { 8633 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M'); 8634 }, 8635 next: function () { 8636 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M'); 8637 }, 8638 hide: function () { 8639 window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker(); 8640 }, 8641 today: function () { 8642 window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id); 8643 }, 8644 selectDay: function () { 8645 window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this); 8646 return false; 8647 }, 8648 selectMonth: function () { 8649 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M'); 8650 return false; 8651 }, 8652 selectYear: function () { 8653 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y'); 8654 return false; 8655 } 8656 }; 8657 $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]); 8658 }); 8659 }, 8660 8661 /* Generate the HTML for the current state of the date picker. */ 8662 _generateHTML: function (inst) { 8663 var today = new Date(); 8664 today = this._daylightSavingAdjust( 8665 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time 8666 var isRTL = this._get(inst, 'isRTL'); 8667 var showButtonPanel = this._get(inst, 'showButtonPanel'); 8668 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); 8669 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); 8670 var numMonths = this._getNumberOfMonths(inst); 8671 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); 8672 var stepMonths = this._get(inst, 'stepMonths'); 8673 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); 8674 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 8675 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 8676 var minDate = this._getMinMaxDate(inst, 'min'); 8677 var maxDate = this._getMinMaxDate(inst, 'max'); 8678 var drawMonth = inst.drawMonth - showCurrentAtPos; 8679 var drawYear = inst.drawYear; 8680 if (drawMonth < 0) { 8681 drawMonth += 12; 8682 drawYear--; 8683 } 8684 if (maxDate) { 8685 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 8686 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 8687 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 8688 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 8689 drawMonth--; 8690 if (drawMonth < 0) { 8691 drawMonth = 11; 8692 drawYear--; 8693 } 8694 } 8695 } 8696 inst.drawMonth = drawMonth; 8697 inst.drawYear = drawYear; 8698 var prevText = this._get(inst, 'prevText'); 8699 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 8700 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 8701 this._getFormatConfig(inst))); 8702 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 8703 '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' + 8704 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + (isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : 8705 (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>')); 8706 var nextText = this._get(inst, 'nextText'); 8707 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 8708 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 8709 this._getFormatConfig(inst))); 8710 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 8711 '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' + 8712 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + (isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : 8713 (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>')); 8714 var currentText = this._get(inst, 'currentText'); 8715 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); 8716 currentText = (!navigationAsDateFormat ? currentText : 8717 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 8718 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">' + 8719 this._get(inst, 'closeText') + '</button>' : ''); 8720 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + 8721 (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click"' + 8722 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; 8723 var firstDay = parseInt(this._get(inst, 'firstDay'), 10); 8724 firstDay = (isNaN(firstDay) ? 0 : firstDay); 8725 var showWeek = this._get(inst, 'showWeek'); 8726 var dayNames = this._get(inst, 'dayNames'); 8727 var dayNamesShort = this._get(inst, 'dayNamesShort'); 8728 var dayNamesMin = this._get(inst, 'dayNamesMin'); 8729 var monthNames = this._get(inst, 'monthNames'); 8730 var monthNamesShort = this._get(inst, 'monthNamesShort'); 8731 var beforeShowDay = this._get(inst, 'beforeShowDay'); 8732 var showOtherMonths = this._get(inst, 'showOtherMonths'); 8733 var selectOtherMonths = this._get(inst, 'selectOtherMonths'); 8734 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; 8735 var defaultDate = this._getDefaultDate(inst); 8736 var html = ''; 8737 for (var row = 0; row < numMonths[0]; row++) { 8738 var group = ''; 8739 this.maxRows = 4; 8740 for (var col = 0; col < numMonths[1]; col++) { 8741 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 8742 var cornerClass = ' ui-corner-all'; 8743 var calender = ''; 8744 if (isMultiMonth) { 8745 calender += '<div class="ui-datepicker-group'; 8746 if (numMonths[1] > 1) 8747 switch (col) { 8748 case 0: calender += ' ui-datepicker-group-first'; 8749 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; 8750 case numMonths[1] - 1: calender += ' ui-datepicker-group-last'; 8751 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; 8752 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break; 8753 } 8754 calender += '">'; 8755 } 8756 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' + 8757 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + 8758 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + 8759 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 8760 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 8761 '</div><table class="ui-datepicker-calendar"><thead>' + 8762 '<tr>'; 8763 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : ''); 8764 for (var dow = 0; dow < 7; dow++) { // days of the week 8765 var day = (dow + firstDay) % 7; 8766 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
8766' + 8767 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>'; 8768 } 8769 calender += thead + '</tr></thead><tbody>'; 8770 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 8771 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) 8772 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 8773 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 8774 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 8775 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 8776 this.maxRows = numRows; 8777 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 8778 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows 8779 calender += '<tr>'; 8780 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' + 8781 this._get(inst, 'calculateWeek')(printDate) + '</td>'); 8782 for (var dow = 0; dow < 7; dow++) { // create date picker days 8783 var daySettings = (beforeShowDay ? 8784 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); 8785 var otherMonth = (printDate.getMonth() != drawMonth); 8786 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 8787 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 8788 tbody += '<td class="' + 8789 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends 8790 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months 8791 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key 8792 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ? 8793 // or defaultDate is current printedDate and defaultDate is selectedDate 8794 ' ' + this._dayOverClass : '') + // highlight selected day 8795 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled' : '') + // highlight unselectable days 8796 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates 8797 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day 8798 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) 8799 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title 8800 (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions 8801 (otherMonth && !showOtherMonths ? ' ' : // display for other months 8802 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + 8803 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + 8804 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day 8805 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months 8806 '" href="#">
8806' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date 8807 printDate.setDate(printDate.getDate() + 1); 8808 printDate = this._daylightSavingAdjust(printDate); 8809 } 8810 calender += tbody + '</tr>'; 8811 } 8812 drawMonth++; 8813 if (drawMonth > 11) { 8814 drawMonth = 0; 8815 drawYear++; 8816 } 8817 calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 8818 ((numMonths[0] > 0 && col == numMonths[1] - 1) ? '<div class="ui-datepicker-row-break"></div>' : '') : ''); 8819 group += calender; 8820 } 8821 html += group; 8822 } 8823 html += buttonPanel + ($.ui.ie6 && !inst.inline ? 8824 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : ''); 8825 inst._keyEvent = false; 8826 return html; 8827 }, 8828 8829 /* Generate the month and year header. */ 8830 _generateMonthYearHeader: function (inst, drawMonth, drawYear, minDate, maxDate, 8831 secondary, monthNames, monthNamesShort) { 8832 var changeMonth = this._get(inst, 'changeMonth'); 8833 var changeYear = this._get(inst, 'changeYear'); 8834 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); 8835 var html = '<div class="ui-datepicker-title">'; 8836 var monthHtml = ''; 8837 // month selection 8838 if (secondary || !changeMonth) 8839 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>'; 8840 else { 8841 var inMinYear = (minDate && minDate.getFullYear() == drawYear); 8842 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); 8843 monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">'; 8844 for (var month = 0; month < 12; month++) { 8845 if ((!inMinYear || month >= minDate.getMonth()) && 8846 (!inMaxYear || month <= maxDate.getMonth())) 8847 monthHtml += '<option value="' + month + '"' + 8848 (month == drawMonth ? ' selected="selected"' : '') + 8849 '>' + monthNamesShort[month] + '</option>'; 8850 } 8851 monthHtml += '</select>'; 8852 } 8853 if (!showMonthAfterYear) 8854 html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); 8855 // year selection 8856 if (!inst.yearshtml) { 8857 inst.yearshtml = ''; 8858 if (secondary || !changeYear) 8859 html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; 8860 else { 8861 // determine range of years to display 8862 var years = this._get(inst, 'yearRange').split(':'); 8863 var thisYear = new Date().getFullYear(); 8864 var determineYear = function (value) { 8865 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : 8866 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : 8867 parseInt(value, 10))); 8868 return (isNaN(year) ? thisYear : year); 8869 }; 8870 var year = determineYear(years[0]); 8871 var endYear = Math.max(year, determineYear(years[1] || '')); 8872 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 8873 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 8874 inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">'; 8875 for (; year <= endYear; year++) { 8876 inst.yearshtml += '<option value="' + year + '"' + 8877 (year == drawYear ? ' selected="selected"' : '') + 8878 '>' + year + '</option>'; 8879 } 8880 inst.yearshtml += '</select>'; 8881 8882 html += inst.yearshtml; 8883 inst.yearshtml = null; 8884 } 8885 } 8886 html += this._get(inst, 'yearSuffix'); 8887 if (showMonthAfterYear) 8888 html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; 8889 html += '</div>'; // Close datepicker_header 8890 return html; 8891 }, 8892 8893 /* Adjust one of the date sub-fields. */ 8894 _adjustInstDate: function (inst, offset, period) { 8895 var year = inst.drawYear + (period == 'Y' ? offset : 0);
8896 var month = inst.drawMonth + (period == 'M' ? offset : 0); 8897 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + 8898 (period == 'D' ? offset : 0); 8899 var date = this._restrictMinMax(inst, 8900 this._daylightSavingAdjust(new Date(year, month, day))); 8901 inst.selectedDay = date.getDate(); 8902 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8903 inst.drawYear = inst.selectedYear = date.getFullYear(); 8904 if (period == 'M' || period == 'Y') 8905 this._notifyChange(inst); 8906 }, 8907 8908 /* Ensure a date is within any min/max bounds. */ 8909 _restrictMinMax: function (inst, date) { 8910 var minDate = this._getMinMaxDate(inst, 'min'); 8911 var maxDate = this._getMinMaxDate(inst, 'max'); 8912 var newDate = (minDate && date < minDate ? minDate : date); 8913 newDate = (maxDate && newDate > maxDate ? maxDate : newDate); 8914 return newDate; 8915 }, 8916 8917 /* Notify change of month/year. */ 8918 _notifyChange: function (inst) { 8919 var onChange = this._get(inst, 'onChangeMonthYear'); 8920 if (onChange) 8921 onChange.apply((inst.input ? inst.input[0] : null), 8922 [inst.selectedYear, inst.selectedMonth + 1, inst]); 8923 }, 8924 8925 /* Determine the number of months to show. */ 8926 _getNumberOfMonths: function (inst) { 8927 var numMonths = this._get(inst, 'numberOfMonths'); 8928 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); 8929 }, 8930 8931 /* Determine the current maximum date - ensure no time components are set. */ 8932 _getMinMaxDate: function (inst, minMax) { 8933 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); 8934 }, 8935 8936 /* Find the number of days in a given month. */ 8937 _getDaysInMonth: function (year, month) { 8938 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 8939 }, 8940 8941 /* Find the day of the week of the first of a month. */ 8942 _getFirstDayOfMonth: function (year, month) { 8943 return new Date(year, month, 1).getDay(); 8944 }, 8945 8946 /* Determines if we should allow a "next/prev" month display change. */ 8947 _canAdjustMonth: function (inst, offset, curYear, curMonth) { 8948 var numMonths = this._getNumberOfMonths(inst); 8949 var date = this._daylightSavingAdjust(new Date(curYear, 8950 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 8951 if (offset < 0) 8952 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 8953 return this._isInRange(inst, date); 8954 }, 8955 8956 /* Is the given date in the accepted range? */ 8957 _isInRange: function (inst, date) { 8958 var minDate = this._getMinMaxDate(inst, 'min'); 8959 var maxDate = this._getMinMaxDate(inst, 'max'); 8960 return ((!minDate || date.getTime() >= minDate.getTime()) && 8961 (!maxDate || date.getTime() <= maxDate.getTime())); 8962 }, 8963 8964 /* Provide the configuration settings for formatting/parsing. */ 8965 _getFormatConfig: function (inst) { 8966 var shortYearCutoff = this._get(inst, 'shortYearCutoff'); 8967 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 8968 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 8969 return { 8970 shortYearCutoff: shortYearCutoff, 8971 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), 8972 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames') 8973 }; 8974 }, 8975 8976 /* Format the given date for display. */ 8977 _formatDate: function (inst, day, month, year) { 8978 if (!day) { 8979 inst.currentDay = inst.selectedDay; 8980 inst.currentMonth = inst.selectedMonth; 8981 inst.currentYear = inst.selectedYear; 8982 } 8983 var date = (day ? (typeof day == 'object' ? day : 8984 this._daylightSavingAdjust(new Date(year, month, day))) : 8985 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 8986 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); 8987 } 8988 });
8989 8990 /* 8991 * Bind hover events for datepicker elements. 8992 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 8993 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 8994 */ 8995 function bindHover(dpDiv) { 8996 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; 8997 return dpDiv.delegate(selector, 'mouseout', function () { 8998 $(this).removeClass('ui-state-hover'); 8999 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); 9000 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); 9001 }) 9002 .delegate(selector, 'mouseover', function () { 9003 if (!$.datepicker._isDisabledDatepicker(instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 9004 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); 9005 $(this).addClass('ui-state-hover'); 9006 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); 9007 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); 9008 } 9009 }); 9010 } 9011 9012 /* jQuery extend now ignores nulls! */ 9013 function extendRemove(target, props) { 9014 $.extend(target, props); 9015 for (var name in props) 9016 if (props[name] == null || props[name] == undefined) 9017 target[name] = props[name]; 9018 return target; 9019 }; 9020 9021 /* Invoke the datepicker functionality. 9022 @param options string - a command, optionally followed by additional parameters or 9023 Object - settings for attaching new datepicker functionality 9024 @return jQuery object */ 9025 $.fn.datepicker = function (options) { 9026 9027 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9028 if (!this.length) { 9029 return this; 9030 } 9031 9032 /* Initialise the date picker. */ 9033 if (!$.datepicker.initialized) { 9034 $(document).mousedown($.datepicker._checkExternalClick). 9035 find(document.body).append($.datepicker.dpDiv); 9036 $.datepicker.initialized = true; 9037 } 9038 9039 var otherArgs = Array.prototype.slice.call(arguments, 1); 9040 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) 9041 return $.datepicker['_' + options + 'Datepicker']. 9042 apply($.datepicker, [this[0]].concat(otherArgs)); 9043 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') 9044 return $.datepicker['_' + options + 'Datepicker']. 9045 apply($.datepicker, [this[0]].concat(otherArgs)); 9046 return this.each(function () { 9047 typeof options == 'string' ? 9048 $.datepicker['_' + options + 'Datepicker']. 9049 apply($.datepicker, [this].concat(otherArgs)) : 9050 $.datepicker._attachDatepicker(this, options); 9051 }); 9052 }; 9053 9054 $.datepicker = new Datepicker(); // singleton instance 9055 $.datepicker.initialized = false; 9056 $.datepicker.uuid = new Date().getTime(); 9057 $.datepicker.version = "1.9.2"; 9058 9059 // Workaround for #4055 9060 // Add another global to avoid noConflict issues with inline event handlers 9061 window['DP_jQuery_' + dpuuid] = $; 9062 9063})(jQuery); 9064 9065(function ($, undefined) { 9066 9067 var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ", 9068 sizeRelatedOptions = { 9069 buttons: true, 9070 height: true, 9071 maxHeight: true, 9072 maxWidth: true, 9073 minHeight: true, 9074 minWidth: true, 9075 width: true 9076 }, 9077 resizableRelatedOptions = { 9078 maxHeight: true, 9079 maxWidth: true, 9080 minHeight: true, 9081 minWidth: true 9082 }; 9083 9084 $.widget("ui.dialog", { 9085 version: "1.9.2", 9086 options: { 9087 autoOpen: true, 9088 buttons: {}, 9089 closeOnEscape: true, 9090 closeText: "close", 9091 dialogClass: "", 9092 draggable: true, 9093 hide: null, 9094 height: "auto", 9095 maxHeight: false, 9096 maxWidth: false, 9097 minHeight: 150, 9098 minWidth: 150, 9099 modal: false, 9100 position: { 9101 my: "center", 9102 at: "center", 9103 of: window, 9104 collision: "fit", 9105 // ensure that the titlebar is never outside the document 9106 using: function (pos) { 9107 var topOffset = $(this).css(pos).offset().top; 9108 if (topOffset < 0) { 9109 $(this).css("top", pos.top - topOffset); 9110 } 9111 } 9112 }, 9113 resizable: true, 9114 show: null, 9115 stack: true, 9116 title: "", 9117 width: 300, 9118 zIndex: 1000 9119 }, 9120 9121 _create: function () { 9122 this.originalTitle = this.element.attr("title"); 9123 // #5742 - .attr() might return a DOMElement 9124 if (typeof this.originalTitle !== "string") { 9125 this.originalTitle = ""; 9126 } 9127 this.oldPosition = { 9128 parent: this.element.parent(), 9129 index: this.element.parent().children().index(this.element) 9130 }; 9131 this.options.title = this.options.title || this.originalTitle; 9132 var that = this, 9133 options = this.options, 9134 9135 title = options.title || " ", 9136 uiDialog, 9137 uiDialogTitlebar, 9138 uiDialogTitlebarClose, 9139 uiDialogTitle, 9140 uiDialogButtonPane; 9141 9142 uiDialog = (this.uiDialog = $("<div>")) 9143 .addClass(uiDialogClasses + options.dialogClass) 9144 .css({ 9145 display: "none", 9146 outline: 0, // TODO: move to stylesheet 9147 zIndex: options.zIndex 9148 }) 9149 // setting tabIndex makes the div focusable 9150 .attr("tabIndex", -1) 9151 .keydown(function (event) { 9152 if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9153 event.keyCode === $.ui.keyCode.ESCAPE) { 9154 that.close(event); 9155 event.preventDefault(); 9156 } 9157 }) 9158 .mousedown(function (event) { 9159 that.moveToTop(false, event); 9160 }) 9161 .appendTo("body"); 9162 9163 this.element 9164 .show() 9165 .removeAttr("title") 9166 .addClass("ui-dialog-content ui-widget-content") 9167 .appendTo(uiDialog); 9168 9169 uiDialogTitlebar = (this.uiDialogTitlebar = $("<div>")) 9170 .addClass("ui-dialog-titlebar ui-widget-header " + 9171 "ui-corner-all ui-helper-clearfix") 9172 .bind("mousedown", function () { 9173 // Dialog isn't getting focus when dragging (#8063) 9174 uiDialog.focus(); 9175 }) 9176 .prependTo(uiDialog); 9177 9178 uiDialogTitlebarClose = $("<a href='#'></a>") 9179 .addClass("ui-dialog-titlebar-close ui-corner-all") 9180 .attr("role", "button") 9181 .click(function (event) { 9182 event.preventDefault(); 9183 that.close(event); 9184 }) 9185 .appendTo(uiDialogTitlebar); 9186 9187 (this.uiDialogTitlebarCloseText = $("<span>")) 9188 .addClass("ui-icon ui-icon-closethick")
9189 .text(options.closeText) 9190 .appendTo(uiDialogTitlebarClose); 9191 9192 uiDialogTitle = $("<span>") 9193 .uniqueId() 9194 .addClass("ui-dialog-title") 9195 .html(title) 9196 .prependTo(uiDialogTitlebar); 9197 9198 uiDialogButtonPane = (this.uiDialogButtonPane = $("<div>")) 9199 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 9200 9201 (this.uiButtonSet = $("<div>")) 9202 .addClass("ui-dialog-buttonset") 9203 .appendTo(uiDialogButtonPane); 9204 9205 uiDialog.attr({ 9206 role: "dialog", 9207 "aria-labelledby": uiDialogTitle.attr("id") 9208 }); 9209 9210 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); 9211 this._hoverable(uiDialogTitlebarClose); 9212 this._focusable(uiDialogTitlebarClose); 9213 9214 if (options.draggable && $.fn.draggable) { 9215 this._makeDraggable(); 9216 } 9217 if (options.resizable && $.fn.resizable) { 9218 this._makeResizable(); 9219 } 9220 9221 this._createButtons(options.buttons); 9222 this._isOpen = false; 9223 9224 if ($.fn.bgiframe) { 9225 uiDialog.bgiframe(); 9226 } 9227 9228 // prevent tabbing out of modal dialogs 9229 this._on(uiDialog, { 9230 keydown: function (event) { 9231 if (!options.modal || event.keyCode !== $.ui.keyCode.TAB) { 9232 return; 9233 } 9234 9235 var tabbables = $(":tabbable", uiDialog), 9236 first = tabbables.filter(":first"), 9237 last = tabbables.filter(":last"); 9238 9239 if (event.target === last[0] && !event.shiftKey) { 9240 first.focus(1); 9241 return false; 9242 } else if (event.target === first[0] && event.shiftKey) { 9243 last.focus(1); 9244 return false; 9245 } 9246 } 9247 }); 9248 }, 9249 9250 _init: function () { 9251 if (this.options.autoOpen) { 9252 this.open(); 9253 } 9254 }, 9255 9256 _destroy: function () { 9257 var next, 9258 oldPosition = this.oldPosition; 9259 9260 if (this.overlay) { 9261 this.overlay.destroy(); 9262 } 9263 this.uiDialog.hide(); 9264 this.element 9265 .removeClass("ui-dialog-content ui-widget-content") 9266 .hide() 9267 .appendTo("body"); 9268 this.uiDialog.remove(); 9269 9270 if (this.originalTitle) { 9271 this.element.attr("title", this.originalTitle); 9272 } 9273 9274 next = oldPosition.parent.children().eq(oldPosition.index); 9275 // Don't try to place the dialog next to itself (#8613) 9276 if (next.length && next[0] !== this.element[0]) { 9277 next.before(this.element); 9278 } else { 9279 oldPosition.parent.append(this.element); 9280 } 9281 }, 9282 9283 widget: function () { 9284 return this.uiDialog; 9285 }, 9286 9287 close: function (event) { 9288 var that = this, 9289 maxZ, thisZ; 9290 9291 if (!this._isOpen) { 9292 return; 9293 } 9294 9295 if (false === this._trigger("beforeClose", event)) { 9296 return; 9297 } 9298 9299 this._isOpen = false; 9300 9301 if (this.overlay) { 9302 this.overlay.destroy(); 9303 } 9304 9305 if (this.options.hide) { 9306 this._hide(this.uiDialog, this.options.hide, function () { 9307 that._trigger("close", event); 9308 }); 9309 } else { 9310 this.uiDialog.hide(); 9311 this._trigger("close", event); 9312 } 9313 9314 $.ui.dialog.overlay.resize(); 9315 9316 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 9317 if (this.options.modal) { 9318 maxZ = 0; 9319 $(".ui-dialog").each(function () { 9320 if (this !== that.uiDialog[0]) { 9321 thisZ = $(this).css("z-index"); 9322 if (!isNaN(thisZ)) { 9323 maxZ = Math.max(maxZ, thisZ); 9324 } 9325 } 9326 }); 9327 $.ui.dialog.maxZ = maxZ; 9328 } 9329 9330 return this; 9331 }, 9332 9333 isOpen: function () { 9334 return this._isOpen; 9335 }, 9336 9337 // the force parameter allows us to move modal dialogs to their correct 9338 // position on open 9339 moveToTop: function (force, event) { 9340 var options = this.options, 9341 saveScroll; 9342 9343 if ((options.modal && !force) || 9344 (!options.stack && !options.modal)) { 9345 return this._trigger("focus", event); 9346 } 9347 9348 if (options.zIndex > $.ui.dialog.maxZ) { 9349 $.ui.dialog.maxZ = options.zIndex; 9350 } 9351 if (this.overlay) { 9352 $.ui.dialog.maxZ += 1; 9353 $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
9354 this.overlay.$el.css("z-index", $.ui.dialog.overlay.maxZ); 9355 } 9356 9357 // Save and then restore scroll 9358 // Opera 9.5+ resets when parent z-index is changed. 9359 // http://bugs.jqueryui.com/ticket/3193 9360 saveScroll = { 9361 scrollTop: this.element.scrollTop(), 9362 scrollLeft: this.element.scrollLeft() 9363 }; 9364 $.ui.dialog.maxZ += 1; 9365 this.uiDialog.css("z-index", $.ui.dialog.maxZ); 9366 this.element.attr(saveScroll); 9367 this._trigger("focus", event); 9368 9369 return this; 9370 }, 9371 9372 open: function () { 9373 if (this._isOpen) { 9374 return; 9375 } 9376 9377 var hasFocus, 9378 options = this.options, 9379 uiDialog = this.uiDialog; 9380 9381 this._size(); 9382 this._position(options.position); 9383 uiDialog.show(options.show); 9384 this.overlay = options.modal ? new $.ui.dialog.overlay(this) : null; 9385 this.moveToTop(true); 9386 9387 // set focus to the first tabbable element in the content area or the first button 9388 // if there are no tabbable elements, set focus on the dialog itself 9389 hasFocus = this.element.find(":tabbable"); 9390 if (!hasFocus.length) { 9391 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 9392 if (!hasFocus.length) { 9393 hasFocus = uiDialog; 9394 } 9395 } 9396 hasFocus.eq(0).focus(); 9397 9398 this._isOpen = true; 9399 this._trigger("open"); 9400 9401 return this; 9402 }, 9403 9404 _createButtons: function (buttons) { 9405 var that = this, 9406 hasButtons = false; 9407 9408 // if we already have a button pane, remove it 9409 this.uiDialogButtonPane.remove(); 9410 this.uiButtonSet.empty(); 9411 9412 if (typeof buttons === "object" && buttons !== null) { 9413 $.each(buttons, function () { 9414 return !(hasButtons = true); 9415 }); 9416 } 9417 if (hasButtons) { 9418 $.each(buttons, function (name, props) { 9419 var button, click; 9420 props = $.isFunction(props) ? 9421 { click: props, text: name } : 9422 props; 9423 // Default to a non-submitting button 9424 props = $.extend({ type: "button" }, props); 9425 // Change the context for the click callback to be the main element 9426 click = props.click; 9427 props.click = function () { 9428 click.apply(that.element[0], arguments); 9429 }; 9430 button = $("<button></button>", props) 9431 .appendTo(that.uiButtonSet); 9432 if ($.fn.button) { 9433 button.button(); 9434 } 9435 }); 9436 this.uiDialog.addClass("ui-dialog-buttons"); 9437 this.uiDialogButtonPane.appendTo(this.uiDialog); 9438 } else { 9439 this.uiDialog.removeClass("ui-dialog-buttons"); 9440 } 9441 }, 9442 9443 _makeDraggable: function () { 9444 var that = this, 9445 options = this.options; 9446 9447 function filteredUi(ui) { 9448 return { 9449 position: ui.position, 9450 offset: ui.offset 9451 }; 9452 } 9453 9454 this.uiDialog.draggable({ 9455 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 9456 handle: ".ui-dialog-titlebar", 9457 containment: "document", 9458 start: function (event, ui) { 9459 $(this) 9460 .addClass("ui-dialog-dragging"); 9461 that._trigger("dragStart", event, filteredUi(ui)); 9462 }, 9463 drag: function (event, ui) { 9464 that._trigger("drag", event, filteredUi(ui)); 9465 }, 9466 stop: function (event, ui) { 9467 options.position = [ 9468 ui.position.left - that.document.scrollLeft(), 9469 ui.position.top - that.document.scrollTop() 9470 ]; 9471 $(this) 9472 .removeClass("ui-dialog-dragging"); 9473 that._trigger("dragStop", event, filteredUi(ui)); 9474 $.ui.dialog.overlay.resize(); 9475 } 9476 }); 9477 }, 9478 9479 _makeResizable: function (handles) { 9480 handles = (handles === undefined ? this.options.resizable : handles); 9481 var that = this, 9482 options = this.options, 9483 // .ui-resizable has position: relative defined in the stylesheet 9484 // but dialogs have to use absolute or fixed positioning 9485 position = this.uiDialog.css("position"), 9486 resizeHandles = typeof handles === 'string' ? 9487 handles : 9488 "n,e,s,w,se,sw,ne,nw"; 9489 9490 function filteredUi(ui) { 9491 return { 9492 originalPosition: ui.originalPosition, 9493 originalSize: ui.originalSize, 9494 position: ui.position, 9495 size: ui.size 9496 }; 9497 } 9498 9499 this.uiDialog.resizable({ 9500 cancel: ".ui-dialog-content", 9501 containment: "document", 9502 alsoResize: this.element, 9503 maxWidth: options.maxWidth, 9504 maxHeight: options.maxHeight, 9505 minWidth: options.minWidth, 9506 minHeight: this._minHeight(), 9507 handles: resizeHandles, 9508 start: function (event, ui) { 9509 $(this).addClass("ui-dialog-resizing"); 9510 that._trigger("resizeStart", event, filteredUi(ui)); 9511 }, 9512 resize: function (event, ui) { 9513 that._trigger("resize", event, filteredUi(ui)); 9514 }, 9515 stop: function (event, ui) { 9516 $(this).removeClass("ui-dialog-resizing"); 9517 options.height = $(this).height(); 9518 options.width = $(this).width(); 9519 that._trigger("resizeStop", event, filteredUi(ui)); 9520 $.ui.dialog.overlay.resize(); 9521 } 9522 }) 9523 .css("position", position) 9524 .find(".ui-resizable-se") 9525 .addClass("ui-icon ui-icon-grip-diagonal-se"); 9526 }, 9527 9528 _minHeight: function () { 9529 var options = this.options; 9530 9531 if (options.height === "auto") { 9532 return options.minHeight; 9533 } else { 9534 return Math.min(options.minHeight, options.height); 9535 } 9536 }, 9537 9538 _position: function (position) { 9539 var myAt = [], 9540 offset = [0, 0], 9541 isVisible; 9542 9543 if (position) { 9544 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( 9545 // if (typeof position == 'string' || $.isArray(position)) { 9546 // myAt = $.isArray(position) ? position : position.split(' '); 9547 9548 if (typeof position === "string" || (typeof position === "object" && "0" in position)) { 9549 myAt = position.split ? position.split(" ") : [position[0], position[1]];
9550 if (myAt.length === 1) { 9551 myAt[1] = myAt[0]; 9552 } 9553 9554 $.each(["left", "top"], function (i, offsetPosition) { 9555 if (+myAt[i] === myAt[i]) { 9556 offset[i] = myAt[i]; 9557 myAt[i] = offsetPosition; 9558 } 9559 }); 9560 9561 position = { 9562 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 9563 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 9564 at: myAt.join(" ") 9565 }; 9566 } 9567 9568 position = $.extend({}, $.ui.dialog.prototype.options.position, position); 9569 } else { 9570 position = $.ui.dialog.prototype.options.position; 9571 } 9572 9573 // need to show the dialog to get the actual offset in the position plugin 9574 isVisible = this.uiDialog.is(":visible"); 9575 if (!isVisible) { 9576 this.uiDialog.show(); 9577 } 9578 this.uiDialog.position(position); 9579 if (!isVisible) { 9580 this.uiDialog.hide(); 9581 } 9582 }, 9583 9584 _setOptions: function (options) { 9585 var that = this, 9586 resizableOptions = {}, 9587 resize = false; 9588 9589 $.each(options, function (key, value) { 9590 that._setOption(key, value); 9591 9592 if (key in sizeRelatedOptions) { 9593 resize = true; 9594 } 9595 if (key in resizableRelatedOptions) { 9596 resizableOptions[key] = value; 9597 } 9598 }); 9599 9600 if (resize) { 9601 this._size(); 9602 } 9603 if (this.uiDialog.is(":data(resizable)")) { 9604 this.uiDialog.resizable("option", resizableOptions); 9605 } 9606 }, 9607 9608 _setOption: function (key, value) { 9609 var isDraggable, isResizable, 9610 uiDialog = this.uiDialog; 9611 9612 switch (key) { 9613 case "buttons": 9614 this._createButtons(value); 9615 break; 9616 case "closeText": 9617 // ensure that we always pass a string 9618 this.uiDialogTitlebarCloseText.text("" + value); 9619 break; 9620 case "dialogClass": 9621 uiDialog 9622 .removeClass(this.options.dialogClass) 9623 .addClass(uiDialogClasses + value); 9624 break; 9625 case "disabled": 9626 if (value) { 9627 uiDialog.addClass("ui-dialog-disabled"); 9628 } else { 9629 uiDialog.removeClass("ui-dialog-disabled"); 9630 } 9631 break; 9632 case "draggable": 9633 isDraggable = uiDialog.is(":data(draggable)"); 9634 if (isDraggable && !value) { 9635 uiDialog.draggable("destroy"); 9636 } 9637 9638 if (!isDraggable && value) { 9639 this._makeDraggable(); 9640 } 9641 break; 9642 case "position": 9643 this._position(value); 9644 break; 9645 case "resizable": 9646 // currently resizable, becoming non-resizable 9647 isResizable = uiDialog.is(":data(resizable)"); 9648 if (isResizable && !value) { 9649 uiDialog.resizable("destroy"); 9650 } 9651 9652 // currently resizable, changing handles 9653 if (isResizable && typeof value === "string") { 9654 uiDialog.resizable("option", "handles", value); 9655 } 9656 9657 // currently non-resizable, becoming resizable 9658 if (!isResizable && value !== false) { 9659 this._makeResizable(value); 9660 } 9661 break; 9662 case "title": 9663 // convert whatever was passed in o a string, for html() to not throw up 9664 $(".ui-dialog-title", this.uiDialogTitlebar) 9665 .html("" + (value || " ")); 9666 break; 9667 } 9668 9669 this._super(key, value); 9670 }, 9671 9672 _size: function () { 9673 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 9674 * divs will both have width and height set, so we need to reset them 9675 */ 9676 var nonContentHeight, minContentHeight, autoHeight, 9677 options = this.options, 9678 isVisible = this.uiDialog.is(":visible"); 9679 9680 // reset content sizing 9681 this.element.show().css({ 9682 width: "auto", 9683 minHeight: 0, 9684 height: 0 9685 }); 9686 9687 if (options.minWidth > options.width) { 9688 options.width = options.minWidth; 9689 } 9690 9691 // reset wrapper sizing 9692 // determine the height of all the non-content elements 9693 nonContentHeight = this.uiDialog.css({ 9694 height: "auto", 9695 width: options.width 9696 }) 9697 .outerHeight(); 9698 minContentHeight = Math.max(0, options.minHeight - nonContentHeight); 9699 9700 if (options.height === "auto") { 9701 // only needed for IE6 support
9702 if ($.support.minHeight) { 9703 this.element.css({ 9704 minHeight: minContentHeight, 9705 height: "auto" 9706 }); 9707 } else { 9708 this.uiDialog.show(); 9709 autoHeight = this.element.css("height", "auto").height(); 9710 if (!isVisible) { 9711 this.uiDialog.hide(); 9712 } 9713 this.element.height(Math.max(autoHeight, minContentHeight)); 9714 } 9715 } else { 9716 this.element.height(Math.max(options.height - nonContentHeight, 0)); 9717 } 9718 9719 if (this.uiDialog.is(":data(resizable)")) { 9720 this.uiDialog.resizable("option", "minHeight", this._minHeight()); 9721 } 9722 } 9723 }); 9724 9725 $.extend($.ui.dialog, { 9726 uuid: 0, 9727 maxZ: 0, 9728 9729 getTitleId: function ($el) { 9730 var id = $el.attr("id"); 9731 if (!id) { 9732 this.uuid += 1; 9733 id = this.uuid; 9734 } 9735 return "ui-dialog-title-" + id; 9736 }, 9737 9738 overlay: function (dialog) { 9739 this.$el = $.ui.dialog.overlay.create(dialog); 9740 } 9741 }); 9742 9743 $.extend($.ui.dialog.overlay, { 9744 instances: [], 9745 // reuse old instances due to IE memory leak with alpha transparency (see #5185) 9746 oldInstances: [], 9747 maxZ: 0, 9748 events: $.map( 9749 "focus,mousedown,mouseup,keydown,keypress,click".split(","), 9750 function (event) { 9751 return event + ".dialog-overlay"; 9752 } 9753 ).join(" "), 9754 create: function (dialog) { 9755 if (this.instances.length === 0) { 9756 // prevent use of anchors and inputs 9757 // we use a setTimeout in case the overlay is created from an 9758 // event that we're going to be cancelling (see #2804) 9759 setTimeout(function () { 9760 // handle $(el).dialog().dialog('close') (see #4065) 9761 if ($.ui.dialog.overlay.instances.length) { 9762 $(document).bind($.ui.dialog.overlay.events, function (event) { 9763 // stop events if the z-index of the target is < the z-index of the overlay 9764 // we cannot return true when we don't want to cancel the event (#3523) 9765 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) { 9766 return false; 9767 } 9768 }); 9769 } 9770 }, 1); 9771 9772 // handle window resize 9773 $(window).bind("resize.dialog-overlay", $.ui.dialog.overlay.resize); 9774 } 9775 9776 var $el = (this.oldInstances.pop() || $("<div>").addClass("ui-widget-overlay")); 9777 9778 // allow closing by pressing the escape key 9779 $(document).bind("keydown.dialog-overlay", function (event) { 9780 var instances = $.ui.dialog.overlay.instances; 9781 // only react to the event if we're the top overlay 9782 if (instances.length !== 0 && instances[instances.length - 1] === $el && 9783 dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9784 event.keyCode === $.ui.keyCode.ESCAPE) { 9785 9786 dialog.close(event); 9787 event.preventDefault(); 9788 } 9789 }); 9790 9791 $el.appendTo(document.body).css({ 9792 width: this.width(), 9793 height: this.height() 9794 }); 9795 9796 if ($.fn.bgiframe) { 9797 $el.bgiframe(); 9798 } 9799 9800 this.instances.push($el); 9801 return $el; 9802 }, 9803 9804 destroy: function ($el) { 9805 var indexOf = $.inArray($el, this.instances), 9806 maxZ = 0; 9807 9808 if (indexOf !== -1) { 9809 this.oldInstances.push(this.instances.splice(indexOf, 1)[0]); 9810 } 9811 9812 if (this.instances.length === 0) { 9813 $([document, window]).unbind(".dialog-overlay"); 9814 } 9815 9816 $el.height(0).width(0).remove(); 9817 9818 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 9819 $.each(this.instances, function () { 9820 maxZ = Math.max(maxZ, this.css("z-index")); 9821 }); 9822 this.maxZ = maxZ; 9823 }, 9824 9825 height: function () { 9826 var scrollHeight, 9827 offsetHeight; 9828 // handle IE 9829 if ($.ui.ie) { 9830 scrollHeight = Math.max( 9831 document.documentElement.scrollHeight, 9832 document.body.scrollHeight 9833 ); 9834 offsetHeight = Math.max( 9835 document.documentElement.offsetHeight, 9836 document.body.offsetHeight 9837 ); 9838 9839 if (scrollHeight < offsetHeight) { 9840 return $(window).height() + "px"; 9841 } else { 9842 return scrollHeight + "px"; 9843 } 9844 // handle "good" browsers 9845 } else { 9846 return $(document).height() + "px"; 9847 } 9848 }, 9849 9850 width: function () { 9851 var scrollWidth, 9852 offsetWidth; 9853 // handle IE 9854 if ($.ui.ie) { 9855 scrollWidth = Math.max( 9856 document.documentElement.scrollWidth, 9857 document.body.scrollWidth 9858 ); 9859 offsetWidth = Math.max( 9860 document.documentElement.offsetWidth, 9861 document.body.offsetWidth 9862 ); 9863 9864 if (scrollWidth < offsetWidth) { 9865 return $(window).width() + "px"; 9866 } else { 9867 return scrollWidth + "px"; 9868 } 9869 // handle "good" browsers 9870 } else { 9871 return $(document).width() + "px"; 9872 } 9873 }, 9874 9875 resize: function () { 9876 /* If the dialog is draggable and the user drags it past the 9877 * right edge of the window, the document becomes wider so we 9878 * need to stretch the overlay. If the user then drags the 9879 * dialog back to the left, the document will become narrower, 9880 * so we need to shrink the overlay to the appropriate size. 9881 * This is handled by shrinking the overlay before setting it 9882 * to the full document size. 9883 */ 9884 var $overlays = $([]); 9885 $.each($.ui.dialog.overlay.instances, function () { 9886 $overlays = $overlays.add(this); 9887 }); 9888 9889 $overlays.css({ 9890 width: 0, 9891 height: 0 9892 }).css({ 9893 width: $.ui.dialog.overlay.width(), 9894 height: $.ui.dialog.overlay.height() 9895 }); 9896 } 9897 });
vendor: 75,916 bytes, lines 9898-11942
9898 9899 $.extend($.ui.dialog.overlay.prototype, { 9900 destroy: function () { 9901 $.ui.dialog.overlay.destroy(this.$el); 9902 } 9903 }); 9904 9905}(jQuery)); 9906 9907(function ($, undefined) { 9908 9909 var rvertical = /up|down|vertical/, 9910 rpositivemotion = /up|left|vertical|horizontal/; 9911 9912 $.effects.effect.blind = function (o, done) { 9913 // Create element 9914 var el = $(this), 9915 props = ["position", "top", "bottom", "left", "right", "height", "width"], 9916 mode = $.effects.setMode(el, o.mode || "hide"), 9917 direction = o.direction || "up", 9918 vertical = rvertical.test(direction), 9919 ref = vertical ? "height" : "width", 9920 ref2 = vertical ? "top" : "left", 9921 motion = rpositivemotion.test(direction), 9922 animation = {}, 9923 show = mode === "show", 9924 wrapper, distance, margin; 9925 9926 // if already wrapped, the wrapper's properties are my property. #6245 9927 if (el.parent().is(".ui-effects-wrapper")) { 9928 $.effects.save(el.parent(), props); 9929 } else { 9930 $.effects.save(el, props); 9931 } 9932 el.show(); 9933 wrapper = $.effects.createWrapper(el).css({ 9934 overflow: "hidden" 9935 }); 9936 9937 distance = wrapper[ref](); 9938 margin = parseFloat(wrapper.css(ref2)) || 0; 9939 9940 animation[ref] = show ? distance : 0; 9941 if (!motion) { 9942 el 9943 .css(vertical ? "bottom" : "right", 0) 9944 .css(vertical ? "top" : "left", "auto") 9945 .css({ position: "absolute" }); 9946 9947 animation[ref2] = show ? margin : distance + margin; 9948 } 9949 9950 // start at 0 if we are showing 9951 if (show) { 9952 wrapper.css(ref, 0); 9953 if (!motion) { 9954 wrapper.css(ref2, margin + distance); 9955 } 9956 } 9957 9958 // Animate 9959 wrapper.animate(animation, { 9960 duration: o.duration, 9961 easing: o.easing, 9962 queue: false, 9963 complete: function () { 9964 if (mode === "hide") { 9965 el.hide(); 9966 } 9967 $.effects.restore(el, props); 9968 $.effects.removeWrapper(el); 9969 done(); 9970 } 9971 }); 9972 9973 }; 9974 9975})(jQuery); 9976 9977(function ($, undefined) { 9978 9979 $.effects.effect.bounce = function (o, done) { 9980 var el = $(this), 9981 props = ["position", "top", "bottom", "left", "right", "height", "width"], 9982 9983 // defaults: 9984 mode = $.effects.setMode(el, o.mode || "effect"), 9985 hide = mode === "hide", 9986 show = mode === "show", 9987 direction = o.direction || "up", 9988 distance = o.distance, 9989 times = o.times || 5, 9990 9991 // number of internal animations 9992 anims = times * 2 + (show || hide ? 1 : 0), 9993 speed = o.duration / anims, 9994 easing = o.easing, 9995 9996 // utility: 9997 ref = (direction === "up" || direction === "down") ? "top" : "left", 9998 motion = (direction === "up" || direction === "left"), 9999 i, 10000 upAnim, 10001 downAnim, 10002 10003 // we will need to re-assemble the queue to stack our animations in place 10004 queue = el.queue(), 10005 queuelen = queue.length; 10006 10007 // Avoid touching opacity to prevent clearType and PNG issues in IE 10008 if (show || hide) { 10009 props.push("opacity"); 10010 } 10011 10012 $.effects.save(el, props); 10013 el.show(); 10014 $.effects.createWrapper(el); // Create Wrapper 10015 10016 // default distance for the BIGGEST bounce is the outer Distance / 3 10017 if (!distance) { 10018 distance = el[ref === "top" ? "outerHeight" : "outerWidth"]() / 3; 10019 } 10020 10021 if (show) { 10022 downAnim = { opacity: 1 }; 10023 downAnim[ref] = 0; 10024 10025 // if we are showing, force opacity 0 and set the initial position 10026 // then do the "first" animation 10027 el.css("opacity", 0) 10028 .css(ref, motion ? -distance * 2 : distance * 2) 10029 .animate(downAnim, speed, easing); 10030 } 10031 10032 // start at the smallest distance if we are hiding 10033 if (hide) { 10034 distance = distance / Math.pow(2, times - 1); 10035 } 10036 10037 downAnim = {}; 10038 downAnim[ref] = 0; 10039 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 10040 for (i = 0; i < times; i++) { 10041 upAnim = {}; 10042 upAnim[ref] = (motion ? "-=" : "+=") + distance; 10043 10044 el.animate(upAnim, speed, easing) 10045 .animate(downAnim, speed, easing); 10046 10047 distance = hide ? distance * 2 : distance / 2; 10048 } 10049 10050 // Last Bounce when Hiding 10051 if (hide) { 10052 upAnim = { opacity: 0 }; 10053 upAnim[ref] = (motion ? "-=" : "+=") + distance; 10054 10055 el.animate(upAnim, speed, easing); 10056 } 10057 10058 el.queue(function () { 10059 if (hide) { 10060 el.hide(); 10061 } 10062 $.effects.restore(el, props); 10063 $.effects.removeWrapper(el); 10064 done(); 10065 }); 10066 10067 // inject all the animations we just queued to be first in line (after "inprogress") 10068 if (queuelen > 1) { 10069 queue.splice.apply(queue, 10070 [1, 0].concat(queue.splice(queuelen, anims + 1))); 10071 } 10072 el.dequeue(); 10073 10074 }; 10075 10076})(jQuery); 10077 10078(function ($, undefined) { 10079 10080 $.effects.effect.clip = function (o, done) { 10081 // Create element 10082 var el = $(this), 10083 props = ["position", "top", "bottom", "left", "right", "height", "width"], 10084 mode = $.effects.setMode(el, o.mode || "hide"), 10085 show = mode === "show", 10086 direction = o.direction || "vertical", 10087 vert = direction === "vertical", 10088 size = vert ? "height" : "width", 10089 position = vert ? "top" : "left", 10090 animation = {}, 10091 wrapper, animate, distance; 10092 10093 // Save & Show 10094 $.effects.save(el, props); 10095 el.show(); 10096 10097 // Create Wrapper 10098 wrapper = $.effects.createWrapper(el).css({ 10099 overflow: "hidden" 10100 }); 10101 animate = (el[0].tagName === "IMG") ? wrapper : el; 10102 distance = animate[size](); 10103 10104 // Shift 10105 if (show) { 10106 animate.css(size, 0); 10107 animate.css(position, distance / 2); 10108 } 10109 10110 // Create Animation Object: 10111 animation[size] = show ? distance : 0; 10112 animation[position] = show ? 0 : distance / 2; 10113 10114 // Animate 10115 animate.animate(animation, { 10116 queue: false, 10117 duration: o.duration, 10118 easing: o.easing, 10119 complete: function () { 10120 if (!show) { 10121 el.hide(); 10122 } 10123 $.effects.restore(el, props); 10124 $.effects.removeWrapper(el); 10125 done(); 10126 } 10127 }); 10128 10129 }; 10130 10131})(jQuery); 10132 10133(function ($, undefined) { 10134 10135 $.effects.effect.drop = function (o, done) { 10136 10137 var el = $(this), 10138 props = ["position", "top", "bottom", "left", "right", "opacity", "height", "width"], 10139 mode = $.effects.setMode(el, o.mode || "hide"), 10140 show = mode === "show", 10141 direction = o.direction || "left", 10142 ref = (direction === "up" || direction === "down") ? "top" : "left", 10143 motion = (direction === "up" || direction === "left") ? "pos" : "neg", 10144 animation = { 10145 opacity: show ? 1 : 0 10146 }, 10147 distance; 10148 10149 // Adjust 10150 $.effects.save(el, props); 10151 el.show(); 10152 $.effects.createWrapper(el); 10153 10154 distance = o.distance || el[ref === "top" ? "outerHeight" : "outerWidth"](true) / 2; 10155 10156 if (show) { 10157 el 10158 .css("opacity", 0) 10159 .css(ref, motion === "pos" ? -distance : distance); 10160 } 10161 10162 // Animation 10163 animation[ref] = (show ? 10164 (motion === "pos" ? "+=" : "-=") : 10165 (motion === "pos" ? "-=" : "+=")) + 10166 distance; 10167 10168 // Animate 10169 el.animate(animation, { 10170 queue: false, 10171 duration: o.duration, 10172 easing: o.easing, 10173 complete: function () { 10174 if (mode === "hide") { 10175 el.hide(); 10176 } 10177 $.effects.restore(el, props); 10178 $.effects.removeWrapper(el); 10179 done(); 10180 } 10181 }); 10182 }; 10183 10184})(jQuery); 10185 10186(function ($, undefined) { 10187 10188 $.effects.effect.explode = function (o, done) { 10189 10190 var rows = o.pieces ? Math.round(Math.sqrt(o.pieces)) : 3, 10191 cells = rows, 10192 el = $(this), 10193 mode = $.effects.setMode(el, o.mode || "hide"), 10194 show = mode === "show", 10195 10196 // show and then visibility:hidden the element before calculating offset 10197 offset = el.show().css("visibility", "hidden").offset(), 10198 10199 // width and height of a piece 10200 width = Math.ceil(el.outerWidth() / cells), 10201 height = Math.ceil(el.outerHeight() / rows), 10202 pieces = [], 10203 10204 // loop 10205 i, j, left, top, mx, my; 10206 10207 // children animate complete: 10208 function childComplete() { 10209 pieces.push(this); 10210 if (pieces.length === rows * cells) { 10211 animComplete(); 10212 } 10213 } 10214 10215 // clone the element for each row and cell. 10216 for (i = 0; i < rows ; i++) { // ===> 10217 top = offset.top + i * height; 10218 my = i - (rows - 1) / 2; 10219 10220 for (j = 0; j < cells ; j++) { // ||| 10221 left = offset.left + j * width; 10222 mx = j - (cells - 1) / 2; 10223 10224 // Create a clone of the now hidden main element that will be absolute positioned 10225 // within a wrapper div off the -left and -top equal to size of our pieces 10226 el 10227 .clone() 10228 .appendTo("body") 10229 .wrap("<div></div>") 10230 .css({ 10231 position: "absolute", 10232 visibility: "visible", 10233 left: -j * width, 10234 top: -i * height 10235 }) 10236 10237 // select the wrapper - make it overflow: hidden and absolute positioned based on 10238 // where the original was located +left and +top equal to the size of pieces 10239 .parent() 10240 .addClass("ui-effects-explode") 10241 .css({ 10242 position: "absolute", 10243 overflow: "hidden", 10244 width: width, 10245 height: height, 10246 left: left + (show ? mx * width : 0), 10247 top: top + (show ? my * height : 0), 10248 opacity: show ? 0 : 1 10249 }).animate({ 10250 left: left + (show ? 0 : mx * width), 10251 top: top + (show ? 0 : my * height), 10252 opacity: show ? 1 : 0 10253 }, o.duration || 500, o.easing, childComplete); 10254 } 10255 } 10256 10257 function animComplete() { 10258 el.css({ 10259 visibility: "visible" 10260 }); 10261 $(pieces).remove(); 10262 if (!show) { 10263 el.hide(); 10264 } 10265 done(); 10266 } 10267 }; 10268 10269})(jQuery); 10270 10271(function ($, undefined) { 10272 10273 $.effects.effect.fade = function (o, done) { 10274 var el = $(this), 10275 mode = $.effects.setMode(el, o.mode || "toggle"); 10276 10277 el.animate({ 10278 opacity: mode 10279 }, { 10280 queue: false, 10281 duration: o.duration, 10282 easing: o.easing, 10283 complete: done 10284 }); 10285 }; 10286 10287})(jQuery); 10288 10289(function ($, undefined) { 10290 10291 $.effects.effect.fold = function (o, done) { 10292 10293 // Create element 10294 var el = $(this), 10295 props = ["position", "top", "bottom", "left", "right", "height", "width"], 10296 mode = $.effects.setMode(el, o.mode || "hide"), 10297 show = mode === "show", 10298 hide = mode === "hide", 10299 size = o.size || 15, 10300 percent = /([0-9]+)%/.exec(size), 10301 horizFirst = !!o.horizFirst, 10302 widthFirst = show !== horizFirst, 10303 ref = widthFirst ? ["width", "height"] : ["height", "width"], 10304 duration = o.duration / 2, 10305 wrapper, distance, 10306 animation1 = {}, 10307 animation2 = {}; 10308 10309 $.effects.save(el, props); 10310 el.show(); 10311 10312 // Create Wrapper 10313 wrapper = $.effects.createWrapper(el).css({ 10314 overflow: "hidden" 10315 }); 10316 distance = widthFirst ? 10317 [wrapper.width(), wrapper.height()] : 10318 [wrapper.height(), wrapper.width()]; 10319 10320 if (percent) { 10321 size = parseInt(percent[1], 10) / 100 * distance[hide ? 0 : 1]; 10322 } 10323 if (show) { 10324 wrapper.css(horizFirst ? { 10325 height: 0, 10326 width: size 10327 } : { 10328 height: size, 10329 width: 0 10330 }); 10331 } 10332 10333 // Animation 10334 animation1[ref[0]] = show ? distance[0] : size; 10335 animation2[ref[1]] = show ? distance[1] : 0; 10336 10337 // Animate 10338 wrapper 10339 .animate(animation1, duration, o.easing) 10340 .animate(animation2, duration, o.easing, function () { 10341 if (hide) { 10342 el.hide(); 10343 } 10344 $.effects.restore(el, props); 10345 $.effects.removeWrapper(el); 10346 done(); 10347 }); 10348 10349 }; 10350 10351})(jQuery); 10352 10353(function ($, undefined) { 10354 10355 $.effects.effect.highlight = function (o, done) { 10356 var elem = $(this), 10357 props = ["backgroundImage", "backgroundColor", "opacity"], 10358 mode = $.effects.setMode(elem, o.mode || "show"), 10359 animation = { 10360 backgroundColor: elem.css("backgroundColor") 10361 }; 10362 10363 if (mode === "hide") { 10364 animation.opacity = 0; 10365 } 10366 10367 $.effects.save(elem, props); 10368 10369 elem 10370 .show() 10371 .css({ 10372 backgroundImage: "none", 10373 backgroundColor: o.color || "#ffff99" 10374 }) 10375 .animate(animation, { 10376 queue: false, 10377 duration: o.duration, 10378 easing: o.easing, 10379 complete: function () { 10380 if (mode === "hide") { 10381 elem.hide(); 10382 } 10383 $.effects.restore(elem, props); 10384 done(); 10385 } 10386 }); 10387 }; 10388 10389})(jQuery); 10390 10391(function ($, undefined) { 10392 10393 $.effects.effect.pulsate = function (o, done) { 10394 var elem = $(this), 10395 mode = $.effects.setMode(elem, o.mode || "show"), 10396 show = mode === "show", 10397 hide = mode === "hide", 10398 showhide = (show || mode === "hide"), 10399 10400 // showing or hiding leaves of the "last" animation 10401 anims = ((o.times || 5) * 2) + (showhide ? 1 : 0), 10402 duration = o.duration / anims, 10403 animateTo = 0, 10404 queue = elem.queue(), 10405 queuelen = queue.length, 10406 i; 10407 10408 if (show || !elem.is(":visible")) { 10409 elem.css("opacity", 0).show(); 10410 animateTo = 1; 10411 } 10412 10413 // anims - 1 opacity "toggles" 10414 for (i = 1; i < anims; i++) { 10415 elem.animate({ 10416 opacity: animateTo 10417 }, duration, o.easing); 10418 animateTo = 1 - animateTo; 10419 } 10420 10421 elem.animate({ 10422 opacity: animateTo 10423 }, duration, o.easing); 10424 10425 elem.queue(function () { 10426 if (hide) { 10427 elem.hide(); 10428 } 10429 done(); 10430 }); 10431 10432 // We just queued up "anims" animations, we need to put them next in the queue 10433 if (queuelen > 1) { 10434 queue.splice.apply(queue, 10435 [1, 0].concat(queue.splice(queuelen, anims + 1))); 10436 } 10437 elem.dequeue(); 10438 }; 10439 10440})(jQuery); 10441 10442(function ($, undefined) { 10443 10444 $.effects.effect.puff = function (o, done) { 10445 var elem = $(this), 10446 mode = $.effects.setMode(elem, o.mode || "hide"), 10447 hide = mode === "hide", 10448 percent = parseInt(o.percent, 10) || 150, 10449 factor = percent / 100, 10450 original = { 10451 height: elem.height(), 10452 width: elem.width(), 10453 outerHeight: elem.outerHeight(), 10454 outerWidth: elem.outerWidth() 10455 }; 10456 10457 $.extend(o, { 10458 effect: "scale", 10459 queue: false, 10460 fade: true, 10461 mode: mode, 10462 complete: done, 10463 percent: hide ? percent : 100, 10464 from: hide ? 10465 original : 10466 { 10467 height: original.height * factor, 10468 width: original.width * factor, 10469 outerHeight: original.outerHeight * factor, 10470 outerWidth: original.outerWidth * factor 10471 } 10472 }); 10473 10474 elem.effect(o); 10475 }; 10476 10477 $.effects.effect.scale = function (o, done) { 10478 10479 // Create element 10480 var el = $(this), 10481 options = $.extend(true, {}, o), 10482 mode = $.effects.setMode(el, o.mode || "effect"), 10483 percent = parseInt(o.percent, 10) || 10484 (parseInt(o.percent, 10) === 0 ? 0 : (mode === "hide" ? 0 : 100)), 10485 direction = o.direction || "both", 10486 origin = o.origin, 10487 original = { 10488 height: el.height(), 10489 width: el.width(), 10490 outerHeight: el.outerHeight(), 10491 outerWidth: el.outerWidth() 10492 }, 10493 factor = { 10494 y: direction !== "horizontal" ? (percent / 100) : 1, 10495 x: direction !== "vertical" ? (percent / 100) : 1 10496 }; 10497 10498 // We are going to pass this effect to the size effect: 10499 options.effect = "size"; 10500 options.queue = false; 10501 options.complete = done; 10502 10503 // Set default origin and restore for show/hide 10504 if (mode !== "effect") { 10505 options.origin = origin || ["middle", "center"]; 10506 options.restore = true; 10507 } 10508 10509 options.from = o.from || (mode === "show" ? { 10510 height: 0, 10511 width: 0, 10512 outerHeight: 0, 10513 outerWidth: 0 10514 } : original); 10515 options.to = { 10516 height: original.height * factor.y, 10517 width: original.width * factor.x, 10518 outerHeight: original.outerHeight * factor.y, 10519 outerWidth: original.outerWidth * factor.x 10520 }; 10521 10522 // Fade option to support puff 10523 if (options.fade) { 10524 if (mode === "show") { 10525 options.from.opacity = 0; 10526 options.to.opacity = 1; 10527 } 10528 if (mode === "hide") { 10529 options.from.opacity = 1; 10530 options.to.opacity = 0; 10531 } 10532 } 10533 10534 // Animate 10535 el.effect(options); 10536 10537 }; 10538 10539 $.effects.effect.size = function (o, done) { 10540 10541 // Create element 10542 var original, baseline, factor, 10543 el = $(this), 10544 props0 = ["position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity"], 10545 10546 // Always restore 10547 props1 = ["position", "top", "bottom", "left", "right", "overflow", "opacity"], 10548 10549 // Copy for children 10550 props2 = ["width", "height", "overflow"], 10551 cProps = ["fontSize"], 10552 vProps = ["borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom"], 10553 hProps = ["borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight"], 10554 10555 // Set options 10556 mode = $.effects.setMode(el, o.mode || "effect"), 10557 restore = o.restore || mode !== "effect", 10558 scale = o.scale || "both", 10559 origin = o.origin || ["middle", "center"], 10560 position = el.css("position"), 10561 props = restore ? props0 : props1, 10562 zero = { 10563 height: 0, 10564 width: 0, 10565 outerHeight: 0, 10566 outerWidth: 0 10567 }; 10568 10569 if (mode === "show") { 10570 el.show(); 10571 } 10572 original = { 10573 height: el.height(), 10574 width: el.width(), 10575 outerHeight: el.outerHeight(), 10576 outerWidth: el.outerWidth() 10577 }; 10578 10579 if (o.mode === "toggle" && mode === "show") { 10580 el.from = o.to || zero; 10581 el.to = o.from || original; 10582 } else { 10583 el.from = o.from || (mode === "show" ? zero : original); 10584 el.to = o.to || (mode === "hide" ? zero : original); 10585 } 10586 10587 // Set scaling factor 10588 factor = { 10589 from: { 10590 y: el.from.height / original.height, 10591 x: el.from.width / original.width 10592 }, 10593 to: { 10594 y: el.to.height / original.height, 10595 x: el.to.width / original.width 10596 } 10597 }; 10598 10599 // Scale the css box 10600 if (scale === "box" || scale === "both") { 10601 10602 // Vertical props scaling 10603 if (factor.from.y !== factor.to.y) { 10604 props = props.concat(vProps); 10605 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from); 10606 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to); 10607 } 10608 10609 // Horizontal props scaling 10610 if (factor.from.x !== factor.to.x) { 10611 props = props.concat(hProps); 10612 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from); 10613 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to); 10614 } 10615 } 10616 10617 // Scale the content 10618 if (scale === "content" || scale === "both") { 10619 10620 // Vertical props scaling 10621 if (factor.from.y !== factor.to.y) { 10622 props = props.concat(cProps).concat(props2); 10623 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from); 10624 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to); 10625 } 10626 } 10627 10628 $.effects.save(el, props); 10629 el.show(); 10630 $.effects.createWrapper(el); 10631 el.css("overflow", "hidden").css(el.from); 10632 10633 // Adjust 10634 if (origin) { // Calculate baseline shifts 10635 baseline = $.effects.getBaseline(origin, original); 10636 el.from.top = (original.outerHeight - el.outerHeight()) * baseline.y; 10637 el.from.left = (original.outerWidth - el.outerWidth()) * baseline.x; 10638 el.to.top = (original.outerHeight - el.to.outerHeight) * baseline.y; 10639 el.to.left = (original.outerWidth - el.to.outerWidth) * baseline.x; 10640 } 10641 el.css(el.from); // set top & left 10642 10643 // Animate 10644 if (scale === "content" || scale === "both") { // Scale the children 10645 10646 // Add margins/font-size 10647 vProps = vProps.concat(["marginTop", "marginBottom"]).concat(cProps); 10648 hProps = hProps.concat(["marginLeft", "marginRight"]); 10649 props2 = props0.concat(vProps).concat(hProps); 10650 10651 el.find("*[width]").each(function () { 10652 var child = $(this), 10653 c_original = { 10654 height: child.height(), 10655 width: child.width(), 10656 outerHeight: child.outerHeight(), 10657 outerWidth: child.outerWidth() 10658 }; 10659 if (restore) { 10660 $.effects.save(child, props2); 10661 } 10662 10663 child.from = { 10664 height: c_original.height * factor.from.y, 10665 width: c_original.width * factor.from.x, 10666 outerHeight: c_original.outerHeight * factor.from.y, 10667 outerWidth: c_original.outerWidth * factor.from.x 10668 }; 10669 child.to = { 10670 height: c_original.height * factor.to.y, 10671 width: c_original.width * factor.to.x, 10672 outerHeight: c_original.height * factor.to.y, 10673 outerWidth: c_original.width * factor.to.x 10674 }; 10675 10676 // Vertical props scaling 10677 if (factor.from.y !== factor.to.y) { 10678 child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from); 10679 child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to); 10680 } 10681 10682 // Horizontal props scaling 10683 if (factor.from.x !== factor.to.x) { 10684 child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from); 10685 child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to); 10686 } 10687 10688 // Animate children 10689 child.css(child.from); 10690 child.animate(child.to, o.duration, o.easing, function () { 10691 10692 // Restore children 10693 if (restore) { 10694 $.effects.restore(child, props2); 10695 } 10696 }); 10697 }); 10698 } 10699 10700 // Animate 10701 el.animate(el.to, { 10702 queue: false, 10703 duration: o.duration, 10704 easing: o.easing, 10705 complete: function () { 10706 if (el.to.opacity === 0) { 10707 el.css("opacity", el.from.opacity); 10708 } 10709 if (mode === "hide") { 10710 el.hide(); 10711 } 10712 $.effects.restore(el, props); 10713 if (!restore) { 10714 10715 // we need to calculate our new positioning based on the scaling 10716 if (position === "static") { 10717 el.css({ 10718 position: "relative", 10719 top: el.to.top, 10720 left: el.to.left 10721 }); 10722 } else { 10723 $.each(["top", "left"], function (idx, pos) { 10724 el.css(pos, function (_, str) { 10725 var val = parseInt(str, 10), 10726 toRef = idx ? el.to.left : el.to.top; 10727 10728 // if original was "auto", recalculate the new value from wrapper 10729 if (str === "auto") { 10730 return toRef + "px"; 10731 } 10732 10733 return val + toRef + "px"; 10734 }); 10735 }); 10736 } 10737 } 10738 10739 $.effects.removeWrapper(el); 10740 done(); 10741 } 10742 }); 10743 10744 }; 10745 10746})(jQuery); 10747 10748(function ($, undefined) { 10749 10750 $.effects.effect.shake = function (o, done) { 10751 10752 var el = $(this), 10753 props = ["position", "top", "bottom", "left", "right", "height", "width"], 10754 mode = $.effects.setMode(el, o.mode || "effect"), 10755 direction = o.direction || "left", 10756 distance = o.distance || 20, 10757 times = o.times || 3, 10758 anims = times * 2 + 1, 10759 speed = Math.round(o.duration / anims), 10760 ref = (direction === "up" || direction === "down") ? "top" : "left", 10761 positiveMotion = (direction === "up" || direction === "left"), 10762 animation = {}, 10763 animation1 = {}, 10764 animation2 = {}, 10765 i, 10766 10767 // we will need to re-assemble the queue to stack our animations in place 10768 queue = el.queue(), 10769 queuelen = queue.length; 10770 10771 $.effects.save(el, props); 10772 el.show(); 10773 $.effects.createWrapper(el); 10774 10775 // Animation 10776 animation[ref] = (positiveMotion ? "-=" : "+=") + distance; 10777 animation1[ref] = (positiveMotion ? "+=" : "-=") + distance * 2; 10778 animation2[ref] = (positiveMotion ? "-=" : "+=") + distance * 2; 10779 10780 // Animate 10781 el.animate(animation, speed, o.easing); 10782 10783 // Shakes 10784 for (i = 1; i < times; i++) { 10785 el.animate(animation1, speed, o.easing).animate(animation2, speed, o.easing); 10786 } 10787 el 10788 .animate(animation1, speed, o.easing) 10789 .animate(animation, speed / 2, o.easing) 10790 .queue(function () { 10791 if (mode === "hide") { 10792 el.hide(); 10793 } 10794 $.effects.restore(el, props); 10795 $.effects.removeWrapper(el); 10796 done(); 10797 }); 10798 10799 // inject all the animations we just queued to be first in line (after "inprogress") 10800 if (queuelen > 1) { 10801 queue.splice.apply(queue, 10802 [1, 0].concat(queue.splice(queuelen, anims + 1))); 10803 } 10804 el.dequeue(); 10805 10806 }; 10807 10808})(jQuery); 10809 10810(function ($, undefined) { 10811 10812 $.effects.effect.slide = function (o, done) { 10813 10814 // Create element 10815 var el = $(this), 10816 props = ["position", "top", "bottom", "left", "right", "width", "height"], 10817 mode = $.effects.setMode(el, o.mode || "show"), 10818 show = mode === "show", 10819 direction = o.direction || "left", 10820 ref = (direction === "up" || direction === "down") ? "top" : "left", 10821 positiveMotion = (direction === "up" || direction === "left"), 10822 distance, 10823 animation = {}; 10824 10825 // Adjust 10826 $.effects.save(el, props); 10827 el.show(); 10828 distance = o.distance || el[ref === "top" ? "outerHeight" : "outerWidth"](true); 10829 10830 $.effects.createWrapper(el).css({ 10831 overflow: "hidden" 10832 }); 10833 10834 if (show) { 10835 el.css(ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance); 10836 } 10837 10838 // Animation 10839 animation[ref] = (show ? 10840 (positiveMotion ? "+=" : "-=") : 10841 (positiveMotion ? "-=" : "+=")) + 10842 distance; 10843 10844 // Animate 10845 el.animate(animation, { 10846 queue: false, 10847 duration: o.duration, 10848 easing: o.easing, 10849 complete: function () { 10850 if (mode === "hide") { 10851 el.hide(); 10852 } 10853 $.effects.restore(el, props); 10854 $.effects.removeWrapper(el); 10855 done(); 10856 } 10857 }); 10858 }; 10859 10860})(jQuery); 10861 10862(function ($, undefined) { 10863 10864 $.effects.effect.transfer = function (o, done) { 10865 var elem = $(this), 10866 target = $(o.to), 10867 targetFixed = target.css("position") === "fixed", 10868 body = $("body"), 10869 fixTop = targetFixed ? body.scrollTop() : 0, 10870 fixLeft = targetFixed ? body.scrollLeft() : 0, 10871 endPosition = target.offset(), 10872 animation = { 10873 top: endPosition.top - fixTop, 10874 left: endPosition.left - fixLeft, 10875 height: target.innerHeight(), 10876 width: target.innerWidth() 10877 }, 10878 startPosition = elem.offset(), 10879 transfer = $('<div class="ui-effects-transfer"></div>') 10880 .appendTo(document.body) 10881 .addClass(o.className) 10882 .css({ 10883 top: startPosition.top - fixTop, 10884 left: startPosition.left - fixLeft, 10885 height: elem.innerHeight(), 10886 width: elem.innerWidth(), 10887 position: targetFixed ? "fixed" : "absolute" 10888 }) 10889 .animate(animation, o.duration, o.easing, function () { 10890 transfer.remove(); 10891 done(); 10892 }); 10893 }; 10894 10895})(jQuery); 10896 10897(function ($, undefined) { 10898 10899 var mouseHandled = false; 10900 10901 $.widget("ui.menu", { 10902 version: "1.9.2", 10903 defaultElement: "<ul>", 10904 delay: 300, 10905 options: { 10906 icons: { 10907 submenu: "ui-icon-carat-1-e" 10908 }, 10909 menus: "ul", 10910 position: { 10911 my: "left top", 10912 at: "right top" 10913 }, 10914 role: "menu", 10915 10916 // callbacks 10917 blur: null, 10918 focus: null, 10919 select: null 10920 }, 10921 10922 _create: function () { 10923 this.activeMenu = this.element; 10924 this.element 10925 .uniqueId() 10926 .addClass("ui-menu ui-widget ui-widget-content ui-corner-all") 10927 .toggleClass("ui-menu-icons", !!this.element.find(".ui-icon").length) 10928 .attr({ 10929 role: this.options.role, 10930 tabIndex: 0 10931 }) 10932 // need to catch all clicks on disabled menu 10933 // not possible through _on 10934 .bind("click" + this.eventNamespace, $.proxy(function (event) { 10935 if (this.options.disabled) { 10936 event.preventDefault(); 10937 } 10938 }, this)); 10939 10940 if (this.options.disabled) { 10941 this.element 10942 .addClass("ui-state-disabled") 10943 .attr("aria-disabled", "true"); 10944 } 10945 10946 this._on({ 10947 // Prevent focus from sticking to links inside menu after clicking 10948 // them (focus should always stay on UL during navigation). 10949 "mousedown .ui-menu-item > a": function (event) { 10950 event.preventDefault(); 10951 }, 10952 "click .ui-state-disabled > a": function (event) { 10953 event.preventDefault(); 10954 }, 10955 "click .ui-menu-item:has(a)": function (event) { 10956 var target = $(event.target).closest(".ui-menu-item"); 10957 if (!mouseHandled && target.not(".ui-state-disabled").length) { 10958 mouseHandled = true; 10959 10960 this.select(event); 10961 // Open submenu on click 10962 if (target.has(".ui-menu").length) { 10963 this.expand(event); 10964 } else if (!this.element.is(":focus")) { 10965 // Redirect focus to the menu 10966 this.element.trigger("focus", [true]); 10967 10968 // If the active item is on the top level, let it stay active. 10969 // Otherwise, blur the active item since it is no longer visible. 10970 if (this.active && this.active.parents(".ui-menu").length === 1) { 10971 clearTimeout(this.timer); 10972 } 10973 } 10974 } 10975 }, 10976 "mouseenter .ui-menu-item": function (event) { 10977 var target = $(event.currentTarget); 10978 // Remove ui-state-active class from siblings of the newly focused menu item 10979 // to avoid a jump caused by adjacent elements both having a class with a border 10980 target.siblings().children(".ui-state-active").removeClass("ui-state-active"); 10981 this.focus(event, target); 10982 }, 10983 mouseleave: "collapseAll", 10984 "mouseleave .ui-menu": "collapseAll", 10985 focus: function (event, keepActiveItem) { 10986 // If there's already an active item, keep it active 10987 // If not, activate the first item 10988 var item = this.active || this.element.children(".ui-menu-item").eq(0); 10989 10990 if (!keepActiveItem) { 10991 this.focus(event, item); 10992 } 10993 }, 10994 blur: function (event) { 10995 this._delay(function () { 10996 if (!$.contains(this.element[0], this.document[0].activeElement)) { 10997 this.collapseAll(event); 10998 } 10999 }); 11000 }, 11001 keydown: "_keydown" 11002 }); 11003 11004 this.refresh(); 11005 11006 // Clicks outside of a menu collapse any open menus 11007 this._on(this.document, { 11008 click: function (event) { 11009 if (!$(event.target).closest(".ui-menu").length) { 11010 this.collapseAll(event); 11011 } 11012 11013 // Reset the mouseHandled flag 11014 mouseHandled = false; 11015 } 11016 }); 11017 }, 11018 11019 _destroy: function () { 11020 // Destroy (sub)menus 11021 this.element 11022 .removeAttr("aria-activedescendant") 11023 .find(".ui-menu").andSelf() 11024 .removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons") 11025 .removeAttr("role") 11026 .removeAttr("tabIndex") 11027 .removeAttr("aria-labelledby") 11028 .removeAttr("aria-expanded") 11029 .removeAttr("aria-hidden") 11030 .removeAttr("aria-disabled") 11031 .removeUniqueId() 11032 .show(); 11033 11034 // Destroy menu items 11035 this.element.find(".ui-menu-item") 11036 .removeClass("ui-menu-item") 11037 .removeAttr("role") 11038 .removeAttr("aria-disabled") 11039 .children("a") 11040 .removeUniqueId() 11041 .removeClass("ui-corner-all ui-state-hover") 11042 .removeAttr("tabIndex") 11043 .removeAttr("role") 11044 .removeAttr("aria-haspopup") 11045 .children().each(function () { 11046 var elem = $(this); 11047 if (elem.data("ui-menu-submenu-carat")) { 11048 elem.remove(); 11049 } 11050 }); 11051 11052 // Destroy menu dividers 11053 this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content"); 11054 }, 11055 11056 _keydown: function (event) { 11057 var match, prev, character, skip, regex, 11058 preventDefault = true; 11059 11060 function escape(value) { 11061 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 11062 } 11063 11064 switch (event.keyCode) { 11065 case $.ui.keyCode.PAGE_UP: 11066 this.previousPage(event); 11067 break; 11068 case $.ui.keyCode.PAGE_DOWN: 11069 this.nextPage(event); 11070 break; 11071 case $.ui.keyCode.HOME: 11072 this._move("first", "first", event); 11073 break; 11074 case $.ui.keyCode.END: 11075 this._move("last", "last", event); 11076 break; 11077 case $.ui.keyCode.UP: 11078 this.previous(event); 11079 break; 11080 case $.ui.keyCode.DOWN: 11081 this.next(event); 11082 break; 11083 case $.ui.keyCode.LEFT: 11084 this.collapse(event); 11085 break; 11086 case $.ui.keyCode.RIGHT: 11087 if (this.active && !this.active.is(".ui-state-disabled")) { 11088 this.expand(event); 11089 } 11090 break; 11091 case $.ui.keyCode.ENTER: 11092 case $.ui.keyCode.SPACE: 11093 this._activate(event); 11094 break; 11095 case $.ui.keyCode.ESCAPE: 11096 this.collapse(event); 11097 break; 11098 default: 11099 preventDefault = false; 11100 prev = this.previousFilter || ""; 11101 character = String.fromCharCode(event.keyCode); 11102 skip = false; 11103 11104 clearTimeout(this.filterTimer); 11105 11106 if (character === prev) { 11107 skip = true; 11108 } else { 11109 character = prev + character; 11110 } 11111 11112 regex = new RegExp("^" + escape(character), "i"); 11113 match = this.activeMenu.children(".ui-menu-item").filter(function () { 11114 return regex.test($(this).children("a").text()); 11115 }); 11116 match = skip && match.index(this.active.next()) !== -1 ? 11117 this.active.nextAll(".ui-menu-item") : 11118 match; 11119 11120 // If no matches on the current filter, reset to the last character pressed 11121 // to move down the menu to the first item that starts with that character 11122 if (!match.length) { 11123 character = String.fromCharCode(event.keyCode); 11124 regex = new RegExp("^" + escape(character), "i"); 11125 match = this.activeMenu.children(".ui-menu-item").filter(function () { 11126 return regex.test($(this).children("a").text()); 11127 }); 11128 } 11129 11130 if (match.length) { 11131 this.focus(event, match); 11132 if (match.length > 1) { 11133 this.previousFilter = character; 11134 this.filterTimer = this._delay(function () { 11135 delete this.previousFilter; 11136 }, 1000); 11137 } else { 11138 delete this.previousFilter; 11139 } 11140 } else { 11141 delete this.previousFilter; 11142 } 11143 } 11144 11145 if (preventDefault) { 11146 event.preventDefault(); 11147 } 11148 }, 11149 11150 _activate: function (event) { 11151 if (!this.active.is(".ui-state-disabled")) { 11152 if (this.active.children("a[aria-haspopup='true']").length) { 11153 this.expand(event); 11154 } else { 11155 this.select(event); 11156 } 11157 } 11158 }, 11159 11160 refresh: function () { 11161 var menus, 11162 icon = this.options.icons.submenu, 11163 submenus = this.element.find(this.options.menus); 11164 11165 // Initialize nested menus 11166 submenus.filter(":not(.ui-menu)") 11167 .addClass("ui-menu ui-widget ui-widget-content ui-corner-all") 11168 .hide() 11169 .attr({ 11170 role: this.options.role, 11171 "aria-hidden": "true", 11172 "aria-expanded": "false" 11173 }) 11174 .each(function () { 11175 var menu = $(this), 11176 item = menu.prev("a"), 11177 submenuCarat = $("<span>") 11178 .addClass("ui-menu-icon ui-icon " + icon) 11179 .data("ui-menu-submenu-carat", true); 11180 11181 item 11182 .attr("aria-haspopup", "true") 11183 .prepend(submenuCarat); 11184 menu.attr("aria-labelledby", item.attr("id")); 11185 }); 11186 11187 menus = submenus.add(this.element); 11188 11189 // Don't refresh list items that are already adapted 11190 menus.children(":not(.ui-menu-item):has(a)") 11191 .addClass("ui-menu-item") 11192 .attr("role", "presentation") 11193 .children("a") 11194 .uniqueId() 11195 .addClass("ui-corner-all") 11196 .attr({ 11197 tabIndex: -1, 11198 role: this._itemRole() 11199 }); 11200 11201 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 11202 menus.children(":not(.ui-menu-item)").each(function () { 11203 var item = $(this); 11204 // hyphen, em dash, en dash 11205 if (!/[^\-—–\s]/.test(item.text())) { 11206 item.addClass("ui-widget-content ui-menu-divider"); 11207 } 11208 }); 11209 11210 // Add aria-disabled attribute to any disabled menu item 11211 menus.children(".ui-state-disabled").attr("aria-disabled", "true"); 11212 11213 // If the active item has been removed, blur the menu 11214 if (this.active && !$.contains(this.element[0], this.active[0])) { 11215 this.blur(); 11216 } 11217 }, 11218 11219 _itemRole: function () { 11220 return { 11221 menu: "menuitem", 11222 listbox: "option" 11223 }[this.options.role]; 11224 }, 11225 11226 focus: function (event, item) { 11227 var nested, focused; 11228 this.blur(event, event && event.type === "focus"); 11229 11230 this._scrollIntoView(item); 11231 11232 this.active = item.first(); 11233 focused = this.active.children("a").addClass("ui-state-focus"); 11234 // Only update aria-activedescendant if there's a role 11235 // otherwise we assume focus is managed elsewhere 11236 if (this.options.role) { 11237 this.element.attr("aria-activedescendant", focused.attr("id")); 11238 } 11239 11240 // Highlight active parent menu item, if any 11241 this.active 11242 .parent() 11243 .closest(".ui-menu-item") 11244 .children("a:first") 11245 .addClass("ui-state-active"); 11246 11247 if (event && event.type === "keydown") { 11248 this._close(); 11249 } else { 11250 this.timer = this._delay(function () { 11251 this._close(); 11252 }, this.delay); 11253 } 11254 11255 nested = item.children(".ui-menu"); 11256 if (nested.length && (/^mouse/.test(event.type))) { 11257 this._startOpening(nested); 11258 } 11259 this.activeMenu = item.parent(); 11260 11261 this._trigger("focus", event, { item: item }); 11262 }, 11263 11264 _scrollIntoView: function (item) { 11265 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 11266 if (this._hasScroll()) { 11267 borderTop = parseFloat($.css(this.activeMenu[0], "borderTopWidth")) || 0; 11268 paddingTop = parseFloat($.css(this.activeMenu[0], "paddingTop")) || 0; 11269 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 11270 scroll = this.activeMenu.scrollTop(); 11271 elementHeight = this.activeMenu.height(); 11272 itemHeight = item.height(); 11273 11274 if (offset < 0) { 11275 this.activeMenu.scrollTop(scroll + offset); 11276 } else if (offset + itemHeight > elementHeight) { 11277 this.activeMenu.scrollTop(scroll + offset - elementHeight + itemHeight); 11278 } 11279 } 11280 }, 11281 11282 blur: function (event, fromFocus) { 11283 if (!fromFocus) { 11284 clearTimeout(this.timer); 11285 } 11286 11287 if (!this.active) { 11288 return; 11289 } 11290 11291 this.active.children("a").removeClass("ui-state-focus"); 11292 this.active = null; 11293 11294 this._trigger("blur", event, { item: this.active }); 11295 }, 11296 11297 _startOpening: function (submenu) { 11298 clearTimeout(this.timer); 11299 11300 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 11301 // shift in the submenu position when mousing over the carat icon 11302 if (submenu.attr("aria-hidden") !== "true") { 11303 return; 11304 } 11305 11306 this.timer = this._delay(function () { 11307 this._close(); 11308 this._open(submenu); 11309 }, this.delay); 11310 }, 11311 11312 _open: function (submenu) { 11313 var position = $.extend({ 11314 of: this.active 11315 }, this.options.position); 11316 11317 clearTimeout(this.timer); 11318 this.element.find(".ui-menu").not(submenu.parents(".ui-menu")) 11319 .hide() 11320 .attr("aria-hidden", "true"); 11321 11322 submenu 11323 .show() 11324 .removeAttr("aria-hidden") 11325 .attr("aria-expanded", "true") 11326 .position(position); 11327 }, 11328 11329 collapseAll: function (event, all) { 11330 clearTimeout(this.timer); 11331 this.timer = this._delay(function () { 11332 // If we were passed an event, look for the submenu that contains the event 11333 var currentMenu = all ? this.element : 11334 $(event && event.target).closest(this.element.find(".ui-menu")); 11335 11336 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 11337 if (!currentMenu.length) { 11338 currentMenu = this.element; 11339 } 11340 11341 this._close(currentMenu); 11342 11343 this.blur(event); 11344 this.activeMenu = currentMenu; 11345 }, this.delay); 11346 }, 11347 11348 // With no arguments, closes the currently active menu - if nothing is active 11349 // it closes all menus. If passed an argument, it will search for menus BELOW 11350 _close: function (startMenu) { 11351 if (!startMenu) { 11352 startMenu = this.active ? this.active.parent() : this.element; 11353 } 11354 11355 startMenu 11356 .find(".ui-menu") 11357 .hide() 11358 .attr("aria-hidden", "true") 11359 .attr("aria-expanded", "false") 11360 .end() 11361 .find("a.ui-state-active") 11362 .removeClass("ui-state-active"); 11363 }, 11364 11365 collapse: function (event) { 11366 var newItem = this.active && 11367 this.active.parent().closest(".ui-menu-item", this.element); 11368 if (newItem && newItem.length) { 11369 this._close(); 11370 this.focus(event, newItem); 11371 } 11372 }, 11373 11374 expand: function (event) { 11375 var newItem = this.active && 11376 this.active 11377 .children(".ui-menu ") 11378 .children(".ui-menu-item") 11379 .first(); 11380 11381 if (newItem && newItem.length) { 11382 this._open(newItem.parent()); 11383 11384 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 11385 this._delay(function () { 11386 this.focus(event, newItem); 11387 }); 11388 } 11389 }, 11390 11391 next: function (event) { 11392 this._move("next", "first", event); 11393 }, 11394 11395 previous: function (event) { 11396 this._move("prev", "last", event); 11397 }, 11398 11399 isFirstItem: function () { 11400 return this.active && !this.active.prevAll(".ui-menu-item").length; 11401 }, 11402 11403 isLastItem: function () { 11404 return this.active && !this.active.nextAll(".ui-menu-item").length; 11405 }, 11406 11407 _move: function (direction, filter, event) { 11408 var next; 11409 if (this.active) { 11410 if (direction === "first" || direction === "last") { 11411 next = this.active 11412 [direction === "first" ? "prevAll" : "nextAll"](".ui-menu-item") 11413 .eq(-1); 11414 } else { 11415 next = this.active 11416 [direction + "All"](".ui-menu-item") 11417 .eq(0); 11418 } 11419 } 11420 if (!next || !next.length || !this.active) { 11421 next = this.activeMenu.children(".ui-menu-item")[filter](); 11422 } 11423 11424 this.focus(event, next); 11425 }, 11426 11427 nextPage: function (event) { 11428 var item, base, height; 11429 11430 if (!this.active) { 11431 this.next(event); 11432 return; 11433 } 11434 if (this.isLastItem()) { 11435 return; 11436 } 11437 if (this._hasScroll()) { 11438 base = this.active.offset().top; 11439 height = this.element.height(); 11440 this.active.nextAll(".ui-menu-item").each(function () { 11441 item = $(this); 11442 return item.offset().top - base - height < 0; 11443 }); 11444 11445 this.focus(event, item); 11446 } else { 11447 this.focus(event, this.activeMenu.children(".ui-menu-item") 11448 [!this.active ? "first" : "last"]()); 11449 } 11450 }, 11451 11452 previousPage: function (event) { 11453 var item, base, height; 11454 if (!this.active) { 11455 this.next(event); 11456 return; 11457 } 11458 if (this.isFirstItem()) { 11459 return; 11460 } 11461 if (this._hasScroll()) { 11462 base = this.active.offset().top; 11463 height = this.element.height(); 11464 this.active.prevAll(".ui-menu-item").each(function () { 11465 item = $(this); 11466 return item.offset().top - base + height > 0; 11467 }); 11468 11469 this.focus(event, item); 11470 } else { 11471 this.focus(event, this.activeMenu.children(".ui-menu-item").first()); 11472 } 11473 }, 11474 11475 _hasScroll: function () { 11476 return this.element.outerHeight() < this.element.prop("scrollHeight"); 11477 }, 11478 11479 select: function (event) { 11480 // TODO: It should never be possible to not have an active item at this 11481 // point, but the tests don't trigger mouseenter before click. 11482 this.active = this.active || $(event.target).closest(".ui-menu-item"); 11483 var ui = { item: this.active }; 11484 if (!this.active.has(".ui-menu").length) { 11485 this.collapseAll(event, true); 11486 } 11487 this._trigger("select", event, ui); 11488 } 11489 }); 11490 11491}(jQuery)); 11492 11493(function ($, undefined) { 11494 11495 $.ui = $.ui || {}; 11496 11497 var cachedScrollbarWidth, 11498 max = Math.max, 11499 abs = Math.abs, 11500 round = Math.round, 11501 rhorizontal = /left|center|right/, 11502 rvertical = /top|center|bottom/, 11503 roffset = /[\+\-]\d+%?/, 11504 rposition = /^\w+/, 11505 rpercent = /%$/, 11506 _position = $.fn.position; 11507 11508 function getOffsets(offsets, width, height) { 11509 return [ 11510 parseInt(offsets[0], 10) * (rpercent.test(offsets[0]) ? width / 100 : 1), 11511 parseInt(offsets[1], 10) * (rpercent.test(offsets[1]) ? height / 100 : 1) 11512 ]; 11513 } 11514 function parseCss(element, property) { 11515 return parseInt($.css(element, property), 10) || 0; 11516 } 11517 11518 $.position = { 11519 scrollbarWidth: function () { 11520 if (cachedScrollbarWidth !== undefined) { 11521 return cachedScrollbarWidth; 11522 } 11523 var w1, w2, 11524 div = $("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"), 11525 innerDiv = div.children()[0]; 11526 11527 $("body").append(div); 11528 w1 = innerDiv.offsetWidth; 11529 div.css("overflow", "scroll"); 11530 11531 w2 = innerDiv.offsetWidth; 11532 11533 if (w1 === w2) { 11534 w2 = div[0].clientWidth; 11535 } 11536 11537 div.remove(); 11538 11539 return (cachedScrollbarWidth = w1 - w2); 11540 }, 11541 getScrollInfo: function (within) { 11542 var overflowX = within.isWindow ? "" : within.element.css("overflow-x"), 11543 overflowY = within.isWindow ? "" : within.element.css("overflow-y"), 11544 hasOverflowX = overflowX === "scroll" || 11545 (overflowX === "auto" && within.width < within.element[0].scrollWidth), 11546 hasOverflowY = overflowY === "scroll" || 11547 (overflowY === "auto" && within.height < within.element[0].scrollHeight); 11548 return { 11549 width: hasOverflowX ? $.position.scrollbarWidth() : 0, 11550 height: hasOverflowY ? $.position.scrollbarWidth() : 0 11551 }; 11552 }, 11553 getWithinInfo: function (element) { 11554 var withinElement = $(element || window), 11555 isWindow = $.isWindow(withinElement[0]); 11556 return { 11557 element: withinElement, 11558 isWindow: isWindow, 11559 offset: withinElement.offset() || { left: 0, top: 0 }, 11560 scrollLeft: withinElement.scrollLeft(), 11561 scrollTop: withinElement.scrollTop(), 11562 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 11563 height: isWindow ? withinElement.height() : withinElement.outerHeight() 11564 }; 11565 } 11566 }; 11567 11568 $.fn.position = function (options) { 11569 if (!options || !options.of) { 11570 return _position.apply(this, arguments); 11571 } 11572 11573 // make a copy, we don't want to modify arguments 11574 options = $.extend({}, options); 11575 11576 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, 11577 target = $(options.of), 11578 within = $.position.getWithinInfo(options.within), 11579 scrollInfo = $.position.getScrollInfo(within), 11580 targetElem = target[0], 11581 collision = (options.collision || "flip").split(" "), 11582 offsets = {}; 11583 11584 if (targetElem.nodeType === 9) { 11585 targetWidth = target.width(); 11586 targetHeight = target.height(); 11587 targetOffset = { top: 0, left: 0 }; 11588 } else if ($.isWindow(targetElem)) { 11589 targetWidth = target.width(); 11590 targetHeight = target.height(); 11591 targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; 11592 } else if (targetElem.preventDefault) { 11593 // force left top to allow flipping 11594 options.at = "left top"; 11595 targetWidth = targetHeight = 0; 11596 targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; 11597 } else { 11598 targetWidth = target.outerWidth(); 11599 targetHeight = target.outerHeight(); 11600 targetOffset = target.offset(); 11601 } 11602 // clone to reuse original targetOffset later 11603 basePosition = $.extend({}, targetOffset); 11604 11605 // force my and at to have valid horizontal and vertical positions 11606 // if a value is missing or invalid, it will be converted to center 11607 $.each(["my", "at"], function () { 11608 var pos = (options[this] || "").split(" "), 11609 horizontalOffset, 11610 verticalOffset; 11611 11612 if (pos.length === 1) { 11613 pos = rhorizontal.test(pos[0]) ? 11614 pos.concat(["center"]) : 11615 rvertical.test(pos[0]) ? 11616 ["center"].concat(pos) : 11617 ["center", "center"]; 11618 } 11619 pos[0] = rhorizontal.test(pos[0]) ? pos[0] : "center"; 11620 pos[1] = rvertical.test(pos[1]) ? pos[1] : "center"; 11621 11622 // calculate offsets 11623 horizontalOffset = roffset.exec(pos[0]); 11624 verticalOffset = roffset.exec(pos[1]); 11625 offsets[this] = [ 11626 horizontalOffset ? horizontalOffset[0] : 0, 11627 verticalOffset ? verticalOffset[0] : 0 11628 ]; 11629 11630 // reduce to just the positions without the offsets 11631 options[this] = [ 11632 rposition.exec(pos[0])[0], 11633 rposition.exec(pos[1])[0] 11634 ]; 11635 }); 11636 11637 // normalize collision option 11638 if (collision.length === 1) { 11639 collision[1] = collision[0]; 11640 } 11641 11642 if (options.at[0] === "right") { 11643 basePosition.left += targetWidth; 11644 } else if (options.at[0] === "center") { 11645 basePosition.left += targetWidth / 2; 11646 } 11647 11648 if (options.at[1] === "bottom") { 11649 basePosition.top += targetHeight; 11650 } else if (options.at[1] === "center") { 11651 basePosition.top += targetHeight / 2; 11652 } 11653 11654 atOffset = getOffsets(offsets.at, targetWidth, targetHeight); 11655 basePosition.left += atOffset[0]; 11656 basePosition.top += atOffset[1]; 11657 11658 return this.each(function () { 11659 var collisionPosition, using, 11660 elem = $(this), 11661 elemWidth = elem.outerWidth(), 11662 elemHeight = elem.outerHeight(), 11663 marginLeft = parseCss(this, "marginLeft"), 11664 marginTop = parseCss(this, "marginTop"), 11665 collisionWidth = elemWidth + marginLeft + parseCss(this, "marginRight") + scrollInfo.width, 11666 collisionHeight = elemHeight + marginTop + parseCss(this, "marginBottom") + scrollInfo.height, 11667 position = $.extend({}, basePosition), 11668 myOffset = getOffsets(offsets.my, elem.outerWidth(), elem.outerHeight()); 11669 11670 if (options.my[0] === "right") { 11671 position.left -= elemWidth; 11672 } else if (options.my[0] === "center") { 11673 position.left -= elemWidth / 2; 11674 } 11675 11676 if (options.my[1] === "bottom") { 11677 position.top -= elemHeight; 11678 } else if (options.my[1] === "center") { 11679 position.top -= elemHeight / 2; 11680 } 11681 11682 position.left += myOffset[0]; 11683 position.top += myOffset[1]; 11684 11685 // if the browser doesn't support fractions, then round for consistent results 11686 if (!$.support.offsetFractions) { 11687 position.left = round(position.left); 11688 position.top = round(position.top); 11689 } 11690 11691 collisionPosition = { 11692 marginLeft: marginLeft, 11693 marginTop: marginTop 11694 }; 11695 11696 $.each(["left", "top"], function (i, dir) { 11697 if ($.ui.position[collision[i]]) { 11698 $.ui.position[collision[i]][dir](position, { 11699 targetWidth: targetWidth, 11700 targetHeight: targetHeight, 11701 elemWidth: elemWidth, 11702 elemHeight: elemHeight, 11703 collisionPosition: collisionPosition, 11704 collisionWidth: collisionWidth, 11705 collisionHeight: collisionHeight, 11706 offset: [atOffset[0] + myOffset[0], atOffset[1] + myOffset[1]], 11707 my: options.my, 11708 at: options.at, 11709 within: within, 11710 elem: elem 11711 }); 11712 } 11713 }); 11714 11715 if ($.fn.bgiframe) { 11716 elem.bgiframe(); 11717 } 11718 11719 if (options.using) { 11720 // adds feedback as second argument to using callback, if present 11721 using = function (props) { 11722 var left = targetOffset.left - position.left, 11723 right = left + targetWidth - elemWidth, 11724 top = targetOffset.top - position.top, 11725 bottom = top + targetHeight - elemHeight, 11726 feedback = { 11727 target: { 11728 element: target, 11729 left: targetOffset.left, 11730 top: targetOffset.top, 11731 width: targetWidth, 11732 height: targetHeight 11733 }, 11734 element: { 11735 element: elem, 11736 left: position.left, 11737 top: position.top, 11738 width: elemWidth, 11739 height: elemHeight 11740 }, 11741 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 11742 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 11743 }; 11744 if (targetWidth < elemWidth && abs(left + right) < targetWidth) { 11745 feedback.horizontal = "center"; 11746 } 11747 if (targetHeight < elemHeight && abs(top + bottom) < targetHeight) { 11748 feedback.vertical = "middle"; 11749 } 11750 if (max(abs(left), abs(right)) > max(abs(top), abs(bottom))) { 11751 feedback.important = "horizontal"; 11752 } else { 11753 feedback.important = "vertical"; 11754 } 11755 options.using.call(this, props, feedback); 11756 }; 11757 } 11758 11759 elem.offset($.extend(position, { using: using })); 11760 }); 11761 }; 11762 11763 $.ui.position = { 11764 fit: { 11765 left: function (position, data) { 11766 var within = data.within, 11767 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 11768 outerWidth = within.width, 11769 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 11770 overLeft = withinOffset - collisionPosLeft, 11771 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 11772 newOverRight; 11773 11774 // element is wider than within 11775 if (data.collisionWidth > outerWidth) { 11776 // element is initially over the left side of within 11777 if (overLeft > 0 && overRight <= 0) { 11778 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 11779 position.left += overLeft - newOverRight; 11780 // element is initially over right side of within 11781 } else if (overRight > 0 && overLeft <= 0) { 11782 position.left = withinOffset; 11783 // element is initially over both left and right sides of within 11784 } else { 11785 if (overLeft > overRight) { 11786 position.left = withinOffset + outerWidth - data.collisionWidth; 11787 } else { 11788 position.left = withinOffset; 11789 } 11790 } 11791 // too far left -> align with left edge 11792 } else if (overLeft > 0) { 11793 position.left += overLeft; 11794 // too far right -> align with right edge 11795 } else if (overRight > 0) { 11796 position.left -= overRight; 11797 // adjust based on position and margin 11798 } else { 11799 position.left = max(position.left - collisionPosLeft, position.left); 11800 } 11801 }, 11802 top: function (position, data) { 11803 var within = data.within, 11804 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 11805 outerHeight = data.within.height, 11806 collisionPosTop = position.top - data.collisionPosition.marginTop, 11807 overTop = withinOffset - collisionPosTop, 11808 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 11809 newOverBottom; 11810 11811 // element is taller than within 11812 if (data.collisionHeight > outerHeight) { 11813 // element is initially over the top of within 11814 if (overTop > 0 && overBottom <= 0) { 11815 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 11816 position.top += overTop - newOverBottom; 11817 // element is initially over bottom of within 11818 } else if (overBottom > 0 && overTop <= 0) { 11819 position.top = withinOffset; 11820 // element is initially over both top and bottom of within 11821 } else { 11822 if (overTop > overBottom) { 11823 position.top = withinOffset + outerHeight - data.collisionHeight; 11824 } else { 11825 position.top = withinOffset; 11826 } 11827 } 11828 // too far up -> align with top 11829 } else if (overTop > 0) { 11830 position.top += overTop; 11831 // too far down -> align with bottom edge 11832 } else if (overBottom > 0) { 11833 position.top -= overBottom; 11834 // adjust based on position and margin 11835 } else { 11836 position.top = max(position.top - collisionPosTop, position.top); 11837 } 11838 } 11839 }, 11840 flip: { 11841 left: function (position, data) { 11842 var within = data.within, 11843 withinOffset = within.offset.left + within.scrollLeft, 11844 outerWidth = within.width, 11845 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 11846 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 11847 overLeft = collisionPosLeft - offsetLeft, 11848 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 11849 myOffset = data.my[0] === "left" ? 11850 -data.elemWidth : 11851 data.my[0] === "right" ? 11852 data.elemWidth : 11853 0, 11854 atOffset = data.at[0] === "left" ? 11855 data.targetWidth : 11856 data.at[0] === "right" ? 11857 -data.targetWidth : 11858 0, 11859 offset = -2 * data.offset[0], 11860 newOverRight, 11861 newOverLeft; 11862 11863 if (overLeft < 0) { 11864 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 11865 if (newOverRight < 0 || newOverRight < abs(overLeft)) { 11866 position.left += myOffset + atOffset + offset; 11867 } 11868 } 11869 else if (overRight > 0) { 11870 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 11871 if (newOverLeft > 0 || abs(newOverLeft) < overRight) { 11872 position.left += myOffset + atOffset + offset; 11873 } 11874 } 11875 }, 11876 top: function (position, data) { 11877 var within = data.within, 11878 withinOffset = within.offset.top + within.scrollTop, 11879 outerHeight = within.height, 11880 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 11881 collisionPosTop = position.top - data.collisionPosition.marginTop, 11882 overTop = collisionPosTop - offsetTop, 11883 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 11884 top = data.my[1] === "top", 11885 myOffset = top ? 11886 -data.elemHeight : 11887 data.my[1] === "bottom" ? 11888 data.elemHeight : 11889 0, 11890 atOffset = data.at[1] === "top" ? 11891 data.targetHeight : 11892 data.at[1] === "bottom" ? 11893 -data.targetHeight : 11894 0, 11895 offset = -2 * data.offset[1], 11896 newOverTop, 11897 newOverBottom; 11898 if (overTop < 0) { 11899 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 11900 if ((position.top + myOffset + atOffset + offset) > overTop && (newOverBottom < 0 || newOverBottom < abs(overTop))) { 11901 position.top += myOffset + atOffset + offset; 11902 } 11903 } 11904 else if (overBottom > 0) { 11905 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 11906 if ((position.top + myOffset + atOffset + offset) > overBottom && (newOverTop > 0 || abs(newOverTop) < overBottom)) { 11907 position.top += myOffset + atOffset + offset; 11908 } 11909 } 11910 } 11911 }, 11912 flipfit: { 11913 left: function () { 11914 $.ui.position.flip.left.apply(this, arguments); 11915 $.ui.position.fit.left.apply(this, arguments); 11916 }, 11917 top: function () { 11918 $.ui.position.flip.top.apply(this, arguments); 11919 $.ui.position.fit.top.apply(this, arguments); 11920 } 11921 } 11922 }; 11923 11924 // fraction support test 11925 (function () { 11926 var testElement, testElementParent, testElementStyle, offsetLeft, i, 11927 body = document.getElementsByTagName("body")[0], 11928 div = document.createElement("div"); 11929 11930 //Create a "fake body" for testing based on method used in jQuery.support 11931 testElement = document.createElement(body ? "div" : "body"); 11932 testElementStyle = { 11933 visibility: "hidden", 11934 width: 0, 11935 height: 0, 11936 border: 0, 11937 margin: 0, 11938 background: "none" 11939 }; 11940 if (body) { 11941 $.extend(testElementStyle, { 11942 position: "absolute",
11943 left: "-1000px", 11944 top: "-1000px" 11945 }); 11946 } 11947 for (i in testElementStyle) { 11948 testElement.style[i] = testElementStyle[i]; 11949 } 11950 testElement.appendChild(div); 11951 testElementParent = body || document.documentElement; 11952 testElementParent.insertBefore(testElement, testElementParent.firstChild); 11953 11954 div.style.cssText = "position: absolute; left: 10.7432222px;"; 11955 11956 offsetLeft = $(div).offset().left; 11957 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 11958 11959 testElement.innerHTML = ""; 11960 testElementParent.removeChild(testElement); 11961 })(); 11962 11963 // DEPRECATED 11964 if ($.uiBackCompat !== false) { 11965 // offset option 11966 (function ($) { 11967 var _position = $.fn.position; 11968 $.fn.position = function (options) { 11969 if (!options || !options.offset) { 11970 return _position.call(this, options); 11971 } 11972 var offset = options.offset.split(" "), 11973 at = options.at.split(" "); 11974 if (offset.length === 1) { 11975 offset[1] = offset[0]; 11976 } 11977 if (/^\d/.test(offset[0])) { 11978 offset[0] = "+" + offset[0]; 11979 } 11980 if (/^\d/.test(offset[1])) { 11981 offset[1] = "+" + offset[1]; 11982 } 11983 if (at.length === 1) { 11984 if (/left|center|right/.test(at[0])) { 11985 at[1] = "center"; 11986 } else { 11987 at[1] = at[0]; 11988 at[0] = "center"; 11989 } 11990 } 11991 return _position.call(this, $.extend(options, { 11992 at: at[0] + offset[0] + " " + at[1] + offset[1], 11993 offset: undefined 11994 })); 11995 }; 11996 }(jQuery)); 11997 } 11998 11999}(jQuery)); 12000 12001(function ($, undefined) { 12002 12003 $.widget("ui.progressbar", { 12004 version: "1.9.2", 12005 options: { 12006 value: 0, 12007 max: 100 12008 }, 12009 12010 min: 0, 12011 12012 _create: function () { 12013 this.element 12014 .addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all") 12015 .attr({ 12016 role: "progressbar", 12017 "aria-valuemin": this.min, 12018 "aria-valuemax": this.options.max, 12019 "aria-valuenow": this._value() 12020 }); 12021 12022 this.valueDiv = $("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>") 12023 .appendTo(this.element); 12024 12025 this.oldValue = this._value(); 12026 this._refreshValue(); 12027 }, 12028 12029 _destroy: function () { 12030 this.element 12031 .removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all") 12032 .removeAttr("role") 12033 .removeAttr("aria-valuemin") 12034 .removeAttr("aria-valuemax") 12035 .removeAttr("aria-valuenow"); 12036 12037 this.valueDiv.remove(); 12038 }, 12039 12040 value: function (newValue) { 12041 if (newValue === undefined) { 12042 return this._value(); 12043 } 12044 12045 this._setOption("value", newValue); 12046 return this; 12047 }, 12048 12049 _setOption: function (key, value) { 12050 if (key === "value") { 12051 this.options.value = value; 12052 this._refreshValue(); 12053 if (this._value() === this.options.max) { 12054 this._trigger("complete"); 12055 } 12056 } 12057 12058 this._super(key, value); 12059 }, 12060 12061 _value: function () { 12062 var val = this.options.value; 12063 // normalize invalid value 12064 if (typeof val !== "number") { 12065 val = 0; 12066 } 12067 return Math.min(this.options.max, Math.max(this.min, val)); 12068 }, 12069 12070 _percentage: function () {
vendor: 37,928 bytes, lines 12071-13072
12071 return 100 * this._value() / this.options.max; 12072 }, 12073 12074 _refreshValue: function () { 12075 var value = this.value(), 12076 percentage = this._percentage(); 12077 12078 if (this.oldValue !== value) { 12079 this.oldValue = value; 12080 this._trigger("change"); 12081 } 12082 12083 this.valueDiv 12084 .toggle(value > this.min) 12085 .toggleClass("ui-corner-right", value === this.options.max) 12086 .width(percentage.toFixed(0) + "%"); 12087 this.element.attr("aria-valuenow", value); 12088 } 12089 }); 12090 12091})(jQuery); 12092 12093(function ($, undefined) { 12094 12095 // number of pages in a slider 12096 // (how many times can you page up/down to go through the whole range) 12097 var numPages = 5; 12098 12099 $.widget("ui.slider", $.ui.mouse, { 12100 version: "1.9.2", 12101 widgetEventPrefix: "slide", 12102 12103 options: { 12104 animate: false, 12105 distance: 0, 12106 max: 100, 12107 min: 0, 12108 orientation: "horizontal", 12109 range: false, 12110 step: 1, 12111 value: 0, 12112 values: null 12113 }, 12114 12115 _create: function () { 12116 var i, handleCount, 12117 o = this.options, 12118 existingHandles = this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"), 12119 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 12120 handles = []; 12121 12122 this._keySliding = false; 12123 this._mouseSliding = false; 12124 this._animateOff = true; 12125 this._handleIndex = null; 12126 this._detectOrientation(); 12127 this._mouseInit(); 12128 12129 this.element 12130 .addClass("ui-slider" + 12131 " ui-slider-" + this.orientation + 12132 " ui-widget" + 12133 " ui-widget-content" + 12134 " ui-corner-all" + 12135 (o.disabled ? " ui-slider-disabled ui-disabled" : "")); 12136 12137 this.range = $([]); 12138 12139 if (o.range) { 12140 if (o.range === true) { 12141 if (!o.values) { 12142 o.values = [this._valueMin(), this._valueMin()]; 12143 } 12144 if (o.values.length && o.values.length !== 2) { 12145 o.values = [o.values[0], o.values[0]]; 12146 } 12147 } 12148 12149 this.range = $("<div></div>") 12150 .appendTo(this.element) 12151 .addClass("ui-slider-range" + 12152 // note: this isn't the most fittingly semantic framework class for this element, 12153 // but worked best visually with a variety of themes 12154 " ui-widget-header" + 12155 ((o.range === "min" || o.range === "max") ? " ui-slider-range-" + o.range : "")); 12156 } 12157 12158 handleCount = (o.values && o.values.length) || 1; 12159 12160 for (i = existingHandles.length; i < handleCount; i++) { 12161 handles.push(handle); 12162 } 12163 12164 this.handles = existingHandles.add($(handles.join("")).appendTo(this.element)); 12165 12166 this.handle = this.handles.eq(0); 12167 12168 this.handles.add(this.range).filter("a") 12169 .click(function (event) { 12170 event.preventDefault(); 12171 }) 12172 .mouseenter(function () { 12173 if (!o.disabled) { 12174 $(this).addClass("ui-state-hover"); 12175 } 12176 }) 12177 .mouseleave(function () { 12178 $(this).removeClass("ui-state-hover"); 12179 }) 12180 .focus(function () { 12181 if (!o.disabled) { 12182 $(".ui-slider .ui-state-focus").removeClass("ui-state-focus"); 12183 $(this).addClass("ui-state-focus"); 12184 } else { 12185 $(this).blur(); 12186 } 12187 }) 12188 .blur(function () { 12189 $(this).removeClass("ui-state-focus"); 12190 }); 12191 12192 this.handles.each(function (i) { 12193 $(this).data("ui-slider-handle-index", i); 12194 }); 12195 12196 this._on(this.handles, { 12197 keydown: function (event) { 12198 var allowed, curVal, newVal, step, 12199 index = $(event.target).data("ui-slider-handle-index"); 12200 12201 switch (event.keyCode) { 12202 case $.ui.keyCode.HOME: 12203 case $.ui.keyCode.END: 12204 case $.ui.keyCode.PAGE_UP: 12205 case $.ui.keyCode.PAGE_DOWN: 12206 case $.ui.keyCode.UP: 12207 case $.ui.keyCode.RIGHT: 12208 case $.ui.keyCode.DOWN: 12209 case $.ui.keyCode.LEFT: 12210 event.preventDefault(); 12211 if (!this._keySliding) { 12212 this._keySliding = true; 12213 $(event.target).addClass("ui-state-active"); 12214 allowed = this._start(event, index); 12215 if (allowed === false) { 12216 return; 12217 } 12218 } 12219 break; 12220 } 12221 12222 step = this.options.step; 12223 if (this.options.values && this.options.values.length) { 12224 curVal = newVal = this.values(index); 12225 } else { 12226 curVal = newVal = this.value(); 12227 } 12228 12229 switch (event.keyCode) { 12230 case $.ui.keyCode.HOME: 12231 newVal = this._valueMin(); 12232 break; 12233 case $.ui.keyCode.END: 12234 newVal = this._valueMax(); 12235 break; 12236 case $.ui.keyCode.PAGE_UP: 12237 newVal = this._trimAlignValue(curVal + ((this._valueMax() - this._valueMin()) / numPages)); 12238 break; 12239 case $.ui.keyCode.PAGE_DOWN: 12240 newVal = this._trimAlignValue(curVal - ((this._valueMax() - this._valueMin()) / numPages)); 12241 break; 12242 case $.ui.keyCode.UP: 12243 case $.ui.keyCode.RIGHT: 12244 if (curVal === this._valueMax()) { 12245 return; 12246 } 12247 newVal = this._trimAlignValue(curVal + step); 12248 break; 12249 case $.ui.keyCode.DOWN: 12250 case $.ui.keyCode.LEFT: 12251 if (curVal === this._valueMin()) { 12252 return; 12253 } 12254 newVal = this._trimAlignValue(curVal - step); 12255 break; 12256 } 12257 12258 this._slide(event, index, newVal); 12259 }, 12260 keyup: function (event) { 12261 var index = $(event.target).data("ui-slider-handle-index"); 12262 12263 if (this._keySliding) { 12264 this._keySliding = false; 12265 this._stop(event, index); 12266 this._change(event, index); 12267 $(event.target).removeClass("ui-state-active"); 12268 } 12269 } 12270 }); 12271 12272 this._refreshValue(); 12273 12274 this._animateOff = false; 12275 }, 12276 12277 _destroy: function () { 12278 this.handles.remove(); 12279 this.range.remove(); 12280 12281 this.element 12282 .removeClass("ui-slider" + 12283 " ui-slider-horizontal" + 12284 " ui-slider-vertical" + 12285 " ui-slider-disabled" + 12286 " ui-widget" + 12287 " ui-widget-content" + 12288 " ui-corner-all"); 12289 12290 this._mouseDestroy(); 12291 }, 12292 12293 _mouseCapture: function (event) { 12294 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 12295 that = this, 12296 o = this.options; 12297 12298 if (o.disabled) { 12299 return false; 12300 } 12301 12302 this.elementSize = { 12303 width: this.element.outerWidth(), 12304 height: this.element.outerHeight() 12305 }; 12306 this.elementOffset = this.element.offset(); 12307 12308 position = { x: event.pageX, y: event.pageY }; 12309 normValue = this._normValueFromMouse(position); 12310 distance = this._valueMax() - this._valueMin() + 1; 12311 this.handles.each(function (i) { 12312 var thisDistance = Math.abs(normValue - that.values(i)); 12313 if (distance > thisDistance) { 12314 distance = thisDistance; 12315 closestHandle = $(this); 12316 index = i; 12317 } 12318 }); 12319 12320 // workaround for bug #3736 (if both handles of a range are at 0, 12321 // the first is always used as the one with least distance, 12322 // and moving it is obviously prevented by preventing negative ranges) 12323 if (o.range === true && this.values(1) === o.min) { 12324 index += 1; 12325 closestHandle = $(this.handles[index]); 12326 } 12327 12328 allowed = this._start(event, index); 12329 if (allowed === false) { 12330 return false; 12331 } 12332 this._mouseSliding = true; 12333 12334 this._handleIndex = index; 12335 12336 closestHandle 12337 .addClass("ui-state-active") 12338 .focus(); 12339 12340 offset = closestHandle.offset(); 12341 mouseOverHandle = !$(event.target).parents().andSelf().is(".ui-slider-handle"); 12342 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 12343 left: event.pageX - offset.left - (closestHandle.width() / 2), 12344 top: event.pageY - offset.top - 12345 (closestHandle.height() / 2) - 12346 (parseInt(closestHandle.css("borderTopWidth"), 10) || 0) - 12347 (parseInt(closestHandle.css("borderBottomWidth"), 10) || 0) + 12348 (parseInt(closestHandle.css("marginTop"), 10) || 0) 12349 }; 12350 12351 if (!this.handles.hasClass("ui-state-hover")) { 12352 this._slide(event, index, normValue); 12353 } 12354 this._animateOff = true; 12355 return true; 12356 }, 12357 12358 _mouseStart: function () { 12359 return true; 12360 }, 12361 12362 _mouseDrag: function (event) { 12363 var position = { x: event.pageX, y: event.pageY }, 12364 normValue = this._normValueFromMouse(position); 12365 12366 this._slide(event, this._handleIndex, normValue); 12367 12368 return false; 12369 }, 12370 12371 _mouseStop: function (event) { 12372 this.handles.removeClass("ui-state-active"); 12373 this._mouseSliding = false; 12374 12375 this._stop(event, this._handleIndex); 12376 this._change(event, this._handleIndex); 12377 12378 this._handleIndex = null; 12379 this._clickOffset = null; 12380 this._animateOff = false; 12381 12382 return false; 12383 }, 12384 12385 _detectOrientation: function () { 12386 this.orientation = (this.options.orientation === "vertical") ? "vertical" : "horizontal"; 12387 }, 12388 12389 _normValueFromMouse: function (position) { 12390 var pixelTotal, 12391 pixelMouse, 12392 percentMouse, 12393 valueTotal, 12394 valueMouse; 12395 12396 if (this.orientation === "horizontal") { 12397 pixelTotal = this.elementSize.width; 12398 pixelMouse = position.x - this.elementOffset.left - (this._clickOffset ? this._clickOffset.left : 0); 12399 } else { 12400 pixelTotal = this.elementSize.height; 12401 pixelMouse = position.y - this.elementOffset.top - (this._clickOffset ? this._clickOffset.top : 0); 12402 } 12403 12404 percentMouse = (pixelMouse / pixelTotal); 12405 if (percentMouse > 1) { 12406 percentMouse = 1; 12407 } 12408 if (percentMouse < 0) { 12409 percentMouse = 0; 12410 } 12411 if (this.orientation === "vertical") { 12412 percentMouse = 1 - percentMouse; 12413 } 12414 12415 valueTotal = this._valueMax() - this._valueMin(); 12416 valueMouse = this._valueMin() + percentMouse * valueTotal; 12417 12418 return this._trimAlignValue(valueMouse); 12419 }, 12420 12421 _start: function (event, index) { 12422 var uiHash = { 12423 handle: this.handles[index], 12424 value: this.value() 12425 }; 12426 if (this.options.values && this.options.values.length) { 12427 uiHash.value = this.values(index); 12428 uiHash.values = this.values(); 12429 } 12430 return this._trigger("start", event, uiHash); 12431 }, 12432 12433 _slide: function (event, index, newVal) { 12434 var otherVal, 12435 newValues, 12436 allowed; 12437 12438 if (this.options.values && this.options.values.length) { 12439 otherVal = this.values(index ? 0 : 1); 12440 12441 if ((this.options.values.length === 2 && this.options.range === true) && 12442 ((index === 0 && newVal > otherVal) || (index === 1 && newVal < otherVal)) 12443 ) { 12444 newVal = otherVal; 12445 } 12446 12447 if (newVal !== this.values(index)) { 12448 newValues = this.values(); 12449 newValues[index] = newVal; 12450 // A slide can be canceled by returning false from the slide callback 12451 allowed = this._trigger("slide", event, { 12452 handle: this.handles[index], 12453 value: newVal, 12454 values: newValues 12455 }); 12456 otherVal = this.values(index ? 0 : 1); 12457 if (allowed !== false) { 12458 this.values(index, newVal, true); 12459 } 12460 } 12461 } else { 12462 if (newVal !== this.value()) { 12463 // A slide can be canceled by returning false from the slide callback 12464 allowed = this._trigger("slide", event, { 12465 handle: this.handles[index], 12466 value: newVal 12467 }); 12468 if (allowed !== false) { 12469 this.value(newVal); 12470 } 12471 } 12472 } 12473 }, 12474 12475 _stop: function (event, index) { 12476 var uiHash = { 12477 handle: this.handles[index], 12478 value: this.value() 12479 }; 12480 if (this.options.values && this.options.values.length) { 12481 uiHash.value = this.values(index); 12482 uiHash.values = this.values(); 12483 } 12484 12485 this._trigger("stop", event, uiHash); 12486 }, 12487 12488 _change: function (event, index) { 12489 if (!this._keySliding && !this._mouseSliding) { 12490 var uiHash = { 12491 handle: this.handles[index], 12492 value: this.value() 12493 }; 12494 if (this.options.values && this.options.values.length) { 12495 uiHash.value = this.values(index); 12496 uiHash.values = this.values(); 12497 } 12498 12499 this._trigger("change", event, uiHash); 12500 } 12501 }, 12502 12503 value: function (newValue) { 12504 if (arguments.length) { 12505 this.options.value = this._trimAlignValue(newValue); 12506 this._refreshValue(); 12507 this._change(null, 0); 12508 return; 12509 } 12510 12511 return this._value(); 12512 }, 12513 12514 values: function (index, newValue) { 12515 var vals, 12516 newValues, 12517 i; 12518 12519 if (arguments.length > 1) { 12520 this.options.values[index] = this._trimAlignValue(newValue); 12521 this._refreshValue(); 12522 this._change(null, index); 12523 return; 12524 } 12525 12526 if (arguments.length) { 12527 if ($.isArray(arguments[0])) { 12528 vals = this.options.values; 12529 newValues = arguments[0]; 12530 for (i = 0; i < vals.length; i += 1) { 12531 vals[i] = this._trimAlignValue(newValues[i]); 12532 this._change(null, i); 12533 } 12534 this._refreshValue(); 12535 } else { 12536 if (this.options.values && this.options.values.length) { 12537 return this._values(index); 12538 } else { 12539 return this.value(); 12540 } 12541 } 12542 } else { 12543 return this._values(); 12544 } 12545 }, 12546 12547 _setOption: function (key, value) { 12548 var i, 12549 valsLength = 0; 12550 12551 if ($.isArray(this.options.values)) { 12552 valsLength = this.options.values.length; 12553 } 12554 12555 $.Widget.prototype._setOption.apply(this, arguments); 12556 12557 switch (key) { 12558 case "disabled": 12559 if (value) { 12560 this.handles.filter(".ui-state-focus").blur(); 12561 this.handles.removeClass("ui-state-hover"); 12562 this.handles.prop("disabled", true); 12563 this.element.addClass("ui-disabled"); 12564 } else { 12565 this.handles.prop("disabled", false); 12566 this.element.removeClass("ui-disabled"); 12567 } 12568 break; 12569 case "orientation": 12570 this._detectOrientation(); 12571 this.element 12572 .removeClass("ui-slider-horizontal ui-slider-vertical") 12573 .addClass("ui-slider-" + this.orientation); 12574 this._refreshValue(); 12575 break; 12576 case "value": 12577 this._animateOff = true; 12578 this._refreshValue(); 12579 this._change(null, 0); 12580 this._animateOff = false; 12581 break; 12582 case "values": 12583 this._animateOff = true; 12584 this._refreshValue(); 12585 for (i = 0; i < valsLength; i += 1) { 12586 this._change(null, i); 12587 } 12588 this._animateOff = false; 12589 break; 12590 case "min": 12591 case "max": 12592 this._animateOff = true; 12593 this._refreshValue(); 12594 this._animateOff = false; 12595 break; 12596 } 12597 }, 12598 12599 //internal value getter 12600 // _value() returns value trimmed by min and max, aligned by step 12601 _value: function () { 12602 var val = this.options.value; 12603 val = this._trimAlignValue(val); 12604 12605 return val; 12606 }, 12607 12608 //internal values getter 12609 // _values() returns array of values trimmed by min and max, aligned by step 12610 // _values( index ) returns single value trimmed by min and max, aligned by step 12611 _values: function (index) { 12612 var val, 12613 vals, 12614 i; 12615 12616 if (arguments.length) { 12617 val = this.options.values[index]; 12618 val = this._trimAlignValue(val); 12619 12620 return val; 12621 } else { 12622 // .slice() creates a copy of the array 12623 // this copy gets trimmed by min and max and then returned 12624 vals = this.options.values.slice(); 12625 for (i = 0; i < vals.length; i += 1) { 12626 vals[i] = this._trimAlignValue(vals[i]); 12627 } 12628 12629 return vals; 12630 } 12631 }, 12632 12633 // returns the step-aligned value that val is closest to, between (inclusive) min and max 12634 _trimAlignValue: function (val) { 12635 if (val <= this._valueMin()) { 12636 return this._valueMin(); 12637 } 12638 if (val >= this._valueMax()) { 12639 return this._valueMax(); 12640 } 12641 var step = (this.options.step > 0) ? this.options.step : 1, 12642 valModStep = (val - this._valueMin()) % step, 12643 alignValue = val - valModStep; 12644 12645 if (Math.abs(valModStep) * 2 >= step) { 12646 alignValue += (valModStep > 0) ? step : (-step); 12647 } 12648 12649 // Since JavaScript has problems with large floats, round 12650 // the final value to 5 digits after the decimal point (see #4124) 12651 return parseFloat(alignValue.toFixed(5)); 12652 }, 12653 12654 _valueMin: function () { 12655 return this.options.min; 12656 }, 12657 12658 _valueMax: function () { 12659 return this.options.max; 12660 }, 12661 12662 _refreshValue: function () { 12663 var lastValPercent, valPercent, value, valueMin, valueMax, 12664 oRange = this.options.range, 12665 o = this.options, 12666 that = this, 12667 animate = (!this._animateOff) ? o.animate : false, 12668 _set = {}; 12669 12670 if (this.options.values && this.options.values.length) { 12671 this.handles.each(function (i) { 12672 valPercent = (that.values(i) - that._valueMin()) / (that._valueMax() - that._valueMin()) * 100; 12673 _set[that.orientation === "horizontal" ? "left" : "bottom"] = valPercent + "%"; 12674 $(this).stop(1, 1)[animate ? "animate" : "css"](_set, o.animate); 12675 if (that.options.range === true) { 12676 if (that.orientation === "horizontal") { 12677 if (i === 0) { 12678 that.range.stop(1, 1)[animate ? "animate" : "css"]({ left: valPercent + "%" }, o.animate); 12679 } 12680 if (i === 1) { 12681 that.range[animate ? "animate" : "css"]({ width: (valPercent - lastValPercent) + "%" }, { queue: false, duration: o.animate }); 12682 } 12683 } else { 12684 if (i === 0) { 12685 that.range.stop(1, 1)[animate ? "animate" : "css"]({ bottom: (valPercent) + "%" }, o.animate); 12686 } 12687 if (i === 1) { 12688 that.range[animate ? "animate" : "css"]({ height: (valPercent - lastValPercent) + "%" }, { queue: false, duration: o.animate }); 12689 } 12690 } 12691 } 12692 lastValPercent = valPercent; 12693 }); 12694 } else { 12695 value = this.value(); 12696 valueMin = this._valueMin(); 12697 valueMax = this._valueMax(); 12698 valPercent = (valueMax !== valueMin) ? 12699 (value - valueMin) / (valueMax - valueMin) * 100 : 12700 0; 12701 _set[this.orientation === "horizontal" ? "left" : "bottom"] = valPercent + "%"; 12702 this.handle.stop(1, 1)[animate ? "animate" : "css"](_set, o.animate); 12703 12704 if (oRange === "min" && this.orientation === "horizontal") { 12705 this.range.stop(1, 1)[animate ? "animate" : "css"]({ width: valPercent + "%" }, o.animate); 12706 } 12707 if (oRange === "max" && this.orientation === "horizontal") { 12708 this.range[animate ? "animate" : "css"]({ width: (100 - valPercent) + "%" }, { queue: false, duration: o.animate }); 12709 } 12710 if (oRange === "min" && this.orientation === "vertical") { 12711 this.range.stop(1, 1)[animate ? "animate" : "css"]({ height: valPercent + "%" }, o.animate); 12712 } 12713 if (oRange === "max" && this.orientation === "vertical") { 12714 this.range[animate ? "animate" : "css"]({ height: (100 - valPercent) + "%" }, { queue: false, duration: o.animate }); 12715 } 12716 } 12717 } 12718 12719 }); 12720 12721}(jQuery)); 12722 12723(function ($) { 12724 12725 function modifier(fn) { 12726 return function () { 12727 var previous = this.element.val(); 12728 fn.apply(this, arguments); 12729 this._refresh(); 12730 if (previous !== this.element.val()) { 12731 this._trigger("change"); 12732 } 12733 }; 12734 } 12735 12736 $.widget("ui.spinner", { 12737 version: "1.9.2", 12738 defaultElement: "<input>", 12739 widgetEventPrefix: "spin", 12740 options: { 12741 culture: null, 12742 icons: { 12743 down: "ui-icon-triangle-1-s", 12744 up: "ui-icon-triangle-1-n" 12745 }, 12746 incremental: true, 12747 max: null, 12748 min: null, 12749 numberFormat: null, 12750 page: 10, 12751 step: 1, 12752 12753 change: null, 12754 spin: null, 12755 start: null, 12756 stop: null 12757 }, 12758 12759 _create: function () { 12760 // handle string values that need to be parsed 12761 this._setOption("max", this.options.max); 12762 this._setOption("min", this.options.min); 12763 this._setOption("step", this.options.step); 12764 12765 // format the value, but don't constrain 12766 this._value(this.element.val(), true); 12767 12768 this._draw(); 12769 this._on(this._events); 12770 this._refresh(); 12771 12772 // turning off autocomplete prevents the browser from remembering the 12773 // value when navigating through history, so we re-enable autocomplete 12774 // if the page is unloaded before the widget is destroyed. #7790 12775 this._on(this.window, { 12776 beforeunload: function () { 12777 this.element.removeAttr("autocomplete"); 12778 } 12779 }); 12780 }, 12781 12782 _getCreateOptions: function () { 12783 var options = {}, 12784 element = this.element; 12785 12786 $.each(["min", "max", "step"], function (i, option) { 12787 var value = element.attr(option); 12788 if (value !== undefined && value.length) { 12789 options[option] = value; 12790 } 12791 }); 12792 12793 return options; 12794 }, 12795 12796 _events: { 12797 keydown: function (event) { 12798 if (this._start(event) && this._keydown(event)) { 12799 event.preventDefault(); 12800 } 12801 }, 12802 keyup: "_stop", 12803 focus: function () { 12804 this.previous = this.element.val(); 12805 }, 12806 blur: function (event) { 12807 if (this.cancelBlur) { 12808 delete this.cancelBlur; 12809 return; 12810 } 12811 12812 this._refresh(); 12813 if (this.previous !== this.element.val()) { 12814 this._trigger("change", event); 12815 } 12816 }, 12817 mousewheel: function (event, delta) { 12818 if (!delta) { 12819 return; 12820 } 12821 if (!this.spinning && !this._start(event)) { 12822 return false; 12823 } 12824 12825 this._spin((delta > 0 ? 1 : -1) * this.options.step, event); 12826 clearTimeout(this.mousewheelTimer); 12827 this.mousewheelTimer = this._delay(function () { 12828 if (this.spinning) { 12829 this._stop(event); 12830 } 12831 }, 100); 12832 event.preventDefault(); 12833 }, 12834 "mousedown .ui-spinner-button": function (event) { 12835 var previous; 12836 12837 // We never want the buttons to have focus; whenever the user is 12838 // interacting with the spinner, the focus should be on the input. 12839 // If the input is focused then this.previous is properly set from 12840 // when the input first received focus. If the input is not focused 12841 // then we need to set this.previous based on the value before spinning. 12842 previous = this.element[0] === this.document[0].activeElement ? 12843 this.previous : this.element.val(); 12844 function checkFocus() { 12845 var isActive = this.element[0] === this.document[0].activeElement; 12846 if (!isActive) { 12847 this.element.focus(); 12848 this.previous = previous; 12849 // support: IE 12850 // IE sets focus asynchronously, so we need to check if focus 12851 // moved off of the input because the user clicked on the button. 12852 this._delay(function () { 12853 this.previous = previous; 12854 }); 12855 } 12856 } 12857 12858 // ensure focus is on (or stays on) the text field 12859 event.preventDefault(); 12860 checkFocus.call(this); 12861 12862 // support: IE 12863 // IE doesn't prevent moving focus even with event.preventDefault() 12864 // so we set a flag to know when we should ignore the blur event 12865 // and check (again) if focus moved off of the input. 12866 this.cancelBlur = true; 12867 this._delay(function () { 12868 delete this.cancelBlur; 12869 checkFocus.call(this); 12870 }); 12871 12872 if (this._start(event) === false) { 12873 return; 12874 } 12875 12876 this._repeat(null, $(event.currentTarget).hasClass("ui-spinner-up") ? 1 : -1, event); 12877 }, 12878 "mouseup .ui-spinner-button": "_stop", 12879 "mouseenter .ui-spinner-button": function (event) { 12880 // button will add ui-state-active if mouse was down while mouseleave and kept down 12881 if (!$(event.currentTarget).hasClass("ui-state-active")) { 12882 return; 12883 } 12884 12885 if (this._start(event) === false) { 12886 return false; 12887 } 12888 this._repeat(null, $(event.currentTarget).hasClass("ui-spinner-up") ? 1 : -1, event); 12889 }, 12890 // TODO: do we really want to consider this a stop? 12891 // shouldn't we just stop the repeater and wait until mouseup before 12892 // we trigger the stop event? 12893 "mouseleave .ui-spinner-button": "_stop" 12894 }, 12895 12896 _draw: function () { 12897 var uiSpinner = this.uiSpinner = this.element 12898 .addClass("ui-spinner-input") 12899 .attr("autocomplete", "off") 12900 .wrap(this._uiSpinnerHtml()) 12901 .parent() 12902 // add buttons 12903 .append(this._buttonHtml()); 12904 12905 this.element.attr("role", "spinbutton"); 12906 12907 // button bindings 12908 this.buttons = uiSpinner.find(".ui-spinner-button") 12909 .attr("tabIndex", -1) 12910 .button() 12911 .removeClass("ui-corner-all"); 12912 12913 // IE 6 doesn't understand height: 50% for the buttons 12914 // unless the wrapper has an explicit height 12915 if (this.buttons.height() > Math.ceil(uiSpinner.height() * 0.5) && 12916 uiSpinner.height() > 0) { 12917 uiSpinner.height(uiSpinner.height()); 12918 } 12919 12920 // disable spinner if element was already disabled 12921 if (this.options.disabled) { 12922 this.disable(); 12923 } 12924 }, 12925 12926 _keydown: function (event) { 12927 var options = this.options, 12928 keyCode = $.ui.keyCode; 12929 12930 switch (event.keyCode) { 12931 case keyCode.UP: 12932 this._repeat(null, 1, event); 12933 return true; 12934 case keyCode.DOWN: 12935 this._repeat(null, -1, event); 12936 return true; 12937 case keyCode.PAGE_UP: 12938 this._repeat(null, options.page, event); 12939 return true; 12940 case keyCode.PAGE_DOWN: 12941 this._repeat(null, -options.page, event); 12942 return true; 12943 } 12944 12945 return false; 12946 }, 12947 12948 _uiSpinnerHtml: function () { 12949 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 12950 }, 12951 12952 _buttonHtml: function () { 12953 return "" + 12954 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 12955 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 12956 "</a>" + 12957 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 12958 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 12959 "</a>"; 12960 }, 12961 12962 _start: function (event) { 12963 if (!this.spinning && this._trigger("start", event) === false) { 12964 return false; 12965 } 12966 12967 if (!this.counter) { 12968 this.counter = 1; 12969 } 12970 this.spinning = true; 12971 return true; 12972 }, 12973 12974 _repeat: function (i, steps, event) { 12975 i = i || 500; 12976 12977 clearTimeout(this.timer); 12978 this.timer = this._delay(function () { 12979 this._repeat(40, steps, event); 12980 }, i); 12981 12982 this._spin(steps * this.options.step, event); 12983 }, 12984 12985 _spin: function (step, event) { 12986 var value = this.value() || 0; 12987 12988 if (!this.counter) { 12989 this.counter = 1; 12990 } 12991 12992 value = this._adjustValue(value + step * this._increment(this.counter)); 12993 12994 if (!this.spinning || this._trigger("spin", event, { value: value }) !== false) { 12995 this._value(value); 12996 this.counter++; 12997 } 12998 }, 12999 13000 _increment: function (i) { 13001 var incremental = this.options.incremental; 13002 13003 if (incremental) { 13004 return $.isFunction(incremental) ? 13005 incremental(i) : 13006 Math.floor(i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1); 13007 } 13008 13009 return 1; 13010 }, 13011 13012 _precision: function () { 13013 var precision = this._precisionOf(this.options.step); 13014 if (this.options.min !== null) { 13015 precision = Math.max(precision, this._precisionOf(this.options.min)); 13016 } 13017 return precision; 13018 }, 13019 13020 _precisionOf: function (num) { 13021 var str = num.toString(), 13022 decimal = str.indexOf("."); 13023 return decimal === -1 ? 0 : str.length - decimal - 1; 13024 }, 13025 13026 _adjustValue: function (value) { 13027 var base, aboveMin, 13028 options = this.options; 13029 13030 // make sure we're at a valid step 13031 // - find out where we are relative to the base (min or 0) 13032 base = options.min !== null ? options.min : 0; 13033 aboveMin = value - base; 13034 // - round to the nearest step 13035 aboveMin = Math.round(aboveMin / options.step) * options.step; 13036 // - rounding is based on 0, so adjust back to our base 13037 value = base + aboveMin; 13038 13039 // fix precision from bad JS floating point math 13040 value = parseFloat(value.toFixed(this._precision())); 13041 13042 // clamp the value 13043 if (options.max !== null && value > options.max) { 13044 return options.max; 13045 } 13046 if (options.min !== null && value < options.min) { 13047 return options.min; 13048 } 13049 13050 return value; 13051 }, 13052 13053 _stop: function (event) { 13054 if (!this.spinning) { 13055 return; 13056 } 13057 13058 clearTimeout(this.timer); 13059 clearTimeout(this.mousewheelTimer); 13060 this.counter = 0; 13061 this.spinning = false; 13062 this._trigger("stop", event); 13063 }, 13064 13065 _setOption: function (key, value) { 13066 if (key === "culture" || key === "numberFormat") { 13067 var prevValue = this._parse(this.element.val()); 13068 this.options[key] = value; 13069 this.element.val(this._format(prevValue)); 13070 return; 13071 } 13072
13073 if (key === "max" || key === "min" || key === "step") { 13074 if (typeof value === "string") { 13075 value = this._parse(value); 13076 } 13077 } 13078 13079 this._super(key, value); 13080 13081 if (key === "disabled") { 13082 if (value) { 13083 this.element.prop("disabled", true); 13084 this.buttons.button("disable"); 13085 } else { 13086 this.element.prop("disabled", false); 13087 this.buttons.button("enable"); 13088 } 13089 } 13090 }, 13091 13092 _setOptions: modifier(function (options) { 13093 this._super(options); 13094 this._value(this.element.val()); 13095 }), 13096 13097 _parse: function (val) { 13098 if (typeof val === "string" && val !== "") { 13099 val = window.Globalize && this.options.numberFormat ? 13100 Globalize.parseFloat(val, 10, this.options.culture) : +val; 13101 } 13102 return val === "" || isNaN(val) ? null : val; 13103 }, 13104 13105 _format: function (value) { 13106 if (value === "") { 13107 return ""; 13108 } 13109 return window.Globalize && this.options.numberFormat ? 13110 Globalize.format(value, this.options.numberFormat, this.options.culture) : 13111 value; 13112 }, 13113 13114 _refresh: function () { 13115 this.element.attr({ 13116 "aria-valuemin": this.options.min, 13117 "aria-valuemax": this.options.max, 13118 // TODO: what should we do with values that can't be parsed? 13119 "aria-valuenow": this._parse(this.element.val()) 13120 }); 13121 }, 13122 13123 // update the value without triggering change 13124 _value: function (value, allowAny) { 13125 var parsed; 13126 if (value !== "") { 13127 parsed = this._parse(value); 13128 if (parsed !== null) { 13129 if (!allowAny) { 13130 parsed = this._adjustValue(parsed); 13131 } 13132 value = this._format(parsed); 13133 } 13134 } 13135 this.element.val(value); 13136 this._refresh(); 13137 }, 13138 13139 _destroy: function () { 13140 this.element 13141 .removeClass("ui-spinner-input") 13142 .prop("disabled", false) 13143 .removeAttr("autocomplete") 13144 .removeAttr("role") 13145 .removeAttr("aria-valuemin") 13146 .removeAttr("aria-valuemax") 13147 .removeAttr("aria-valuenow"); 13148 this.uiSpinner.replaceWith(this.element); 13149 }, 13150 13151 stepUp: modifier(function (steps) { 13152 this._stepUp(steps); 13153 }), 13154 _stepUp: function (steps) { 13155 this._spin((steps || 1) * this.options.step); 13156 }, 13157 13158 stepDown: modifier(function (steps) { 13159 this._stepDown(steps); 13160 }), 13161 _stepDown: function (steps) { 13162 this._spin((steps || 1) * -this.options.step); 13163 }, 13164 13165 pageUp: modifier(function (pages) { 13166 this._stepUp((pages || 1) * this.options.page); 13167 }), 13168 13169 pageDown: modifier(function (pages) { 13170 this._stepDown((pages || 1) * this.options.page); 13171 }), 13172 13173 value: function (newVal) { 13174 if (!arguments.length) { 13175 return this._parse(this.element.val()); 13176 } 13177 modifier(this._value).call(this, newVal); 13178 }, 13179 13180 widget: function () { 13181 return this.uiSpinner; 13182 } 13183 }); 13184 13185}(jQuery)); 13186 13187(function ($, undefined) { 13188 13189 var tabId = 0, 13190 rhash = /#.*$/; 13191 13192 function getNextTabId() { 13193 return ++tabId; 13194 } 13195 13196 function isLocal(anchor) { 13197 return anchor.hash.length > 1 && 13198 anchor.href.replace(rhash, "") === 13199 location.href.replace(rhash, "") 13200 // support: Safari 5.1 13201 // Safari 5.1 doesn't encode spaces in window.location
vendor: 30,831 bytes, lines 13202-14023
13202 // but it does encode spaces from anchors (#8777) 13203 .replace(/\s/g, "%20"); 13204 } 13205 13206 $.widget("ui.tabs", { 13207 version: "1.9.2", 13208 delay: 300, 13209 options: { 13210 active: null, 13211 collapsible: false, 13212 event: "click", 13213 heightStyle: "content", 13214 hide: null, 13215 show: null, 13216 13217 // callbacks 13218 activate: null, 13219 beforeActivate: null, 13220 beforeLoad: null, 13221 load: null 13222 }, 13223 13224 _create: function () { 13225 var that = this, 13226 options = this.options, 13227 active = options.active, 13228 locationHash = location.hash.substring(1); 13229 13230 this.running = false; 13231 13232 this.element 13233 .addClass("ui-tabs ui-widget ui-widget-content ui-corner-all") 13234 .toggleClass("ui-tabs-collapsible", options.collapsible) 13235 // Prevent users from focusing disabled tabs via click 13236 .delegate(".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function (event) { 13237 if ($(this).is(".ui-state-disabled")) { 13238 event.preventDefault(); 13239 } 13240 }) 13241 // support: IE <9 13242 // Preventing the default action in mousedown doesn't prevent IE 13243 // from focusing the element, so if the anchor gets focused, blur. 13244 // We don't have to worry about focusing the previously focused 13245 // element since clicking on a non-focusable element should focus 13246 // the body anyway. 13247 .delegate(".ui-tabs-anchor", "focus" + this.eventNamespace, function () { 13248 if ($(this).closest("li").is(".ui-state-disabled")) { 13249 this.blur(); 13250 } 13251 }); 13252 13253 this._processTabs(); 13254 13255 if (active === null) { 13256 // check the fragment identifier in the URL 13257 if (locationHash) { 13258 this.tabs.each(function (i, tab) { 13259 if ($(tab).attr("aria-controls") === locationHash) { 13260 active = i; 13261 return false; 13262 } 13263 }); 13264 } 13265 13266 // check for a tab marked active via a class 13267 if (active === null) { 13268 active = this.tabs.index(this.tabs.filter(".ui-tabs-active")); 13269 } 13270 13271 // no active tab, set to false 13272 if (active === null || active === -1) { 13273 active = this.tabs.length ? 0 : false; 13274 } 13275 } 13276 13277 // handle numbers: negative, out of range 13278 if (active !== false) { 13279 active = this.tabs.index(this.tabs.eq(active)); 13280 if (active === -1) { 13281 active = options.collapsible ? false : 0; 13282 } 13283 } 13284 options.active = active; 13285 13286 // don't allow collapsible: false and active: false 13287 if (!options.collapsible && options.active === false && this.anchors.length) { 13288 options.active = 0; 13289 } 13290 13291 // Take disabling tabs via class attribute from HTML 13292 // into account and update option properly. 13293 if ($.isArray(options.disabled)) { 13294 options.disabled = $.unique(options.disabled.concat( 13295 $.map(this.tabs.filter(".ui-state-disabled"), function (li) { 13296 return that.tabs.index(li); 13297 }) 13298 )).sort(); 13299 } 13300 13301 // check for length avoids error when initializing empty list 13302 if (this.options.active !== false && this.anchors.length) { 13303 this.active = this._findActive(this.options.active); 13304 } else { 13305 this.active = $(); 13306 } 13307 13308 this._refresh(); 13309 13310 if (this.active.length) { 13311 this.load(options.active); 13312 } 13313 }, 13314 13315 _getCreateEventData: function () { 13316 return { 13317 tab: this.active, 13318 panel: !this.active.length ? $() : this._getPanelForTab(this.active) 13319 }; 13320 }, 13321 13322 _tabKeydown: function (event) { 13323 var focusedTab = $(this.document[0].activeElement).closest("li"), 13324 selectedIndex = this.tabs.index(focusedTab), 13325 goingForward = true; 13326 13327 if (this._handlePageNav(event)) { 13328 return; 13329 } 13330 13331 switch (event.keyCode) { 13332 case $.ui.keyCode.RIGHT: 13333 case $.ui.keyCode.DOWN: 13334 selectedIndex++; 13335 break; 13336 case $.ui.keyCode.UP: 13337 case $.ui.keyCode.LEFT: 13338 goingForward = false; 13339 selectedIndex--; 13340 break; 13341 case $.ui.keyCode.END: 13342 selectedIndex = this.anchors.length - 1; 13343 break; 13344 case $.ui.keyCode.HOME: 13345 selectedIndex = 0; 13346 break; 13347 case $.ui.keyCode.SPACE: 13348 // Activate only, no collapsing 13349 event.preventDefault(); 13350 clearTimeout(this.activating); 13351 this._activate(selectedIndex); 13352 return; 13353 case $.ui.keyCode.ENTER: 13354 // Toggle (cancel delayed activation, allow collapsing) 13355 event.preventDefault(); 13356 clearTimeout(this.activating); 13357 // Determine if we should collapse or activate 13358 this._activate(selectedIndex === this.options.active ? false : selectedIndex); 13359 return; 13360 default: 13361 return; 13362 } 13363 13364 // Focus the appropriate tab, based on which key was pressed 13365 event.preventDefault(); 13366 clearTimeout(this.activating); 13367 selectedIndex = this._focusNextTab(selectedIndex, goingForward); 13368 13369 // Navigating with control key will prevent automatic activation 13370 if (!event.ctrlKey) { 13371 // Update aria-selected immediately so that AT think the tab is already selected. 13372 // Otherwise AT may confuse the user by stating that they need to activate the tab, 13373 // but the tab will already be activated by the time the announcement finishes. 13374 focusedTab.attr("aria-selected", "false"); 13375 this.tabs.eq(selectedIndex).attr("aria-selected", "true"); 13376 13377 this.activating = this._delay(function () { 13378 this.option("active", selectedIndex); 13379 }, this.delay); 13380 } 13381 }, 13382 13383 _panelKeydown: function (event) { 13384 if (this._handlePageNav(event)) { 13385 return; 13386 } 13387 13388 // Ctrl+up moves focus to the current tab 13389 if (event.ctrlKey && event.keyCode === $.ui.keyCode.UP) { 13390 event.preventDefault(); 13391 this.active.focus(); 13392 } 13393 }, 13394 13395 // Alt+page up/down moves focus to the previous/next tab (and activates) 13396 _handlePageNav: function (event) { 13397 if (event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP) { 13398 this._activate(this._focusNextTab(this.options.active - 1, false)); 13399 return true; 13400 } 13401 if (event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN) { 13402 this._activate(this._focusNextTab(this.options.active + 1, true)); 13403 return true; 13404 } 13405 }, 13406 13407 _findNextTab: function (index, goingForward) { 13408 var lastTabIndex = this.tabs.length - 1; 13409 13410 function constrain() { 13411 if (index > lastTabIndex) { 13412 index = 0; 13413 } 13414 if (index < 0) { 13415 index = lastTabIndex; 13416 } 13417 return index; 13418 } 13419 13420 while ($.inArray(constrain(), this.options.disabled) !== -1) { 13421 index = goingForward ? index + 1 : index - 1; 13422 } 13423 13424 return index; 13425 }, 13426 13427 _focusNextTab: function (index, goingForward) { 13428 index = this._findNextTab(index, goingForward); 13429 this.tabs.eq(index).focus(); 13430 return index; 13431 }, 13432 13433 _setOption: function (key, value) { 13434 if (key === "active") { 13435 // _activate() will handle invalid values and update this.options 13436 this._activate(value); 13437 return; 13438 } 13439 13440 if (key === "disabled") { 13441 // don't use the widget factory's disabled handling 13442 this._setupDisabled(value); 13443 return; 13444 } 13445 13446 this._super(key, value); 13447 13448 if (key === "collapsible") { 13449 this.element.toggleClass("ui-tabs-collapsible", value); 13450 // Setting collapsible: false while collapsed; open first panel 13451 if (!value && this.options.active === false) { 13452 this._activate(0); 13453 } 13454 } 13455 13456 if (key === "event") { 13457 this._setupEvents(value); 13458 } 13459 13460 if (key === "heightStyle") { 13461 this._setupHeightStyle(value); 13462 } 13463 }, 13464 13465 _tabId: function (tab) { 13466 return tab.attr("aria-controls") || "ui-tabs-" + getNextTabId(); 13467 }, 13468 13469 _sanitizeSelector: function (hash) { 13470 return hash ? hash.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&") : ""; 13471 }, 13472 13473 refresh: function () { 13474 var options = this.options, 13475 lis = this.tablist.children(":has(a[href])"); 13476 13477 // get disabled tabs from class attribute from HTML 13478 // this will get converted to a boolean if needed in _refresh() 13479 options.disabled = $.map(lis.filter(".ui-state-disabled"), function (tab) { 13480 return lis.index(tab); 13481 }); 13482 13483 this._processTabs(); 13484 13485 // was collapsed or no tabs 13486 if (options.active === false || !this.anchors.length) { 13487 options.active = false; 13488 this.active = $(); 13489 // was active, but active tab is gone 13490 } else if (this.active.length && !$.contains(this.tablist[0], this.active[0])) { 13491 // all remaining tabs are disabled 13492 if (this.tabs.length === options.disabled.length) { 13493 options.active = false; 13494 this.active = $(); 13495 // activate previous tab 13496 } else { 13497 this._activate(this._findNextTab(Math.max(0, options.active - 1), false)); 13498 } 13499 // was active, active tab still exists 13500 } else { 13501 // make sure active index is correct 13502 options.active = this.tabs.index(this.active); 13503 } 13504 13505 this._refresh(); 13506 }, 13507 13508 _refresh: function () { 13509 this._setupDisabled(this.options.disabled); 13510 this._setupEvents(this.options.event); 13511 this._setupHeightStyle(this.options.heightStyle); 13512 13513 this.tabs.not(this.active).attr({ 13514 "aria-selected": "false", 13515 tabIndex: -1 13516 }); 13517 this.panels.not(this._getPanelForTab(this.active)) 13518 .hide() 13519 .attr({ 13520 "aria-expanded": "false", 13521 "aria-hidden": "true" 13522 }); 13523 13524 // Make sure one tab is in the tab order 13525 if (!this.active.length) { 13526 this.tabs.eq(0).attr("tabIndex", 0); 13527 } else { 13528 this.active 13529 .addClass("ui-tabs-active ui-state-active") 13530 .attr({ 13531 "aria-selected": "true", 13532 tabIndex: 0 13533 }); 13534 this._getPanelForTab(this.active) 13535 .show() 13536 .attr({ 13537 "aria-expanded": "true", 13538 "aria-hidden": "false" 13539 }); 13540 } 13541 }, 13542 13543 _processTabs: function () { 13544 var that = this; 13545 13546 this.tablist = this._getList() 13547 .addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all") 13548 .attr("role", "tablist"); 13549 13550 this.tabs = this.tablist.find("> li:has(a[href])") 13551 .addClass("ui-state-default ui-corner-top") 13552 .attr({ 13553 role: "tab", 13554 tabIndex: -1 13555 }); 13556 13557 this.anchors = this.tabs.map(function () { 13558 return $("a", this)[0]; 13559 }) 13560 .addClass("ui-tabs-anchor") 13561 .attr({ 13562 role: "presentation", 13563 tabIndex: -1 13564 }); 13565 13566 this.panels = $(); 13567 13568 this.anchors.each(function (i, anchor) { 13569 var selector, panel, panelId, 13570 anchorId = $(anchor).uniqueId().attr("id"), 13571 tab = $(anchor).closest("li"), 13572 originalAriaControls = tab.attr("aria-controls"); 13573 13574 // inline tab 13575 if (isLocal(anchor)) { 13576 selector = anchor.hash; 13577 panel = that.element.find(that._sanitizeSelector(selector)); 13578 // remote tab 13579 } else { 13580 panelId = that._tabId(tab); 13581 selector = "#" + panelId; 13582 panel = that.element.find(selector); 13583 if (!panel.length) { 13584 panel = that._createPanel(panelId); 13585 panel.insertAfter(that.panels[i - 1] || that.tablist); 13586 } 13587 panel.attr("aria-live", "polite"); 13588 } 13589 13590 if (panel.length) { 13591 that.panels = that.panels.add(panel); 13592 } 13593 if (originalAriaControls) { 13594 tab.data("ui-tabs-aria-controls", originalAriaControls); 13595 } 13596 tab.attr({ 13597 "aria-controls": selector.substring(1), 13598 "aria-labelledby": anchorId 13599 }); 13600 panel.attr("aria-labelledby", anchorId); 13601 }); 13602 13603 this.panels 13604 .addClass("ui-tabs-panel ui-widget-content ui-corner-bottom") 13605 .attr("role", "tabpanel"); 13606 }, 13607 13608 // allow overriding how to find the list for rare usage scenarios (#7715) 13609 _getList: function () { 13610 return this.element.find("ol,ul").eq(0); 13611 }, 13612 13613 _createPanel: function (id) { 13614 return $("<div>") 13615 .attr("id", id) 13616 .addClass("ui-tabs-panel ui-widget-content ui-corner-bottom") 13617 .data("ui-tabs-destroy", true); 13618 }, 13619 13620 _setupDisabled: function (disabled) { 13621 if ($.isArray(disabled)) { 13622 if (!disabled.length) { 13623 disabled = false; 13624 } else if (disabled.length === this.anchors.length) { 13625 disabled = true; 13626 } 13627 } 13628 13629 // disable tabs 13630 for (var i = 0, li; (li = this.tabs[i]) ; i++) { 13631 if (disabled === true || $.inArray(i, disabled) !== -1) { 13632 $(li) 13633 .addClass("ui-state-disabled") 13634 .attr("aria-disabled", "true"); 13635 } else { 13636 $(li) 13637 .removeClass("ui-state-disabled") 13638 .removeAttr("aria-disabled"); 13639 } 13640 } 13641 13642 this.options.disabled = disabled; 13643 }, 13644 13645 _setupEvents: function (event) { 13646 var events = { 13647 click: function (event) { 13648 event.preventDefault(); 13649 } 13650 }; 13651 if (event) { 13652 $.each(event.split(" "), function (index, eventName) { 13653 events[eventName] = "_eventHandler"; 13654 }); 13655 } 13656 13657 this._off(this.anchors.add(this.tabs).add(this.panels)); 13658 this._on(this.anchors, events); 13659 this._on(this.tabs, { keydown: "_tabKeydown" }); 13660 this._on(this.panels, { keydown: "_panelKeydown" }); 13661 13662 this._focusable(this.tabs); 13663 this._hoverable(this.tabs); 13664 }, 13665 13666 _setupHeightStyle: function (heightStyle) { 13667 var maxHeight, overflow, 13668 parent = this.element.parent(); 13669 13670 if (heightStyle === "fill") { 13671 // IE 6 treats height like minHeight, so we need to turn off overflow 13672 // in order to get a reliable height 13673 // we use the minHeight support test because we assume that only 13674 // browsers that don't support minHeight will treat height as minHeight 13675 if (!$.support.minHeight) { 13676 overflow = parent.css("overflow"); 13677 parent.css("overflow", "hidden"); 13678 } 13679 maxHeight = parent.height(); 13680 this.element.siblings(":visible").each(function () { 13681 var elem = $(this), 13682 position = elem.css("position"); 13683 13684 if (position === "absolute" || position === "fixed") { 13685 return; 13686 } 13687 maxHeight -= elem.outerHeight(true); 13688 }); 13689 if (overflow) { 13690 parent.css("overflow", overflow); 13691 } 13692 13693 this.element.children().not(this.panels).each(function () { 13694 maxHeight -= $(this).outerHeight(true); 13695 }); 13696 13697 this.panels.each(function () { 13698 $(this).height(Math.max(0, maxHeight - 13699 $(this).innerHeight() + $(this).height())); 13700 }) 13701 .css("overflow", "auto"); 13702 } else if (heightStyle === "auto") { 13703 maxHeight = 0; 13704 this.panels.each(function () { 13705 maxHeight = Math.max(maxHeight, $(this).height("").height()); 13706 }).height(maxHeight); 13707 } 13708 }, 13709 13710 _eventHandler: function (event) { 13711 var options = this.options, 13712 active = this.active, 13713 anchor = $(event.currentTarget), 13714 tab = anchor.closest("li"), 13715 clickedIsActive = tab[0] === active[0], 13716 collapsing = clickedIsActive && options.collapsible, 13717 toShow = collapsing ? $() : this._getPanelForTab(tab), 13718 toHide = !active.length ? $() : this._getPanelForTab(active), 13719 eventData = { 13720 oldTab: active, 13721 oldPanel: toHide, 13722 newTab: collapsing ? $() : tab, 13723 newPanel: toShow 13724 }; 13725 13726 event.preventDefault(); 13727 13728 if (tab.hasClass("ui-state-disabled") || 13729 // tab is already loading 13730 tab.hasClass("ui-tabs-loading") || 13731 // can't switch durning an animation 13732 this.running || 13733 // click on active header, but not collapsible 13734 (clickedIsActive && !options.collapsible) || 13735 // allow canceling activation 13736 (this._trigger("beforeActivate", event, eventData) === false)) { 13737 return; 13738 } 13739 13740 options.active = collapsing ? false : this.tabs.index(tab); 13741 13742 this.active = clickedIsActive ? $() : tab; 13743 if (this.xhr) { 13744 this.xhr.abort(); 13745 } 13746 13747 if (!toHide.length && !toShow.length) { 13748 $.error("jQuery UI Tabs: Mismatching fragment identifier."); 13749 } 13750 13751 if (toShow.length) { 13752 this.load(this.tabs.index(tab), event); 13753 } 13754 this._toggle(event, eventData); 13755 }, 13756 13757 // handles show/hide for selecting tabs 13758 _toggle: function (event, eventData) { 13759 var that = this, 13760 toShow = eventData.newPanel, 13761 toHide = eventData.oldPanel; 13762 13763 this.running = true; 13764 13765 function complete() { 13766 that.running = false; 13767 that._trigger("activate", event, eventData); 13768 } 13769 13770 function show() { 13771 eventData.newTab.closest("li").addClass("ui-tabs-active ui-state-active"); 13772 13773 if (toShow.length && that.options.show) { 13774 that._show(toShow, that.options.show, complete); 13775 } else { 13776 toShow.show(); 13777 complete(); 13778 } 13779 } 13780 13781 // start out by hiding, then showing, then completing 13782 if (toHide.length && this.options.hide) { 13783 this._hide(toHide, this.options.hide, function () { 13784 eventData.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"); 13785 show(); 13786 }); 13787 } else { 13788 eventData.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"); 13789 toHide.hide(); 13790 show(); 13791 } 13792 13793 toHide.attr({ 13794 "aria-expanded": "false", 13795 "aria-hidden": "true" 13796 }); 13797 eventData.oldTab.attr("aria-selected", "false"); 13798 // If we're switching tabs, remove the old tab from the tab order. 13799 // If we're opening from collapsed state, remove the previous tab from the tab order. 13800 // If we're collapsing, then keep the collapsing tab in the tab order. 13801 if (toShow.length && toHide.length) { 13802 eventData.oldTab.attr("tabIndex", -1); 13803 } else if (toShow.length) { 13804 this.tabs.filter(function () { 13805 return $(this).attr("tabIndex") === 0; 13806 }) 13807 .attr("tabIndex", -1); 13808 } 13809 13810 toShow.attr({ 13811 "aria-expanded": "true", 13812 "aria-hidden": "false" 13813 }); 13814 eventData.newTab.attr({ 13815 "aria-selected": "true", 13816 tabIndex: 0 13817 }); 13818 }, 13819 13820 _activate: function (index) { 13821 var anchor, 13822 active = this._findActive(index); 13823 13824 // trying to activate the already active panel 13825 if (active[0] === this.active[0]) { 13826 return; 13827 } 13828 13829 // trying to collapse, simulate a click on the current active header 13830 if (!active.length) { 13831 active = this.active; 13832 } 13833 13834 anchor = active.find(".ui-tabs-anchor")[0]; 13835 this._eventHandler({ 13836 target: anchor, 13837 currentTarget: anchor, 13838 preventDefault: $.noop 13839 }); 13840 }, 13841 13842 _findActive: function (index) { 13843 return index === false ? $() : this.tabs.eq(index); 13844 }, 13845 13846 _getIndex: function (index) { 13847 // meta-function to give users option to provide a href string instead of a numerical index. 13848 if (typeof index === "string") { 13849 index = this.anchors.index(this.anchors.filter("[href$='" + index + "']")); 13850 } 13851 13852 return index; 13853 }, 13854 13855 _destroy: function () { 13856 if (this.xhr) { 13857 this.xhr.abort(); 13858 } 13859 13860 this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"); 13861 13862 this.tablist 13863 .removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all") 13864 .removeAttr("role"); 13865 13866 this.anchors 13867 .removeClass("ui-tabs-anchor") 13868 .removeAttr("role") 13869 .removeAttr("tabIndex") 13870 .removeData("href.tabs") 13871 .removeData("load.tabs") 13872 .removeUniqueId(); 13873 13874 this.tabs.add(this.panels).each(function () { 13875 if ($.data(this, "ui-tabs-destroy")) { 13876 $(this).remove(); 13877 } else { 13878 $(this) 13879 .removeClass("ui-state-default ui-state-active ui-state-disabled " + 13880 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel") 13881 .removeAttr("tabIndex") 13882 .removeAttr("aria-live") 13883 .removeAttr("aria-busy") 13884 .removeAttr("aria-selected") 13885 .removeAttr("aria-labelledby") 13886 .removeAttr("aria-hidden") 13887 .removeAttr("aria-expanded") 13888 .removeAttr("role"); 13889 } 13890 }); 13891 13892 this.tabs.each(function () { 13893 var li = $(this), 13894 prev = li.data("ui-tabs-aria-controls"); 13895 if (prev) { 13896 li.attr("aria-controls", prev); 13897 } else { 13898 li.removeAttr("aria-controls"); 13899 } 13900 }); 13901 13902 this.panels.show(); 13903 13904 if (this.options.heightStyle !== "content") { 13905 this.panels.css("height", ""); 13906 } 13907 }, 13908 13909 enable: function (index) { 13910 var disabled = this.options.disabled; 13911 if (disabled === false) { 13912 return; 13913 } 13914 13915 if (index === undefined) { 13916 disabled = false; 13917 } else { 13918 index = this._getIndex(index); 13919 if ($.isArray(disabled)) { 13920 disabled = $.map(disabled, function (num) { 13921 return num !== index ? num : null; 13922 }); 13923 } else { 13924 disabled = $.map(this.tabs, function (li, num) { 13925 return num !== index ? num : null; 13926 }); 13927 } 13928 } 13929 this._setupDisabled(disabled); 13930 }, 13931 13932 disable: function (index) { 13933 var disabled = this.options.disabled; 13934 if (disabled === true) { 13935 return; 13936 } 13937 13938 if (index === undefined) { 13939 disabled = true; 13940 } else { 13941 index = this._getIndex(index); 13942 if ($.inArray(index, disabled) !== -1) { 13943 return; 13944 } 13945 if ($.isArray(disabled)) { 13946 disabled = $.merge([index], disabled).sort(); 13947 } else { 13948 disabled = [index]; 13949 } 13950 } 13951 this._setupDisabled(disabled); 13952 }, 13953 13954 load: function (index, event) { 13955 index = this._getIndex(index); 13956 var that = this, 13957 tab = this.tabs.eq(index), 13958 anchor = tab.find(".ui-tabs-anchor"), 13959 panel = this._getPanelForTab(tab), 13960 eventData = { 13961 tab: tab, 13962 panel: panel 13963 }; 13964 13965 // not remote 13966 if (isLocal(anchor[0])) { 13967 return; 13968 } 13969 13970 this.xhr = $.ajax(this._ajaxSettings(anchor, event, eventData)); 13971 13972 // support: jQuery <1.8 13973 // jQuery <1.8 returns false if the request is canceled in beforeSend, 13974 // but as of 1.8, $.ajax() always returns a jqXHR object. 13975 if (this.xhr && this.xhr.statusText !== "canceled") { 13976 tab.addClass("ui-tabs-loading"); 13977 panel.attr("aria-busy", "true"); 13978 13979 this.xhr 13980 .success(function (response) { 13981 // support: jQuery <1.8 13982 // http://bugs.jquery.com/ticket/11778 13983 setTimeout(function () { 13984 panel.html(response); 13985 that._trigger("load", event, eventData); 13986 }, 1); 13987 }) 13988 .complete(function (jqXHR, status) { 13989 // support: jQuery <1.8 13990 // http://bugs.jquery.com/ticket/11778 13991 setTimeout(function () { 13992 if (status === "abort") { 13993 that.panels.stop(false, true); 13994 } 13995 13996 tab.removeClass("ui-tabs-loading"); 13997 panel.removeAttr("aria-busy"); 13998 13999 if (jqXHR === that.xhr) { 14000 delete that.xhr; 14001 } 14002 }, 1); 14003 }); 14004 } 14005 }, 14006 14007 // TODO: Remove this function in 1.10 when ajaxOptions is removed 14008 _ajaxSettings: function (anchor, event, eventData) { 14009 var that = this; 14010 return { 14011 url: anchor.attr("href"), 14012 beforeSend: function (jqXHR, settings) { 14013 return that._trigger("beforeLoad", event, 14014 $.extend({ jqXHR: jqXHR, ajaxSettings: settings }, eventData)); 14015 } 14016 }; 14017 }, 14018 14019 _getPanelForTab: function (tab) { 14020 var id = $(tab).attr("aria-controls"); 14021 return this.element.find(this._sanitizeSelector("#" + id)); 14022 } 14023 });
14024 14025 // DEPRECATED 14026 if ($.uiBackCompat !== false) { 14027 14028 // helper method for a lot of the back compat extensions 14029 $.ui.tabs.prototype._ui = function (tab, panel) { 14030 return { 14031 tab: tab, 14032 panel: panel, 14033 index: this.anchors.index(tab) 14034 }; 14035 }; 14036 14037 // url method 14038 $.widget("ui.tabs", $.ui.tabs, { 14039 url: function (index, url) { 14040 this.anchors.eq(index).attr("href", url); 14041 } 14042 }); 14043 14044 // TODO: Remove _ajaxSettings() method when removing this extension 14045 // ajaxOptions and cache options 14046 $.widget("ui.tabs", $.ui.tabs, { 14047 options: { 14048 ajaxOptions: null, 14049 cache: false 14050 }, 14051 14052 _create: function () { 14053 this._super(); 14054 14055 var that = this; 14056 14057 this._on({ 14058 tabsbeforeload: function (event, ui) { 14059 // tab is already cached 14060 if ($.data(ui.tab[0], "cache.tabs")) { 14061 event.preventDefault(); 14062 return; 14063 } 14064 14065 ui.jqXHR.success(function () { 14066 if (that.options.cache) { 14067 $.data(ui.tab[0], "cache.tabs", true); 14068 } 14069 }); 14070 } 14071 }); 14072 }, 14073 14074 _ajaxSettings: function (anchor, event, ui) { 14075 var ajaxOptions = this.options.ajaxOptions; 14076 return $.extend({}, ajaxOptions, { 14077 error: function (xhr, status) { 14078 try { 14079 // Passing index avoid a race condition when this method is 14080 // called after the user has selected another tab. 14081 // Pass the anchor that initiated this request allows 14082 // loadError to manipulate the tab content panel via $(a.hash) 14083 ajaxOptions.error( 14084 xhr, status, ui.tab.closest("li").index(), ui.tab[0]); 14085 } 14086 catch (error) { } 14087 } 14088 }, this._superApply(arguments)); 14089 }, 14090 14091 _setOption: function (key, value) { 14092 // reset cache if switching from cached to not cached 14093 if (key === "cache" && value === false) { 14094 this.anchors.removeData("cache.tabs"); 14095 } 14096 this._super(key, value); 14097 }, 14098 14099 _destroy: function () { 14100 this.anchors.removeData("cache.tabs"); 14101 this._super(); 14102 }, 14103 14104 url: function (index) { 14105 this.anchors.eq(index).removeData("cache.tabs"); 14106 this._superApply(arguments); 14107 } 14108 }); 14109 14110 // abort method 14111 $.widget("ui.tabs", $.ui.tabs, { 14112 abort: function () { 14113 if (this.xhr) { 14114 this.xhr.abort(); 14115 } 14116 } 14117 }); 14118 14119 // spinner 14120 $.widget("ui.tabs", $.ui.tabs, { 14121 options: { 14122 spinner: "<em>Loading…</em>" 14123 }, 14124 _create: function () { 14125 this._super(); 14126 this._on({ 14127 tabsbeforeload: function (event, ui) { 14128 // Don't react to nested tabs or tabs that don't use a spinner 14129 if (event.target !== this.element[0] || 14130 !this.options.spinner) { 14131 return; 14132 } 14133 14134 var span = ui.tab.find("span"), 14135 html = span.html(); 14136 span.html(this.options.spinner); 14137 ui.jqXHR.complete(function () { 14138 span.html(html); 14139 }); 14140 } 14141 }); 14142 } 14143 }); 14144 14145 // enable/disable events 14146 $.widget("ui.tabs", $.ui.tabs, { 14147 options: { 14148 enable: null, 14149 disable: null 14150 }, 14151 14152 enable: function (index) { 14153 var options = this.options, 14154 trigger; 14155 14156 if (index && options.disabled === true || 14157 ($.isArray(options.disabled) && $.inArray(index, options.disabled) !== -1)) { 14158 trigger = true; 14159 } 14160 14161 this._superApply(arguments); 14162 14163 if (trigger) { 14164 this._trigger("enable", null, this._ui(this.anchors[index], this.panels[index])); 14165 } 14166 }, 14167 14168 disable: function (index) { 14169 var options = this.options, 14170 trigger; 14171 14172 if (index && options.disabled === false || 14173 ($.isArray(options.disabled) && $.inArray(index, options.disabled) === -1)) { 14174 trigger = true; 14175 } 14176 14177 this._superApply(arguments); 14178 14179 if (trigger) { 14180 this._trigger("disable", null, this._ui(this.anchors[index], this.panels[index])); 14181 } 14182 } 14183 }); 14184 14185 // add/remove methods and events 14186 $.widget("ui.tabs", $.ui.tabs, { 14187 options: { 14188 add: null, 14189 remove: null, 14190 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>" 14191 }, 14192 14193 add: function (url, label, index) { 14194 if (index === undefined) { 14195 index = this.anchors.length; 14196 } 14197 14198 var doInsertAfter, panel, 14199 options = this.options, 14200 li = $(options.tabTemplate 14201 .replace(/#\{href\}/g, url) 14202 .replace(/#\{label\}/g, label)), 14203 id = !url.indexOf("#") ? 14204 url.replace("#", "") : 14205 this._tabId(li); 14206 14207 li.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy", true); 14208 li.attr("aria-controls", id); 14209 14210 doInsertAfter = index >= this.tabs.length; 14211 14212 // try to find an existing element before creating a new one 14213 panel = this.element.find("#" + id); 14214 if (!panel.length) { 14215 panel = this._createPanel(id); 14216 if (doInsertAfter) { 14217 if (index > 0) { 14218 panel.insertAfter(this.panels.eq(-1)); 14219 } else { 14220 panel.appendTo(this.element); 14221 } 14222 } else { 14223 panel.insertBefore(this.panels[index]); 14224 } 14225 } 14226 panel.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(); 14227 14228 if (doInsertAfter) { 14229 li.appendTo(this.tablist); 14230 } else { 14231 li.insertBefore(this.tabs[index]); 14232 } 14233 14234 options.disabled = $.map(options.disabled, function (n) { 14235 return n >= index ? ++n : n; 14236 }); 14237 14238 this.refresh();
14239 if (this.tabs.length === 1 && options.active === false) { 14240 this.option("active", 0); 14241 } 14242 14243 this._trigger("add", null, this._ui(this.anchors[index], this.panels[index])); 14244 return this; 14245 }, 14246 14247 remove: function (index) { 14248 index = this._getIndex(index); 14249 var options = this.options, 14250 tab = this.tabs.eq(index).remove(), 14251 panel = this._getPanelForTab(tab).remove(); 14252 14253 // If selected tab was removed focus tab to the right or 14254 // in case the last tab was removed the tab to the left. 14255 // We check for more than 2 tabs, because if there are only 2, 14256 // then when we remove this tab, there will only be one tab left 14257 // so we don't need to detect which tab to activate. 14258 if (tab.hasClass("ui-tabs-active") && this.anchors.length > 2) { 14259 this._activate(index + (index + 1 < this.anchors.length ? 1 : -1)); 14260 } 14261 14262 options.disabled = $.map( 14263 $.grep(options.disabled, function (n) { 14264 return n !== index; 14265 }), 14266 function (n) { 14267 return n >= index ? --n : n; 14268 }); 14269 14270 this.refresh(); 14271 14272 this._trigger("remove", null, this._ui(tab.find("a")[0], panel[0])); 14273 return this; 14274 } 14275 }); 14276 14277 // length method 14278 $.widget("ui.tabs", $.ui.tabs, { 14279 length: function () { 14280 return this.anchors.length; 14281 } 14282 }); 14283 14284 // panel ids (idPrefix option + title attribute) 14285 $.widget("ui.tabs", $.ui.tabs, { 14286 options: { 14287 idPrefix: "ui-tabs-" 14288 }, 14289 14290 _tabId: function (tab) { 14291 var a = tab.is("li") ? tab.find("a[href]") : tab; 14292 a = a[0]; 14293 return $(a).closest("li").attr("aria-controls") || 14294 a.title && a.title.replace(/\s/g, "_").replace(/[^\w\u00c0-\uFFFF\-]/g, "") || 14295 this.options.idPrefix + getNextTabId(); 14296 } 14297 }); 14298 14299 // _createPanel method 14300 $.widget("ui.tabs", $.ui.tabs, { 14301 options: { 14302 panelTemplate: "<div></div>" 14303 }, 14304 14305 _createPanel: function (id) { 14306 return $(this.options.panelTemplate) 14307 .attr("id", id) 14308 .addClass("ui-tabs-panel ui-widget-content ui-corner-bottom") 14309 .data("ui-tabs-destroy", true); 14310 } 14311 }); 14312 14313 // selected option 14314 $.widget("ui.tabs", $.ui.tabs, { 14315 _create: function () { 14316 var options = this.options; 14317 if (options.active === null && options.selected !== undefined) { 14318 options.active = options.selected === -1 ? false : options.selected; 14319 } 14320 this._super(); 14321 options.selected = options.active; 14322 if (options.selected === false) { 14323 options.selected = -1; 14324 } 14325 }, 14326 14327 _setOption: function (key, value) { 14328 if (key !== "selected") { 14329 return this._super(key, value); 14330 } 14331 14332 var options = this.options; 14333 this._super("active", value === -1 ? false : value); 14334 options.selected = options.active; 14335 if (options.selected === false) { 14336 options.selected = -1; 14337 } 14338 }, 14339 14340 _eventHandler: function () { 14341 this._superApply(arguments); 14342 this.options.selected = this.options.active; 14343 if (this.options.selected === false) { 14344 this.options.selected = -1; 14345 } 14346 } 14347 }); 14348 14349 // show and select event 14350 $.widget("ui.tabs", $.ui.tabs, { 14351 options: { 14352 show: null, 14353 select: null 14354 }, 14355 _create: function () { 14356 this._super(); 14357 if (this.options.active !== false) { 14358 this._trigger("show", null, this._ui( 14359 this.active.find(".ui-tabs-anchor")[0], 14360 this._getPanelForTab(this.active)[0])); 14361 } 14362 }, 14363 _trigger: function (type, event, data) { 14364 var tab, panel, 14365 ret = this._superApply(arguments); 14366 14367 if (!ret) { 14368 return false; 14369 } 14370 14371 if (type === "beforeActivate") { 14372 tab = data.newTab.length ? data.newTab : data.oldTab; 14373 panel = data.newPanel.length ? data.newPanel : data.oldPanel; 14374 ret = this._super("select", event, { 14375 tab: tab.find(".ui-tabs-anchor")[0], 14376 panel: panel[0], 14377 index: tab.closest("li").index() 14378 }); 14379 } else if (type === "activate" && data.newTab.length) { 14380 ret = this._super("show", event, { 14381 tab: data.newTab.find(".ui-tabs-anchor")[0], 14382 panel: data.newPanel[0], 14383 index: data.newTab.closest("li").index() 14384 }); 14385 } 14386 return ret; 14387 } 14388 }); 14389 14390 // select method 14391 $.widget("ui.tabs", $.ui.tabs, { 14392 select: function (index) { 14393 index = this._getIndex(index); 14394 if (index === -1) { 14395 if (this.options.collapsible && this.options.selected !== -1) { 14396 index = this.options.selected; 14397 } else { 14398 return; 14399 } 14400 } 14401 this.anchors.eq(index).trigger(this.options.event + this.eventNamespace); 14402 } 14403 }); 14404 14405 // cookie option 14406 (function () { 14407 14408 var listId = 0; 14409 14410 $.widget("ui.tabs", $.ui.tabs, { 14411 options: { 14412 cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } 14413 }, 14414 _create: function () { 14415 var options = this.options, 14416 active; 14417 if (options.active == null && options.cookie) { 14418 active = parseInt(this._cookie(), 10); 14419 if (active === -1) { 14420 active = false; 14421 } 14422 options.active = active; 14423 } 14424 this._super(); 14425 }, 14426 _cookie: function (active) { 14427 var cookie = [this.cookie || 14428 (this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId))]; 14429 if (arguments.length) { 14430 cookie.push(active === false ? -1 : active); 14431 cookie.push(this.options.cookie); 14432 } 14433 return $.cookie.apply(null, cookie); 14434 }, 14435 _refresh: function () { 14436 this._super(); 14437 if (this.options.cookie) { 14438 this._cookie(this.options.active, this.options.cookie); 14439 } 14440 }, 14441 _eventHandler: function () { 14442 this._superApply(arguments); 14443 if (this.options.cookie) { 14444 this._cookie(this.options.active, this.options.cookie); 14445 } 14446 }, 14447 _destroy: function () { 14448 this._super(); 14449 if (this.options.cookie) { 14450 this._cookie(null, this.options.cookie); 14451 } 14452 } 14453 }); 14454 14455 })(); 14456 14457 // load event 14458 $.widget("ui.tabs", $.ui.tabs, { 14459 _trigger: function (type, event, data) { 14460 var _data = $.extend({}, data); 14461 if (type === "load") { 14462 _data.panel = _data.panel[0]; 14463 _data.tab = _data.tab.find(".ui-tabs-anchor")[0]; 14464 } 14465 return this._super(type, event, _data); 14466 } 14467 }); 14468 14469 // fx option 14470 // The new animation options (show, hide) conflict with the old show callback. 14471 // The old fx option wins over show/hide anyway (always favor back-compat). 14472 // If a user wants to use the new animation API, they must give up the old API. 14473 $.widget("ui.tabs", $.ui.tabs, { 14474 options: { 14475 fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 } 14476 }, 14477 14478 _getFx: function () { 14479 var hide, show, 14480 fx = this.options.fx; 14481 14482 if (fx) { 14483 if ($.isArray(fx)) { 14484 hide = fx[0]; 14485 show = fx[1]; 14486 } else { 14487 hide = show = fx; 14488 } 14489 } 14490 14491 return fx ? { show: show, hide: hide } : null; 14492 }, 14493 14494 _toggle: function (event, eventData) { 14495 var that = this, 14496 toShow = eventData.newPanel, 14497 toHide = eventData.oldPanel, 14498 fx = this._getFx();
vendor: 15,562 bytes, lines 14499-14924
14499 14500 if (!fx) { 14501 return this._super(event, eventData); 14502 } 14503 14504 that.running = true; 14505 14506 function complete() { 14507 that.running = false; 14508 that._trigger("activate", event, eventData); 14509 } 14510 14511 function show() { 14512 eventData.newTab.closest("li").addClass("ui-tabs-active ui-state-active"); 14513 14514 if (toShow.length && fx.show) { 14515 toShow 14516 .animate(fx.show, fx.show.duration, function () { 14517 complete(); 14518 }); 14519 } else { 14520 toShow.show(); 14521 complete(); 14522 } 14523 } 14524 14525 // start out by hiding, then showing, then completing 14526 if (toHide.length && fx.hide) { 14527 toHide.animate(fx.hide, fx.hide.duration, function () { 14528 eventData.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"); 14529 show(); 14530 }); 14531 } else { 14532 eventData.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"); 14533 toHide.hide(); 14534 show(); 14535 } 14536 } 14537 }); 14538 } 14539 14540})(jQuery); 14541 14542(function ($) { 14543 14544 var increments = 0; 14545 14546 function addDescribedBy(elem, id) { 14547 var describedby = (elem.attr("aria-describedby") || "").split(/\s+/); 14548 describedby.push(id); 14549 elem 14550 .data("ui-tooltip-id", id) 14551 .attr("aria-describedby", $.trim(describedby.join(" "))); 14552 } 14553 14554 function removeDescribedBy(elem) { 14555 var id = elem.data("ui-tooltip-id"), 14556 describedby = (elem.attr("aria-describedby") || "").split(/\s+/), 14557 index = $.inArray(id, describedby); 14558 if (index !== -1) { 14559 describedby.splice(index, 1); 14560 } 14561 14562 elem.removeData("ui-tooltip-id"); 14563 describedby = $.trim(describedby.join(" ")); 14564 if (describedby) { 14565 elem.attr("aria-describedby", describedby); 14566 } else { 14567 elem.removeAttr("aria-describedby"); 14568 } 14569 } 14570 14571 $.widget("ui.tooltip", { 14572 version: "1.9.2", 14573 options: { 14574 content: function () { 14575 return $(this).attr("title"); 14576 }, 14577 hide: true, 14578 // Disabled elements have inconsistent behavior across browsers (#8661) 14579 items: "[title]:not([disabled])", 14580 position: { 14581 my: "left top+15", 14582 at: "left bottom", 14583 collision: "flipfit flip" 14584 }, 14585 show: true, 14586 tooltipClass: null, 14587 track: false, 14588 14589 // callbacks 14590 close: null, 14591 open: null 14592 }, 14593 14594 _create: function () { 14595 this._on({ 14596 mouseover: "open", 14597 focusin: "open" 14598 }); 14599 14600 // IDs of generated tooltips, needed for destroy 14601 this.tooltips = {}; 14602 // IDs of parent tooltips where we removed the title attribute 14603 this.parents = {}; 14604 14605 if (this.options.disabled) { 14606 this._disable(); 14607 } 14608 }, 14609 14610 _setOption: function (key, value) { 14611 var that = this; 14612 14613 if (key === "disabled") { 14614 this[value ? "_disable" : "_enable"](); 14615 this.options[key] = value; 14616 // disable element style changes 14617 return; 14618 } 14619 14620 this._super(key, value); 14621 14622 if (key === "content") { 14623 $.each(this.tooltips, function (id, element) { 14624 that._updateContent(element); 14625 }); 14626 } 14627 }, 14628 14629 _disable: function () { 14630 var that = this; 14631 14632 // close open tooltips 14633 $.each(this.tooltips, function (id, element) { 14634 var event = $.Event("blur"); 14635 event.target = event.currentTarget = element[0]; 14636 that.close(event, true); 14637 }); 14638 14639 // remove title attributes to prevent native tooltips 14640 this.element.find(this.options.items).andSelf().each(function () { 14641 var element = $(this); 14642 if (element.is("[title]")) { 14643 element 14644 .data("ui-tooltip-title", element.attr("title")) 14645 .attr("title", ""); 14646 } 14647 }); 14648 }, 14649 14650 _enable: function () { 14651 // restore title attributes 14652 this.element.find(this.options.items).andSelf().each(function () { 14653 var element = $(this); 14654 if (element.data("ui-tooltip-title")) { 14655 element.attr("title", element.data("ui-tooltip-title")); 14656 } 14657 }); 14658 }, 14659 14660 open: function (event) { 14661 var that = this, 14662 target = $(event ? event.target : this.element) 14663 // we need closest here due to mouseover bubbling, 14664 // but always pointing at the same event target 14665 .closest(this.options.items); 14666 14667 // No element to show a tooltip for or the tooltip is already open 14668 if (!target.length || target.data("ui-tooltip-id")) { 14669 return; 14670 } 14671 14672 if (target.attr("title")) { 14673 target.data("ui-tooltip-title", target.attr("title")); 14674 } 14675 14676 target.data("ui-tooltip-open", true); 14677 14678 // kill parent tooltips, custom or native, for hover 14679 if (event && event.type === "mouseover") { 14680 target.parents().each(function () { 14681 var parent = $(this), 14682 blurEvent; 14683 if (parent.data("ui-tooltip-open")) { 14684 blurEvent = $.Event("blur"); 14685 blurEvent.target = blurEvent.currentTarget = this; 14686 that.close(blurEvent, true); 14687 } 14688 if (parent.attr("title")) { 14689 parent.uniqueId(); 14690 that.parents[this.id] = { 14691 element: this, 14692 title: parent.attr("title") 14693 }; 14694 parent.attr("title", ""); 14695 } 14696 }); 14697 } 14698 14699 this._updateContent(target, event); 14700 }, 14701 14702 _updateContent: function (target, event) { 14703 var content, 14704 contentOption = this.options.content, 14705 that = this, 14706 eventType = event ? event.type : null; 14707 14708 if (typeof contentOption === "string") { 14709 return this._open(event, target, contentOption); 14710 } 14711 14712 content = contentOption.call(target[0], function (response) { 14713 // ignore async response if tooltip was closed already 14714 if (!target.data("ui-tooltip-open")) { 14715 return; 14716 } 14717 // IE may instantly serve a cached response for ajax requests 14718 // delay this call to _open so the other call to _open runs first 14719 that._delay(function () { 14720 // jQuery creates a special event for focusin when it doesn't 14721 // exist natively. To improve performance, the native event 14722 // object is reused and the type is changed. Therefore, we can't 14723 // rely on the type being correct after the event finished 14724 // bubbling, so we set it back to the previous value. (#8740) 14725 if (event) { 14726 event.type = eventType; 14727 } 14728 this._open(event, target, response); 14729 }); 14730 }); 14731 if (content) { 14732 this._open(event, target, content); 14733 } 14734 }, 14735 14736 _open: function (event, target, content) { 14737 var tooltip, events, delayedShow, 14738 positionOption = $.extend({}, this.options.position); 14739 14740 if (!content) { 14741 return; 14742 } 14743 14744 // Content can be updated multiple times. If the tooltip already 14745 // exists, then just update the content and bail. 14746 tooltip = this._find(target); 14747 if (tooltip.length) { 14748 tooltip.find(".ui-tooltip-content").html(content); 14749 return; 14750 } 14751 14752 // if we have a title, clear it to prevent the native tooltip 14753 // we have to check first to avoid defining a title if none exists 14754 // (we don't want to cause an element to start matching [title]) 14755 // 14756 // We use removeAttr only for key events, to allow IE to export the correct 14757 // accessible attributes. For mouse events, set to empty string to avoid 14758 // native tooltip showing up (happens only when removing inside mouseover). 14759 if (target.is("[title]")) { 14760 if (event && event.type === "mouseover") { 14761 target.attr("title", ""); 14762 } else { 14763 target.removeAttr("title"); 14764 } 14765 } 14766 14767 tooltip = this._tooltip(target); 14768 addDescribedBy(target, tooltip.attr("id")); 14769 tooltip.find(".ui-tooltip-content").html(content); 14770 14771 function position(event) { 14772 positionOption.of = event; 14773 if (tooltip.is(":hidden")) { 14774 return; 14775 } 14776 tooltip.position(positionOption); 14777 } 14778 if (this.options.track && event && /^mouse/.test(event.type)) { 14779 this._on(this.document, { 14780 mousemove: position 14781 }); 14782 // trigger once to override element-relative positioning 14783 position(event); 14784 } else { 14785 tooltip.position($.extend({ 14786 of: target 14787 }, this.options.position)); 14788 } 14789 14790 tooltip.hide(); 14791 14792 this._show(tooltip, this.options.show); 14793 // Handle tracking tooltips that are shown with a delay (#8644). As soon 14794 // as the tooltip is visible, position the tooltip using the most recent 14795 // event. 14796 if (this.options.show && this.options.show.delay) { 14797 delayedShow = setInterval(function () { 14798 if (tooltip.is(":visible")) { 14799 position(positionOption.of); 14800 clearInterval(delayedShow); 14801 } 14802 }, $.fx.interval); 14803 } 14804 14805 this._trigger("open", event, { tooltip: tooltip }); 14806 14807 events = { 14808 keyup: function (event) { 14809 if (event.keyCode === $.ui.keyCode.ESCAPE) { 14810 var fakeEvent = $.Event(event); 14811 fakeEvent.currentTarget = target[0]; 14812 this.close(fakeEvent, true); 14813 } 14814 }, 14815 remove: function () { 14816 this._removeTooltip(tooltip); 14817 } 14818 }; 14819 if (!event || event.type === "mouseover") { 14820 events.mouseleave = "close"; 14821 } 14822 if (!event || event.type === "focusin") { 14823 events.focusout = "close"; 14824 } 14825 this._on(true, target, events); 14826 }, 14827 14828 close: function (event) { 14829 var that = this, 14830 target = $(event ? event.currentTarget : this.element), 14831 tooltip = this._find(target); 14832 14833 // disabling closes the tooltip, so we need to track when we're closing 14834 // to avoid an infinite loop in case the tooltip becomes disabled on close 14835 if (this.closing) { 14836 return; 14837 } 14838 14839 // only set title if we had one before (see comment in _open()) 14840 if (target.data("ui-tooltip-title")) { 14841 target.attr("title", target.data("ui-tooltip-title")); 14842 } 14843 14844 removeDescribedBy(target); 14845 14846 tooltip.stop(true); 14847 this._hide(tooltip, this.options.hide, function () { 14848 that._removeTooltip($(this)); 14849 }); 14850 14851 target.removeData("ui-tooltip-open"); 14852 this._off(target, "mouseleave focusout keyup"); 14853 // Remove 'remove' binding only on delegated targets 14854 if (target[0] !== this.element[0]) { 14855 this._off(target, "remove"); 14856 } 14857 this._off(this.document, "mousemove"); 14858 14859 if (event && event.type === "mouseleave") { 14860 $.each(this.parents, function (id, parent) { 14861 $(parent.element).attr("title", parent.title); 14862 delete that.parents[id]; 14863 }); 14864 } 14865 14866 this.closing = true; 14867 this._trigger("close", event, { tooltip: tooltip }); 14868 this.closing = false; 14869 }, 14870 14871 _tooltip: function (element) { 14872 var id = "ui-tooltip-" + increments++, 14873 tooltip = $("<div>") 14874 .attr({ 14875 id: id, 14876 role: "tooltip" 14877 }) 14878 .addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content " + 14879 (this.options.tooltipClass || "")); 14880 $("<div>") 14881 .addClass("ui-tooltip-content") 14882 .appendTo(tooltip); 14883 tooltip.appendTo(this.document[0].body); 14884 if ($.fn.bgiframe) { 14885 tooltip.bgiframe(); 14886 } 14887 this.tooltips[id] = element; 14888 return tooltip; 14889 }, 14890 14891 _find: function (target) { 14892 var id = target.data("ui-tooltip-id"); 14893 return id ? $("#" + id) : $(); 14894 }, 14895 14896 _removeTooltip: function (tooltip) { 14897 tooltip.remove(); 14898 delete this.tooltips[tooltip.attr("id")]; 14899 }, 14900 14901 _destroy: function () { 14902 var that = this; 14903 14904 // close open tooltips 14905 $.each(this.tooltips, function (id, element) { 14906 // Delegate to close method to handle common cleanup 14907 var event = $.Event("blur"); 14908 event.target = event.currentTarget = element[0]; 14909 that.close(event, true); 14910 14911 // Remove immediately; destroying an open tooltip doesn't use the 14912 // hide animation 14913 $("#" + id).remove(); 14914 14915 // Restore the title 14916 if (element.data("ui-tooltip-title")) { 14917 element.attr("title", element.data("ui-tooltip-title")); 14918 element.removeData("ui-tooltip-title"); 14919 } 14920 }); 14921 } 14922 }); 14923 14924}(jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.