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