Index: trunk/phase3/js2/js2stopgap.js |
— | — | @@ -4374,5083 +4374,7 @@ |
4375 | 4375 | |
4376 | 4376 | }); |
4377 | 4377 | })(); |
4378 | | -/* |
4379 | | - * jQuery UI 1.7.2 |
4380 | | - * |
4381 | | - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
4382 | | - * Dual licensed under the MIT (MIT-LICENSE.txt) |
4383 | | - * and GPL (GPL-LICENSE.txt) licenses. |
4384 | | - * |
4385 | | - * http://docs.jquery.com/UI |
4386 | | - */ |
4387 | | -;jQuery.ui || (function($) { |
4388 | 4378 | |
4389 | | -var _remove = $.fn.remove, |
4390 | | - isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9); |
4391 | | - |
4392 | | -//Helper functions and ui object |
4393 | | -$.ui = { |
4394 | | - version: "1.7.2", |
4395 | | - |
4396 | | - // $.ui.plugin is deprecated. Use the proxy pattern instead. |
4397 | | - plugin: { |
4398 | | - add: function(module, option, set) { |
4399 | | - var proto = $.ui[module].prototype; |
4400 | | - for(var i in set) { |
4401 | | - proto.plugins[i] = proto.plugins[i] || []; |
4402 | | - proto.plugins[i].push([option, set[i]]); |
4403 | | - } |
4404 | | - }, |
4405 | | - call: function(instance, name, args) { |
4406 | | - var set = instance.plugins[name]; |
4407 | | - if(!set || !instance.element[0].parentNode) { return; } |
4408 | | - |
4409 | | - for (var i = 0; i < set.length; i++) { |
4410 | | - if (instance.options[set[i][0]]) { |
4411 | | - set[i][1].apply(instance.element, args); |
4412 | | - } |
4413 | | - } |
4414 | | - } |
4415 | | - }, |
4416 | | - |
4417 | | - contains: function(a, b) { |
4418 | | - return document.compareDocumentPosition |
4419 | | - ? a.compareDocumentPosition(b) & 16 |
4420 | | - : a !== b && a.contains(b); |
4421 | | - }, |
4422 | | - |
4423 | | - hasScroll: function(el, a) { |
4424 | | - |
4425 | | - //If overflow is hidden, the element might have extra content, but the user wants to hide it |
4426 | | - if ($(el).css('overflow') == 'hidden') { return false; } |
4427 | | - |
4428 | | - var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop', |
4429 | | - has = false; |
4430 | | - |
4431 | | - if (el[scroll] > 0) { return true; } |
4432 | | - |
4433 | | - // TODO: determine which cases actually cause this to happen |
4434 | | - // if the element doesn't have the scroll set, see if it's possible to |
4435 | | - // set the scroll |
4436 | | - el[scroll] = 1; |
4437 | | - has = (el[scroll] > 0); |
4438 | | - el[scroll] = 0; |
4439 | | - return has; |
4440 | | - }, |
4441 | | - |
4442 | | - isOverAxis: function(x, reference, size) { |
4443 | | - //Determines when x coordinate is over "b" element axis |
4444 | | - return (x > reference) && (x < (reference + size)); |
4445 | | - }, |
4446 | | - |
4447 | | - isOver: function(y, x, top, left, height, width) { |
4448 | | - //Determines when x, y coordinates is over "b" element |
4449 | | - return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width); |
4450 | | - }, |
4451 | | - |
4452 | | - keyCode: { |
4453 | | - BACKSPACE: 8, |
4454 | | - CAPS_LOCK: 20, |
4455 | | - COMMA: 188, |
4456 | | - CONTROL: 17, |
4457 | | - DELETE: 46, |
4458 | | - DOWN: 40, |
4459 | | - END: 35, |
4460 | | - ENTER: 13, |
4461 | | - ESCAPE: 27, |
4462 | | - HOME: 36, |
4463 | | - INSERT: 45, |
4464 | | - LEFT: 37, |
4465 | | - NUMPAD_ADD: 107, |
4466 | | - NUMPAD_DECIMAL: 110, |
4467 | | - NUMPAD_DIVIDE: 111, |
4468 | | - NUMPAD_ENTER: 108, |
4469 | | - NUMPAD_MULTIPLY: 106, |
4470 | | - NUMPAD_SUBTRACT: 109, |
4471 | | - PAGE_DOWN: 34, |
4472 | | - PAGE_UP: 33, |
4473 | | - PERIOD: 190, |
4474 | | - RIGHT: 39, |
4475 | | - SHIFT: 16, |
4476 | | - SPACE: 32, |
4477 | | - TAB: 9, |
4478 | | - UP: 38 |
4479 | | - } |
4480 | | -}; |
4481 | | - |
4482 | | -// WAI-ARIA normalization |
4483 | | -if (isFF2) { |
4484 | | - var attr = $.attr, |
4485 | | - removeAttr = $.fn.removeAttr, |
4486 | | - ariaNS = "http://www.w3.org/2005/07/aaa", |
4487 | | - ariaState = /^aria-/, |
4488 | | - ariaRole = /^wairole:/; |
4489 | | - |
4490 | | - $.attr = function(elem, name, value) { |
4491 | | - var set = value !== undefined; |
4492 | | - |
4493 | | - return (name == 'role' |
4494 | | - ? (set |
4495 | | - ? attr.call(this, elem, name, "wairole:" + value) |
4496 | | - : (attr.apply(this, arguments) || "").replace(ariaRole, "")) |
4497 | | - : (ariaState.test(name) |
4498 | | - ? (set |
4499 | | - ? elem.setAttributeNS(ariaNS, |
4500 | | - name.replace(ariaState, "aaa:"), value) |
4501 | | - : attr.call(this, elem, name.replace(ariaState, "aaa:"))) |
4502 | | - : attr.apply(this, arguments))); |
4503 | | - }; |
4504 | | - |
4505 | | - $.fn.removeAttr = function(name) { |
4506 | | - return (ariaState.test(name) |
4507 | | - ? this.each(function() { |
4508 | | - this.removeAttributeNS(ariaNS, name.replace(ariaState, "")); |
4509 | | - }) : removeAttr.call(this, name)); |
4510 | | - }; |
4511 | | -} |
4512 | | - |
4513 | | -//jQuery plugins |
4514 | | -$.fn.extend({ |
4515 | | - remove: function() { |
4516 | | - // Safari has a native remove event which actually removes DOM elements, |
4517 | | - // so we have to use triggerHandler instead of trigger (#3037). |
4518 | | - $("*", this).add(this).each(function() { |
4519 | | - $(this).triggerHandler("remove"); |
4520 | | - }); |
4521 | | - return _remove.apply(this, arguments ); |
4522 | | - }, |
4523 | | - |
4524 | | - enableSelection: function() { |
4525 | | - return this |
4526 | | - .attr('unselectable', 'off') |
4527 | | - .css('MozUserSelect', '') |
4528 | | - .unbind('selectstart.ui'); |
4529 | | - }, |
4530 | | - |
4531 | | - disableSelection: function() { |
4532 | | - return this |
4533 | | - .attr('unselectable', 'on') |
4534 | | - .css('MozUserSelect', 'none') |
4535 | | - .bind('selectstart.ui', function() { return false; }); |
4536 | | - }, |
4537 | | - |
4538 | | - scrollParent: function() { |
4539 | | - var scrollParent; |
4540 | | - if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { |
4541 | | - scrollParent = this.parents().filter(function() { |
4542 | | - return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); |
4543 | | - }).eq(0); |
4544 | | - } else { |
4545 | | - scrollParent = this.parents().filter(function() { |
4546 | | - return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); |
4547 | | - }).eq(0); |
4548 | | - } |
4549 | | - |
4550 | | - return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; |
4551 | | - } |
4552 | | -}); |
4553 | | - |
4554 | | - |
4555 | | -//Additional selectors |
4556 | | -$.extend($.expr[':'], { |
4557 | | - data: function(elem, i, match) { |
4558 | | - return !!$.data(elem, match[3]); |
4559 | | - }, |
4560 | | - |
4561 | | - focusable: function(element) { |
4562 | | - var nodeName = element.nodeName.toLowerCase(), |
4563 | | - tabIndex = $.attr(element, 'tabindex'); |
4564 | | - return (/input|select|textarea|button|object/.test(nodeName) |
4565 | | - ? !element.disabled |
4566 | | - : 'a' == nodeName || 'area' == nodeName |
4567 | | - ? element.href || !isNaN(tabIndex) |
4568 | | - : !isNaN(tabIndex)) |
4569 | | - // the element and all of its ancestors must be visible |
4570 | | - // the browser may report that the area is hidden |
4571 | | - && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length; |
4572 | | - }, |
4573 | | - |
4574 | | - tabbable: function(element) { |
4575 | | - var tabIndex = $.attr(element, 'tabindex'); |
4576 | | - return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable'); |
4577 | | - } |
4578 | | -}); |
4579 | | - |
4580 | | - |
4581 | | -// $.widget is a factory to create jQuery plugins |
4582 | | -// taking some boilerplate code out of the plugin code |
4583 | | -function getter(namespace, plugin, method, args) { |
4584 | | - function getMethods(type) { |
4585 | | - var methods = $[namespace][plugin][type] || []; |
4586 | | - return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods); |
4587 | | - } |
4588 | | - |
4589 | | - var methods = getMethods('getter'); |
4590 | | - if (args.length == 1 && typeof args[0] == 'string') { |
4591 | | - methods = methods.concat(getMethods('getterSetter')); |
4592 | | - } |
4593 | | - return ($.inArray(method, methods) != -1); |
4594 | | -} |
4595 | | - |
4596 | | -$.widget = function(name, prototype) { |
4597 | | - var namespace = name.split(".")[0]; |
4598 | | - name = name.split(".")[1]; |
4599 | | - |
4600 | | - // create plugin method |
4601 | | - $.fn[name] = function(options) { |
4602 | | - var isMethodCall = (typeof options == 'string'), |
4603 | | - args = Array.prototype.slice.call(arguments, 1); |
4604 | | - |
4605 | | - // prevent calls to internal methods |
4606 | | - if (isMethodCall && options.substring(0, 1) == '_') { |
4607 | | - return this; |
4608 | | - } |
4609 | | - |
4610 | | - // handle getter methods |
4611 | | - if (isMethodCall && getter(namespace, name, options, args)) { |
4612 | | - var instance = $.data(this[0], name); |
4613 | | - return (instance ? instance[options].apply(instance, args) |
4614 | | - : undefined); |
4615 | | - } |
4616 | | - |
4617 | | - // handle initialization and non-getter methods |
4618 | | - return this.each(function() { |
4619 | | - var instance = $.data(this, name); |
4620 | | - |
4621 | | - // constructor |
4622 | | - (!instance && !isMethodCall && |
4623 | | - $.data(this, name, new $[namespace][name](this, options))._init()); |
4624 | | - |
4625 | | - // method call |
4626 | | - (instance && isMethodCall && $.isFunction(instance[options]) && |
4627 | | - instance[options].apply(instance, args)); |
4628 | | - }); |
4629 | | - }; |
4630 | | - |
4631 | | - // create widget constructor |
4632 | | - $[namespace] = $[namespace] || {}; |
4633 | | - $[namespace][name] = function(element, options) { |
4634 | | - var self = this; |
4635 | | - |
4636 | | - this.namespace = namespace; |
4637 | | - this.widgetName = name; |
4638 | | - this.widgetEventPrefix = $[namespace][name].eventPrefix || name; |
4639 | | - this.widgetBaseClass = namespace + '-' + name; |
4640 | | - |
4641 | | - this.options = $.extend({}, |
4642 | | - $.widget.defaults, |
4643 | | - $[namespace][name].defaults, |
4644 | | - $.metadata && $.metadata.get(element)[name], |
4645 | | - options); |
4646 | | - |
4647 | | - this.element = $(element) |
4648 | | - .bind('setData.' + name, function(event, key, value) { |
4649 | | - if (event.target == element) { |
4650 | | - return self._setData(key, value); |
4651 | | - } |
4652 | | - }) |
4653 | | - .bind('getData.' + name, function(event, key) { |
4654 | | - if (event.target == element) { |
4655 | | - return self._getData(key); |
4656 | | - } |
4657 | | - }) |
4658 | | - .bind('remove', function() { |
4659 | | - return self.destroy(); |
4660 | | - }); |
4661 | | - }; |
4662 | | - |
4663 | | - // add widget prototype |
4664 | | - $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype); |
4665 | | - |
4666 | | - // TODO: merge getter and getterSetter properties from widget prototype |
4667 | | - // and plugin prototype |
4668 | | - $[namespace][name].getterSetter = 'option'; |
4669 | | -}; |
4670 | | - |
4671 | | -$.widget.prototype = { |
4672 | | - _init: function() {}, |
4673 | | - destroy: function() { |
4674 | | - this.element.removeData(this.widgetName) |
4675 | | - .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled') |
4676 | | - .removeAttr('aria-disabled'); |
4677 | | - }, |
4678 | | - |
4679 | | - option: function(key, value) { |
4680 | | - var options = key, |
4681 | | - self = this; |
4682 | | - |
4683 | | - if (typeof key == "string") { |
4684 | | - if (value === undefined) { |
4685 | | - return this._getData(key); |
4686 | | - } |
4687 | | - options = {}; |
4688 | | - options[key] = value; |
4689 | | - } |
4690 | | - |
4691 | | - $.each(options, function(key, value) { |
4692 | | - self._setData(key, value); |
4693 | | - }); |
4694 | | - }, |
4695 | | - _getData: function(key) { |
4696 | | - return this.options[key]; |
4697 | | - }, |
4698 | | - _setData: function(key, value) { |
4699 | | - this.options[key] = value; |
4700 | | - |
4701 | | - if (key == 'disabled') { |
4702 | | - this.element |
4703 | | - [value ? 'addClass' : 'removeClass']( |
4704 | | - this.widgetBaseClass + '-disabled' + ' ' + |
4705 | | - this.namespace + '-state-disabled') |
4706 | | - .attr("aria-disabled", value); |
4707 | | - } |
4708 | | - }, |
4709 | | - |
4710 | | - enable: function() { |
4711 | | - this._setData('disabled', false); |
4712 | | - }, |
4713 | | - disable: function() { |
4714 | | - this._setData('disabled', true); |
4715 | | - }, |
4716 | | - |
4717 | | - _trigger: function(type, event, data) { |
4718 | | - var callback = this.options[type], |
4719 | | - eventName = (type == this.widgetEventPrefix |
4720 | | - ? type : this.widgetEventPrefix + type); |
4721 | | - |
4722 | | - event = $.Event(event); |
4723 | | - event.type = eventName; |
4724 | | - |
4725 | | - // copy original event properties over to the new event |
4726 | | - // this would happen if we could call $.event.fix instead of $.Event |
4727 | | - // but we don't have a way to force an event to be fixed multiple times |
4728 | | - if (event.originalEvent) { |
4729 | | - for (var i = $.event.props.length, prop; i;) { |
4730 | | - prop = $.event.props[--i]; |
4731 | | - event[prop] = event.originalEvent[prop]; |
4732 | | - } |
4733 | | - } |
4734 | | - |
4735 | | - this.element.trigger(event, data); |
4736 | | - |
4737 | | - return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false |
4738 | | - || event.isDefaultPrevented()); |
4739 | | - } |
4740 | | -}; |
4741 | | - |
4742 | | -$.widget.defaults = { |
4743 | | - disabled: false |
4744 | | -}; |
4745 | | - |
4746 | | - |
4747 | | -/** Mouse Interaction Plugin **/ |
4748 | | - |
4749 | | -$.ui.mouse = { |
4750 | | - _mouseInit: function() { |
4751 | | - var self = this; |
4752 | | - |
4753 | | - this.element |
4754 | | - .bind('mousedown.'+this.widgetName, function(event) { |
4755 | | - return self._mouseDown(event); |
4756 | | - }) |
4757 | | - .bind('click.'+this.widgetName, function(event) { |
4758 | | - if(self._preventClickEvent) { |
4759 | | - self._preventClickEvent = false; |
4760 | | - event.stopImmediatePropagation(); |
4761 | | - return false; |
4762 | | - } |
4763 | | - }); |
4764 | | - |
4765 | | - // Prevent text selection in IE |
4766 | | - if ($.browser.msie) { |
4767 | | - this._mouseUnselectable = this.element.attr('unselectable'); |
4768 | | - this.element.attr('unselectable', 'on'); |
4769 | | - } |
4770 | | - |
4771 | | - this.started = false; |
4772 | | - }, |
4773 | | - |
4774 | | - // TODO: make sure destroying one instance of mouse doesn't mess with |
4775 | | - // other instances of mouse |
4776 | | - _mouseDestroy: function() { |
4777 | | - this.element.unbind('.'+this.widgetName); |
4778 | | - |
4779 | | - // Restore text selection in IE |
4780 | | - ($.browser.msie |
4781 | | - && this.element.attr('unselectable', this._mouseUnselectable)); |
4782 | | - }, |
4783 | | - |
4784 | | - _mouseDown: function(event) { |
4785 | | - // don't let more than one widget handle mouseStart |
4786 | | - // TODO: figure out why we have to use originalEvent |
4787 | | - event.originalEvent = event.originalEvent || {}; |
4788 | | - if (event.originalEvent.mouseHandled) { return; } |
4789 | | - |
4790 | | - // we may have missed mouseup (out of window) |
4791 | | - (this._mouseStarted && this._mouseUp(event)); |
4792 | | - |
4793 | | - this._mouseDownEvent = event; |
4794 | | - |
4795 | | - var self = this, |
4796 | | - btnIsLeft = (event.which == 1), |
4797 | | - elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false); |
4798 | | - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { |
4799 | | - return true; |
4800 | | - } |
4801 | | - |
4802 | | - this.mouseDelayMet = !this.options.delay; |
4803 | | - if (!this.mouseDelayMet) { |
4804 | | - this._mouseDelayTimer = setTimeout(function() { |
4805 | | - self.mouseDelayMet = true; |
4806 | | - }, this.options.delay); |
4807 | | - } |
4808 | | - |
4809 | | - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { |
4810 | | - this._mouseStarted = (this._mouseStart(event) !== false); |
4811 | | - if (!this._mouseStarted) { |
4812 | | - event.preventDefault(); |
4813 | | - return true; |
4814 | | - } |
4815 | | - } |
4816 | | - |
4817 | | - // these delegates are required to keep context |
4818 | | - this._mouseMoveDelegate = function(event) { |
4819 | | - return self._mouseMove(event); |
4820 | | - }; |
4821 | | - this._mouseUpDelegate = function(event) { |
4822 | | - return self._mouseUp(event); |
4823 | | - }; |
4824 | | - $(document) |
4825 | | - .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) |
4826 | | - .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); |
4827 | | - |
4828 | | - // preventDefault() is used to prevent the selection of text here - |
4829 | | - // however, in Safari, this causes select boxes not to be selectable |
4830 | | - // anymore, so this fix is needed |
4831 | | - ($.browser.safari || event.preventDefault()); |
4832 | | - |
4833 | | - event.originalEvent.mouseHandled = true; |
4834 | | - return true; |
4835 | | - }, |
4836 | | - |
4837 | | - _mouseMove: function(event) { |
4838 | | - // IE mouseup check - mouseup happened when mouse was out of window |
4839 | | - if ($.browser.msie && !event.button) { |
4840 | | - return this._mouseUp(event); |
4841 | | - } |
4842 | | - |
4843 | | - if (this._mouseStarted) { |
4844 | | - this._mouseDrag(event); |
4845 | | - return event.preventDefault(); |
4846 | | - } |
4847 | | - |
4848 | | - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { |
4849 | | - this._mouseStarted = |
4850 | | - (this._mouseStart(this._mouseDownEvent, event) !== false); |
4851 | | - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); |
4852 | | - } |
4853 | | - |
4854 | | - return !this._mouseStarted; |
4855 | | - }, |
4856 | | - |
4857 | | - _mouseUp: function(event) { |
4858 | | - $(document) |
4859 | | - .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) |
4860 | | - .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); |
4861 | | - |
4862 | | - if (this._mouseStarted) { |
4863 | | - this._mouseStarted = false; |
4864 | | - this._preventClickEvent = (event.target == this._mouseDownEvent.target); |
4865 | | - this._mouseStop(event); |
4866 | | - } |
4867 | | - |
4868 | | - return false; |
4869 | | - }, |
4870 | | - |
4871 | | - _mouseDistanceMet: function(event) { |
4872 | | - return (Math.max( |
4873 | | - Math.abs(this._mouseDownEvent.pageX - event.pageX), |
4874 | | - Math.abs(this._mouseDownEvent.pageY - event.pageY) |
4875 | | - ) >= this.options.distance |
4876 | | - ); |
4877 | | - }, |
4878 | | - |
4879 | | - _mouseDelayMet: function(event) { |
4880 | | - return this.mouseDelayMet; |
4881 | | - }, |
4882 | | - |
4883 | | - // These are placeholder methods, to be overriden by extending plugin |
4884 | | - _mouseStart: function(event) {}, |
4885 | | - _mouseDrag: function(event) {}, |
4886 | | - _mouseStop: function(event) {}, |
4887 | | - _mouseCapture: function(event) { return true; } |
4888 | | -}; |
4889 | | - |
4890 | | -$.ui.mouse.defaults = { |
4891 | | - cancel: null, |
4892 | | - distance: 1, |
4893 | | - delay: 0 |
4894 | | -}; |
4895 | | - |
4896 | | -})(jQuery); |
4897 | | -/* |
4898 | | - * jQuery UI Draggable 1.7.2 |
4899 | | - * |
4900 | | - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
4901 | | - * Dual licensed under the MIT (MIT-LICENSE.txt) |
4902 | | - * and GPL (GPL-LICENSE.txt) licenses. |
4903 | | - * |
4904 | | - * http://docs.jquery.com/UI/Draggables |
4905 | | - * |
4906 | | - * Depends: |
4907 | | - * ui.core.js |
4908 | | - */ |
4909 | | -(function($) { |
4910 | | - |
4911 | | -$.widget("ui.draggable", $.extend({}, $.ui.mouse, { |
4912 | | - |
4913 | | - _init: function() { |
4914 | | - |
4915 | | - if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) |
4916 | | - this.element[0].style.position = 'relative'; |
4917 | | - |
4918 | | - (this.options.addClasses && this.element.addClass("ui-draggable")); |
4919 | | - (this.options.disabled && this.element.addClass("ui-draggable-disabled")); |
4920 | | - |
4921 | | - this._mouseInit(); |
4922 | | - |
4923 | | - }, |
4924 | | - |
4925 | | - destroy: function() { |
4926 | | - if(!this.element.data('draggable')) return; |
4927 | | - this.element |
4928 | | - .removeData("draggable") |
4929 | | - .unbind(".draggable") |
4930 | | - .removeClass("ui-draggable" |
4931 | | - + " ui-draggable-dragging" |
4932 | | - + " ui-draggable-disabled"); |
4933 | | - this._mouseDestroy(); |
4934 | | - }, |
4935 | | - |
4936 | | - _mouseCapture: function(event) { |
4937 | | - |
4938 | | - var o = this.options; |
4939 | | - |
4940 | | - if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) |
4941 | | - return false; |
4942 | | - |
4943 | | - //Quit if we're not on a valid handle |
4944 | | - this.handle = this._getHandle(event); |
4945 | | - if (!this.handle) |
4946 | | - return false; |
4947 | | - |
4948 | | - return true; |
4949 | | - |
4950 | | - }, |
4951 | | - |
4952 | | - _mouseStart: function(event) { |
4953 | | - |
4954 | | - var o = this.options; |
4955 | | - |
4956 | | - //Create and append the visible helper |
4957 | | - this.helper = this._createHelper(event); |
4958 | | - |
4959 | | - //Cache the helper size |
4960 | | - this._cacheHelperProportions(); |
4961 | | - |
4962 | | - //If ddmanager is used for droppables, set the global draggable |
4963 | | - if($.ui.ddmanager) |
4964 | | - $.ui.ddmanager.current = this; |
4965 | | - |
4966 | | - /* |
4967 | | - * - Position generation - |
4968 | | - * This block generates everything position related - it's the core of draggables. |
4969 | | - */ |
4970 | | - |
4971 | | - //Cache the margins of the original element |
4972 | | - this._cacheMargins(); |
4973 | | - |
4974 | | - //Store the helper's css position |
4975 | | - this.cssPosition = this.helper.css("position"); |
4976 | | - this.scrollParent = this.helper.scrollParent(); |
4977 | | - |
4978 | | - //The element's absolute position on the page minus margins |
4979 | | - this.offset = this.element.offset(); |
4980 | | - this.offset = { |
4981 | | - top: this.offset.top - this.margins.top, |
4982 | | - left: this.offset.left - this.margins.left |
4983 | | - }; |
4984 | | - |
4985 | | - $.extend(this.offset, { |
4986 | | - click: { //Where the click happened, relative to the element |
4987 | | - left: event.pageX - this.offset.left, |
4988 | | - top: event.pageY - this.offset.top |
4989 | | - }, |
4990 | | - parent: this._getParentOffset(), |
4991 | | - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper |
4992 | | - }); |
4993 | | - |
4994 | | - //Generate the original position |
4995 | | - this.originalPosition = this._generatePosition(event); |
4996 | | - this.originalPageX = event.pageX; |
4997 | | - this.originalPageY = event.pageY; |
4998 | | - |
4999 | | - //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied |
5000 | | - if(o.cursorAt) |
5001 | | - this._adjustOffsetFromHelper(o.cursorAt); |
5002 | | - |
5003 | | - //Set a containment if given in the options |
5004 | | - if(o.containment) |
5005 | | - this._setContainment(); |
5006 | | - |
5007 | | - //Call plugins and callbacks |
5008 | | - this._trigger("start", event); |
5009 | | - |
5010 | | - //Recache the helper size |
5011 | | - this._cacheHelperProportions(); |
5012 | | - |
5013 | | - //Prepare the droppable offsets |
5014 | | - if ($.ui.ddmanager && !o.dropBehaviour) |
5015 | | - $.ui.ddmanager.prepareOffsets(this, event); |
5016 | | - |
5017 | | - this.helper.addClass("ui-draggable-dragging"); |
5018 | | - this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position |
5019 | | - return true; |
5020 | | - }, |
5021 | | - |
5022 | | - _mouseDrag: function(event, noPropagation) { |
5023 | | - |
5024 | | - //Compute the helpers position |
5025 | | - this.position = this._generatePosition(event); |
5026 | | - this.positionAbs = this._convertPositionTo("absolute"); |
5027 | | - |
5028 | | - //Call plugins and callbacks and use the resulting position if something is returned |
5029 | | - if (!noPropagation) { |
5030 | | - var ui = this._uiHash(); |
5031 | | - this._trigger('drag', event, ui); |
5032 | | - this.position = ui.position; |
5033 | | - } |
5034 | | - |
5035 | | - if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; |
5036 | | - if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; |
5037 | | - if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); |
5038 | | - |
5039 | | - return false; |
5040 | | - }, |
5041 | | - |
5042 | | - _mouseStop: function(event) { |
5043 | | - |
5044 | | - //If we are using droppables, inform the manager about the drop |
5045 | | - var dropped = false; |
5046 | | - if ($.ui.ddmanager && !this.options.dropBehaviour) |
5047 | | - dropped = $.ui.ddmanager.drop(this, event); |
5048 | | - |
5049 | | - //if a drop comes from outside (a sortable) |
5050 | | - if(this.dropped) { |
5051 | | - dropped = this.dropped; |
5052 | | - this.dropped = false; |
5053 | | - } |
5054 | | - |
5055 | | - 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))) { |
5056 | | - var self = this; |
5057 | | - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { |
5058 | | - self._trigger("stop", event); |
5059 | | - self._clear(); |
5060 | | - }); |
5061 | | - } else { |
5062 | | - this._trigger("stop", event); |
5063 | | - this._clear(); |
5064 | | - } |
5065 | | - |
5066 | | - return false; |
5067 | | - }, |
5068 | | - |
5069 | | - _getHandle: function(event) { |
5070 | | - |
5071 | | - var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; |
5072 | | - $(this.options.handle, this.element) |
5073 | | - .find("*") |
5074 | | - .andSelf() |
5075 | | - .each(function() { |
5076 | | - if(this == event.target) handle = true; |
5077 | | - }); |
5078 | | - |
5079 | | - return handle; |
5080 | | - |
5081 | | - }, |
5082 | | - |
5083 | | - _createHelper: function(event) { |
5084 | | - |
5085 | | - var o = this.options; |
5086 | | - var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element); |
5087 | | - |
5088 | | - if(!helper.parents('body').length) |
5089 | | - helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); |
5090 | | - |
5091 | | - if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) |
5092 | | - helper.css("position", "absolute"); |
5093 | | - |
5094 | | - return helper; |
5095 | | - |
5096 | | - }, |
5097 | | - |
5098 | | - _adjustOffsetFromHelper: function(obj) { |
5099 | | - if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left; |
5100 | | - if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; |
5101 | | - if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top; |
5102 | | - if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; |
5103 | | - }, |
5104 | | - |
5105 | | - _getParentOffset: function() { |
5106 | | - |
5107 | | - //Get the offsetParent and cache its position |
5108 | | - this.offsetParent = this.helper.offsetParent(); |
5109 | | - var po = this.offsetParent.offset(); |
5110 | | - |
5111 | | - // This is a special case where we need to modify a offset calculated on start, since the following happened: |
5112 | | - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent |
5113 | | - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that |
5114 | | - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag |
5115 | | - if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { |
5116 | | - po.left += this.scrollParent.scrollLeft(); |
5117 | | - po.top += this.scrollParent.scrollTop(); |
5118 | | - } |
5119 | | - |
5120 | | - if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information |
5121 | | - || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix |
5122 | | - po = { top: 0, left: 0 }; |
5123 | | - |
5124 | | - return { |
5125 | | - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), |
5126 | | - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) |
5127 | | - }; |
5128 | | - |
5129 | | - }, |
5130 | | - |
5131 | | - _getRelativeOffset: function() { |
5132 | | - |
5133 | | - if(this.cssPosition == "relative") { |
5134 | | - var p = this.element.position(); |
5135 | | - return { |
5136 | | - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), |
5137 | | - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() |
5138 | | - }; |
5139 | | - } else { |
5140 | | - return { top: 0, left: 0 }; |
5141 | | - } |
5142 | | - |
5143 | | - }, |
5144 | | - |
5145 | | - _cacheMargins: function() { |
5146 | | - this.margins = { |
5147 | | - left: (parseInt(this.element.css("marginLeft"),10) || 0), |
5148 | | - top: (parseInt(this.element.css("marginTop"),10) || 0) |
5149 | | - }; |
5150 | | - }, |
5151 | | - |
5152 | | - _cacheHelperProportions: function() { |
5153 | | - this.helperProportions = { |
5154 | | - width: this.helper.outerWidth(), |
5155 | | - height: this.helper.outerHeight() |
5156 | | - }; |
5157 | | - }, |
5158 | | - |
5159 | | - _setContainment: function() { |
5160 | | - |
5161 | | - var o = this.options; |
5162 | | - if(o.containment == 'parent') o.containment = this.helper[0].parentNode; |
5163 | | - if(o.containment == 'document' || o.containment == 'window') this.containment = [ |
5164 | | - 0 - this.offset.relative.left - this.offset.parent.left, |
5165 | | - 0 - this.offset.relative.top - this.offset.parent.top, |
5166 | | - $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, |
5167 | | - ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top |
5168 | | - ]; |
5169 | | - |
5170 | | - if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { |
5171 | | - var ce = $(o.containment)[0]; if(!ce) return; |
5172 | | - var co = $(o.containment).offset(); |
5173 | | - var over = ($(ce).css("overflow") != 'hidden'); |
5174 | | - |
5175 | | - this.containment = [ |
5176 | | - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, |
5177 | | - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, |
5178 | | - 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, |
5179 | | - 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 |
5180 | | - ]; |
5181 | | - } else if(o.containment.constructor == Array) { |
5182 | | - this.containment = o.containment; |
5183 | | - } |
5184 | | - |
5185 | | - }, |
5186 | | - |
5187 | | - _convertPositionTo: function(d, pos) { |
5188 | | - |
5189 | | - if(!pos) pos = this.position; |
5190 | | - var mod = d == "absolute" ? 1 : -1; |
5191 | | - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); |
5192 | | - |
5193 | | - return { |
5194 | | - top: ( |
5195 | | - pos.top // The absolute mouse position |
5196 | | - + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent |
5197 | | - + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) |
5198 | | - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) |
5199 | | - ), |
5200 | | - left: ( |
5201 | | - pos.left // The absolute mouse position |
5202 | | - + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent |
5203 | | - + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) |
5204 | | - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) |
5205 | | - ) |
5206 | | - }; |
5207 | | - |
5208 | | - }, |
5209 | | - |
5210 | | - _generatePosition: function(event) { |
5211 | | - |
5212 | | - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); |
5213 | | - |
5214 | | - // This is another very weird special case that only happens for relative elements: |
5215 | | - // 1. If the css position is relative |
5216 | | - // 2. and the scroll parent is the document or similar to the offset parent |
5217 | | - // we have to refresh the relative offset during the scroll so there are no jumps |
5218 | | - if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { |
5219 | | - this.offset.relative = this._getRelativeOffset(); |
5220 | | - } |
5221 | | - |
5222 | | - var pageX = event.pageX; |
5223 | | - var pageY = event.pageY; |
5224 | | - |
5225 | | - /* |
5226 | | - * - Position constraining - |
5227 | | - * Constrain the position to a mix of grid, containment. |
5228 | | - */ |
5229 | | - |
5230 | | - if(this.originalPosition) { //If we are not dragging yet, we won't check for options |
5231 | | - |
5232 | | - if(this.containment) { |
5233 | | - if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; |
5234 | | - if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; |
5235 | | - if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; |
5236 | | - if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; |
5237 | | - } |
5238 | | - |
5239 | | - if(o.grid) { |
5240 | | - var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; |
5241 | | - 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; |
5242 | | - |
5243 | | - var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; |
5244 | | - 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; |
5245 | | - } |
5246 | | - |
5247 | | - } |
5248 | | - |
5249 | | - return { |
5250 | | - top: ( |
5251 | | - pageY // The absolute mouse position |
5252 | | - - this.offset.click.top // Click offset (relative to the element) |
5253 | | - - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent |
5254 | | - - this.offset.parent.top // The offsetParent's offset without borders (offset + border) |
5255 | | - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) |
5256 | | - ), |
5257 | | - left: ( |
5258 | | - pageX // The absolute mouse position |
5259 | | - - this.offset.click.left // Click offset (relative to the element) |
5260 | | - - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent |
5261 | | - - this.offset.parent.left // The offsetParent's offset without borders (offset + border) |
5262 | | - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) |
5263 | | - ) |
5264 | | - }; |
5265 | | - |
5266 | | - }, |
5267 | | - |
5268 | | - _clear: function() { |
5269 | | - this.helper.removeClass("ui-draggable-dragging"); |
5270 | | - if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); |
5271 | | - //if($.ui.ddmanager) $.ui.ddmanager.current = null; |
5272 | | - this.helper = null; |
5273 | | - this.cancelHelperRemoval = false; |
5274 | | - }, |
5275 | | - |
5276 | | - // From now on bulk stuff - mainly helpers |
5277 | | - |
5278 | | - _trigger: function(type, event, ui) { |
5279 | | - ui = ui || this._uiHash(); |
5280 | | - $.ui.plugin.call(this, type, [event, ui]); |
5281 | | - if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins |
5282 | | - return $.widget.prototype._trigger.call(this, type, event, ui); |
5283 | | - }, |
5284 | | - |
5285 | | - plugins: {}, |
5286 | | - |
5287 | | - _uiHash: function(event) { |
5288 | | - return { |
5289 | | - helper: this.helper, |
5290 | | - position: this.position, |
5291 | | - absolutePosition: this.positionAbs, //deprecated |
5292 | | - offset: this.positionAbs |
5293 | | - }; |
5294 | | - } |
5295 | | - |
5296 | | -})); |
5297 | | - |
5298 | | -$.extend($.ui.draggable, { |
5299 | | - version: "1.7.2", |
5300 | | - eventPrefix: "drag", |
5301 | | - defaults: { |
5302 | | - addClasses: true, |
5303 | | - appendTo: "parent", |
5304 | | - axis: false, |
5305 | | - cancel: ":input,option", |
5306 | | - connectToSortable: false, |
5307 | | - containment: false, |
5308 | | - cursor: "auto", |
5309 | | - cursorAt: false, |
5310 | | - delay: 0, |
5311 | | - distance: 1, |
5312 | | - grid: false, |
5313 | | - handle: false, |
5314 | | - helper: "original", |
5315 | | - iframeFix: false, |
5316 | | - opacity: false, |
5317 | | - refreshPositions: false, |
5318 | | - revert: false, |
5319 | | - revertDuration: 500, |
5320 | | - scope: "default", |
5321 | | - scroll: true, |
5322 | | - scrollSensitivity: 20, |
5323 | | - scrollSpeed: 20, |
5324 | | - snap: false, |
5325 | | - snapMode: "both", |
5326 | | - snapTolerance: 20, |
5327 | | - stack: false, |
5328 | | - zIndex: false |
5329 | | - } |
5330 | | -}); |
5331 | | - |
5332 | | -$.ui.plugin.add("draggable", "connectToSortable", { |
5333 | | - start: function(event, ui) { |
5334 | | - |
5335 | | - var inst = $(this).data("draggable"), o = inst.options, |
5336 | | - uiSortable = $.extend({}, ui, { item: inst.element }); |
5337 | | - inst.sortables = []; |
5338 | | - $(o.connectToSortable).each(function() { |
5339 | | - var sortable = $.data(this, 'sortable'); |
5340 | | - if (sortable && !sortable.options.disabled) { |
5341 | | - inst.sortables.push({ |
5342 | | - instance: sortable, |
5343 | | - shouldRevert: sortable.options.revert |
5344 | | - }); |
5345 | | - sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache |
5346 | | - sortable._trigger("activate", event, uiSortable); |
5347 | | - } |
5348 | | - }); |
5349 | | - |
5350 | | - }, |
5351 | | - stop: function(event, ui) { |
5352 | | - |
5353 | | - //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper |
5354 | | - var inst = $(this).data("draggable"), |
5355 | | - uiSortable = $.extend({}, ui, { item: inst.element }); |
5356 | | - |
5357 | | - $.each(inst.sortables, function() { |
5358 | | - if(this.instance.isOver) { |
5359 | | - |
5360 | | - this.instance.isOver = 0; |
5361 | | - |
5362 | | - inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance |
5363 | | - this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) |
5364 | | - |
5365 | | - //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' |
5366 | | - if(this.shouldRevert) this.instance.options.revert = true; |
5367 | | - |
5368 | | - //Trigger the stop of the sortable |
5369 | | - this.instance._mouseStop(event); |
5370 | | - |
5371 | | - this.instance.options.helper = this.instance.options._helper; |
5372 | | - |
5373 | | - //If the helper has been the original item, restore properties in the sortable |
5374 | | - if(inst.options.helper == 'original') |
5375 | | - this.instance.currentItem.css({ top: 'auto', left: 'auto' }); |
5376 | | - |
5377 | | - } else { |
5378 | | - this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance |
5379 | | - this.instance._trigger("deactivate", event, uiSortable); |
5380 | | - } |
5381 | | - |
5382 | | - }); |
5383 | | - |
5384 | | - }, |
5385 | | - drag: function(event, ui) { |
5386 | | - |
5387 | | - var inst = $(this).data("draggable"), self = this; |
5388 | | - |
5389 | | - var checkPos = function(o) { |
5390 | | - var dyClick = this.offset.click.top, dxClick = this.offset.click.left; |
5391 | | - var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; |
5392 | | - var itemHeight = o.height, itemWidth = o.width; |
5393 | | - var itemTop = o.top, itemLeft = o.left; |
5394 | | - |
5395 | | - return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); |
5396 | | - }; |
5397 | | - |
5398 | | - $.each(inst.sortables, function(i) { |
5399 | | - |
5400 | | - //Copy over some variables to allow calling the sortable's native _intersectsWith |
5401 | | - this.instance.positionAbs = inst.positionAbs; |
5402 | | - this.instance.helperProportions = inst.helperProportions; |
5403 | | - this.instance.offset.click = inst.offset.click; |
5404 | | - |
5405 | | - if(this.instance._intersectsWith(this.instance.containerCache)) { |
5406 | | - |
5407 | | - //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once |
5408 | | - if(!this.instance.isOver) { |
5409 | | - |
5410 | | - this.instance.isOver = 1; |
5411 | | - //Now we fake the start of dragging for the sortable instance, |
5412 | | - //by cloning the list group item, appending it to the sortable and using it as inst.currentItem |
5413 | | - //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) |
5414 | | - this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true); |
5415 | | - this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it |
5416 | | - this.instance.options.helper = function() { return ui.helper[0]; }; |
5417 | | - |
5418 | | - event.target = this.instance.currentItem[0]; |
5419 | | - this.instance._mouseCapture(event, true); |
5420 | | - this.instance._mouseStart(event, true, true); |
5421 | | - |
5422 | | - //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes |
5423 | | - this.instance.offset.click.top = inst.offset.click.top; |
5424 | | - this.instance.offset.click.left = inst.offset.click.left; |
5425 | | - this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; |
5426 | | - this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; |
5427 | | - |
5428 | | - inst._trigger("toSortable", event); |
5429 | | - inst.dropped = this.instance.element; //draggable revert needs that |
5430 | | - //hack so receive/update callbacks work (mostly) |
5431 | | - inst.currentItem = inst.element; |
5432 | | - this.instance.fromOutside = inst; |
5433 | | - |
5434 | | - } |
5435 | | - |
5436 | | - //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 |
5437 | | - if(this.instance.currentItem) this.instance._mouseDrag(event); |
5438 | | - |
5439 | | - } else { |
5440 | | - |
5441 | | - //If it doesn't intersect with the sortable, and it intersected before, |
5442 | | - //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval |
5443 | | - if(this.instance.isOver) { |
5444 | | - |
5445 | | - this.instance.isOver = 0; |
5446 | | - this.instance.cancelHelperRemoval = true; |
5447 | | - |
5448 | | - //Prevent reverting on this forced stop |
5449 | | - this.instance.options.revert = false; |
5450 | | - |
5451 | | - // The out event needs to be triggered independently |
5452 | | - this.instance._trigger('out', event, this.instance._uiHash(this.instance)); |
5453 | | - |
5454 | | - this.instance._mouseStop(event, true); |
5455 | | - this.instance.options.helper = this.instance.options._helper; |
5456 | | - |
5457 | | - //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size |
5458 | | - this.instance.currentItem.remove(); |
5459 | | - if(this.instance.placeholder) this.instance.placeholder.remove(); |
5460 | | - |
5461 | | - inst._trigger("fromSortable", event); |
5462 | | - inst.dropped = false; //draggable revert needs that |
5463 | | - } |
5464 | | - |
5465 | | - }; |
5466 | | - |
5467 | | - }); |
5468 | | - |
5469 | | - } |
5470 | | -}); |
5471 | | - |
5472 | | -$.ui.plugin.add("draggable", "cursor", { |
5473 | | - start: function(event, ui) { |
5474 | | - var t = $('body'), o = $(this).data('draggable').options; |
5475 | | - if (t.css("cursor")) o._cursor = t.css("cursor"); |
5476 | | - t.css("cursor", o.cursor); |
5477 | | - }, |
5478 | | - stop: function(event, ui) { |
5479 | | - var o = $(this).data('draggable').options; |
5480 | | - if (o._cursor) $('body').css("cursor", o._cursor); |
5481 | | - } |
5482 | | -}); |
5483 | | - |
5484 | | -$.ui.plugin.add("draggable", "iframeFix", { |
5485 | | - start: function(event, ui) { |
5486 | | - var o = $(this).data('draggable').options; |
5487 | | - $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { |
5488 | | - $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>') |
5489 | | - .css({ |
5490 | | - width: this.offsetWidth+"px", height: this.offsetHeight+"px", |
5491 | | - position: "absolute", opacity: "0.001", zIndex: 1000 |
5492 | | - }) |
5493 | | - .css($(this).offset()) |
5494 | | - .appendTo("body"); |
5495 | | - }); |
5496 | | - }, |
5497 | | - stop: function(event, ui) { |
5498 | | - $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers |
5499 | | - } |
5500 | | -}); |
5501 | | - |
5502 | | -$.ui.plugin.add("draggable", "opacity", { |
5503 | | - start: function(event, ui) { |
5504 | | - var t = $(ui.helper), o = $(this).data('draggable').options; |
5505 | | - if(t.css("opacity")) o._opacity = t.css("opacity"); |
5506 | | - t.css('opacity', o.opacity); |
5507 | | - }, |
5508 | | - stop: function(event, ui) { |
5509 | | - var o = $(this).data('draggable').options; |
5510 | | - if(o._opacity) $(ui.helper).css('opacity', o._opacity); |
5511 | | - } |
5512 | | -}); |
5513 | | - |
5514 | | -$.ui.plugin.add("draggable", "scroll", { |
5515 | | - start: function(event, ui) { |
5516 | | - var i = $(this).data("draggable"); |
5517 | | - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); |
5518 | | - }, |
5519 | | - drag: function(event, ui) { |
5520 | | - |
5521 | | - var i = $(this).data("draggable"), o = i.options, scrolled = false; |
5522 | | - |
5523 | | - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { |
5524 | | - |
5525 | | - if(!o.axis || o.axis != 'x') { |
5526 | | - if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) |
5527 | | - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; |
5528 | | - else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) |
5529 | | - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; |
5530 | | - } |
5531 | | - |
5532 | | - if(!o.axis || o.axis != 'y') { |
5533 | | - if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) |
5534 | | - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; |
5535 | | - else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) |
5536 | | - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; |
5537 | | - } |
5538 | | - |
5539 | | - } else { |
5540 | | - |
5541 | | - if(!o.axis || o.axis != 'x') { |
5542 | | - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) |
5543 | | - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); |
5544 | | - else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) |
5545 | | - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); |
5546 | | - } |
5547 | | - |
5548 | | - if(!o.axis || o.axis != 'y') { |
5549 | | - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) |
5550 | | - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); |
5551 | | - else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) |
5552 | | - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); |
5553 | | - } |
5554 | | - |
5555 | | - } |
5556 | | - |
5557 | | - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) |
5558 | | - $.ui.ddmanager.prepareOffsets(i, event); |
5559 | | - |
5560 | | - } |
5561 | | -}); |
5562 | | - |
5563 | | -$.ui.plugin.add("draggable", "snap", { |
5564 | | - start: function(event, ui) { |
5565 | | - |
5566 | | - var i = $(this).data("draggable"), o = i.options; |
5567 | | - i.snapElements = []; |
5568 | | - |
5569 | | - $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { |
5570 | | - var $t = $(this); var $o = $t.offset(); |
5571 | | - if(this != i.element[0]) i.snapElements.push({ |
5572 | | - item: this, |
5573 | | - width: $t.outerWidth(), height: $t.outerHeight(), |
5574 | | - top: $o.top, left: $o.left |
5575 | | - }); |
5576 | | - }); |
5577 | | - |
5578 | | - }, |
5579 | | - drag: function(event, ui) { |
5580 | | - |
5581 | | - var inst = $(this).data("draggable"), o = inst.options; |
5582 | | - var d = o.snapTolerance; |
5583 | | - |
5584 | | - var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, |
5585 | | - y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; |
5586 | | - |
5587 | | - for (var i = inst.snapElements.length - 1; i >= 0; i--){ |
5588 | | - |
5589 | | - var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, |
5590 | | - t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; |
5591 | | - |
5592 | | - //Yes, I know, this is insane ;) |
5593 | | - if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { |
5594 | | - if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); |
5595 | | - inst.snapElements[i].snapping = false; |
5596 | | - continue; |
5597 | | - } |
5598 | | - |
5599 | | - if(o.snapMode != 'inner') { |
5600 | | - var ts = Math.abs(t - y2) <= d; |
5601 | | - var bs = Math.abs(b - y1) <= d; |
5602 | | - var ls = Math.abs(l - x2) <= d; |
5603 | | - var rs = Math.abs(r - x1) <= d; |
5604 | | - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; |
5605 | | - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; |
5606 | | - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; |
5607 | | - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; |
5608 | | - } |
5609 | | - |
5610 | | - var first = (ts || bs || ls || rs); |
5611 | | - |
5612 | | - if(o.snapMode != 'outer') { |
5613 | | - var ts = Math.abs(t - y1) <= d; |
5614 | | - var bs = Math.abs(b - y2) <= d; |
5615 | | - var ls = Math.abs(l - x1) <= d; |
5616 | | - var rs = Math.abs(r - x2) <= d; |
5617 | | - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; |
5618 | | - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; |
5619 | | - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; |
5620 | | - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; |
5621 | | - } |
5622 | | - |
5623 | | - if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) |
5624 | | - (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); |
5625 | | - inst.snapElements[i].snapping = (ts || bs || ls || rs || first); |
5626 | | - |
5627 | | - }; |
5628 | | - |
5629 | | - } |
5630 | | -}); |
5631 | | - |
5632 | | -$.ui.plugin.add("draggable", "stack", { |
5633 | | - start: function(event, ui) { |
5634 | | - |
5635 | | - var o = $(this).data("draggable").options; |
5636 | | - |
5637 | | - var group = $.makeArray($(o.stack.group)).sort(function(a,b) { |
5638 | | - return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min); |
5639 | | - }); |
5640 | | - |
5641 | | - $(group).each(function(i) { |
5642 | | - this.style.zIndex = o.stack.min + i; |
5643 | | - }); |
5644 | | - |
5645 | | - this[0].style.zIndex = o.stack.min + group.length; |
5646 | | - |
5647 | | - } |
5648 | | -}); |
5649 | | - |
5650 | | -$.ui.plugin.add("draggable", "zIndex", { |
5651 | | - start: function(event, ui) { |
5652 | | - var t = $(ui.helper), o = $(this).data("draggable").options; |
5653 | | - if(t.css("zIndex")) o._zIndex = t.css("zIndex"); |
5654 | | - t.css('zIndex', o.zIndex); |
5655 | | - }, |
5656 | | - stop: function(event, ui) { |
5657 | | - var o = $(this).data("draggable").options; |
5658 | | - if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); |
5659 | | - } |
5660 | | -}); |
5661 | | - |
5662 | | -})(jQuery); |
5663 | | -/* |
5664 | | - * jQuery UI Resizable 1.7.2 |
5665 | | - * |
5666 | | - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
5667 | | - * Dual licensed under the MIT (MIT-LICENSE.txt) |
5668 | | - * and GPL (GPL-LICENSE.txt) licenses. |
5669 | | - * |
5670 | | - * http://docs.jquery.com/UI/Resizables |
5671 | | - * |
5672 | | - * Depends: |
5673 | | - * ui.core.js |
5674 | | - */ |
5675 | | -(function($) { |
5676 | | - |
5677 | | -$.widget("ui.resizable", $.extend({}, $.ui.mouse, { |
5678 | | - |
5679 | | - _init: function() { |
5680 | | - |
5681 | | - var self = this, o = this.options; |
5682 | | - this.element.addClass("ui-resizable"); |
5683 | | - |
5684 | | - $.extend(this, { |
5685 | | - _aspectRatio: !!(o.aspectRatio), |
5686 | | - aspectRatio: o.aspectRatio, |
5687 | | - originalElement: this.element, |
5688 | | - _proportionallyResizeElements: [], |
5689 | | - _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null |
5690 | | - }); |
5691 | | - |
5692 | | - //Wrap the element if it cannot hold child nodes |
5693 | | - if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { |
5694 | | - |
5695 | | - //Opera fix for relative positioning |
5696 | | - if (/relative/.test(this.element.css('position')) && $.browser.opera) |
5697 | | - this.element.css({ position: 'relative', top: 'auto', left: 'auto' }); |
5698 | | - |
5699 | | - //Create a wrapper element and set the wrapper to the new current internal element |
5700 | | - this.element.wrap( |
5701 | | - $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({ |
5702 | | - position: this.element.css('position'), |
5703 | | - width: this.element.outerWidth(), |
5704 | | - height: this.element.outerHeight(), |
5705 | | - top: this.element.css('top'), |
5706 | | - left: this.element.css('left') |
5707 | | - }) |
5708 | | - ); |
5709 | | - |
5710 | | - //Overwrite the original this.element |
5711 | | - this.element = this.element.parent().data( |
5712 | | - "resizable", this.element.data('resizable') |
5713 | | - ); |
5714 | | - |
5715 | | - this.elementIsWrapper = true; |
5716 | | - |
5717 | | - //Move margins to the wrapper |
5718 | | - this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); |
5719 | | - this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); |
5720 | | - |
5721 | | - //Prevent Safari textarea resize |
5722 | | - this.originalResizeStyle = this.originalElement.css('resize'); |
5723 | | - this.originalElement.css('resize', 'none'); |
5724 | | - |
5725 | | - //Push the actual element to our proportionallyResize internal array |
5726 | | - this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); |
5727 | | - |
5728 | | - // avoid IE jump (hard set the margin) |
5729 | | - this.originalElement.css({ margin: this.originalElement.css('margin') }); |
5730 | | - |
5731 | | - // fix handlers offset |
5732 | | - this._proportionallyResize(); |
5733 | | - |
5734 | | - } |
5735 | | - |
5736 | | - this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' }); |
5737 | | - if(this.handles.constructor == String) { |
5738 | | - |
5739 | | - if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; |
5740 | | - var n = this.handles.split(","); this.handles = {}; |
5741 | | - |
5742 | | - for(var i = 0; i < n.length; i++) { |
5743 | | - |
5744 | | - var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; |
5745 | | - var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); |
5746 | | - |
5747 | | - // increase zIndex of sw, se, ne, nw axis |
5748 | | - //TODO : this modifies original option |
5749 | | - if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex }); |
5750 | | - |
5751 | | - //TODO : What's going on here? |
5752 | | - if ('se' == handle) { |
5753 | | - axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); |
5754 | | - }; |
5755 | | - |
5756 | | - //Insert into internal handles object and append to element |
5757 | | - this.handles[handle] = '.ui-resizable-'+handle; |
5758 | | - this.element.append(axis); |
5759 | | - } |
5760 | | - |
5761 | | - } |
5762 | | - |
5763 | | - this._renderAxis = function(target) { |
5764 | | - |
5765 | | - target = target || this.element; |
5766 | | - |
5767 | | - for(var i in this.handles) { |
5768 | | - |
5769 | | - if(this.handles[i].constructor == String) |
5770 | | - this.handles[i] = $(this.handles[i], this.element).show(); |
5771 | | - |
5772 | | - //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) |
5773 | | - if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { |
5774 | | - |
5775 | | - var axis = $(this.handles[i], this.element), padWrapper = 0; |
5776 | | - |
5777 | | - //Checking the correct pad and border |
5778 | | - padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); |
5779 | | - |
5780 | | - //The padding type i have to apply... |
5781 | | - var padPos = [ 'padding', |
5782 | | - /ne|nw|n/.test(i) ? 'Top' : |
5783 | | - /se|sw|s/.test(i) ? 'Bottom' : |
5784 | | - /^e$/.test(i) ? 'Right' : 'Left' ].join(""); |
5785 | | - |
5786 | | - target.css(padPos, padWrapper); |
5787 | | - |
5788 | | - this._proportionallyResize(); |
5789 | | - |
5790 | | - } |
5791 | | - |
5792 | | - //TODO: What's that good for? There's not anything to be executed left |
5793 | | - if(!$(this.handles[i]).length) |
5794 | | - continue; |
5795 | | - |
5796 | | - } |
5797 | | - }; |
5798 | | - |
5799 | | - //TODO: make renderAxis a prototype function |
5800 | | - this._renderAxis(this.element); |
5801 | | - |
5802 | | - this._handles = $('.ui-resizable-handle', this.element) |
5803 | | - .disableSelection(); |
5804 | | - |
5805 | | - //Matching axis name |
5806 | | - this._handles.mouseover(function() { |
5807 | | - if (!self.resizing) { |
5808 | | - if (this.className) |
5809 | | - var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); |
5810 | | - //Axis, default = se |
5811 | | - self.axis = axis && axis[1] ? axis[1] : 'se'; |
5812 | | - } |
5813 | | - }); |
5814 | | - |
5815 | | - //If we want to auto hide the elements |
5816 | | - if (o.autoHide) { |
5817 | | - this._handles.hide(); |
5818 | | - $(this.element) |
5819 | | - .addClass("ui-resizable-autohide") |
5820 | | - .hover(function() { |
5821 | | - $(this).removeClass("ui-resizable-autohide"); |
5822 | | - self._handles.show(); |
5823 | | - }, |
5824 | | - function(){ |
5825 | | - if (!self.resizing) { |
5826 | | - $(this).addClass("ui-resizable-autohide"); |
5827 | | - self._handles.hide(); |
5828 | | - } |
5829 | | - }); |
5830 | | - } |
5831 | | - |
5832 | | - //Initialize the mouse interaction |
5833 | | - this._mouseInit(); |
5834 | | - |
5835 | | - }, |
5836 | | - |
5837 | | - destroy: function() { |
5838 | | - |
5839 | | - this._mouseDestroy(); |
5840 | | - |
5841 | | - var _destroy = function(exp) { |
5842 | | - $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") |
5843 | | - .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); |
5844 | | - }; |
5845 | | - |
5846 | | - //TODO: Unwrap at same DOM position |
5847 | | - if (this.elementIsWrapper) { |
5848 | | - _destroy(this.element); |
5849 | | - var wrapper = this.element; |
5850 | | - wrapper.parent().append( |
5851 | | - this.originalElement.css({ |
5852 | | - position: wrapper.css('position'), |
5853 | | - width: wrapper.outerWidth(), |
5854 | | - height: wrapper.outerHeight(), |
5855 | | - top: wrapper.css('top'), |
5856 | | - left: wrapper.css('left') |
5857 | | - }) |
5858 | | - ).end().remove(); |
5859 | | - } |
5860 | | - |
5861 | | - this.originalElement.css('resize', this.originalResizeStyle); |
5862 | | - _destroy(this.originalElement); |
5863 | | - |
5864 | | - }, |
5865 | | - |
5866 | | - _mouseCapture: function(event) { |
5867 | | - |
5868 | | - var handle = false; |
5869 | | - for(var i in this.handles) { |
5870 | | - if($(this.handles[i])[0] == event.target) handle = true; |
5871 | | - } |
5872 | | - |
5873 | | - return this.options.disabled || !!handle; |
5874 | | - |
5875 | | - }, |
5876 | | - |
5877 | | - _mouseStart: function(event) { |
5878 | | - |
5879 | | - var o = this.options, iniPos = this.element.position(), el = this.element; |
5880 | | - |
5881 | | - this.resizing = true; |
5882 | | - this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; |
5883 | | - |
5884 | | - // bugfix for http://dev.jquery.com/ticket/1749 |
5885 | | - if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { |
5886 | | - el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); |
5887 | | - } |
5888 | | - |
5889 | | - //Opera fixing relative position |
5890 | | - if ($.browser.opera && (/relative/).test(el.css('position'))) |
5891 | | - el.css({ position: 'relative', top: 'auto', left: 'auto' }); |
5892 | | - |
5893 | | - this._renderProxy(); |
5894 | | - |
5895 | | - var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); |
5896 | | - |
5897 | | - if (o.containment) { |
5898 | | - curleft += $(o.containment).scrollLeft() || 0; |
5899 | | - curtop += $(o.containment).scrollTop() || 0; |
5900 | | - } |
5901 | | - |
5902 | | - //Store needed variables |
5903 | | - this.offset = this.helper.offset(); |
5904 | | - this.position = { left: curleft, top: curtop }; |
5905 | | - this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; |
5906 | | - this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; |
5907 | | - this.originalPosition = { left: curleft, top: curtop }; |
5908 | | - this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; |
5909 | | - this.originalMousePosition = { left: event.pageX, top: event.pageY }; |
5910 | | - |
5911 | | - //Aspect Ratio |
5912 | | - this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); |
5913 | | - |
5914 | | - var cursor = $('.ui-resizable-' + this.axis).css('cursor'); |
5915 | | - $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); |
5916 | | - |
5917 | | - el.addClass("ui-resizable-resizing"); |
5918 | | - this._propagate("start", event); |
5919 | | - return true; |
5920 | | - }, |
5921 | | - |
5922 | | - _mouseDrag: function(event) { |
5923 | | - |
5924 | | - //Increase performance, avoid regex |
5925 | | - var el = this.helper, o = this.options, props = {}, |
5926 | | - self = this, smp = this.originalMousePosition, a = this.axis; |
5927 | | - |
5928 | | - var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; |
5929 | | - var trigger = this._change[a]; |
5930 | | - if (!trigger) return false; |
5931 | | - |
5932 | | - // Calculate the attrs that will be change |
5933 | | - var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; |
5934 | | - |
5935 | | - if (this._aspectRatio || event.shiftKey) |
5936 | | - data = this._updateRatio(data, event); |
5937 | | - |
5938 | | - data = this._respectSize(data, event); |
5939 | | - |
5940 | | - // plugins callbacks need to be called first |
5941 | | - this._propagate("resize", event); |
5942 | | - |
5943 | | - el.css({ |
5944 | | - top: this.position.top + "px", left: this.position.left + "px", |
5945 | | - width: this.size.width + "px", height: this.size.height + "px" |
5946 | | - }); |
5947 | | - |
5948 | | - if (!this._helper && this._proportionallyResizeElements.length) |
5949 | | - this._proportionallyResize(); |
5950 | | - |
5951 | | - this._updateCache(data); |
5952 | | - |
5953 | | - // calling the user callback at the end |
5954 | | - this._trigger('resize', event, this.ui()); |
5955 | | - |
5956 | | - return false; |
5957 | | - }, |
5958 | | - |
5959 | | - _mouseStop: function(event) { |
5960 | | - |
5961 | | - this.resizing = false; |
5962 | | - var o = this.options, self = this; |
5963 | | - |
5964 | | - if(this._helper) { |
5965 | | - var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), |
5966 | | - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, |
5967 | | - soffsetw = ista ? 0 : self.sizeDiff.width; |
5968 | | - |
5969 | | - var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, |
5970 | | - left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, |
5971 | | - top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; |
5972 | | - |
5973 | | - if (!o.animate) |
5974 | | - this.element.css($.extend(s, { top: top, left: left })); |
5975 | | - |
5976 | | - self.helper.height(self.size.height); |
5977 | | - self.helper.width(self.size.width); |
5978 | | - |
5979 | | - if (this._helper && !o.animate) this._proportionallyResize(); |
5980 | | - } |
5981 | | - |
5982 | | - $('body').css('cursor', 'auto'); |
5983 | | - |
5984 | | - this.element.removeClass("ui-resizable-resizing"); |
5985 | | - |
5986 | | - this._propagate("stop", event); |
5987 | | - |
5988 | | - if (this._helper) this.helper.remove(); |
5989 | | - return false; |
5990 | | - |
5991 | | - }, |
5992 | | - |
5993 | | - _updateCache: function(data) { |
5994 | | - var o = this.options; |
5995 | | - this.offset = this.helper.offset(); |
5996 | | - if (isNumber(data.left)) this.position.left = data.left; |
5997 | | - if (isNumber(data.top)) this.position.top = data.top; |
5998 | | - if (isNumber(data.height)) this.size.height = data.height; |
5999 | | - if (isNumber(data.width)) this.size.width = data.width; |
6000 | | - }, |
6001 | | - |
6002 | | - _updateRatio: function(data, event) { |
6003 | | - |
6004 | | - var o = this.options, cpos = this.position, csize = this.size, a = this.axis; |
6005 | | - |
6006 | | - if (data.height) data.width = (csize.height * this.aspectRatio); |
6007 | | - else if (data.width) data.height = (csize.width / this.aspectRatio); |
6008 | | - |
6009 | | - if (a == 'sw') { |
6010 | | - data.left = cpos.left + (csize.width - data.width); |
6011 | | - data.top = null; |
6012 | | - } |
6013 | | - if (a == 'nw') { |
6014 | | - data.top = cpos.top + (csize.height - data.height); |
6015 | | - data.left = cpos.left + (csize.width - data.width); |
6016 | | - } |
6017 | | - |
6018 | | - return data; |
6019 | | - }, |
6020 | | - |
6021 | | - _respectSize: function(data, event) { |
6022 | | - |
6023 | | - var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, |
6024 | | - ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), |
6025 | | - isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); |
6026 | | - |
6027 | | - if (isminw) data.width = o.minWidth; |
6028 | | - if (isminh) data.height = o.minHeight; |
6029 | | - if (ismaxw) data.width = o.maxWidth; |
6030 | | - if (ismaxh) data.height = o.maxHeight; |
6031 | | - |
6032 | | - var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; |
6033 | | - var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); |
6034 | | - |
6035 | | - if (isminw && cw) data.left = dw - o.minWidth; |
6036 | | - if (ismaxw && cw) data.left = dw - o.maxWidth; |
6037 | | - if (isminh && ch) data.top = dh - o.minHeight; |
6038 | | - if (ismaxh && ch) data.top = dh - o.maxHeight; |
6039 | | - |
6040 | | - // fixing jump error on top/left - bug #2330 |
6041 | | - var isNotwh = !data.width && !data.height; |
6042 | | - if (isNotwh && !data.left && data.top) data.top = null; |
6043 | | - else if (isNotwh && !data.top && data.left) data.left = null; |
6044 | | - |
6045 | | - return data; |
6046 | | - }, |
6047 | | - |
6048 | | - _proportionallyResize: function() { |
6049 | | - |
6050 | | - var o = this.options; |
6051 | | - if (!this._proportionallyResizeElements.length) return; |
6052 | | - var element = this.helper || this.element; |
6053 | | - |
6054 | | - for (var i=0; i < this._proportionallyResizeElements.length; i++) { |
6055 | | - |
6056 | | - var prel = this._proportionallyResizeElements[i]; |
6057 | | - |
6058 | | - if (!this.borderDif) { |
6059 | | - var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], |
6060 | | - p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; |
6061 | | - |
6062 | | - this.borderDif = $.map(b, function(v, i) { |
6063 | | - var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; |
6064 | | - return border + padding; |
6065 | | - }); |
6066 | | - } |
6067 | | - |
6068 | | - if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length))) |
6069 | | - continue; |
6070 | | - |
6071 | | - prel.css({ |
6072 | | - height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, |
6073 | | - width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 |
6074 | | - }); |
6075 | | - |
6076 | | - }; |
6077 | | - |
6078 | | - }, |
6079 | | - |
6080 | | - _renderProxy: function() { |
6081 | | - |
6082 | | - var el = this.element, o = this.options; |
6083 | | - this.elementOffset = el.offset(); |
6084 | | - |
6085 | | - if(this._helper) { |
6086 | | - |
6087 | | - this.helper = this.helper || $('<div style="overflow:hidden;"></div>'); |
6088 | | - |
6089 | | - // fix ie6 offset TODO: This seems broken |
6090 | | - var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0), |
6091 | | - pxyoffset = ( ie6 ? 2 : -1 ); |
6092 | | - |
6093 | | - this.helper.addClass(this._helper).css({ |
6094 | | - width: this.element.outerWidth() + pxyoffset, |
6095 | | - height: this.element.outerHeight() + pxyoffset, |
6096 | | - position: 'absolute', |
6097 | | - left: this.elementOffset.left - ie6offset +'px', |
6098 | | - top: this.elementOffset.top - ie6offset +'px', |
6099 | | - zIndex: ++o.zIndex //TODO: Don't modify option |
6100 | | - }); |
6101 | | - |
6102 | | - this.helper |
6103 | | - .appendTo("body") |
6104 | | - .disableSelection(); |
6105 | | - |
6106 | | - } else { |
6107 | | - this.helper = this.element; |
6108 | | - } |
6109 | | - |
6110 | | - }, |
6111 | | - |
6112 | | - _change: { |
6113 | | - e: function(event, dx, dy) { |
6114 | | - return { width: this.originalSize.width + dx }; |
6115 | | - }, |
6116 | | - w: function(event, dx, dy) { |
6117 | | - var o = this.options, cs = this.originalSize, sp = this.originalPosition; |
6118 | | - return { left: sp.left + dx, width: cs.width - dx }; |
6119 | | - }, |
6120 | | - n: function(event, dx, dy) { |
6121 | | - var o = this.options, cs = this.originalSize, sp = this.originalPosition; |
6122 | | - return { top: sp.top + dy, height: cs.height - dy }; |
6123 | | - }, |
6124 | | - s: function(event, dx, dy) { |
6125 | | - return { height: this.originalSize.height + dy }; |
6126 | | - }, |
6127 | | - se: function(event, dx, dy) { |
6128 | | - return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); |
6129 | | - }, |
6130 | | - sw: function(event, dx, dy) { |
6131 | | - return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); |
6132 | | - }, |
6133 | | - ne: function(event, dx, dy) { |
6134 | | - return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); |
6135 | | - }, |
6136 | | - nw: function(event, dx, dy) { |
6137 | | - return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); |
6138 | | - } |
6139 | | - }, |
6140 | | - |
6141 | | - _propagate: function(n, event) { |
6142 | | - $.ui.plugin.call(this, n, [event, this.ui()]); |
6143 | | - (n != "resize" && this._trigger(n, event, this.ui())); |
6144 | | - }, |
6145 | | - |
6146 | | - plugins: {}, |
6147 | | - |
6148 | | - ui: function() { |
6149 | | - return { |
6150 | | - originalElement: this.originalElement, |
6151 | | - element: this.element, |
6152 | | - helper: this.helper, |
6153 | | - position: this.position, |
6154 | | - size: this.size, |
6155 | | - originalSize: this.originalSize, |
6156 | | - originalPosition: this.originalPosition |
6157 | | - }; |
6158 | | - } |
6159 | | - |
6160 | | -})); |
6161 | | - |
6162 | | -$.extend($.ui.resizable, { |
6163 | | - version: "1.7.2", |
6164 | | - eventPrefix: "resize", |
6165 | | - defaults: { |
6166 | | - alsoResize: false, |
6167 | | - animate: false, |
6168 | | - animateDuration: "slow", |
6169 | | - animateEasing: "swing", |
6170 | | - aspectRatio: false, |
6171 | | - autoHide: false, |
6172 | | - cancel: ":input,option", |
6173 | | - containment: false, |
6174 | | - delay: 0, |
6175 | | - distance: 1, |
6176 | | - ghost: false, |
6177 | | - grid: false, |
6178 | | - handles: "e,s,se", |
6179 | | - helper: false, |
6180 | | - maxHeight: null, |
6181 | | - maxWidth: null, |
6182 | | - minHeight: 10, |
6183 | | - minWidth: 10, |
6184 | | - zIndex: 1000 |
6185 | | - } |
6186 | | -}); |
6187 | | - |
6188 | | -/* |
6189 | | - * Resizable Extensions |
6190 | | - */ |
6191 | | - |
6192 | | -$.ui.plugin.add("resizable", "alsoResize", { |
6193 | | - |
6194 | | - start: function(event, ui) { |
6195 | | - |
6196 | | - var self = $(this).data("resizable"), o = self.options; |
6197 | | - |
6198 | | - _store = function(exp) { |
6199 | | - $(exp).each(function() { |
6200 | | - $(this).data("resizable-alsoresize", { |
6201 | | - width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10), |
6202 | | - left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10) |
6203 | | - }); |
6204 | | - }); |
6205 | | - }; |
6206 | | - |
6207 | | - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { |
6208 | | - if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } |
6209 | | - else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); } |
6210 | | - }else{ |
6211 | | - _store(o.alsoResize); |
6212 | | - } |
6213 | | - }, |
6214 | | - |
6215 | | - resize: function(event, ui){ |
6216 | | - var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition; |
6217 | | - |
6218 | | - var delta = { |
6219 | | - height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0, |
6220 | | - top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 |
6221 | | - }, |
6222 | | - |
6223 | | - _alsoResize = function(exp, c) { |
6224 | | - $(exp).each(function() { |
6225 | | - var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left']; |
6226 | | - |
6227 | | - $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) { |
6228 | | - var sum = (start[prop]||0) + (delta[prop]||0); |
6229 | | - if (sum && sum >= 0) |
6230 | | - style[prop] = sum || null; |
6231 | | - }); |
6232 | | - |
6233 | | - //Opera fixing relative position |
6234 | | - if (/relative/.test(el.css('position')) && $.browser.opera) { |
6235 | | - self._revertToRelativePosition = true; |
6236 | | - el.css({ position: 'absolute', top: 'auto', left: 'auto' }); |
6237 | | - } |
6238 | | - |
6239 | | - el.css(style); |
6240 | | - }); |
6241 | | - }; |
6242 | | - |
6243 | | - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { |
6244 | | - $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); }); |
6245 | | - }else{ |
6246 | | - _alsoResize(o.alsoResize); |
6247 | | - } |
6248 | | - }, |
6249 | | - |
6250 | | - stop: function(event, ui){ |
6251 | | - var self = $(this).data("resizable"); |
6252 | | - |
6253 | | - //Opera fixing relative position |
6254 | | - if (self._revertToRelativePosition && $.browser.opera) { |
6255 | | - self._revertToRelativePosition = false; |
6256 | | - el.css({ position: 'relative' }); |
6257 | | - } |
6258 | | - |
6259 | | - $(this).removeData("resizable-alsoresize-start"); |
6260 | | - } |
6261 | | -}); |
6262 | | - |
6263 | | -$.ui.plugin.add("resizable", "animate", { |
6264 | | - |
6265 | | - stop: function(event, ui) { |
6266 | | - var self = $(this).data("resizable"), o = self.options; |
6267 | | - |
6268 | | - var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), |
6269 | | - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, |
6270 | | - soffsetw = ista ? 0 : self.sizeDiff.width; |
6271 | | - |
6272 | | - var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, |
6273 | | - left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, |
6274 | | - top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; |
6275 | | - |
6276 | | - self.element.animate( |
6277 | | - $.extend(style, top && left ? { top: top, left: left } : {}), { |
6278 | | - duration: o.animateDuration, |
6279 | | - easing: o.animateEasing, |
6280 | | - step: function() { |
6281 | | - |
6282 | | - var data = { |
6283 | | - width: parseInt(self.element.css('width'), 10), |
6284 | | - height: parseInt(self.element.css('height'), 10), |
6285 | | - top: parseInt(self.element.css('top'), 10), |
6286 | | - left: parseInt(self.element.css('left'), 10) |
6287 | | - }; |
6288 | | - |
6289 | | - if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); |
6290 | | - |
6291 | | - // propagating resize, and updating values for each animation step |
6292 | | - self._updateCache(data); |
6293 | | - self._propagate("resize", event); |
6294 | | - |
6295 | | - } |
6296 | | - } |
6297 | | - ); |
6298 | | - } |
6299 | | - |
6300 | | -}); |
6301 | | - |
6302 | | -$.ui.plugin.add("resizable", "containment", { |
6303 | | - |
6304 | | - start: function(event, ui) { |
6305 | | - var self = $(this).data("resizable"), o = self.options, el = self.element; |
6306 | | - var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; |
6307 | | - if (!ce) return; |
6308 | | - |
6309 | | - self.containerElement = $(ce); |
6310 | | - |
6311 | | - if (/document/.test(oc) || oc == document) { |
6312 | | - self.containerOffset = { left: 0, top: 0 }; |
6313 | | - self.containerPosition = { left: 0, top: 0 }; |
6314 | | - |
6315 | | - self.parentData = { |
6316 | | - element: $(document), left: 0, top: 0, |
6317 | | - width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight |
6318 | | - }; |
6319 | | - } |
6320 | | - |
6321 | | - // i'm a node, so compute top, left, right, bottom |
6322 | | - else { |
6323 | | - var element = $(ce), p = []; |
6324 | | - $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); |
6325 | | - |
6326 | | - self.containerOffset = element.offset(); |
6327 | | - self.containerPosition = element.position(); |
6328 | | - self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; |
6329 | | - |
6330 | | - var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width, |
6331 | | - width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); |
6332 | | - |
6333 | | - self.parentData = { |
6334 | | - element: ce, left: co.left, top: co.top, width: width, height: height |
6335 | | - }; |
6336 | | - } |
6337 | | - }, |
6338 | | - |
6339 | | - resize: function(event, ui) { |
6340 | | - var self = $(this).data("resizable"), o = self.options, |
6341 | | - ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position, |
6342 | | - pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement; |
6343 | | - |
6344 | | - if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; |
6345 | | - |
6346 | | - if (cp.left < (self._helper ? co.left : 0)) { |
6347 | | - self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left)); |
6348 | | - if (pRatio) self.size.height = self.size.width / o.aspectRatio; |
6349 | | - self.position.left = o.helper ? co.left : 0; |
6350 | | - } |
6351 | | - |
6352 | | - if (cp.top < (self._helper ? co.top : 0)) { |
6353 | | - self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top); |
6354 | | - if (pRatio) self.size.width = self.size.height * o.aspectRatio; |
6355 | | - self.position.top = self._helper ? co.top : 0; |
6356 | | - } |
6357 | | - |
6358 | | - self.offset.left = self.parentData.left+self.position.left; |
6359 | | - self.offset.top = self.parentData.top+self.position.top; |
6360 | | - |
6361 | | - var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ), |
6362 | | - hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height ); |
6363 | | - |
6364 | | - var isParent = self.containerElement.get(0) == self.element.parent().get(0), |
6365 | | - isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position')); |
6366 | | - |
6367 | | - if(isParent && isOffsetRelative) woset -= self.parentData.left; |
6368 | | - |
6369 | | - if (woset + self.size.width >= self.parentData.width) { |
6370 | | - self.size.width = self.parentData.width - woset; |
6371 | | - if (pRatio) self.size.height = self.size.width / self.aspectRatio; |
6372 | | - } |
6373 | | - |
6374 | | - if (hoset + self.size.height >= self.parentData.height) { |
6375 | | - self.size.height = self.parentData.height - hoset; |
6376 | | - if (pRatio) self.size.width = self.size.height * self.aspectRatio; |
6377 | | - } |
6378 | | - }, |
6379 | | - |
6380 | | - stop: function(event, ui){ |
6381 | | - var self = $(this).data("resizable"), o = self.options, cp = self.position, |
6382 | | - co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement; |
6383 | | - |
6384 | | - var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height; |
6385 | | - |
6386 | | - if (self._helper && !o.animate && (/relative/).test(ce.css('position'))) |
6387 | | - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); |
6388 | | - |
6389 | | - if (self._helper && !o.animate && (/static/).test(ce.css('position'))) |
6390 | | - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); |
6391 | | - |
6392 | | - } |
6393 | | -}); |
6394 | | - |
6395 | | -$.ui.plugin.add("resizable", "ghost", { |
6396 | | - |
6397 | | - start: function(event, ui) { |
6398 | | - |
6399 | | - var self = $(this).data("resizable"), o = self.options, cs = self.size; |
6400 | | - |
6401 | | - self.ghost = self.originalElement.clone(); |
6402 | | - self.ghost |
6403 | | - .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) |
6404 | | - .addClass('ui-resizable-ghost') |
6405 | | - .addClass(typeof o.ghost == 'string' ? o.ghost : ''); |
6406 | | - |
6407 | | - self.ghost.appendTo(self.helper); |
6408 | | - |
6409 | | - }, |
6410 | | - |
6411 | | - resize: function(event, ui){ |
6412 | | - var self = $(this).data("resizable"), o = self.options; |
6413 | | - if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width }); |
6414 | | - }, |
6415 | | - |
6416 | | - stop: function(event, ui){ |
6417 | | - var self = $(this).data("resizable"), o = self.options; |
6418 | | - if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0)); |
6419 | | - } |
6420 | | - |
6421 | | -}); |
6422 | | - |
6423 | | -$.ui.plugin.add("resizable", "grid", { |
6424 | | - |
6425 | | - resize: function(event, ui) { |
6426 | | - var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey; |
6427 | | - o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; |
6428 | | - var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); |
6429 | | - |
6430 | | - if (/^(se|s|e)$/.test(a)) { |
6431 | | - self.size.width = os.width + ox; |
6432 | | - self.size.height = os.height + oy; |
6433 | | - } |
6434 | | - else if (/^(ne)$/.test(a)) { |
6435 | | - self.size.width = os.width + ox; |
6436 | | - self.size.height = os.height + oy; |
6437 | | - self.position.top = op.top - oy; |
6438 | | - } |
6439 | | - else if (/^(sw)$/.test(a)) { |
6440 | | - self.size.width = os.width + ox; |
6441 | | - self.size.height = os.height + oy; |
6442 | | - self.position.left = op.left - ox; |
6443 | | - } |
6444 | | - else { |
6445 | | - self.size.width = os.width + ox; |
6446 | | - self.size.height = os.height + oy; |
6447 | | - self.position.top = op.top - oy; |
6448 | | - self.position.left = op.left - ox; |
6449 | | - } |
6450 | | - } |
6451 | | - |
6452 | | -}); |
6453 | | - |
6454 | | -var num = function(v) { |
6455 | | - return parseInt(v, 10) || 0; |
6456 | | -}; |
6457 | | - |
6458 | | -var isNumber = function(value) { |
6459 | | - return !isNaN(parseInt(value, 10)); |
6460 | | -}; |
6461 | | - |
6462 | | -})(jQuery); |
6463 | | -/* |
6464 | | - * jQuery UI Dialog 1.7.2 |
6465 | | - * |
6466 | | - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
6467 | | - * Dual licensed under the MIT (MIT-LICENSE.txt) |
6468 | | - * and GPL (GPL-LICENSE.txt) licenses. |
6469 | | - * |
6470 | | - * http://docs.jquery.com/UI/Dialog |
6471 | | - * |
6472 | | - * Depends: |
6473 | | - * ui.core.js |
6474 | | - * ui.draggable.js |
6475 | | - * ui.resizable.js |
6476 | | - */ |
6477 | | -(function($) { |
6478 | | - |
6479 | | -var setDataSwitch = { |
6480 | | - dragStart: "start.draggable", |
6481 | | - drag: "drag.draggable", |
6482 | | - dragStop: "stop.draggable", |
6483 | | - maxHeight: "maxHeight.resizable", |
6484 | | - minHeight: "minHeight.resizable", |
6485 | | - maxWidth: "maxWidth.resizable", |
6486 | | - minWidth: "minWidth.resizable", |
6487 | | - resizeStart: "start.resizable", |
6488 | | - resize: "drag.resizable", |
6489 | | - resizeStop: "stop.resizable" |
6490 | | - }, |
6491 | | - |
6492 | | - uiDialogClasses = |
6493 | | - 'ui-dialog ' + |
6494 | | - 'ui-widget ' + |
6495 | | - 'ui-widget-content ' + |
6496 | | - 'ui-corner-all '; |
6497 | | - |
6498 | | -$.widget("ui.dialog", { |
6499 | | - |
6500 | | - _init: function() { |
6501 | | - this.originalTitle = this.element.attr('title'); |
6502 | | - |
6503 | | - var self = this, |
6504 | | - options = this.options, |
6505 | | - |
6506 | | - title = options.title || this.originalTitle || ' ', |
6507 | | - titleId = $.ui.dialog.getTitleId(this.element), |
6508 | | - |
6509 | | - uiDialog = (this.uiDialog = $('<div/>')) |
6510 | | - .appendTo(document.body) |
6511 | | - .hide() |
6512 | | - .addClass(uiDialogClasses + options.dialogClass) |
6513 | | - .css({ |
6514 | | - position: 'absolute', |
6515 | | - overflow: 'hidden', |
6516 | | - zIndex: options.zIndex |
6517 | | - }) |
6518 | | - // setting tabIndex makes the div focusable |
6519 | | - // setting outline to 0 prevents a border on focus in Mozilla |
6520 | | - .attr('tabIndex', -1).css('outline', 0).keydown(function(event) { |
6521 | | - (options.closeOnEscape && event.keyCode |
6522 | | - && event.keyCode == $.ui.keyCode.ESCAPE && self.close(event)); |
6523 | | - }) |
6524 | | - .attr({ |
6525 | | - role: 'dialog', |
6526 | | - 'aria-labelledby': titleId |
6527 | | - }) |
6528 | | - .mousedown(function(event) { |
6529 | | - self.moveToTop(false, event); |
6530 | | - }), |
6531 | | - |
6532 | | - uiDialogContent = this.element |
6533 | | - .show() |
6534 | | - .removeAttr('title') |
6535 | | - .addClass( |
6536 | | - 'ui-dialog-content ' + |
6537 | | - 'ui-widget-content') |
6538 | | - .appendTo(uiDialog), |
6539 | | - |
6540 | | - uiDialogTitlebar = (this.uiDialogTitlebar = $('<div></div>')) |
6541 | | - .addClass( |
6542 | | - 'ui-dialog-titlebar ' + |
6543 | | - 'ui-widget-header ' + |
6544 | | - 'ui-corner-all ' + |
6545 | | - 'ui-helper-clearfix' |
6546 | | - ) |
6547 | | - .prependTo(uiDialog), |
6548 | | - |
6549 | | - uiDialogTitlebarClose = $('<a href="#"/>') |
6550 | | - .addClass( |
6551 | | - 'ui-dialog-titlebar-close ' + |
6552 | | - 'ui-corner-all' |
6553 | | - ) |
6554 | | - .attr('role', 'button') |
6555 | | - .hover( |
6556 | | - function() { |
6557 | | - uiDialogTitlebarClose.addClass('ui-state-hover'); |
6558 | | - }, |
6559 | | - function() { |
6560 | | - uiDialogTitlebarClose.removeClass('ui-state-hover'); |
6561 | | - } |
6562 | | - ) |
6563 | | - .focus(function() { |
6564 | | - uiDialogTitlebarClose.addClass('ui-state-focus'); |
6565 | | - }) |
6566 | | - .blur(function() { |
6567 | | - uiDialogTitlebarClose.removeClass('ui-state-focus'); |
6568 | | - }) |
6569 | | - .mousedown(function(ev) { |
6570 | | - ev.stopPropagation(); |
6571 | | - }) |
6572 | | - .click(function(event) { |
6573 | | - self.close(event); |
6574 | | - return false; |
6575 | | - }) |
6576 | | - .appendTo(uiDialogTitlebar), |
6577 | | - |
6578 | | - uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>')) |
6579 | | - .addClass( |
6580 | | - 'ui-icon ' + |
6581 | | - 'ui-icon-closethick' |
6582 | | - ) |
6583 | | - .text(options.closeText) |
6584 | | - .appendTo(uiDialogTitlebarClose), |
6585 | | - |
6586 | | - uiDialogTitle = $('<span/>') |
6587 | | - .addClass('ui-dialog-title') |
6588 | | - .attr('id', titleId) |
6589 | | - .html(title) |
6590 | | - .prependTo(uiDialogTitlebar); |
6591 | | - |
6592 | | - uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); |
6593 | | - |
6594 | | - (options.draggable && $.fn.draggable && this._makeDraggable()); |
6595 | | - (options.resizable && $.fn.resizable && this._makeResizable()); |
6596 | | - |
6597 | | - this._createButtons(options.buttons); |
6598 | | - this._isOpen = false; |
6599 | | - |
6600 | | - (options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe()); |
6601 | | - (options.autoOpen && this.open()); |
6602 | | - |
6603 | | - }, |
6604 | | - |
6605 | | - destroy: function() { |
6606 | | - (this.overlay && this.overlay.destroy()); |
6607 | | - this.uiDialog.hide(); |
6608 | | - this.element |
6609 | | - .unbind('.dialog') |
6610 | | - .removeData('dialog') |
6611 | | - .removeClass('ui-dialog-content ui-widget-content') |
6612 | | - .hide().appendTo('body'); |
6613 | | - this.uiDialog.remove(); |
6614 | | - |
6615 | | - (this.originalTitle && this.element.attr('title', this.originalTitle)); |
6616 | | - }, |
6617 | | - |
6618 | | - close: function(event) { |
6619 | | - var self = this; |
6620 | | - |
6621 | | - if (false === self._trigger('beforeclose', event)) { |
6622 | | - return; |
6623 | | - } |
6624 | | - |
6625 | | - (self.overlay && self.overlay.destroy()); |
6626 | | - self.uiDialog.unbind('keypress.ui-dialog'); |
6627 | | - |
6628 | | - (self.options.hide |
6629 | | - ? self.uiDialog.hide(self.options.hide, function() { |
6630 | | - self._trigger('close', event); |
6631 | | - }) |
6632 | | - : self.uiDialog.hide() && self._trigger('close', event)); |
6633 | | - |
6634 | | - $.ui.dialog.overlay.resize(); |
6635 | | - |
6636 | | - self._isOpen = false; |
6637 | | - |
6638 | | - // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) |
6639 | | - if (self.options.modal) { |
6640 | | - var maxZ = 0; |
6641 | | - $('.ui-dialog').each(function() { |
6642 | | - if (this != self.uiDialog[0]) { |
6643 | | - maxZ = Math.max(maxZ, $(this).css('z-index')); |
6644 | | - } |
6645 | | - }); |
6646 | | - $.ui.dialog.maxZ = maxZ; |
6647 | | - } |
6648 | | - }, |
6649 | | - |
6650 | | - isOpen: function() { |
6651 | | - return this._isOpen; |
6652 | | - }, |
6653 | | - |
6654 | | - // the force parameter allows us to move modal dialogs to their correct |
6655 | | - // position on open |
6656 | | - moveToTop: function(force, event) { |
6657 | | - |
6658 | | - if ((this.options.modal && !force) |
6659 | | - || (!this.options.stack && !this.options.modal)) { |
6660 | | - return this._trigger('focus', event); |
6661 | | - } |
6662 | | - |
6663 | | - if (this.options.zIndex > $.ui.dialog.maxZ) { |
6664 | | - $.ui.dialog.maxZ = this.options.zIndex; |
6665 | | - } |
6666 | | - (this.overlay && this.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = ++$.ui.dialog.maxZ)); |
6667 | | - |
6668 | | - //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed. |
6669 | | - // http://ui.jquery.com/bugs/ticket/3193 |
6670 | | - var saveScroll = { scrollTop: this.element.attr('scrollTop'), scrollLeft: this.element.attr('scrollLeft') }; |
6671 | | - this.uiDialog.css('z-index', ++$.ui.dialog.maxZ); |
6672 | | - this.element.attr(saveScroll); |
6673 | | - this._trigger('focus', event); |
6674 | | - }, |
6675 | | - |
6676 | | - open: function() { |
6677 | | - if (this._isOpen) { return; } |
6678 | | - |
6679 | | - var options = this.options, |
6680 | | - uiDialog = this.uiDialog; |
6681 | | - |
6682 | | - this.overlay = options.modal ? new $.ui.dialog.overlay(this) : null; |
6683 | | - (uiDialog.next().length && uiDialog.appendTo('body')); |
6684 | | - this._size(); |
6685 | | - this._position(options.position); |
6686 | | - uiDialog.show(options.show); |
6687 | | - this.moveToTop(true); |
6688 | | - |
6689 | | - // prevent tabbing out of modal dialogs |
6690 | | - (options.modal && uiDialog.bind('keypress.ui-dialog', function(event) { |
6691 | | - if (event.keyCode != $.ui.keyCode.TAB) { |
6692 | | - return; |
6693 | | - } |
6694 | | - |
6695 | | - var tabbables = $(':tabbable', this), |
6696 | | - first = tabbables.filter(':first')[0], |
6697 | | - last = tabbables.filter(':last')[0]; |
6698 | | - |
6699 | | - if (event.target == last && !event.shiftKey) { |
6700 | | - setTimeout(function() { |
6701 | | - first.focus(); |
6702 | | - }, 1); |
6703 | | - } else if (event.target == first && event.shiftKey) { |
6704 | | - setTimeout(function() { |
6705 | | - last.focus(); |
6706 | | - }, 1); |
6707 | | - } |
6708 | | - })); |
6709 | | - |
6710 | | - // set focus to the first tabbable element in the content area or the first button |
6711 | | - // if there are no tabbable elements, set focus on the dialog itself |
6712 | | - $([]) |
6713 | | - .add(uiDialog.find('.ui-dialog-content :tabbable:first')) |
6714 | | - .add(uiDialog.find('.ui-dialog-buttonpane :tabbable:first')) |
6715 | | - .add(uiDialog) |
6716 | | - .filter(':first') |
6717 | | - .focus(); |
6718 | | - |
6719 | | - this._trigger('open'); |
6720 | | - this._isOpen = true; |
6721 | | - }, |
6722 | | - |
6723 | | - _createButtons: function(buttons) { |
6724 | | - var self = this, |
6725 | | - hasButtons = false, |
6726 | | - uiDialogButtonPane = $('<div></div>') |
6727 | | - .addClass( |
6728 | | - 'ui-dialog-buttonpane ' + |
6729 | | - 'ui-widget-content ' + |
6730 | | - 'ui-helper-clearfix' |
6731 | | - ); |
6732 | | - |
6733 | | - // if we already have a button pane, remove it |
6734 | | - this.uiDialog.find('.ui-dialog-buttonpane').remove(); |
6735 | | - |
6736 | | - (typeof buttons == 'object' && buttons !== null && |
6737 | | - $.each(buttons, function() { return !(hasButtons = true); })); |
6738 | | - if (hasButtons) { |
6739 | | - $.each(buttons, function(name, fn) { |
6740 | | - $('<button type="button"></button>') |
6741 | | - .addClass( |
6742 | | - 'ui-state-default ' + |
6743 | | - 'ui-corner-all' |
6744 | | - ) |
6745 | | - .text(name) |
6746 | | - .click(function() { fn.apply(self.element[0], arguments); }) |
6747 | | - .hover( |
6748 | | - function() { |
6749 | | - $(this).addClass('ui-state-hover'); |
6750 | | - }, |
6751 | | - function() { |
6752 | | - $(this).removeClass('ui-state-hover'); |
6753 | | - } |
6754 | | - ) |
6755 | | - .focus(function() { |
6756 | | - $(this).addClass('ui-state-focus'); |
6757 | | - }) |
6758 | | - .blur(function() { |
6759 | | - $(this).removeClass('ui-state-focus'); |
6760 | | - }) |
6761 | | - .appendTo(uiDialogButtonPane); |
6762 | | - }); |
6763 | | - uiDialogButtonPane.appendTo(this.uiDialog); |
6764 | | - } |
6765 | | - }, |
6766 | | - |
6767 | | - _makeDraggable: function() { |
6768 | | - var self = this, |
6769 | | - options = this.options, |
6770 | | - heightBeforeDrag; |
6771 | | - |
6772 | | - this.uiDialog.draggable({ |
6773 | | - cancel: '.ui-dialog-content', |
6774 | | - handle: '.ui-dialog-titlebar', |
6775 | | - containment: 'document', |
6776 | | - start: function() { |
6777 | | - heightBeforeDrag = options.height; |
6778 | | - $(this).height($(this).height()).addClass("ui-dialog-dragging"); |
6779 | | - (options.dragStart && options.dragStart.apply(self.element[0], arguments)); |
6780 | | - }, |
6781 | | - drag: function() { |
6782 | | - (options.drag && options.drag.apply(self.element[0], arguments)); |
6783 | | - }, |
6784 | | - stop: function() { |
6785 | | - $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag); |
6786 | | - (options.dragStop && options.dragStop.apply(self.element[0], arguments)); |
6787 | | - $.ui.dialog.overlay.resize(); |
6788 | | - } |
6789 | | - }); |
6790 | | - }, |
6791 | | - |
6792 | | - _makeResizable: function(handles) { |
6793 | | - handles = (handles === undefined ? this.options.resizable : handles); |
6794 | | - var self = this, |
6795 | | - options = this.options, |
6796 | | - resizeHandles = typeof handles == 'string' |
6797 | | - ? handles |
6798 | | - : 'n,e,s,w,se,sw,ne,nw'; |
6799 | | - |
6800 | | - this.uiDialog.resizable({ |
6801 | | - cancel: '.ui-dialog-content', |
6802 | | - alsoResize: this.element, |
6803 | | - maxWidth: options.maxWidth, |
6804 | | - maxHeight: options.maxHeight, |
6805 | | - minWidth: options.minWidth, |
6806 | | - minHeight: options.minHeight, |
6807 | | - start: function() { |
6808 | | - $(this).addClass("ui-dialog-resizing"); |
6809 | | - (options.resizeStart && options.resizeStart.apply(self.element[0], arguments)); |
6810 | | - }, |
6811 | | - resize: function() { |
6812 | | - (options.resize && options.resize.apply(self.element[0], arguments)); |
6813 | | - }, |
6814 | | - handles: resizeHandles, |
6815 | | - stop: function() { |
6816 | | - $(this).removeClass("ui-dialog-resizing"); |
6817 | | - options.height = $(this).height(); |
6818 | | - options.width = $(this).width(); |
6819 | | - (options.resizeStop && options.resizeStop.apply(self.element[0], arguments)); |
6820 | | - $.ui.dialog.overlay.resize(); |
6821 | | - } |
6822 | | - }) |
6823 | | - .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se'); |
6824 | | - }, |
6825 | | - |
6826 | | - _position: function(pos) { |
6827 | | - var wnd = $(window), doc = $(document), |
6828 | | - pTop = doc.scrollTop(), pLeft = doc.scrollLeft(), |
6829 | | - minTop = pTop; |
6830 | | - |
6831 | | - if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) { |
6832 | | - pos = [ |
6833 | | - pos == 'right' || pos == 'left' ? pos : 'center', |
6834 | | - pos == 'top' || pos == 'bottom' ? pos : 'middle' |
6835 | | - ]; |
6836 | | - } |
6837 | | - if (pos.constructor != Array) { |
6838 | | - pos = ['center', 'middle']; |
6839 | | - } |
6840 | | - if (pos[0].constructor == Number) { |
6841 | | - pLeft += pos[0]; |
6842 | | - } else { |
6843 | | - switch (pos[0]) { |
6844 | | - case 'left': |
6845 | | - pLeft += 0; |
6846 | | - break; |
6847 | | - case 'right': |
6848 | | - pLeft += wnd.width() - this.uiDialog.outerWidth(); |
6849 | | - break; |
6850 | | - default: |
6851 | | - case 'center': |
6852 | | - pLeft += (wnd.width() - this.uiDialog.outerWidth()) / 2; |
6853 | | - } |
6854 | | - } |
6855 | | - if (pos[1].constructor == Number) { |
6856 | | - pTop += pos[1]; |
6857 | | - } else { |
6858 | | - switch (pos[1]) { |
6859 | | - case 'top': |
6860 | | - pTop += 0; |
6861 | | - break; |
6862 | | - case 'bottom': |
6863 | | - pTop += wnd.height() - this.uiDialog.outerHeight(); |
6864 | | - break; |
6865 | | - default: |
6866 | | - case 'middle': |
6867 | | - pTop += (wnd.height() - this.uiDialog.outerHeight()) / 2; |
6868 | | - } |
6869 | | - } |
6870 | | - |
6871 | | - // prevent the dialog from being too high (make sure the titlebar |
6872 | | - // is accessible) |
6873 | | - pTop = Math.max(pTop, minTop); |
6874 | | - this.uiDialog.css({top: pTop, left: pLeft}); |
6875 | | - }, |
6876 | | - |
6877 | | - _setData: function(key, value){ |
6878 | | - (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value)); |
6879 | | - switch (key) { |
6880 | | - case "buttons": |
6881 | | - this._createButtons(value); |
6882 | | - break; |
6883 | | - case "closeText": |
6884 | | - this.uiDialogTitlebarCloseText.text(value); |
6885 | | - break; |
6886 | | - case "dialogClass": |
6887 | | - this.uiDialog |
6888 | | - .removeClass(this.options.dialogClass) |
6889 | | - .addClass(uiDialogClasses + value); |
6890 | | - break; |
6891 | | - case "draggable": |
6892 | | - (value |
6893 | | - ? this._makeDraggable() |
6894 | | - : this.uiDialog.draggable('destroy')); |
6895 | | - break; |
6896 | | - case "height": |
6897 | | - this.uiDialog.height(value); |
6898 | | - break; |
6899 | | - case "position": |
6900 | | - this._position(value); |
6901 | | - break; |
6902 | | - case "resizable": |
6903 | | - var uiDialog = this.uiDialog, |
6904 | | - isResizable = this.uiDialog.is(':data(resizable)'); |
6905 | | - |
6906 | | - // currently resizable, becoming non-resizable |
6907 | | - (isResizable && !value && uiDialog.resizable('destroy')); |
6908 | | - |
6909 | | - // currently resizable, changing handles |
6910 | | - (isResizable && typeof value == 'string' && |
6911 | | - uiDialog.resizable('option', 'handles', value)); |
6912 | | - |
6913 | | - // currently non-resizable, becoming resizable |
6914 | | - (isResizable || this._makeResizable(value)); |
6915 | | - break; |
6916 | | - case "title": |
6917 | | - $(".ui-dialog-title", this.uiDialogTitlebar).html(value || ' '); |
6918 | | - break; |
6919 | | - case "width": |
6920 | | - this.uiDialog.width(value); |
6921 | | - break; |
6922 | | - } |
6923 | | - |
6924 | | - $.widget.prototype._setData.apply(this, arguments); |
6925 | | - }, |
6926 | | - |
6927 | | - _size: function() { |
6928 | | - /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content |
6929 | | - * divs will both have width and height set, so we need to reset them |
6930 | | - */ |
6931 | | - var options = this.options; |
6932 | | - |
6933 | | - // reset content sizing |
6934 | | - this.element.css({ |
6935 | | - height: 0, |
6936 | | - minHeight: 0, |
6937 | | - width: 'auto' |
6938 | | - }); |
6939 | | - |
6940 | | - // reset wrapper sizing |
6941 | | - // determine the height of all the non-content elements |
6942 | | - var nonContentHeight = this.uiDialog.css({ |
6943 | | - height: 'auto', |
6944 | | - width: options.width |
6945 | | - }) |
6946 | | - .height(); |
6947 | | - |
6948 | | - this.element |
6949 | | - .css({ |
6950 | | - minHeight: Math.max(options.minHeight - nonContentHeight, 0), |
6951 | | - height: options.height == 'auto' |
6952 | | - ? 'auto' |
6953 | | - : Math.max(options.height - nonContentHeight, 0) |
6954 | | - }); |
6955 | | - } |
6956 | | -}); |
6957 | | - |
6958 | | -$.extend($.ui.dialog, { |
6959 | | - version: "1.7.2", |
6960 | | - defaults: { |
6961 | | - autoOpen: true, |
6962 | | - bgiframe: false, |
6963 | | - buttons: {}, |
6964 | | - closeOnEscape: true, |
6965 | | - closeText: 'close', |
6966 | | - dialogClass: '', |
6967 | | - draggable: true, |
6968 | | - hide: null, |
6969 | | - height: 'auto', |
6970 | | - maxHeight: false, |
6971 | | - maxWidth: false, |
6972 | | - minHeight: 150, |
6973 | | - minWidth: 150, |
6974 | | - modal: false, |
6975 | | - position: 'center', |
6976 | | - resizable: true, |
6977 | | - show: null, |
6978 | | - stack: true, |
6979 | | - title: '', |
6980 | | - width: 300, |
6981 | | - zIndex: 1000 |
6982 | | - }, |
6983 | | - |
6984 | | - getter: 'isOpen', |
6985 | | - |
6986 | | - uuid: 0, |
6987 | | - maxZ: 0, |
6988 | | - |
6989 | | - getTitleId: function($el) { |
6990 | | - return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid); |
6991 | | - }, |
6992 | | - |
6993 | | - overlay: function(dialog) { |
6994 | | - this.$el = $.ui.dialog.overlay.create(dialog); |
6995 | | - } |
6996 | | -}); |
6997 | | - |
6998 | | -$.extend($.ui.dialog.overlay, { |
6999 | | - instances: [], |
7000 | | - maxZ: 0, |
7001 | | - events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','), |
7002 | | - function(event) { return event + '.dialog-overlay'; }).join(' '), |
7003 | | - create: function(dialog) { |
7004 | | - if (this.instances.length === 0) { |
7005 | | - // prevent use of anchors and inputs |
7006 | | - // we use a setTimeout in case the overlay is created from an |
7007 | | - // event that we're going to be cancelling (see #2804) |
7008 | | - setTimeout(function() { |
7009 | | - // handle $(el).dialog().dialog('close') (see #4065) |
7010 | | - if ($.ui.dialog.overlay.instances.length) { |
7011 | | - $(document).bind($.ui.dialog.overlay.events, function(event) { |
7012 | | - var dialogZ = $(event.target).parents('.ui-dialog').css('zIndex') || 0; |
7013 | | - return (dialogZ > $.ui.dialog.overlay.maxZ); |
7014 | | - }); |
7015 | | - } |
7016 | | - }, 1); |
7017 | | - |
7018 | | - // allow closing by pressing the escape key |
7019 | | - $(document).bind('keydown.dialog-overlay', function(event) { |
7020 | | - (dialog.options.closeOnEscape && event.keyCode |
7021 | | - && event.keyCode == $.ui.keyCode.ESCAPE && dialog.close(event)); |
7022 | | - }); |
7023 | | - |
7024 | | - // handle window resize |
7025 | | - $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize); |
7026 | | - } |
7027 | | - |
7028 | | - var $el = $('<div></div>').appendTo(document.body) |
7029 | | - .addClass('ui-widget-overlay').css({ |
7030 | | - width: this.width(), |
7031 | | - height: this.height() |
7032 | | - }); |
7033 | | - |
7034 | | - (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe()); |
7035 | | - |
7036 | | - this.instances.push($el); |
7037 | | - return $el; |
7038 | | - }, |
7039 | | - |
7040 | | - destroy: function($el) { |
7041 | | - this.instances.splice($.inArray(this.instances, $el), 1); |
7042 | | - |
7043 | | - if (this.instances.length === 0) { |
7044 | | - $([document, window]).unbind('.dialog-overlay'); |
7045 | | - } |
7046 | | - |
7047 | | - $el.remove(); |
7048 | | - |
7049 | | - // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) |
7050 | | - var maxZ = 0; |
7051 | | - $.each(this.instances, function() { |
7052 | | - maxZ = Math.max(maxZ, this.css('z-index')); |
7053 | | - }); |
7054 | | - this.maxZ = maxZ; |
7055 | | - }, |
7056 | | - |
7057 | | - height: function() { |
7058 | | - // handle IE 6 |
7059 | | - if ($.browser.msie && $.browser.version < 7) { |
7060 | | - var scrollHeight = Math.max( |
7061 | | - document.documentElement.scrollHeight, |
7062 | | - document.body.scrollHeight |
7063 | | - ); |
7064 | | - var offsetHeight = Math.max( |
7065 | | - document.documentElement.offsetHeight, |
7066 | | - document.body.offsetHeight |
7067 | | - ); |
7068 | | - |
7069 | | - if (scrollHeight < offsetHeight) { |
7070 | | - return $(window).height() + 'px'; |
7071 | | - } else { |
7072 | | - return scrollHeight + 'px'; |
7073 | | - } |
7074 | | - // handle "good" browsers |
7075 | | - } else { |
7076 | | - return $(document).height() + 'px'; |
7077 | | - } |
7078 | | - }, |
7079 | | - |
7080 | | - width: function() { |
7081 | | - // handle IE 6 |
7082 | | - if ($.browser.msie && $.browser.version < 7) { |
7083 | | - var scrollWidth = Math.max( |
7084 | | - document.documentElement.scrollWidth, |
7085 | | - document.body.scrollWidth |
7086 | | - ); |
7087 | | - var offsetWidth = Math.max( |
7088 | | - document.documentElement.offsetWidth, |
7089 | | - document.body.offsetWidth |
7090 | | - ); |
7091 | | - |
7092 | | - if (scrollWidth < offsetWidth) { |
7093 | | - return $(window).width() + 'px'; |
7094 | | - } else { |
7095 | | - return scrollWidth + 'px'; |
7096 | | - } |
7097 | | - // handle "good" browsers |
7098 | | - } else { |
7099 | | - return $(document).width() + 'px'; |
7100 | | - } |
7101 | | - }, |
7102 | | - |
7103 | | - resize: function() { |
7104 | | - /* If the dialog is draggable and the user drags it past the |
7105 | | - * right edge of the window, the document becomes wider so we |
7106 | | - * need to stretch the overlay. If the user then drags the |
7107 | | - * dialog back to the left, the document will become narrower, |
7108 | | - * so we need to shrink the overlay to the appropriate size. |
7109 | | - * This is handled by shrinking the overlay before setting it |
7110 | | - * to the full document size. |
7111 | | - */ |
7112 | | - var $overlays = $([]); |
7113 | | - $.each($.ui.dialog.overlay.instances, function() { |
7114 | | - $overlays = $overlays.add(this); |
7115 | | - }); |
7116 | | - |
7117 | | - $overlays.css({ |
7118 | | - width: 0, |
7119 | | - height: 0 |
7120 | | - }).css({ |
7121 | | - width: $.ui.dialog.overlay.width(), |
7122 | | - height: $.ui.dialog.overlay.height() |
7123 | | - }); |
7124 | | - } |
7125 | | -}); |
7126 | | - |
7127 | | -$.extend($.ui.dialog.overlay.prototype, { |
7128 | | - destroy: function() { |
7129 | | - $.ui.dialog.overlay.destroy(this.$el); |
7130 | | - } |
7131 | | -}); |
7132 | | - |
7133 | | -})(jQuery); |
7134 | | -/* |
7135 | | - * jQuery UI Tabs 1.7.2 |
7136 | | - * |
7137 | | - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
7138 | | - * Dual licensed under the MIT (MIT-LICENSE.txt) |
7139 | | - * and GPL (GPL-LICENSE.txt) licenses. |
7140 | | - * |
7141 | | - * http://docs.jquery.com/UI/Tabs |
7142 | | - * |
7143 | | - * Depends: |
7144 | | - * ui.core.js |
7145 | | - */ |
7146 | | -(function($) { |
7147 | | - |
7148 | | -$.widget("ui.tabs", { |
7149 | | - |
7150 | | - _init: function() { |
7151 | | - if (this.options.deselectable !== undefined) { |
7152 | | - this.options.collapsible = this.options.deselectable; |
7153 | | - } |
7154 | | - this._tabify(true); |
7155 | | - }, |
7156 | | - |
7157 | | - _setData: function(key, value) { |
7158 | | - if (key == 'selected') { |
7159 | | - if (this.options.collapsible && value == this.options.selected) { |
7160 | | - return; |
7161 | | - } |
7162 | | - this.select(value); |
7163 | | - } |
7164 | | - else { |
7165 | | - this.options[key] = value; |
7166 | | - if (key == 'deselectable') { |
7167 | | - this.options.collapsible = value; |
7168 | | - } |
7169 | | - this._tabify(); |
7170 | | - } |
7171 | | - }, |
7172 | | - |
7173 | | - _tabId: function(a) { |
7174 | | - return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') || |
7175 | | - this.options.idPrefix + $.data(a); |
7176 | | - }, |
7177 | | - |
7178 | | - _sanitizeSelector: function(hash) { |
7179 | | - return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":" |
7180 | | - }, |
7181 | | - |
7182 | | - _cookie: function() { |
7183 | | - var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + $.data(this.list[0])); |
7184 | | - return $.cookie.apply(null, [cookie].concat($.makeArray(arguments))); |
7185 | | - }, |
7186 | | - |
7187 | | - _ui: function(tab, panel) { |
7188 | | - return { |
7189 | | - tab: tab, |
7190 | | - panel: panel, |
7191 | | - index: this.anchors.index(tab) |
7192 | | - }; |
7193 | | - }, |
7194 | | - |
7195 | | - _cleanup: function() { |
7196 | | - // restore all former loading tabs labels |
7197 | | - this.lis.filter('.ui-state-processing').removeClass('ui-state-processing') |
7198 | | - .find('span:data(label.tabs)') |
7199 | | - .each(function() { |
7200 | | - var el = $(this); |
7201 | | - el.html(el.data('label.tabs')).removeData('label.tabs'); |
7202 | | - }); |
7203 | | - }, |
7204 | | - |
7205 | | - _tabify: function(init) { |
7206 | | - |
7207 | | - this.list = this.element.children('ul:first'); |
7208 | | - this.lis = $('li:has(a[href])', this.list); |
7209 | | - this.anchors = this.lis.map(function() { return $('a', this)[0]; }); |
7210 | | - this.panels = $([]); |
7211 | | - |
7212 | | - var self = this, o = this.options; |
7213 | | - |
7214 | | - var fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash |
7215 | | - this.anchors.each(function(i, a) { |
7216 | | - var href = $(a).attr('href'); |
7217 | | - |
7218 | | - // For dynamically created HTML that contains a hash as href IE < 8 expands |
7219 | | - // such href to the full page url with hash and then misinterprets tab as ajax. |
7220 | | - // Same consideration applies for an added tab with a fragment identifier |
7221 | | - // since a[href=#fragment-identifier] does unexpectedly not match. |
7222 | | - // Thus normalize href attribute... |
7223 | | - var hrefBase = href.split('#')[0], baseEl; |
7224 | | - if (hrefBase && (hrefBase === location.toString().split('#')[0] || |
7225 | | - (baseEl = $('base')[0]) && hrefBase === baseEl.href)) { |
7226 | | - href = a.hash; |
7227 | | - a.href = href; |
7228 | | - } |
7229 | | - |
7230 | | - // inline tab |
7231 | | - if (fragmentId.test(href)) { |
7232 | | - self.panels = self.panels.add(self._sanitizeSelector(href)); |
7233 | | - } |
7234 | | - |
7235 | | - // remote tab |
7236 | | - else if (href != '#') { // prevent loading the page itself if href is just "#" |
7237 | | - $.data(a, 'href.tabs', href); // required for restore on destroy |
7238 | | - |
7239 | | - // TODO until #3808 is fixed strip fragment identifier from url |
7240 | | - // (IE fails to load from such url) |
7241 | | - $.data(a, 'load.tabs', href.replace(/#.*$/, '')); // mutable data |
7242 | | - |
7243 | | - var id = self._tabId(a); |
7244 | | - a.href = '#' + id; |
7245 | | - var $panel = $('#' + id); |
7246 | | - if (!$panel.length) { |
7247 | | - $panel = $(o.panelTemplate).attr('id', id).addClass('ui-tabs-panel ui-widget-content ui-corner-bottom') |
7248 | | - .insertAfter(self.panels[i - 1] || self.list); |
7249 | | - $panel.data('destroy.tabs', true); |
7250 | | - } |
7251 | | - self.panels = self.panels.add($panel); |
7252 | | - } |
7253 | | - |
7254 | | - // invalid tab href |
7255 | | - else { |
7256 | | - o.disabled.push(i); |
7257 | | - } |
7258 | | - }); |
7259 | | - |
7260 | | - // initialization from scratch |
7261 | | - if (init) { |
7262 | | - |
7263 | | - // attach necessary classes for styling |
7264 | | - this.element.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all'); |
7265 | | - this.list.addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all'); |
7266 | | - this.lis.addClass('ui-state-default ui-corner-top'); |
7267 | | - this.panels.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom'); |
7268 | | - |
7269 | | - // Selected tab |
7270 | | - // use "selected" option or try to retrieve: |
7271 | | - // 1. from fragment identifier in url |
7272 | | - // 2. from cookie |
7273 | | - // 3. from selected class attribute on <li> |
7274 | | - if (o.selected === undefined) { |
7275 | | - if (location.hash) { |
7276 | | - this.anchors.each(function(i, a) { |
7277 | | - if (a.hash == location.hash) { |
7278 | | - o.selected = i; |
7279 | | - return false; // break |
7280 | | - } |
7281 | | - }); |
7282 | | - } |
7283 | | - if (typeof o.selected != 'number' && o.cookie) { |
7284 | | - o.selected = parseInt(self._cookie(), 10); |
7285 | | - } |
7286 | | - if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) { |
7287 | | - o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected')); |
7288 | | - } |
7289 | | - o.selected = o.selected || 0; |
7290 | | - } |
7291 | | - else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release |
7292 | | - o.selected = -1; |
7293 | | - } |
7294 | | - |
7295 | | - // sanity check - default to first tab... |
7296 | | - o.selected = ((o.selected >= 0 && this.anchors[o.selected]) || o.selected < 0) ? o.selected : 0; |
7297 | | - |
7298 | | - // Take disabling tabs via class attribute from HTML |
7299 | | - // into account and update option properly. |
7300 | | - // A selected tab cannot become disabled. |
7301 | | - o.disabled = $.unique(o.disabled.concat( |
7302 | | - $.map(this.lis.filter('.ui-state-disabled'), |
7303 | | - function(n, i) { return self.lis.index(n); } ) |
7304 | | - )).sort(); |
7305 | | - |
7306 | | - if ($.inArray(o.selected, o.disabled) != -1) { |
7307 | | - o.disabled.splice($.inArray(o.selected, o.disabled), 1); |
7308 | | - } |
7309 | | - |
7310 | | - // highlight selected tab |
7311 | | - this.panels.addClass('ui-tabs-hide'); |
7312 | | - this.lis.removeClass('ui-tabs-selected ui-state-active'); |
7313 | | - if (o.selected >= 0 && this.anchors.length) { // check for length avoids error when initializing empty list |
7314 | | - this.panels.eq(o.selected).removeClass('ui-tabs-hide'); |
7315 | | - this.lis.eq(o.selected).addClass('ui-tabs-selected ui-state-active'); |
7316 | | - |
7317 | | - // seems to be expected behavior that the show callback is fired |
7318 | | - self.element.queue("tabs", function() { |
7319 | | - self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected])); |
7320 | | - }); |
7321 | | - |
7322 | | - this.load(o.selected); |
7323 | | - } |
7324 | | - |
7325 | | - // clean up to avoid memory leaks in certain versions of IE 6 |
7326 | | - $(window).bind('unload', function() { |
7327 | | - self.lis.add(self.anchors).unbind('.tabs'); |
7328 | | - self.lis = self.anchors = self.panels = null; |
7329 | | - }); |
7330 | | - |
7331 | | - } |
7332 | | - // update selected after add/remove |
7333 | | - else { |
7334 | | - o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected')); |
7335 | | - } |
7336 | | - |
7337 | | - // update collapsible |
7338 | | - this.element[o.collapsible ? 'addClass' : 'removeClass']('ui-tabs-collapsible'); |
7339 | | - |
7340 | | - // set or update cookie after init and add/remove respectively |
7341 | | - if (o.cookie) { |
7342 | | - this._cookie(o.selected, o.cookie); |
7343 | | - } |
7344 | | - |
7345 | | - // disable tabs |
7346 | | - for (var i = 0, li; (li = this.lis[i]); i++) { |
7347 | | - $(li)[$.inArray(i, o.disabled) != -1 && |
7348 | | - !$(li).hasClass('ui-tabs-selected') ? 'addClass' : 'removeClass']('ui-state-disabled'); |
7349 | | - } |
7350 | | - |
7351 | | - // reset cache if switching from cached to not cached |
7352 | | - if (o.cache === false) { |
7353 | | - this.anchors.removeData('cache.tabs'); |
7354 | | - } |
7355 | | - |
7356 | | - // remove all handlers before, tabify may run on existing tabs after add or option change |
7357 | | - this.lis.add(this.anchors).unbind('.tabs'); |
7358 | | - |
7359 | | - if (o.event != 'mouseover') { |
7360 | | - var addState = function(state, el) { |
7361 | | - if (el.is(':not(.ui-state-disabled)')) { |
7362 | | - el.addClass('ui-state-' + state); |
7363 | | - } |
7364 | | - }; |
7365 | | - var removeState = function(state, el) { |
7366 | | - el.removeClass('ui-state-' + state); |
7367 | | - }; |
7368 | | - this.lis.bind('mouseover.tabs', function() { |
7369 | | - addState('hover', $(this)); |
7370 | | - }); |
7371 | | - this.lis.bind('mouseout.tabs', function() { |
7372 | | - removeState('hover', $(this)); |
7373 | | - }); |
7374 | | - this.anchors.bind('focus.tabs', function() { |
7375 | | - addState('focus', $(this).closest('li')); |
7376 | | - }); |
7377 | | - this.anchors.bind('blur.tabs', function() { |
7378 | | - removeState('focus', $(this).closest('li')); |
7379 | | - }); |
7380 | | - } |
7381 | | - |
7382 | | - // set up animations |
7383 | | - var hideFx, showFx; |
7384 | | - if (o.fx) { |
7385 | | - if ($.isArray(o.fx)) { |
7386 | | - hideFx = o.fx[0]; |
7387 | | - showFx = o.fx[1]; |
7388 | | - } |
7389 | | - else { |
7390 | | - hideFx = showFx = o.fx; |
7391 | | - } |
7392 | | - } |
7393 | | - |
7394 | | - // Reset certain styles left over from animation |
7395 | | - // and prevent IE's ClearType bug... |
7396 | | - function resetStyle($el, fx) { |
7397 | | - $el.css({ display: '' }); |
7398 | | - if ($.browser.msie && fx.opacity) { |
7399 | | - $el[0].style.removeAttribute('filter'); |
7400 | | - } |
7401 | | - } |
7402 | | - |
7403 | | - // Show a tab... |
7404 | | - var showTab = showFx ? |
7405 | | - function(clicked, $show) { |
7406 | | - $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active'); |
7407 | | - $show.hide().removeClass('ui-tabs-hide') // avoid flicker that way |
7408 | | - .animate(showFx, showFx.duration || 'normal', function() { |
7409 | | - resetStyle($show, showFx); |
7410 | | - self._trigger('show', null, self._ui(clicked, $show[0])); |
7411 | | - }); |
7412 | | - } : |
7413 | | - function(clicked, $show) { |
7414 | | - $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active'); |
7415 | | - $show.removeClass('ui-tabs-hide'); |
7416 | | - self._trigger('show', null, self._ui(clicked, $show[0])); |
7417 | | - }; |
7418 | | - |
7419 | | - // Hide a tab, $show is optional... |
7420 | | - var hideTab = hideFx ? |
7421 | | - function(clicked, $hide) { |
7422 | | - $hide.animate(hideFx, hideFx.duration || 'normal', function() { |
7423 | | - self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default'); |
7424 | | - $hide.addClass('ui-tabs-hide'); |
7425 | | - resetStyle($hide, hideFx); |
7426 | | - self.element.dequeue("tabs"); |
7427 | | - }); |
7428 | | - } : |
7429 | | - function(clicked, $hide, $show) { |
7430 | | - self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default'); |
7431 | | - $hide.addClass('ui-tabs-hide'); |
7432 | | - self.element.dequeue("tabs"); |
7433 | | - }; |
7434 | | - |
7435 | | - // attach tab event handler, unbind to avoid duplicates from former tabifying... |
7436 | | - this.anchors.bind(o.event + '.tabs', function() { |
7437 | | - var el = this, $li = $(this).closest('li'), $hide = self.panels.filter(':not(.ui-tabs-hide)'), |
7438 | | - $show = $(self._sanitizeSelector(this.hash)); |
7439 | | - |
7440 | | - // If tab is already selected and not collapsible or tab disabled or |
7441 | | - // or is already loading or click callback returns false stop here. |
7442 | | - // Check if click handler returns false last so that it is not executed |
7443 | | - // for a disabled or loading tab! |
7444 | | - if (($li.hasClass('ui-tabs-selected') && !o.collapsible) || |
7445 | | - $li.hasClass('ui-state-disabled') || |
7446 | | - $li.hasClass('ui-state-processing') || |
7447 | | - self._trigger('select', null, self._ui(this, $show[0])) === false) { |
7448 | | - this.blur(); |
7449 | | - return false; |
7450 | | - } |
7451 | | - |
7452 | | - o.selected = self.anchors.index(this); |
7453 | | - |
7454 | | - self.abort(); |
7455 | | - |
7456 | | - // if tab may be closed |
7457 | | - if (o.collapsible) { |
7458 | | - if ($li.hasClass('ui-tabs-selected')) { |
7459 | | - o.selected = -1; |
7460 | | - |
7461 | | - if (o.cookie) { |
7462 | | - self._cookie(o.selected, o.cookie); |
7463 | | - } |
7464 | | - |
7465 | | - self.element.queue("tabs", function() { |
7466 | | - hideTab(el, $hide); |
7467 | | - }).dequeue("tabs"); |
7468 | | - |
7469 | | - this.blur(); |
7470 | | - return false; |
7471 | | - } |
7472 | | - else if (!$hide.length) { |
7473 | | - if (o.cookie) { |
7474 | | - self._cookie(o.selected, o.cookie); |
7475 | | - } |
7476 | | - |
7477 | | - self.element.queue("tabs", function() { |
7478 | | - showTab(el, $show); |
7479 | | - }); |
7480 | | - |
7481 | | - self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 |
7482 | | - |
7483 | | - this.blur(); |
7484 | | - return false; |
7485 | | - } |
7486 | | - } |
7487 | | - |
7488 | | - if (o.cookie) { |
7489 | | - self._cookie(o.selected, o.cookie); |
7490 | | - } |
7491 | | - |
7492 | | - // show new tab |
7493 | | - if ($show.length) { |
7494 | | - if ($hide.length) { |
7495 | | - self.element.queue("tabs", function() { |
7496 | | - hideTab(el, $hide); |
7497 | | - }); |
7498 | | - } |
7499 | | - self.element.queue("tabs", function() { |
7500 | | - showTab(el, $show); |
7501 | | - }); |
7502 | | - |
7503 | | - self.load(self.anchors.index(this)); |
7504 | | - } |
7505 | | - else { |
7506 | | - throw 'jQuery UI Tabs: Mismatching fragment identifier.'; |
7507 | | - } |
7508 | | - |
7509 | | - // Prevent IE from keeping other link focussed when using the back button |
7510 | | - // and remove dotted border from clicked link. This is controlled via CSS |
7511 | | - // in modern browsers; blur() removes focus from address bar in Firefox |
7512 | | - // which can become a usability and annoying problem with tabs('rotate'). |
7513 | | - if ($.browser.msie) { |
7514 | | - this.blur(); |
7515 | | - } |
7516 | | - |
7517 | | - }); |
7518 | | - |
7519 | | - // disable click in any case |
7520 | | - this.anchors.bind('click.tabs', function(){return false;}); |
7521 | | - |
7522 | | - }, |
7523 | | - |
7524 | | - destroy: function() { |
7525 | | - var o = this.options; |
7526 | | - |
7527 | | - this.abort(); |
7528 | | - |
7529 | | - this.element.unbind('.tabs') |
7530 | | - .removeClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible') |
7531 | | - .removeData('tabs'); |
7532 | | - |
7533 | | - this.list.removeClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all'); |
7534 | | - |
7535 | | - this.anchors.each(function() { |
7536 | | - var href = $.data(this, 'href.tabs'); |
7537 | | - if (href) { |
7538 | | - this.href = href; |
7539 | | - } |
7540 | | - var $this = $(this).unbind('.tabs'); |
7541 | | - $.each(['href', 'load', 'cache'], function(i, prefix) { |
7542 | | - $this.removeData(prefix + '.tabs'); |
7543 | | - }); |
7544 | | - }); |
7545 | | - |
7546 | | - this.lis.unbind('.tabs').add(this.panels).each(function() { |
7547 | | - if ($.data(this, 'destroy.tabs')) { |
7548 | | - $(this).remove(); |
7549 | | - } |
7550 | | - else { |
7551 | | - $(this).removeClass([ |
7552 | | - 'ui-state-default', |
7553 | | - 'ui-corner-top', |
7554 | | - 'ui-tabs-selected', |
7555 | | - 'ui-state-active', |
7556 | | - 'ui-state-hover', |
7557 | | - 'ui-state-focus', |
7558 | | - 'ui-state-disabled', |
7559 | | - 'ui-tabs-panel', |
7560 | | - 'ui-widget-content', |
7561 | | - 'ui-corner-bottom', |
7562 | | - 'ui-tabs-hide' |
7563 | | - ].join(' ')); |
7564 | | - } |
7565 | | - }); |
7566 | | - |
7567 | | - if (o.cookie) { |
7568 | | - this._cookie(null, o.cookie); |
7569 | | - } |
7570 | | - }, |
7571 | | - |
7572 | | - add: function(url, label, index) { |
7573 | | - if (index === undefined) { |
7574 | | - index = this.anchors.length; // append by default |
7575 | | - } |
7576 | | - |
7577 | | - var self = this, o = this.options, |
7578 | | - $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label)), |
7579 | | - id = !url.indexOf('#') ? url.replace('#', '') : this._tabId($('a', $li)[0]); |
7580 | | - |
7581 | | - $li.addClass('ui-state-default ui-corner-top').data('destroy.tabs', true); |
7582 | | - |
7583 | | - // try to find an existing element before creating a new one |
7584 | | - var $panel = $('#' + id); |
7585 | | - if (!$panel.length) { |
7586 | | - $panel = $(o.panelTemplate).attr('id', id).data('destroy.tabs', true); |
7587 | | - } |
7588 | | - $panel.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide'); |
7589 | | - |
7590 | | - if (index >= this.lis.length) { |
7591 | | - $li.appendTo(this.list); |
7592 | | - $panel.appendTo(this.list[0].parentNode); |
7593 | | - } |
7594 | | - else { |
7595 | | - $li.insertBefore(this.lis[index]); |
7596 | | - $panel.insertBefore(this.panels[index]); |
7597 | | - } |
7598 | | - |
7599 | | - o.disabled = $.map(o.disabled, |
7600 | | - function(n, i) { return n >= index ? ++n : n; }); |
7601 | | - |
7602 | | - this._tabify(); |
7603 | | - |
7604 | | - if (this.anchors.length == 1) { // after tabify |
7605 | | - $li.addClass('ui-tabs-selected ui-state-active'); |
7606 | | - $panel.removeClass('ui-tabs-hide'); |
7607 | | - this.element.queue("tabs", function() { |
7608 | | - self._trigger('show', null, self._ui(self.anchors[0], self.panels[0])); |
7609 | | - }); |
7610 | | - |
7611 | | - this.load(0); |
7612 | | - } |
7613 | | - |
7614 | | - // callback |
7615 | | - this._trigger('add', null, this._ui(this.anchors[index], this.panels[index])); |
7616 | | - }, |
7617 | | - |
7618 | | - remove: function(index) { |
7619 | | - var o = this.options, $li = this.lis.eq(index).remove(), |
7620 | | - $panel = this.panels.eq(index).remove(); |
7621 | | - |
7622 | | - // If selected tab was removed focus tab to the right or |
7623 | | - // in case the last tab was removed the tab to the left. |
7624 | | - if ($li.hasClass('ui-tabs-selected') && this.anchors.length > 1) { |
7625 | | - this.select(index + (index + 1 < this.anchors.length ? 1 : -1)); |
7626 | | - } |
7627 | | - |
7628 | | - o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }), |
7629 | | - function(n, i) { return n >= index ? --n : n; }); |
7630 | | - |
7631 | | - this._tabify(); |
7632 | | - |
7633 | | - // callback |
7634 | | - this._trigger('remove', null, this._ui($li.find('a')[0], $panel[0])); |
7635 | | - }, |
7636 | | - |
7637 | | - enable: function(index) { |
7638 | | - var o = this.options; |
7639 | | - if ($.inArray(index, o.disabled) == -1) { |
7640 | | - return; |
7641 | | - } |
7642 | | - |
7643 | | - this.lis.eq(index).removeClass('ui-state-disabled'); |
7644 | | - o.disabled = $.grep(o.disabled, function(n, i) { return n != index; }); |
7645 | | - |
7646 | | - // callback |
7647 | | - this._trigger('enable', null, this._ui(this.anchors[index], this.panels[index])); |
7648 | | - }, |
7649 | | - |
7650 | | - disable: function(index) { |
7651 | | - var self = this, o = this.options; |
7652 | | - if (index != o.selected) { // cannot disable already selected tab |
7653 | | - this.lis.eq(index).addClass('ui-state-disabled'); |
7654 | | - |
7655 | | - o.disabled.push(index); |
7656 | | - o.disabled.sort(); |
7657 | | - |
7658 | | - // callback |
7659 | | - this._trigger('disable', null, this._ui(this.anchors[index], this.panels[index])); |
7660 | | - } |
7661 | | - }, |
7662 | | - |
7663 | | - select: function(index) { |
7664 | | - if (typeof index == 'string') { |
7665 | | - index = this.anchors.index(this.anchors.filter('[href$=' + index + ']')); |
7666 | | - } |
7667 | | - else if (index === null) { // usage of null is deprecated, TODO remove in next release |
7668 | | - index = -1; |
7669 | | - } |
7670 | | - if (index == -1 && this.options.collapsible) { |
7671 | | - index = this.options.selected; |
7672 | | - } |
7673 | | - |
7674 | | - this.anchors.eq(index).trigger(this.options.event + '.tabs'); |
7675 | | - }, |
7676 | | - |
7677 | | - load: function(index) { |
7678 | | - var self = this, o = this.options, a = this.anchors.eq(index)[0], url = $.data(a, 'load.tabs'); |
7679 | | - |
7680 | | - this.abort(); |
7681 | | - |
7682 | | - // not remote or from cache |
7683 | | - if (!url || this.element.queue("tabs").length !== 0 && $.data(a, 'cache.tabs')) { |
7684 | | - this.element.dequeue("tabs"); |
7685 | | - return; |
7686 | | - } |
7687 | | - |
7688 | | - // load remote from here on |
7689 | | - this.lis.eq(index).addClass('ui-state-processing'); |
7690 | | - |
7691 | | - if (o.spinner) { |
7692 | | - var span = $('span', a); |
7693 | | - span.data('label.tabs', span.html()).html(o.spinner); |
7694 | | - } |
7695 | | - |
7696 | | - this.xhr = $.ajax($.extend({}, o.ajaxOptions, { |
7697 | | - url: url, |
7698 | | - success: function(r, s) { |
7699 | | - $(self._sanitizeSelector(a.hash)).html(r); |
7700 | | - |
7701 | | - // take care of tab labels |
7702 | | - self._cleanup(); |
7703 | | - |
7704 | | - if (o.cache) { |
7705 | | - $.data(a, 'cache.tabs', true); // if loaded once do not load them again |
7706 | | - } |
7707 | | - |
7708 | | - // callbacks |
7709 | | - self._trigger('load', null, self._ui(self.anchors[index], self.panels[index])); |
7710 | | - try { |
7711 | | - o.ajaxOptions.success(r, s); |
7712 | | - } |
7713 | | - catch (e) {} |
7714 | | - |
7715 | | - // last, so that load event is fired before show... |
7716 | | - self.element.dequeue("tabs"); |
7717 | | - } |
7718 | | - })); |
7719 | | - }, |
7720 | | - |
7721 | | - abort: function() { |
7722 | | - // stop possibly running animations |
7723 | | - this.element.queue([]); |
7724 | | - this.panels.stop(false, true); |
7725 | | - |
7726 | | - // terminate pending requests from other tabs |
7727 | | - if (this.xhr) { |
7728 | | - this.xhr.abort(); |
7729 | | - delete this.xhr; |
7730 | | - } |
7731 | | - |
7732 | | - // take care of tab labels |
7733 | | - this._cleanup(); |
7734 | | - |
7735 | | - }, |
7736 | | - |
7737 | | - url: function(index, url) { |
7738 | | - this.anchors.eq(index).removeData('cache.tabs').data('load.tabs', url); |
7739 | | - }, |
7740 | | - |
7741 | | - length: function() { |
7742 | | - return this.anchors.length; |
7743 | | - } |
7744 | | - |
7745 | | -}); |
7746 | | - |
7747 | | -$.extend($.ui.tabs, { |
7748 | | - version: '1.7.2', |
7749 | | - getter: 'length', |
7750 | | - defaults: { |
7751 | | - ajaxOptions: null, |
7752 | | - cache: false, |
7753 | | - cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } |
7754 | | - collapsible: false, |
7755 | | - disabled: [], |
7756 | | - event: 'click', |
7757 | | - fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } |
7758 | | - idPrefix: 'ui-tabs-', |
7759 | | - panelTemplate: '<div></div>', |
7760 | | - spinner: '<em>Loading…</em>', |
7761 | | - tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>' |
7762 | | - } |
7763 | | -}); |
7764 | | - |
7765 | | -/* |
7766 | | - * Tabs Extensions |
7767 | | - */ |
7768 | | - |
7769 | | -/* |
7770 | | - * Rotate |
7771 | | - */ |
7772 | | -$.extend($.ui.tabs.prototype, { |
7773 | | - rotation: null, |
7774 | | - rotate: function(ms, continuing) { |
7775 | | - |
7776 | | - var self = this, o = this.options; |
7777 | | - |
7778 | | - var rotate = self._rotate || (self._rotate = function(e) { |
7779 | | - clearTimeout(self.rotation); |
7780 | | - self.rotation = setTimeout(function() { |
7781 | | - var t = o.selected; |
7782 | | - self.select( ++t < self.anchors.length ? t : 0 ); |
7783 | | - }, ms); |
7784 | | - |
7785 | | - if (e) { |
7786 | | - e.stopPropagation(); |
7787 | | - } |
7788 | | - }); |
7789 | | - |
7790 | | - var stop = self._unrotate || (self._unrotate = !continuing ? |
7791 | | - function(e) { |
7792 | | - if (e.clientX) { // in case of a true click |
7793 | | - self.rotate(null); |
7794 | | - } |
7795 | | - } : |
7796 | | - function(e) { |
7797 | | - t = o.selected; |
7798 | | - rotate(); |
7799 | | - }); |
7800 | | - |
7801 | | - // start rotation |
7802 | | - if (ms) { |
7803 | | - this.element.bind('tabsshow', rotate); |
7804 | | - this.anchors.bind(o.event + '.tabs', stop); |
7805 | | - rotate(); |
7806 | | - } |
7807 | | - // stop rotation |
7808 | | - else { |
7809 | | - clearTimeout(self.rotation); |
7810 | | - this.element.unbind('tabsshow', rotate); |
7811 | | - this.anchors.unbind(o.event + '.tabs', stop); |
7812 | | - delete this._rotate; |
7813 | | - delete this._unrotate; |
7814 | | - } |
7815 | | - } |
7816 | | -}); |
7817 | | - |
7818 | | -})(jQuery); |
7819 | | -/* |
7820 | | - * jQuery UI Datepicker 1.7.2 |
7821 | | - * |
7822 | | - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
7823 | | - * Dual licensed under the MIT (MIT-LICENSE.txt) |
7824 | | - * and GPL (GPL-LICENSE.txt) licenses. |
7825 | | - * |
7826 | | - * http://docs.jquery.com/UI/Datepicker |
7827 | | - * |
7828 | | - * Depends: |
7829 | | - * ui.core.js |
7830 | | - */ |
7831 | | - |
7832 | | -(function($) { // hide the namespace |
7833 | | - |
7834 | | -$.extend($.ui, { datepicker: { version: "1.7.2" } }); |
7835 | | - |
7836 | | -var PROP_NAME = 'datepicker'; |
7837 | | - |
7838 | | -/* Date picker manager. |
7839 | | - Use the singleton instance of this class, $.datepicker, to interact with the date picker. |
7840 | | - Settings for (groups of) date pickers are maintained in an instance object, |
7841 | | - allowing multiple different settings on the same page. */ |
7842 | | - |
7843 | | -function Datepicker() { |
7844 | | - this.debug = false; // Change this to true to start debugging |
7845 | | - this._curInst = null; // The current instance in use |
7846 | | - this._keyEvent = false; // If the last event was a key event |
7847 | | - this._disabledInputs = []; // List of date picker inputs that have been disabled |
7848 | | - this._datepickerShowing = false; // True if the popup picker is showing , false if not |
7849 | | - this._inDialog = false; // True if showing within a "dialog", false if not |
7850 | | - this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division |
7851 | | - this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class |
7852 | | - this._appendClass = 'ui-datepicker-append'; // The name of the append marker class |
7853 | | - this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class |
7854 | | - this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class |
7855 | | - this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class |
7856 | | - this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class |
7857 | | - this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class |
7858 | | - this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class |
7859 | | - this.regional = []; // Available regional settings, indexed by language code |
7860 | | - this.regional[''] = { // Default regional settings |
7861 | | - closeText: 'Done', // Display text for close link |
7862 | | - prevText: 'Prev', // Display text for previous month link |
7863 | | - nextText: 'Next', // Display text for next month link |
7864 | | - currentText: 'Today', // Display text for current month link |
7865 | | - monthNames: ['January','February','March','April','May','June', |
7866 | | - 'July','August','September','October','November','December'], // Names of months for drop-down and formatting |
7867 | | - monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting |
7868 | | - dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting |
7869 | | - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting |
7870 | | - dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday |
7871 | | - dateFormat: 'mm/dd/yy', // See format options on parseDate |
7872 | | - firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... |
7873 | | - isRTL: false // True if right-to-left language, false if left-to-right |
7874 | | - }; |
7875 | | - this._defaults = { // Global defaults for all the date picker instances |
7876 | | - showOn: 'focus', // 'focus' for popup on focus, |
7877 | | - // 'button' for trigger button, or 'both' for either |
7878 | | - showAnim: 'show', // Name of jQuery animation for popup |
7879 | | - showOptions: {}, // Options for enhanced animations |
7880 | | - defaultDate: null, // Used when field is blank: actual date, |
7881 | | - // +/-number for offset from today, null for today |
7882 | | - appendText: '', // Display text following the input box, e.g. showing the format |
7883 | | - buttonText: '...', // Text for trigger button |
7884 | | - buttonImage: '', // URL for trigger button image |
7885 | | - buttonImageOnly: false, // True if the image appears alone, false if it appears on a button |
7886 | | - hideIfNoPrevNext: false, // True to hide next/previous month links |
7887 | | - // if not applicable, false to just disable them |
7888 | | - navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links |
7889 | | - gotoCurrent: false, // True if today link goes back to current selection instead |
7890 | | - changeMonth: false, // True if month can be selected directly, false if only prev/next |
7891 | | - changeYear: false, // True if year can be selected directly, false if only prev/next |
7892 | | - showMonthAfterYear: false, // True if the year select precedes month, false for month then year |
7893 | | - yearRange: '-10:+10', // Range of years to display in drop-down, |
7894 | | - // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn) |
7895 | | - showOtherMonths: false, // True to show dates in other months, false to leave blank |
7896 | | - calculateWeek: this.iso8601Week, // How to calculate the week of the year, |
7897 | | - // takes a Date and returns the number of the week for it |
7898 | | - shortYearCutoff: '+10', // Short year values < this are in the current century, |
7899 | | - // > this are in the previous century, |
7900 | | - // string value starting with '+' for current year + value |
7901 | | - minDate: null, // The earliest selectable date, or null for no limit |
7902 | | - maxDate: null, // The latest selectable date, or null for no limit |
7903 | | - duration: 'normal', // Duration of display/closure |
7904 | | - beforeShowDay: null, // Function that takes a date and returns an array with |
7905 | | - // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', |
7906 | | - // [2] = cell title (optional), e.g. $.datepicker.noWeekends |
7907 | | - beforeShow: null, // Function that takes an input field and |
7908 | | - // returns a set of custom settings for the date picker |
7909 | | - onSelect: null, // Define a callback function when a date is selected |
7910 | | - onChangeMonthYear: null, // Define a callback function when the month or year is changed |
7911 | | - onClose: null, // Define a callback function when the datepicker is closed |
7912 | | - numberOfMonths: 1, // Number of months to show at a time |
7913 | | - showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) |
7914 | | - stepMonths: 1, // Number of months to step back/forward |
7915 | | - stepBigMonths: 12, // Number of months to step back/forward for the big links |
7916 | | - altField: '', // Selector for an alternate field to store selected dates into |
7917 | | - altFormat: '', // The date format to use for the alternate field |
7918 | | - constrainInput: true, // The input is constrained by the current date format |
7919 | | - showButtonPanel: false // True to show button panel, false to not show it |
7920 | | - }; |
7921 | | - $.extend(this._defaults, this.regional['']); |
7922 | | - this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>'); |
7923 | | -} |
7924 | | - |
7925 | | -$.extend(Datepicker.prototype, { |
7926 | | - /* Class name added to elements to indicate already configured with a date picker. */ |
7927 | | - markerClassName: 'hasDatepicker', |
7928 | | - |
7929 | | - /* Debug logging (if enabled). */ |
7930 | | - log: function () { |
7931 | | - if (this.debug) |
7932 | | - console.log.apply('', arguments); |
7933 | | - }, |
7934 | | - |
7935 | | - /* Override the default settings for all instances of the date picker. |
7936 | | - @param settings object - the new settings to use as defaults (anonymous object) |
7937 | | - @return the manager object */ |
7938 | | - setDefaults: function(settings) { |
7939 | | - extendRemove(this._defaults, settings || {}); |
7940 | | - return this; |
7941 | | - }, |
7942 | | - |
7943 | | - /* Attach the date picker to a jQuery selection. |
7944 | | - @param target element - the target input field or division or span |
7945 | | - @param settings object - the new settings to use for this date picker instance (anonymous) */ |
7946 | | - _attachDatepicker: function(target, settings) { |
7947 | | - // check for settings on the control itself - in namespace 'date:' |
7948 | | - var inlineSettings = null; |
7949 | | - for (var attrName in this._defaults) { |
7950 | | - var attrValue = target.getAttribute('date:' + attrName); |
7951 | | - if (attrValue) { |
7952 | | - inlineSettings = inlineSettings || {}; |
7953 | | - try { |
7954 | | - inlineSettings[attrName] = eval(attrValue); |
7955 | | - } catch (err) { |
7956 | | - inlineSettings[attrName] = attrValue; |
7957 | | - } |
7958 | | - } |
7959 | | - } |
7960 | | - var nodeName = target.nodeName.toLowerCase(); |
7961 | | - var inline = (nodeName == 'div' || nodeName == 'span'); |
7962 | | - if (!target.id) |
7963 | | - target.id = 'dp' + (++this.uuid); |
7964 | | - var inst = this._newInst($(target), inline); |
7965 | | - inst.settings = $.extend({}, settings || {}, inlineSettings || {}); |
7966 | | - if (nodeName == 'input') { |
7967 | | - this._connectDatepicker(target, inst); |
7968 | | - } else if (inline) { |
7969 | | - this._inlineDatepicker(target, inst); |
7970 | | - } |
7971 | | - }, |
7972 | | - |
7973 | | - /* Create a new instance object. */ |
7974 | | - _newInst: function(target, inline) { |
7975 | | - var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars |
7976 | | - return {id: id, input: target, // associated target |
7977 | | - selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection |
7978 | | - drawMonth: 0, drawYear: 0, // month being drawn |
7979 | | - inline: inline, // is datepicker inline or not |
7980 | | - dpDiv: (!inline ? this.dpDiv : // presentation div |
7981 | | - $('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}; |
7982 | | - }, |
7983 | | - |
7984 | | - /* Attach the date picker to an input field. */ |
7985 | | - _connectDatepicker: function(target, inst) { |
7986 | | - var input = $(target); |
7987 | | - inst.append = $([]); |
7988 | | - inst.trigger = $([]); |
7989 | | - if (input.hasClass(this.markerClassName)) |
7990 | | - return; |
7991 | | - var appendText = this._get(inst, 'appendText'); |
7992 | | - var isRTL = this._get(inst, 'isRTL'); |
7993 | | - if (appendText) { |
7994 | | - inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>'); |
7995 | | - input[isRTL ? 'before' : 'after'](inst.append); |
7996 | | - } |
7997 | | - var showOn = this._get(inst, 'showOn'); |
7998 | | - if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field |
7999 | | - input.focus(this._showDatepicker); |
8000 | | - if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked |
8001 | | - var buttonText = this._get(inst, 'buttonText'); |
8002 | | - var buttonImage = this._get(inst, 'buttonImage'); |
8003 | | - inst.trigger = $(this._get(inst, 'buttonImageOnly') ? |
8004 | | - $('<img/>').addClass(this._triggerClass). |
8005 | | - attr({ src: buttonImage, alt: buttonText, title: buttonText }) : |
8006 | | - $('<button type="button"></button>').addClass(this._triggerClass). |
8007 | | - html(buttonImage == '' ? buttonText : $('<img/>').attr( |
8008 | | - { src:buttonImage, alt:buttonText, title:buttonText }))); |
8009 | | - input[isRTL ? 'before' : 'after'](inst.trigger); |
8010 | | - inst.trigger.click(function() { |
8011 | | - if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target) |
8012 | | - $.datepicker._hideDatepicker(); |
8013 | | - else |
8014 | | - $.datepicker._showDatepicker(target); |
8015 | | - return false; |
8016 | | - }); |
8017 | | - } |
8018 | | - input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress). |
8019 | | - bind("setData.datepicker", function(event, key, value) { |
8020 | | - inst.settings[key] = value; |
8021 | | - }).bind("getData.datepicker", function(event, key) { |
8022 | | - return this._get(inst, key); |
8023 | | - }); |
8024 | | - $.data(target, PROP_NAME, inst); |
8025 | | - }, |
8026 | | - |
8027 | | - /* Attach an inline date picker to a div. */ |
8028 | | - _inlineDatepicker: function(target, inst) { |
8029 | | - var divSpan = $(target); |
8030 | | - if (divSpan.hasClass(this.markerClassName)) |
8031 | | - return; |
8032 | | - divSpan.addClass(this.markerClassName).append(inst.dpDiv). |
8033 | | - bind("setData.datepicker", function(event, key, value){ |
8034 | | - inst.settings[key] = value; |
8035 | | - }).bind("getData.datepicker", function(event, key){ |
8036 | | - return this._get(inst, key); |
8037 | | - }); |
8038 | | - $.data(target, PROP_NAME, inst); |
8039 | | - this._setDate(inst, this._getDefaultDate(inst)); |
8040 | | - this._updateDatepicker(inst); |
8041 | | - this._updateAlternate(inst); |
8042 | | - }, |
8043 | | - |
8044 | | - /* Pop-up the date picker in a "dialog" box. |
8045 | | - @param input element - ignored |
8046 | | - @param dateText string - the initial date to display (in the current format) |
8047 | | - @param onSelect function - the function(dateText) to call when a date is selected |
8048 | | - @param settings object - update the dialog date picker instance's settings (anonymous object) |
8049 | | - @param pos int[2] - coordinates for the dialog's position within the screen or |
8050 | | - event - with x/y coordinates or |
8051 | | - leave empty for default (screen centre) |
8052 | | - @return the manager object */ |
8053 | | - _dialogDatepicker: function(input, dateText, onSelect, settings, pos) { |
8054 | | - var inst = this._dialogInst; // internal instance |
8055 | | - if (!inst) { |
8056 | | - var id = 'dp' + (++this.uuid); |
8057 | | - this._dialogInput = $('<input type="text" id="' + id + |
8058 | | - '" size="1" style="position: absolute; top: -100px;"/>'); |
8059 | | - this._dialogInput.keydown(this._doKeyDown); |
8060 | | - $('body').append(this._dialogInput); |
8061 | | - inst = this._dialogInst = this._newInst(this._dialogInput, false); |
8062 | | - inst.settings = {}; |
8063 | | - $.data(this._dialogInput[0], PROP_NAME, inst); |
8064 | | - } |
8065 | | - extendRemove(inst.settings, settings || {}); |
8066 | | - this._dialogInput.val(dateText); |
8067 | | - |
8068 | | - this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); |
8069 | | - if (!this._pos) { |
8070 | | - var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; |
8071 | | - var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; |
8072 | | - var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; |
8073 | | - var scrollY = document.documentElement.scrollTop || document.body.scrollTop; |
8074 | | - this._pos = // should use actual width/height below |
8075 | | - [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; |
8076 | | - } |
8077 | | - |
8078 | | - // move input on screen for focus, but hidden behind dialog |
8079 | | - this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px'); |
8080 | | - inst.settings.onSelect = onSelect; |
8081 | | - this._inDialog = true; |
8082 | | - this.dpDiv.addClass(this._dialogClass); |
8083 | | - this._showDatepicker(this._dialogInput[0]); |
8084 | | - if ($.blockUI) |
8085 | | - $.blockUI(this.dpDiv); |
8086 | | - $.data(this._dialogInput[0], PROP_NAME, inst); |
8087 | | - return this; |
8088 | | - }, |
8089 | | - |
8090 | | - /* Detach a datepicker from its control. |
8091 | | - @param target element - the target input field or division or span */ |
8092 | | - _destroyDatepicker: function(target) { |
8093 | | - var $target = $(target); |
8094 | | - var inst = $.data(target, PROP_NAME); |
8095 | | - if (!$target.hasClass(this.markerClassName)) { |
8096 | | - return; |
8097 | | - } |
8098 | | - var nodeName = target.nodeName.toLowerCase(); |
8099 | | - $.removeData(target, PROP_NAME); |
8100 | | - if (nodeName == 'input') { |
8101 | | - inst.append.remove(); |
8102 | | - inst.trigger.remove(); |
8103 | | - $target.removeClass(this.markerClassName). |
8104 | | - unbind('focus', this._showDatepicker). |
8105 | | - unbind('keydown', this._doKeyDown). |
8106 | | - unbind('keypress', this._doKeyPress); |
8107 | | - } else if (nodeName == 'div' || nodeName == 'span') |
8108 | | - $target.removeClass(this.markerClassName).empty(); |
8109 | | - }, |
8110 | | - |
8111 | | - /* Enable the date picker to a jQuery selection. |
8112 | | - @param target element - the target input field or division or span */ |
8113 | | - _enableDatepicker: function(target) { |
8114 | | - var $target = $(target); |
8115 | | - var inst = $.data(target, PROP_NAME); |
8116 | | - if (!$target.hasClass(this.markerClassName)) { |
8117 | | - return; |
8118 | | - } |
8119 | | - var nodeName = target.nodeName.toLowerCase(); |
8120 | | - if (nodeName == 'input') { |
8121 | | - target.disabled = false; |
8122 | | - inst.trigger.filter('button'). |
8123 | | - each(function() { this.disabled = false; }).end(). |
8124 | | - filter('img').css({opacity: '1.0', cursor: ''}); |
8125 | | - } |
8126 | | - else if (nodeName == 'div' || nodeName == 'span') { |
8127 | | - var inline = $target.children('.' + this._inlineClass); |
8128 | | - inline.children().removeClass('ui-state-disabled'); |
8129 | | - } |
8130 | | - this._disabledInputs = $.map(this._disabledInputs, |
8131 | | - function(value) { return (value == target ? null : value); }); // delete entry |
8132 | | - }, |
8133 | | - |
8134 | | - /* Disable the date picker to a jQuery selection. |
8135 | | - @param target element - the target input field or division or span */ |
8136 | | - _disableDatepicker: function(target) { |
8137 | | - var $target = $(target); |
8138 | | - var inst = $.data(target, PROP_NAME); |
8139 | | - if (!$target.hasClass(this.markerClassName)) { |
8140 | | - return; |
8141 | | - } |
8142 | | - var nodeName = target.nodeName.toLowerCase(); |
8143 | | - if (nodeName == 'input') { |
8144 | | - target.disabled = true; |
8145 | | - inst.trigger.filter('button'). |
8146 | | - each(function() { this.disabled = true; }).end(). |
8147 | | - filter('img').css({opacity: '0.5', cursor: 'default'}); |
8148 | | - } |
8149 | | - else if (nodeName == 'div' || nodeName == 'span') { |
8150 | | - var inline = $target.children('.' + this._inlineClass); |
8151 | | - inline.children().addClass('ui-state-disabled'); |
8152 | | - } |
8153 | | - this._disabledInputs = $.map(this._disabledInputs, |
8154 | | - function(value) { return (value == target ? null : value); }); // delete entry |
8155 | | - this._disabledInputs[this._disabledInputs.length] = target; |
8156 | | - }, |
8157 | | - |
8158 | | - /* Is the first field in a jQuery collection disabled as a datepicker? |
8159 | | - @param target element - the target input field or division or span |
8160 | | - @return boolean - true if disabled, false if enabled */ |
8161 | | - _isDisabledDatepicker: function(target) { |
8162 | | - if (!target) { |
8163 | | - return false; |
8164 | | - } |
8165 | | - for (var i = 0; i < this._disabledInputs.length; i++) { |
8166 | | - if (this._disabledInputs[i] == target) |
8167 | | - return true; |
8168 | | - } |
8169 | | - return false; |
8170 | | - }, |
8171 | | - |
8172 | | - /* Retrieve the instance data for the target control. |
8173 | | - @param target element - the target input field or division or span |
8174 | | - @return object - the associated instance data |
8175 | | - @throws error if a jQuery problem getting data */ |
8176 | | - _getInst: function(target) { |
8177 | | - try { |
8178 | | - return $.data(target, PROP_NAME); |
8179 | | - } |
8180 | | - catch (err) { |
8181 | | - throw 'Missing instance data for this datepicker'; |
8182 | | - } |
8183 | | - }, |
8184 | | - |
8185 | | - /* Update or retrieve the settings for a date picker attached to an input field or division. |
8186 | | - @param target element - the target input field or division or span |
8187 | | - @param name object - the new settings to update or |
8188 | | - string - the name of the setting to change or retrieve, |
8189 | | - when retrieving also 'all' for all instance settings or |
8190 | | - 'defaults' for all global defaults |
8191 | | - @param value any - the new value for the setting |
8192 | | - (omit if above is an object or to retrieve a value) */ |
8193 | | - _optionDatepicker: function(target, name, value) { |
8194 | | - var inst = this._getInst(target); |
8195 | | - if (arguments.length == 2 && typeof name == 'string') { |
8196 | | - return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) : |
8197 | | - (inst ? (name == 'all' ? $.extend({}, inst.settings) : |
8198 | | - this._get(inst, name)) : null)); |
8199 | | - } |
8200 | | - var settings = name || {}; |
8201 | | - if (typeof name == 'string') { |
8202 | | - settings = {}; |
8203 | | - settings[name] = value; |
8204 | | - } |
8205 | | - if (inst) { |
8206 | | - if (this._curInst == inst) { |
8207 | | - this._hideDatepicker(null); |
8208 | | - } |
8209 | | - var date = this._getDateDatepicker(target); |
8210 | | - extendRemove(inst.settings, settings); |
8211 | | - this._setDateDatepicker(target, date); |
8212 | | - this._updateDatepicker(inst); |
8213 | | - } |
8214 | | - }, |
8215 | | - |
8216 | | - // change method deprecated |
8217 | | - _changeDatepicker: function(target, name, value) { |
8218 | | - this._optionDatepicker(target, name, value); |
8219 | | - }, |
8220 | | - |
8221 | | - /* Redraw the date picker attached to an input field or division. |
8222 | | - @param target element - the target input field or division or span */ |
8223 | | - _refreshDatepicker: function(target) { |
8224 | | - var inst = this._getInst(target); |
8225 | | - if (inst) { |
8226 | | - this._updateDatepicker(inst); |
8227 | | - } |
8228 | | - }, |
8229 | | - |
8230 | | - /* Set the dates for a jQuery selection. |
8231 | | - @param target element - the target input field or division or span |
8232 | | - @param date Date - the new date |
8233 | | - @param endDate Date - the new end date for a range (optional) */ |
8234 | | - _setDateDatepicker: function(target, date, endDate) { |
8235 | | - var inst = this._getInst(target); |
8236 | | - if (inst) { |
8237 | | - this._setDate(inst, date, endDate); |
8238 | | - this._updateDatepicker(inst); |
8239 | | - this._updateAlternate(inst); |
8240 | | - } |
8241 | | - }, |
8242 | | - |
8243 | | - /* Get the date(s) for the first entry in a jQuery selection. |
8244 | | - @param target element - the target input field or division or span |
8245 | | - @return Date - the current date or |
8246 | | - Date[2] - the current dates for a range */ |
8247 | | - _getDateDatepicker: function(target) { |
8248 | | - var inst = this._getInst(target); |
8249 | | - if (inst && !inst.inline) |
8250 | | - this._setDateFromField(inst); |
8251 | | - return (inst ? this._getDate(inst) : null); |
8252 | | - }, |
8253 | | - |
8254 | | - /* Handle keystrokes. */ |
8255 | | - _doKeyDown: function(event) { |
8256 | | - var inst = $.datepicker._getInst(event.target); |
8257 | | - var handled = true; |
8258 | | - var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); |
8259 | | - inst._keyEvent = true; |
8260 | | - if ($.datepicker._datepickerShowing) |
8261 | | - switch (event.keyCode) { |
8262 | | - case 9: $.datepicker._hideDatepicker(null, ''); |
8263 | | - break; // hide on tab out |
8264 | | - case 13: var sel = $('td.' + $.datepicker._dayOverClass + |
8265 | | - ', td.' + $.datepicker._currentClass, inst.dpDiv); |
8266 | | - if (sel[0]) |
8267 | | - $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); |
8268 | | - else |
8269 | | - $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration')); |
8270 | | - return false; // don't submit the form |
8271 | | - break; // select the value on enter |
8272 | | - case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration')); |
8273 | | - break; // hide on escape |
8274 | | - case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? |
8275 | | - -$.datepicker._get(inst, 'stepBigMonths') : |
8276 | | - -$.datepicker._get(inst, 'stepMonths')), 'M'); |
8277 | | - break; // previous month/year on page up/+ ctrl |
8278 | | - case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? |
8279 | | - +$.datepicker._get(inst, 'stepBigMonths') : |
8280 | | - +$.datepicker._get(inst, 'stepMonths')), 'M'); |
8281 | | - break; // next month/year on page down/+ ctrl |
8282 | | - case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); |
8283 | | - handled = event.ctrlKey || event.metaKey; |
8284 | | - break; // clear on ctrl or command +end |
8285 | | - case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); |
8286 | | - handled = event.ctrlKey || event.metaKey; |
8287 | | - break; // current on ctrl or command +home |
8288 | | - case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); |
8289 | | - handled = event.ctrlKey || event.metaKey; |
8290 | | - // -1 day on ctrl or command +left |
8291 | | - if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? |
8292 | | - -$.datepicker._get(inst, 'stepBigMonths') : |
8293 | | - -$.datepicker._get(inst, 'stepMonths')), 'M'); |
8294 | | - // next month/year on alt +left on Mac |
8295 | | - break; |
8296 | | - case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); |
8297 | | - handled = event.ctrlKey || event.metaKey; |
8298 | | - break; // -1 week on ctrl or command +up |
8299 | | - case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); |
8300 | | - handled = event.ctrlKey || event.metaKey; |
8301 | | - // +1 day on ctrl or command +right |
8302 | | - if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? |
8303 | | - +$.datepicker._get(inst, 'stepBigMonths') : |
8304 | | - +$.datepicker._get(inst, 'stepMonths')), 'M'); |
8305 | | - // next month/year on alt +right |
8306 | | - break; |
8307 | | - case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); |
8308 | | - handled = event.ctrlKey || event.metaKey; |
8309 | | - break; // +1 week on ctrl or command +down |
8310 | | - default: handled = false; |
8311 | | - } |
8312 | | - else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home |
8313 | | - $.datepicker._showDatepicker(this); |
8314 | | - else { |
8315 | | - handled = false; |
8316 | | - } |
8317 | | - if (handled) { |
8318 | | - event.preventDefault(); |
8319 | | - event.stopPropagation(); |
8320 | | - } |
8321 | | - }, |
8322 | | - |
8323 | | - /* Filter entered characters - based on date format. */ |
8324 | | - _doKeyPress: function(event) { |
8325 | | - var inst = $.datepicker._getInst(event.target); |
8326 | | - if ($.datepicker._get(inst, 'constrainInput')) { |
8327 | | - var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); |
8328 | | - var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); |
8329 | | - return event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); |
8330 | | - } |
8331 | | - }, |
8332 | | - |
8333 | | - /* Pop-up the date picker for a given input field. |
8334 | | - @param input element - the input field attached to the date picker or |
8335 | | - event - if triggered by focus */ |
8336 | | - _showDatepicker: function(input) { |
8337 | | - input = input.target || input; |
8338 | | - if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger |
8339 | | - input = $('input', input.parentNode)[0]; |
8340 | | - if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here |
8341 | | - return; |
8342 | | - var inst = $.datepicker._getInst(input); |
8343 | | - var beforeShow = $.datepicker._get(inst, 'beforeShow'); |
8344 | | - extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {})); |
8345 | | - $.datepicker._hideDatepicker(null, ''); |
8346 | | - $.datepicker._lastInput = input; |
8347 | | - $.datepicker._setDateFromField(inst); |
8348 | | - if ($.datepicker._inDialog) // hide cursor |
8349 | | - input.value = ''; |
8350 | | - if (!$.datepicker._pos) { // position below input |
8351 | | - $.datepicker._pos = $.datepicker._findPos(input); |
8352 | | - $.datepicker._pos[1] += input.offsetHeight; // add the height |
8353 | | - } |
8354 | | - var isFixed = false; |
8355 | | - $(input).parents().each(function() { |
8356 | | - isFixed |= $(this).css('position') == 'fixed'; |
8357 | | - return !isFixed; |
8358 | | - }); |
8359 | | - if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled |
8360 | | - $.datepicker._pos[0] -= document.documentElement.scrollLeft; |
8361 | | - $.datepicker._pos[1] -= document.documentElement.scrollTop; |
8362 | | - } |
8363 | | - var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; |
8364 | | - $.datepicker._pos = null; |
8365 | | - inst.rangeStart = null; |
8366 | | - // determine sizing offscreen |
8367 | | - inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); |
8368 | | - $.datepicker._updateDatepicker(inst); |
8369 | | - // fix width for dynamic number of date pickers |
8370 | | - // and adjust position before showing |
8371 | | - offset = $.datepicker._checkOffset(inst, offset, isFixed); |
8372 | | - inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? |
8373 | | - 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', |
8374 | | - left: offset.left + 'px', top: offset.top + 'px'}); |
8375 | | - if (!inst.inline) { |
8376 | | - var showAnim = $.datepicker._get(inst, 'showAnim') || 'show'; |
8377 | | - var duration = $.datepicker._get(inst, 'duration'); |
8378 | | - var postProcess = function() { |
8379 | | - $.datepicker._datepickerShowing = true; |
8380 | | - if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems |
8381 | | - $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4, |
8382 | | - height: inst.dpDiv.height() + 4}); |
8383 | | - }; |
8384 | | - if ($.effects && $.effects[showAnim]) |
8385 | | - inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); |
8386 | | - else |
8387 | | - inst.dpDiv[showAnim](duration, postProcess); |
8388 | | - if (duration == '') |
8389 | | - postProcess(); |
8390 | | - if (inst.input[0].type != 'hidden') |
8391 | | - inst.input[0].focus(); |
8392 | | - $.datepicker._curInst = inst; |
8393 | | - } |
8394 | | - }, |
8395 | | - |
8396 | | - /* Generate the date picker content. */ |
8397 | | - _updateDatepicker: function(inst) { |
8398 | | - var dims = {width: inst.dpDiv.width() + 4, |
8399 | | - height: inst.dpDiv.height() + 4}; |
8400 | | - var self = this; |
8401 | | - inst.dpDiv.empty().append(this._generateHTML(inst)) |
8402 | | - .find('iframe.ui-datepicker-cover'). |
8403 | | - css({width: dims.width, height: dims.height}) |
8404 | | - .end() |
8405 | | - .find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a') |
8406 | | - .bind('mouseout', function(){ |
8407 | | - $(this).removeClass('ui-state-hover'); |
8408 | | - if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); |
8409 | | - if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); |
8410 | | - }) |
8411 | | - .bind('mouseover', function(){ |
8412 | | - if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) { |
8413 | | - $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); |
8414 | | - $(this).addClass('ui-state-hover'); |
8415 | | - if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); |
8416 | | - if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); |
8417 | | - } |
8418 | | - }) |
8419 | | - .end() |
8420 | | - .find('.' + this._dayOverClass + ' a') |
8421 | | - .trigger('mouseover') |
8422 | | - .end(); |
8423 | | - var numMonths = this._getNumberOfMonths(inst); |
8424 | | - var cols = numMonths[1]; |
8425 | | - var width = 17; |
8426 | | - if (cols > 1) { |
8427 | | - inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); |
8428 | | - } else { |
8429 | | - inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); |
8430 | | - } |
8431 | | - inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + |
8432 | | - 'Class']('ui-datepicker-multi'); |
8433 | | - inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + |
8434 | | - 'Class']('ui-datepicker-rtl'); |
8435 | | - if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst) |
8436 | | - $(inst.input[0]).focus(); |
8437 | | - }, |
8438 | | - |
8439 | | - /* Check positioning to remain on screen. */ |
8440 | | - _checkOffset: function(inst, offset, isFixed) { |
8441 | | - var dpWidth = inst.dpDiv.outerWidth(); |
8442 | | - var dpHeight = inst.dpDiv.outerHeight(); |
8443 | | - var inputWidth = inst.input ? inst.input.outerWidth() : 0; |
8444 | | - var inputHeight = inst.input ? inst.input.outerHeight() : 0; |
8445 | | - var viewWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) + $(document).scrollLeft(); |
8446 | | - var viewHeight = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) + $(document).scrollTop(); |
8447 | | - |
8448 | | - offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); |
8449 | | - offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; |
8450 | | - offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; |
8451 | | - |
8452 | | - // now check if datepicker is showing outside window viewport - move to a better place if so. |
8453 | | - offset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0; |
8454 | | - offset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight*2 - viewHeight) : 0; |
8455 | | - |
8456 | | - return offset; |
8457 | | - }, |
8458 | | - |
8459 | | - /* Find an object's position on the screen. */ |
8460 | | - _findPos: function(obj) { |
8461 | | - while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) { |
8462 | | - obj = obj.nextSibling; |
8463 | | - } |
8464 | | - var position = $(obj).offset(); |
8465 | | - return [position.left, position.top]; |
8466 | | - }, |
8467 | | - |
8468 | | - /* Hide the date picker from view. |
8469 | | - @param input element - the input field attached to the date picker |
8470 | | - @param duration string - the duration over which to close the date picker */ |
8471 | | - _hideDatepicker: function(input, duration) { |
8472 | | - var inst = this._curInst; |
8473 | | - if (!inst || (input && inst != $.data(input, PROP_NAME))) |
8474 | | - return; |
8475 | | - if (inst.stayOpen) |
8476 | | - this._selectDate('#' + inst.id, this._formatDate(inst, |
8477 | | - inst.currentDay, inst.currentMonth, inst.currentYear)); |
8478 | | - inst.stayOpen = false; |
8479 | | - if (this._datepickerShowing) { |
8480 | | - duration = (duration != null ? duration : this._get(inst, 'duration')); |
8481 | | - var showAnim = this._get(inst, 'showAnim'); |
8482 | | - var postProcess = function() { |
8483 | | - $.datepicker._tidyDialog(inst); |
8484 | | - }; |
8485 | | - if (duration != '' && $.effects && $.effects[showAnim]) |
8486 | | - inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), |
8487 | | - duration, postProcess); |
8488 | | - else |
8489 | | - inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' : |
8490 | | - (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess); |
8491 | | - if (duration == '') |
8492 | | - this._tidyDialog(inst); |
8493 | | - var onClose = this._get(inst, 'onClose'); |
8494 | | - if (onClose) |
8495 | | - onClose.apply((inst.input ? inst.input[0] : null), |
8496 | | - [(inst.input ? inst.input.val() : ''), inst]); // trigger custom callback |
8497 | | - this._datepickerShowing = false; |
8498 | | - this._lastInput = null; |
8499 | | - if (this._inDialog) { |
8500 | | - this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); |
8501 | | - if ($.blockUI) { |
8502 | | - $.unblockUI(); |
8503 | | - $('body').append(this.dpDiv); |
8504 | | - } |
8505 | | - } |
8506 | | - this._inDialog = false; |
8507 | | - } |
8508 | | - this._curInst = null; |
8509 | | - }, |
8510 | | - |
8511 | | - /* Tidy up after a dialog display. */ |
8512 | | - _tidyDialog: function(inst) { |
8513 | | - inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); |
8514 | | - }, |
8515 | | - |
8516 | | - /* Close date picker if clicked elsewhere. */ |
8517 | | - _checkExternalClick: function(event) { |
8518 | | - if (!$.datepicker._curInst) |
8519 | | - return; |
8520 | | - var $target = $(event.target); |
8521 | | - if (($target.parents('#' + $.datepicker._mainDivId).length == 0) && |
8522 | | - !$target.hasClass($.datepicker.markerClassName) && |
8523 | | - !$target.hasClass($.datepicker._triggerClass) && |
8524 | | - $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) |
8525 | | - $.datepicker._hideDatepicker(null, ''); |
8526 | | - }, |
8527 | | - |
8528 | | - /* Adjust one of the date sub-fields. */ |
8529 | | - _adjustDate: function(id, offset, period) { |
8530 | | - var target = $(id); |
8531 | | - var inst = this._getInst(target[0]); |
8532 | | - if (this._isDisabledDatepicker(target[0])) { |
8533 | | - return; |
8534 | | - } |
8535 | | - this._adjustInstDate(inst, offset + |
8536 | | - (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning |
8537 | | - period); |
8538 | | - this._updateDatepicker(inst); |
8539 | | - }, |
8540 | | - |
8541 | | - /* Action for current link. */ |
8542 | | - _gotoToday: function(id) { |
8543 | | - var target = $(id); |
8544 | | - var inst = this._getInst(target[0]); |
8545 | | - if (this._get(inst, 'gotoCurrent') && inst.currentDay) { |
8546 | | - inst.selectedDay = inst.currentDay; |
8547 | | - inst.drawMonth = inst.selectedMonth = inst.currentMonth; |
8548 | | - inst.drawYear = inst.selectedYear = inst.currentYear; |
8549 | | - } |
8550 | | - else { |
8551 | | - var date = new Date(); |
8552 | | - inst.selectedDay = date.getDate(); |
8553 | | - inst.drawMonth = inst.selectedMonth = date.getMonth(); |
8554 | | - inst.drawYear = inst.selectedYear = date.getFullYear(); |
8555 | | - } |
8556 | | - this._notifyChange(inst); |
8557 | | - this._adjustDate(target); |
8558 | | - }, |
8559 | | - |
8560 | | - /* Action for selecting a new month/year. */ |
8561 | | - _selectMonthYear: function(id, select, period) { |
8562 | | - var target = $(id); |
8563 | | - var inst = this._getInst(target[0]); |
8564 | | - inst._selectingMonthYear = false; |
8565 | | - inst['selected' + (period == 'M' ? 'Month' : 'Year')] = |
8566 | | - inst['draw' + (period == 'M' ? 'Month' : 'Year')] = |
8567 | | - parseInt(select.options[select.selectedIndex].value,10); |
8568 | | - this._notifyChange(inst); |
8569 | | - this._adjustDate(target); |
8570 | | - }, |
8571 | | - |
8572 | | - /* Restore input focus after not changing month/year. */ |
8573 | | - _clickMonthYear: function(id) { |
8574 | | - var target = $(id); |
8575 | | - var inst = this._getInst(target[0]); |
8576 | | - if (inst.input && inst._selectingMonthYear && !$.browser.msie) |
8577 | | - inst.input[0].focus(); |
8578 | | - inst._selectingMonthYear = !inst._selectingMonthYear; |
8579 | | - }, |
8580 | | - |
8581 | | - /* Action for selecting a day. */ |
8582 | | - _selectDay: function(id, month, year, td) { |
8583 | | - var target = $(id); |
8584 | | - if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { |
8585 | | - return; |
8586 | | - } |
8587 | | - var inst = this._getInst(target[0]); |
8588 | | - inst.selectedDay = inst.currentDay = $('a', td).html(); |
8589 | | - inst.selectedMonth = inst.currentMonth = month; |
8590 | | - inst.selectedYear = inst.currentYear = year; |
8591 | | - if (inst.stayOpen) { |
8592 | | - inst.endDay = inst.endMonth = inst.endYear = null; |
8593 | | - } |
8594 | | - this._selectDate(id, this._formatDate(inst, |
8595 | | - inst.currentDay, inst.currentMonth, inst.currentYear)); |
8596 | | - if (inst.stayOpen) { |
8597 | | - inst.rangeStart = this._daylightSavingAdjust( |
8598 | | - new Date(inst.currentYear, inst.currentMonth, inst.currentDay)); |
8599 | | - this._updateDatepicker(inst); |
8600 | | - } |
8601 | | - }, |
8602 | | - |
8603 | | - /* Erase the input field and hide the date picker. */ |
8604 | | - _clearDate: function(id) { |
8605 | | - var target = $(id); |
8606 | | - var inst = this._getInst(target[0]); |
8607 | | - inst.stayOpen = false; |
8608 | | - inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null; |
8609 | | - this._selectDate(target, ''); |
8610 | | - }, |
8611 | | - |
8612 | | - /* Update the input field with the selected date. */ |
8613 | | - _selectDate: function(id, dateStr) { |
8614 | | - var target = $(id); |
8615 | | - var inst = this._getInst(target[0]); |
8616 | | - dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); |
8617 | | - if (inst.input) |
8618 | | - inst.input.val(dateStr); |
8619 | | - this._updateAlternate(inst); |
8620 | | - var onSelect = this._get(inst, 'onSelect'); |
8621 | | - if (onSelect) |
8622 | | - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback |
8623 | | - else if (inst.input) |
8624 | | - inst.input.trigger('change'); // fire the change event |
8625 | | - if (inst.inline) |
8626 | | - this._updateDatepicker(inst); |
8627 | | - else if (!inst.stayOpen) { |
8628 | | - this._hideDatepicker(null, this._get(inst, 'duration')); |
8629 | | - this._lastInput = inst.input[0]; |
8630 | | - if (typeof(inst.input[0]) != 'object') |
8631 | | - inst.input[0].focus(); // restore focus |
8632 | | - this._lastInput = null; |
8633 | | - } |
8634 | | - }, |
8635 | | - |
8636 | | - /* Update any alternate field to synchronise with the main field. */ |
8637 | | - _updateAlternate: function(inst) { |
8638 | | - var altField = this._get(inst, 'altField'); |
8639 | | - if (altField) { // update alternate field too |
8640 | | - var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); |
8641 | | - var date = this._getDate(inst); |
8642 | | - dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); |
8643 | | - $(altField).each(function() { $(this).val(dateStr); }); |
8644 | | - } |
8645 | | - }, |
8646 | | - |
8647 | | - /* Set as beforeShowDay function to prevent selection of weekends. |
8648 | | - @param date Date - the date to customise |
8649 | | - @return [boolean, string] - is this date selectable?, what is its CSS class? */ |
8650 | | - noWeekends: function(date) { |
8651 | | - var day = date.getDay(); |
8652 | | - return [(day > 0 && day < 6), '']; |
8653 | | - }, |
8654 | | - |
8655 | | - /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. |
8656 | | - @param date Date - the date to get the week for |
8657 | | - @return number - the number of the week within the year that contains this date */ |
8658 | | - iso8601Week: function(date) { |
8659 | | - var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()); |
8660 | | - var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan |
8661 | | - var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7 |
8662 | | - firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday |
8663 | | - if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary |
8664 | | - checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year |
8665 | | - return $.datepicker.iso8601Week(checkDate); |
8666 | | - } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year |
8667 | | - firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7; |
8668 | | - if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary |
8669 | | - return 1; |
8670 | | - } |
8671 | | - } |
8672 | | - return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date |
8673 | | - }, |
8674 | | - |
8675 | | - /* Parse a string value into a date object. |
8676 | | - See formatDate below for the possible formats. |
8677 | | - |
8678 | | - @param format string - the expected format of the date |
8679 | | - @param value string - the date in the above format |
8680 | | - @param settings Object - attributes include: |
8681 | | - shortYearCutoff number - the cutoff year for determining the century (optional) |
8682 | | - dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) |
8683 | | - dayNames string[7] - names of the days from Sunday (optional) |
8684 | | - monthNamesShort string[12] - abbreviated names of the months (optional) |
8685 | | - monthNames string[12] - names of the months (optional) |
8686 | | - @return Date - the extracted date value or null if value is blank */ |
8687 | | - parseDate: function (format, value, settings) { |
8688 | | - if (format == null || value == null) |
8689 | | - throw 'Invalid arguments'; |
8690 | | - value = (typeof value == 'object' ? value.toString() : value + ''); |
8691 | | - if (value == '') |
8692 | | - return null; |
8693 | | - var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; |
8694 | | - var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; |
8695 | | - var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; |
8696 | | - var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; |
8697 | | - var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; |
8698 | | - var year = -1; |
8699 | | - var month = -1; |
8700 | | - var day = -1; |
8701 | | - var doy = -1; |
8702 | | - var literal = false; |
8703 | | - // Check whether a format character is doubled |
8704 | | - var lookAhead = function(match) { |
8705 | | - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); |
8706 | | - if (matches) |
8707 | | - iFormat++; |
8708 | | - return matches; |
8709 | | - }; |
8710 | | - // Extract a number from the string value |
8711 | | - var getNumber = function(match) { |
8712 | | - lookAhead(match); |
8713 | | - var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2))); |
8714 | | - var size = origSize; |
8715 | | - var num = 0; |
8716 | | - while (size > 0 && iValue < value.length && |
8717 | | - value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') { |
8718 | | - num = num * 10 + parseInt(value.charAt(iValue++),10); |
8719 | | - size--; |
8720 | | - } |
8721 | | - if (size == origSize) |
8722 | | - throw 'Missing number at position ' + iValue; |
8723 | | - return num; |
8724 | | - }; |
8725 | | - // Extract a name from the string value and convert to an index |
8726 | | - var getName = function(match, shortNames, longNames) { |
8727 | | - var names = (lookAhead(match) ? longNames : shortNames); |
8728 | | - var size = 0; |
8729 | | - for (var j = 0; j < names.length; j++) |
8730 | | - size = Math.max(size, names[j].length); |
8731 | | - var name = ''; |
8732 | | - var iInit = iValue; |
8733 | | - while (size > 0 && iValue < value.length) { |
8734 | | - name += value.charAt(iValue++); |
8735 | | - for (var i = 0; i < names.length; i++) |
8736 | | - if (name == names[i]) |
8737 | | - return i + 1; |
8738 | | - size--; |
8739 | | - } |
8740 | | - throw 'Unknown name at position ' + iInit; |
8741 | | - }; |
8742 | | - // Confirm that a literal character matches the string value |
8743 | | - var checkLiteral = function() { |
8744 | | - if (value.charAt(iValue) != format.charAt(iFormat)) |
8745 | | - throw 'Unexpected literal at position ' + iValue; |
8746 | | - iValue++; |
8747 | | - }; |
8748 | | - var iValue = 0; |
8749 | | - for (var iFormat = 0; iFormat < format.length; iFormat++) { |
8750 | | - if (literal) |
8751 | | - if (format.charAt(iFormat) == "'" && !lookAhead("'")) |
8752 | | - literal = false; |
8753 | | - else |
8754 | | - checkLiteral(); |
8755 | | - else |
8756 | | - switch (format.charAt(iFormat)) { |
8757 | | - case 'd': |
8758 | | - day = getNumber('d'); |
8759 | | - break; |
8760 | | - case 'D': |
8761 | | - getName('D', dayNamesShort, dayNames); |
8762 | | - break; |
8763 | | - case 'o': |
8764 | | - doy = getNumber('o'); |
8765 | | - break; |
8766 | | - case 'm': |
8767 | | - month = getNumber('m'); |
8768 | | - break; |
8769 | | - case 'M': |
8770 | | - month = getName('M', monthNamesShort, monthNames); |
8771 | | - break; |
8772 | | - case 'y': |
8773 | | - year = getNumber('y'); |
8774 | | - break; |
8775 | | - case '@': |
8776 | | - var date = new Date(getNumber('@')); |
8777 | | - year = date.getFullYear(); |
8778 | | - month = date.getMonth() + 1; |
8779 | | - day = date.getDate(); |
8780 | | - break; |
8781 | | - case "'": |
8782 | | - if (lookAhead("'")) |
8783 | | - checkLiteral(); |
8784 | | - else |
8785 | | - literal = true; |
8786 | | - break; |
8787 | | - default: |
8788 | | - checkLiteral(); |
8789 | | - } |
8790 | | - } |
8791 | | - if (year == -1) |
8792 | | - year = new Date().getFullYear(); |
8793 | | - else if (year < 100) |
8794 | | - year += new Date().getFullYear() - new Date().getFullYear() % 100 + |
8795 | | - (year <= shortYearCutoff ? 0 : -100); |
8796 | | - if (doy > -1) { |
8797 | | - month = 1; |
8798 | | - day = doy; |
8799 | | - do { |
8800 | | - var dim = this._getDaysInMonth(year, month - 1); |
8801 | | - if (day <= dim) |
8802 | | - break; |
8803 | | - month++; |
8804 | | - day -= dim; |
8805 | | - } while (true); |
8806 | | - } |
8807 | | - var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); |
8808 | | - if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) |
8809 | | - throw 'Invalid date'; // E.g. 31/02/* |
8810 | | - return date; |
8811 | | - }, |
8812 | | - |
8813 | | - /* Standard date formats. */ |
8814 | | - ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) |
8815 | | - COOKIE: 'D, dd M yy', |
8816 | | - ISO_8601: 'yy-mm-dd', |
8817 | | - RFC_822: 'D, d M y', |
8818 | | - RFC_850: 'DD, dd-M-y', |
8819 | | - RFC_1036: 'D, d M y', |
8820 | | - RFC_1123: 'D, d M yy', |
8821 | | - RFC_2822: 'D, d M yy', |
8822 | | - RSS: 'D, d M y', // RFC 822 |
8823 | | - TIMESTAMP: '@', |
8824 | | - W3C: 'yy-mm-dd', // ISO 8601 |
8825 | | - |
8826 | | - /* Format a date object into a string value. |
8827 | | - The format can be combinations of the following: |
8828 | | - d - day of month (no leading zero) |
8829 | | - dd - day of month (two digit) |
8830 | | - o - day of year (no leading zeros) |
8831 | | - oo - day of year (three digit) |
8832 | | - D - day name short |
8833 | | - DD - day name long |
8834 | | - m - month of year (no leading zero) |
8835 | | - mm - month of year (two digit) |
8836 | | - M - month name short |
8837 | | - MM - month name long |
8838 | | - y - year (two digit) |
8839 | | - yy - year (four digit) |
8840 | | - @ - Unix timestamp (ms since 01/01/1970) |
8841 | | - '...' - literal text |
8842 | | - '' - single quote |
8843 | | - |
8844 | | - @param format string - the desired format of the date |
8845 | | - @param date Date - the date value to format |
8846 | | - @param settings Object - attributes include: |
8847 | | - dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) |
8848 | | - dayNames string[7] - names of the days from Sunday (optional) |
8849 | | - monthNamesShort string[12] - abbreviated names of the months (optional) |
8850 | | - monthNames string[12] - names of the months (optional) |
8851 | | - @return string - the date in the above format */ |
8852 | | - formatDate: function (format, date, settings) { |
8853 | | - if (!date) |
8854 | | - return ''; |
8855 | | - var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; |
8856 | | - var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; |
8857 | | - var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; |
8858 | | - var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; |
8859 | | - // Check whether a format character is doubled |
8860 | | - var lookAhead = function(match) { |
8861 | | - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); |
8862 | | - if (matches) |
8863 | | - iFormat++; |
8864 | | - return matches; |
8865 | | - }; |
8866 | | - // Format a number, with leading zero if necessary |
8867 | | - var formatNumber = function(match, value, len) { |
8868 | | - var num = '' + value; |
8869 | | - if (lookAhead(match)) |
8870 | | - while (num.length < len) |
8871 | | - num = '0' + num; |
8872 | | - return num; |
8873 | | - }; |
8874 | | - // Format a name, short or long as requested |
8875 | | - var formatName = function(match, value, shortNames, longNames) { |
8876 | | - return (lookAhead(match) ? longNames[value] : shortNames[value]); |
8877 | | - }; |
8878 | | - var output = ''; |
8879 | | - var literal = false; |
8880 | | - if (date) |
8881 | | - for (var iFormat = 0; iFormat < format.length; iFormat++) { |
8882 | | - if (literal) |
8883 | | - if (format.charAt(iFormat) == "'" && !lookAhead("'")) |
8884 | | - literal = false; |
8885 | | - else |
8886 | | - output += format.charAt(iFormat); |
8887 | | - else |
8888 | | - switch (format.charAt(iFormat)) { |
8889 | | - case 'd': |
8890 | | - output += formatNumber('d', date.getDate(), 2); |
8891 | | - break; |
8892 | | - case 'D': |
8893 | | - output += formatName('D', date.getDay(), dayNamesShort, dayNames); |
8894 | | - break; |
8895 | | - case 'o': |
8896 | | - var doy = date.getDate(); |
8897 | | - for (var m = date.getMonth() - 1; m >= 0; m--) |
8898 | | - doy += this._getDaysInMonth(date.getFullYear(), m); |
8899 | | - output += formatNumber('o', doy, 3); |
8900 | | - break; |
8901 | | - case 'm': |
8902 | | - output += formatNumber('m', date.getMonth() + 1, 2); |
8903 | | - break; |
8904 | | - case 'M': |
8905 | | - output += formatName('M', date.getMonth(), monthNamesShort, monthNames); |
8906 | | - break; |
8907 | | - case 'y': |
8908 | | - output += (lookAhead('y') ? date.getFullYear() : |
8909 | | - (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); |
8910 | | - break; |
8911 | | - case '@': |
8912 | | - output += date.getTime(); |
8913 | | - break; |
8914 | | - case "'": |
8915 | | - if (lookAhead("'")) |
8916 | | - output += "'"; |
8917 | | - else |
8918 | | - literal = true; |
8919 | | - break; |
8920 | | - default: |
8921 | | - output += format.charAt(iFormat); |
8922 | | - } |
8923 | | - } |
8924 | | - return output; |
8925 | | - }, |
8926 | | - |
8927 | | - /* Extract all possible characters from the date format. */ |
8928 | | - _possibleChars: function (format) { |
8929 | | - var chars = ''; |
8930 | | - var literal = false; |
8931 | | - for (var iFormat = 0; iFormat < format.length; iFormat++) |
8932 | | - if (literal) |
8933 | | - if (format.charAt(iFormat) == "'" && !lookAhead("'")) |
8934 | | - literal = false; |
8935 | | - else |
8936 | | - chars += format.charAt(iFormat); |
8937 | | - else |
8938 | | - switch (format.charAt(iFormat)) { |
8939 | | - case 'd': case 'm': case 'y': case '@': |
8940 | | - chars += '0123456789'; |
8941 | | - break; |
8942 | | - case 'D': case 'M': |
8943 | | - return null; // Accept anything |
8944 | | - case "'": |
8945 | | - if (lookAhead("'")) |
8946 | | - chars += "'"; |
8947 | | - else |
8948 | | - literal = true; |
8949 | | - break; |
8950 | | - default: |
8951 | | - chars += format.charAt(iFormat); |
8952 | | - } |
8953 | | - return chars; |
8954 | | - }, |
8955 | | - |
8956 | | - /* Get a setting value, defaulting if necessary. */ |
8957 | | - _get: function(inst, name) { |
8958 | | - return inst.settings[name] !== undefined ? |
8959 | | - inst.settings[name] : this._defaults[name]; |
8960 | | - }, |
8961 | | - |
8962 | | - /* Parse existing date and initialise date picker. */ |
8963 | | - _setDateFromField: function(inst) { |
8964 | | - var dateFormat = this._get(inst, 'dateFormat'); |
8965 | | - var dates = inst.input ? inst.input.val() : null; |
8966 | | - inst.endDay = inst.endMonth = inst.endYear = null; |
8967 | | - var date = defaultDate = this._getDefaultDate(inst); |
8968 | | - var settings = this._getFormatConfig(inst); |
8969 | | - try { |
8970 | | - date = this.parseDate(dateFormat, dates, settings) || defaultDate; |
8971 | | - } catch (event) { |
8972 | | - this.log(event); |
8973 | | - date = defaultDate; |
8974 | | - } |
8975 | | - inst.selectedDay = date.getDate(); |
8976 | | - inst.drawMonth = inst.selectedMonth = date.getMonth(); |
8977 | | - inst.drawYear = inst.selectedYear = date.getFullYear(); |
8978 | | - inst.currentDay = (dates ? date.getDate() : 0); |
8979 | | - inst.currentMonth = (dates ? date.getMonth() : 0); |
8980 | | - inst.currentYear = (dates ? date.getFullYear() : 0); |
8981 | | - this._adjustInstDate(inst); |
8982 | | - }, |
8983 | | - |
8984 | | - /* Retrieve the default date shown on opening. */ |
8985 | | - _getDefaultDate: function(inst) { |
8986 | | - var date = this._determineDate(this._get(inst, 'defaultDate'), new Date()); |
8987 | | - var minDate = this._getMinMaxDate(inst, 'min', true); |
8988 | | - var maxDate = this._getMinMaxDate(inst, 'max'); |
8989 | | - date = (minDate && date < minDate ? minDate : date); |
8990 | | - date = (maxDate && date > maxDate ? maxDate : date); |
8991 | | - return date; |
8992 | | - }, |
8993 | | - |
8994 | | - /* A date may be specified as an exact value or a relative one. */ |
8995 | | - _determineDate: function(date, defaultDate) { |
8996 | | - var offsetNumeric = function(offset) { |
8997 | | - var date = new Date(); |
8998 | | - date.setDate(date.getDate() + offset); |
8999 | | - return date; |
9000 | | - }; |
9001 | | - var offsetString = function(offset, getDaysInMonth) { |
9002 | | - var date = new Date(); |
9003 | | - var year = date.getFullYear(); |
9004 | | - var month = date.getMonth(); |
9005 | | - var day = date.getDate(); |
9006 | | - var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; |
9007 | | - var matches = pattern.exec(offset); |
9008 | | - while (matches) { |
9009 | | - switch (matches[2] || 'd') { |
9010 | | - case 'd' : case 'D' : |
9011 | | - day += parseInt(matches[1],10); break; |
9012 | | - case 'w' : case 'W' : |
9013 | | - day += parseInt(matches[1],10) * 7; break; |
9014 | | - case 'm' : case 'M' : |
9015 | | - month += parseInt(matches[1],10); |
9016 | | - day = Math.min(day, getDaysInMonth(year, month)); |
9017 | | - break; |
9018 | | - case 'y': case 'Y' : |
9019 | | - year += parseInt(matches[1],10); |
9020 | | - day = Math.min(day, getDaysInMonth(year, month)); |
9021 | | - break; |
9022 | | - } |
9023 | | - matches = pattern.exec(offset); |
9024 | | - } |
9025 | | - return new Date(year, month, day); |
9026 | | - }; |
9027 | | - date = (date == null ? defaultDate : |
9028 | | - (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) : |
9029 | | - (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date))); |
9030 | | - date = (date && date.toString() == 'Invalid Date' ? defaultDate : date); |
9031 | | - if (date) { |
9032 | | - date.setHours(0); |
9033 | | - date.setMinutes(0); |
9034 | | - date.setSeconds(0); |
9035 | | - date.setMilliseconds(0); |
9036 | | - } |
9037 | | - return this._daylightSavingAdjust(date); |
9038 | | - }, |
9039 | | - |
9040 | | - /* Handle switch to/from daylight saving. |
9041 | | - Hours may be non-zero on daylight saving cut-over: |
9042 | | - > 12 when midnight changeover, but then cannot generate |
9043 | | - midnight datetime, so jump to 1AM, otherwise reset. |
9044 | | - @param date (Date) the date to check |
9045 | | - @return (Date) the corrected date */ |
9046 | | - _daylightSavingAdjust: function(date) { |
9047 | | - if (!date) return null; |
9048 | | - date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); |
9049 | | - return date; |
9050 | | - }, |
9051 | | - |
9052 | | - /* Set the date(s) directly. */ |
9053 | | - _setDate: function(inst, date, endDate) { |
9054 | | - var clear = !(date); |
9055 | | - var origMonth = inst.selectedMonth; |
9056 | | - var origYear = inst.selectedYear; |
9057 | | - date = this._determineDate(date, new Date()); |
9058 | | - inst.selectedDay = inst.currentDay = date.getDate(); |
9059 | | - inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth(); |
9060 | | - inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear(); |
9061 | | - if (origMonth != inst.selectedMonth || origYear != inst.selectedYear) |
9062 | | - this._notifyChange(inst); |
9063 | | - this._adjustInstDate(inst); |
9064 | | - if (inst.input) { |
9065 | | - inst.input.val(clear ? '' : this._formatDate(inst)); |
9066 | | - } |
9067 | | - }, |
9068 | | - |
9069 | | - /* Retrieve the date(s) directly. */ |
9070 | | - _getDate: function(inst) { |
9071 | | - var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : |
9072 | | - this._daylightSavingAdjust(new Date( |
9073 | | - inst.currentYear, inst.currentMonth, inst.currentDay))); |
9074 | | - return startDate; |
9075 | | - }, |
9076 | | - |
9077 | | - /* Generate the HTML for the current state of the date picker. */ |
9078 | | - _generateHTML: function(inst) { |
9079 | | - var today = new Date(); |
9080 | | - today = this._daylightSavingAdjust( |
9081 | | - new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time |
9082 | | - var isRTL = this._get(inst, 'isRTL'); |
9083 | | - var showButtonPanel = this._get(inst, 'showButtonPanel'); |
9084 | | - var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); |
9085 | | - var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); |
9086 | | - var numMonths = this._getNumberOfMonths(inst); |
9087 | | - var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); |
9088 | | - var stepMonths = this._get(inst, 'stepMonths'); |
9089 | | - var stepBigMonths = this._get(inst, 'stepBigMonths'); |
9090 | | - var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); |
9091 | | - var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : |
9092 | | - new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); |
9093 | | - var minDate = this._getMinMaxDate(inst, 'min', true); |
9094 | | - var maxDate = this._getMinMaxDate(inst, 'max'); |
9095 | | - var drawMonth = inst.drawMonth - showCurrentAtPos; |
9096 | | - var drawYear = inst.drawYear; |
9097 | | - if (drawMonth < 0) { |
9098 | | - drawMonth += 12; |
9099 | | - drawYear--; |
9100 | | - } |
9101 | | - if (maxDate) { |
9102 | | - var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), |
9103 | | - maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate())); |
9104 | | - maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); |
9105 | | - while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { |
9106 | | - drawMonth--; |
9107 | | - if (drawMonth < 0) { |
9108 | | - drawMonth = 11; |
9109 | | - drawYear--; |
9110 | | - } |
9111 | | - } |
9112 | | - } |
9113 | | - inst.drawMonth = drawMonth; |
9114 | | - inst.drawYear = drawYear; |
9115 | | - var prevText = this._get(inst, 'prevText'); |
9116 | | - prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, |
9117 | | - this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), |
9118 | | - this._getFormatConfig(inst))); |
9119 | | - var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? |
9120 | | - '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' + |
9121 | | - ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : |
9122 | | - (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>')); |
9123 | | - var nextText = this._get(inst, 'nextText'); |
9124 | | - nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, |
9125 | | - this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), |
9126 | | - this._getFormatConfig(inst))); |
9127 | | - var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? |
9128 | | - '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' + |
9129 | | - ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : |
9130 | | - (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>')); |
9131 | | - var currentText = this._get(inst, 'currentText'); |
9132 | | - var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); |
9133 | | - currentText = (!navigationAsDateFormat ? currentText : |
9134 | | - this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); |
9135 | | - var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : ''); |
9136 | | - var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + |
9137 | | - (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' + |
9138 | | - '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; |
9139 | | - var firstDay = parseInt(this._get(inst, 'firstDay'),10); |
9140 | | - firstDay = (isNaN(firstDay) ? 0 : firstDay); |
9141 | | - var dayNames = this._get(inst, 'dayNames'); |
9142 | | - var dayNamesShort = this._get(inst, 'dayNamesShort'); |
9143 | | - var dayNamesMin = this._get(inst, 'dayNamesMin'); |
9144 | | - var monthNames = this._get(inst, 'monthNames'); |
9145 | | - var monthNamesShort = this._get(inst, 'monthNamesShort'); |
9146 | | - var beforeShowDay = this._get(inst, 'beforeShowDay'); |
9147 | | - var showOtherMonths = this._get(inst, 'showOtherMonths'); |
9148 | | - var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; |
9149 | | - var endDate = inst.endDay ? this._daylightSavingAdjust( |
9150 | | - new Date(inst.endYear, inst.endMonth, inst.endDay)) : currentDate; |
9151 | | - var defaultDate = this._getDefaultDate(inst); |
9152 | | - var html = ''; |
9153 | | - for (var row = 0; row < numMonths[0]; row++) { |
9154 | | - var group = ''; |
9155 | | - for (var col = 0; col < numMonths[1]; col++) { |
9156 | | - var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); |
9157 | | - var cornerClass = ' ui-corner-all'; |
9158 | | - var calender = ''; |
9159 | | - if (isMultiMonth) { |
9160 | | - calender += '<div class="ui-datepicker-group ui-datepicker-group-'; |
9161 | | - switch (col) { |
9162 | | - case 0: calender += 'first'; cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; |
9163 | | - case numMonths[1]-1: calender += 'last'; cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; |
9164 | | - default: calender += 'middle'; cornerClass = ''; break; |
9165 | | - } |
9166 | | - calender += '">'; |
9167 | | - } |
9168 | | - calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' + |
9169 | | - (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + |
9170 | | - (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + |
9171 | | - this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, |
9172 | | - selectedDate, row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers |
9173 | | - '</div><table class="ui-datepicker-calendar"><thead>' + |
9174 | | - '<tr>'; |
9175 | | - var thead = ''; |
9176 | | - for (var dow = 0; dow < 7; dow++) { // days of the week |
9177 | | - var day = (dow + firstDay) % 7; |
9178 | | - thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' + |
9179 | | - '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>'; |
9180 | | - } |
9181 | | - calender += thead + '</tr></thead><tbody>'; |
9182 | | - var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); |
9183 | | - if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) |
9184 | | - inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); |
9185 | | - var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; |
9186 | | - var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate |
9187 | | - var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); |
9188 | | - for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows |
9189 | | - calender += '<tr>'; |
9190 | | - var tbody = ''; |
9191 | | - for (var dow = 0; dow < 7; dow++) { // create date picker days |
9192 | | - var daySettings = (beforeShowDay ? |
9193 | | - beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); |
9194 | | - var otherMonth = (printDate.getMonth() != drawMonth); |
9195 | | - var unselectable = otherMonth || !daySettings[0] || |
9196 | | - (minDate && printDate < minDate) || (maxDate && printDate > maxDate); |
9197 | | - tbody += '<td class="' + |
9198 | | - ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends |
9199 | | - (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months |
9200 | | - ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key |
9201 | | - (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ? |
9202 | | - // or defaultDate is current printedDate and defaultDate is selectedDate |
9203 | | - ' ' + this._dayOverClass : '') + // highlight selected day |
9204 | | - (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days |
9205 | | - (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates |
9206 | | - (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range |
9207 | | - ' ' + this._currentClass : '') + // highlight selected day |
9208 | | - (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) |
9209 | | - ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title |
9210 | | - (unselectable ? '' : ' onclick="DP_jQuery.datepicker._selectDay(\'#' + |
9211 | | - inst.id + '\',' + drawMonth + ',' + drawYear + ', this);return false;"') + '>' + // actions |
9212 | | - (otherMonth ? (showOtherMonths ? printDate.getDate() : ' ') : // display for other months |
9213 | | - (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + |
9214 | | - (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + |
9215 | | - (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range |
9216 | | - ' ui-state-active' : '') + // highlight selected day |
9217 | | - '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display for this month |
9218 | | - printDate.setDate(printDate.getDate() + 1); |
9219 | | - printDate = this._daylightSavingAdjust(printDate); |
9220 | | - } |
9221 | | - calender += tbody + '</tr>'; |
9222 | | - } |
9223 | | - drawMonth++; |
9224 | | - if (drawMonth > 11) { |
9225 | | - drawMonth = 0; |
9226 | | - drawYear++; |
9227 | | - } |
9228 | | - calender += '</tbody></table>' + (isMultiMonth ? '</div>' + |
9229 | | - ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : ''); |
9230 | | - group += calender; |
9231 | | - } |
9232 | | - html += group; |
9233 | | - } |
9234 | | - html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ? |
9235 | | - '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : ''); |
9236 | | - inst._keyEvent = false; |
9237 | | - return html; |
9238 | | - }, |
9239 | | - |
9240 | | - /* Generate the month and year header. */ |
9241 | | - _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, |
9242 | | - selectedDate, secondary, monthNames, monthNamesShort) { |
9243 | | - minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate); |
9244 | | - var changeMonth = this._get(inst, 'changeMonth'); |
9245 | | - var changeYear = this._get(inst, 'changeYear'); |
9246 | | - var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); |
9247 | | - var html = '<div class="ui-datepicker-title">'; |
9248 | | - var monthHtml = ''; |
9249 | | - // month selection |
9250 | | - if (secondary || !changeMonth) |
9251 | | - monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span> '; |
9252 | | - else { |
9253 | | - var inMinYear = (minDate && minDate.getFullYear() == drawYear); |
9254 | | - var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); |
9255 | | - monthHtml += '<select class="ui-datepicker-month" ' + |
9256 | | - 'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' + |
9257 | | - 'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + |
9258 | | - '>'; |
9259 | | - for (var month = 0; month < 12; month++) { |
9260 | | - if ((!inMinYear || month >= minDate.getMonth()) && |
9261 | | - (!inMaxYear || month <= maxDate.getMonth())) |
9262 | | - monthHtml += '<option value="' + month + '"' + |
9263 | | - (month == drawMonth ? ' selected="selected"' : '') + |
9264 | | - '>' + monthNamesShort[month] + '</option>'; |
9265 | | - } |
9266 | | - monthHtml += '</select>'; |
9267 | | - } |
9268 | | - if (!showMonthAfterYear) |
9269 | | - html += monthHtml + ((secondary || changeMonth || changeYear) && (!(changeMonth && changeYear)) ? ' ' : ''); |
9270 | | - // year selection |
9271 | | - if (secondary || !changeYear) |
9272 | | - html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; |
9273 | | - else { |
9274 | | - // determine range of years to display |
9275 | | - var years = this._get(inst, 'yearRange').split(':'); |
9276 | | - var year = 0; |
9277 | | - var endYear = 0; |
9278 | | - if (years.length != 2) { |
9279 | | - year = drawYear - 10; |
9280 | | - endYear = drawYear + 10; |
9281 | | - } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') { |
9282 | | - year = drawYear + parseInt(years[0], 10); |
9283 | | - endYear = drawYear + parseInt(years[1], 10); |
9284 | | - } else { |
9285 | | - year = parseInt(years[0], 10); |
9286 | | - endYear = parseInt(years[1], 10); |
9287 | | - } |
9288 | | - year = (minDate ? Math.max(year, minDate.getFullYear()) : year); |
9289 | | - endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); |
9290 | | - html += '<select class="ui-datepicker-year" ' + |
9291 | | - 'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' + |
9292 | | - 'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + |
9293 | | - '>'; |
9294 | | - for (; year <= endYear; year++) { |
9295 | | - html += '<option value="' + year + '"' + |
9296 | | - (year == drawYear ? ' selected="selected"' : '') + |
9297 | | - '>' + year + '</option>'; |
9298 | | - } |
9299 | | - html += '</select>'; |
9300 | | - } |
9301 | | - if (showMonthAfterYear) |
9302 | | - html += (secondary || changeMonth || changeYear ? ' ' : '') + monthHtml; |
9303 | | - html += '</div>'; // Close datepicker_header |
9304 | | - return html; |
9305 | | - }, |
9306 | | - |
9307 | | - /* Adjust one of the date sub-fields. */ |
9308 | | - _adjustInstDate: function(inst, offset, period) { |
9309 | | - var year = inst.drawYear + (period == 'Y' ? offset : 0); |
9310 | | - var month = inst.drawMonth + (period == 'M' ? offset : 0); |
9311 | | - var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + |
9312 | | - (period == 'D' ? offset : 0); |
9313 | | - var date = this._daylightSavingAdjust(new Date(year, month, day)); |
9314 | | - // ensure it is within the bounds set |
9315 | | - var minDate = this._getMinMaxDate(inst, 'min', true); |
9316 | | - var maxDate = this._getMinMaxDate(inst, 'max'); |
9317 | | - date = (minDate && date < minDate ? minDate : date); |
9318 | | - date = (maxDate && date > maxDate ? maxDate : date); |
9319 | | - inst.selectedDay = date.getDate(); |
9320 | | - inst.drawMonth = inst.selectedMonth = date.getMonth(); |
9321 | | - inst.drawYear = inst.selectedYear = date.getFullYear(); |
9322 | | - if (period == 'M' || period == 'Y') |
9323 | | - this._notifyChange(inst); |
9324 | | - }, |
9325 | | - |
9326 | | - /* Notify change of month/year. */ |
9327 | | - _notifyChange: function(inst) { |
9328 | | - var onChange = this._get(inst, 'onChangeMonthYear'); |
9329 | | - if (onChange) |
9330 | | - onChange.apply((inst.input ? inst.input[0] : null), |
9331 | | - [inst.selectedYear, inst.selectedMonth + 1, inst]); |
9332 | | - }, |
9333 | | - |
9334 | | - /* Determine the number of months to show. */ |
9335 | | - _getNumberOfMonths: function(inst) { |
9336 | | - var numMonths = this._get(inst, 'numberOfMonths'); |
9337 | | - return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); |
9338 | | - }, |
9339 | | - |
9340 | | - /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */ |
9341 | | - _getMinMaxDate: function(inst, minMax, checkRange) { |
9342 | | - var date = this._determineDate(this._get(inst, minMax + 'Date'), null); |
9343 | | - return (!checkRange || !inst.rangeStart ? date : |
9344 | | - (!date || inst.rangeStart > date ? inst.rangeStart : date)); |
9345 | | - }, |
9346 | | - |
9347 | | - /* Find the number of days in a given month. */ |
9348 | | - _getDaysInMonth: function(year, month) { |
9349 | | - return 32 - new Date(year, month, 32).getDate(); |
9350 | | - }, |
9351 | | - |
9352 | | - /* Find the day of the week of the first of a month. */ |
9353 | | - _getFirstDayOfMonth: function(year, month) { |
9354 | | - return new Date(year, month, 1).getDay(); |
9355 | | - }, |
9356 | | - |
9357 | | - /* Determines if we should allow a "next/prev" month display change. */ |
9358 | | - _canAdjustMonth: function(inst, offset, curYear, curMonth) { |
9359 | | - var numMonths = this._getNumberOfMonths(inst); |
9360 | | - var date = this._daylightSavingAdjust(new Date( |
9361 | | - curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1)); |
9362 | | - if (offset < 0) |
9363 | | - date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); |
9364 | | - return this._isInRange(inst, date); |
9365 | | - }, |
9366 | | - |
9367 | | - /* Is the given date in the accepted range? */ |
9368 | | - _isInRange: function(inst, date) { |
9369 | | - // during range selection, use minimum of selected date and range start |
9370 | | - var newMinDate = (!inst.rangeStart ? null : this._daylightSavingAdjust( |
9371 | | - new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay))); |
9372 | | - newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate); |
9373 | | - var minDate = newMinDate || this._getMinMaxDate(inst, 'min'); |
9374 | | - var maxDate = this._getMinMaxDate(inst, 'max'); |
9375 | | - return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate)); |
9376 | | - }, |
9377 | | - |
9378 | | - /* Provide the configuration settings for formatting/parsing. */ |
9379 | | - _getFormatConfig: function(inst) { |
9380 | | - var shortYearCutoff = this._get(inst, 'shortYearCutoff'); |
9381 | | - shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : |
9382 | | - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); |
9383 | | - return {shortYearCutoff: shortYearCutoff, |
9384 | | - dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), |
9385 | | - monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; |
9386 | | - }, |
9387 | | - |
9388 | | - /* Format the given date for display. */ |
9389 | | - _formatDate: function(inst, day, month, year) { |
9390 | | - if (!day) { |
9391 | | - inst.currentDay = inst.selectedDay; |
9392 | | - inst.currentMonth = inst.selectedMonth; |
9393 | | - inst.currentYear = inst.selectedYear; |
9394 | | - } |
9395 | | - var date = (day ? (typeof day == 'object' ? day : |
9396 | | - this._daylightSavingAdjust(new Date(year, month, day))) : |
9397 | | - this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); |
9398 | | - return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); |
9399 | | - } |
9400 | | -}); |
9401 | | - |
9402 | | -/* jQuery extend now ignores nulls! */ |
9403 | | -function extendRemove(target, props) { |
9404 | | - $.extend(target, props); |
9405 | | - for (var name in props) |
9406 | | - if (props[name] == null || props[name] == undefined) |
9407 | | - target[name] = props[name]; |
9408 | | - return target; |
9409 | | -}; |
9410 | | - |
9411 | | -/* Determine whether an object is an array. */ |
9412 | | -function isArray(a) { |
9413 | | - return (a && (($.browser.safari && typeof a == 'object' && a.length) || |
9414 | | - (a.constructor && a.constructor.toString().match(/\Array\(\)/)))); |
9415 | | -}; |
9416 | | - |
9417 | | -/* Invoke the datepicker functionality. |
9418 | | - @param options string - a command, optionally followed by additional parameters or |
9419 | | - Object - settings for attaching new datepicker functionality |
9420 | | - @return jQuery object */ |
9421 | | -$.fn.datepicker = function(options){ |
9422 | | - |
9423 | | - /* Initialise the date picker. */ |
9424 | | - if (!$.datepicker.initialized) { |
9425 | | - $(document).mousedown($.datepicker._checkExternalClick). |
9426 | | - find('body').append($.datepicker.dpDiv); |
9427 | | - $.datepicker.initialized = true; |
9428 | | - } |
9429 | | - |
9430 | | - var otherArgs = Array.prototype.slice.call(arguments, 1); |
9431 | | - if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate')) |
9432 | | - return $.datepicker['_' + options + 'Datepicker']. |
9433 | | - apply($.datepicker, [this[0]].concat(otherArgs)); |
9434 | | - if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') |
9435 | | - return $.datepicker['_' + options + 'Datepicker']. |
9436 | | - apply($.datepicker, [this[0]].concat(otherArgs)); |
9437 | | - return this.each(function() { |
9438 | | - typeof options == 'string' ? |
9439 | | - $.datepicker['_' + options + 'Datepicker']. |
9440 | | - apply($.datepicker, [this].concat(otherArgs)) : |
9441 | | - $.datepicker._attachDatepicker(this, options); |
9442 | | - }); |
9443 | | -}; |
9444 | | - |
9445 | | -$.datepicker = new Datepicker(); // singleton instance |
9446 | | -$.datepicker.initialized = false; |
9447 | | -$.datepicker.uuid = new Date().getTime(); |
9448 | | -$.datepicker.version = "1.7.2"; |
9449 | | - |
9450 | | -// Workaround for #4055 |
9451 | | -// Add another global to avoid noConflict issues with inline event handlers |
9452 | | -window.DP_jQuery = $; |
9453 | | - |
9454 | | -})(jQuery); |
9455 | 4379 | /* JavaScript for MediaWIki JS2 */ |
9456 | 4380 | |
9457 | 4381 | /** |
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | class UsabilityInitiativeHooks { |
11 | 11 | |
12 | 12 | /* Static Members */ |
13 | | - |
| 13 | + |
14 | 14 | private static $doOutput = false; |
15 | 15 | private static $messages = array(); |
16 | 16 | private static $variables = array(); |
— | — | @@ -62,6 +62,16 @@ |
63 | 63 | // Core functionality of extension |
64 | 64 | 'base_sets' => array( |
65 | 65 | 'raw' => array( |
| 66 | + |
| 67 | + // These scripts can be pulled from core once the js2 is merged |
| 68 | + array( 'src' => 'js/js2stopgap/ui.core.js', 'version' => 1 ), |
| 69 | + array( 'src' => 'js/js2stopgap/ui.datepicker.js', 'version' => 1 ), |
| 70 | + array( 'src' => 'js/js2stopgap/ui.dialog.js', 'version' => 1 ), |
| 71 | + array( 'src' => 'js/js2stopgap/ui.draggable.js', 'version' => 1 ), |
| 72 | + array( 'src' => 'js/js2stopgap/ui.resizable.js', 'version' => 1 ), |
| 73 | + array( 'src' => 'js/js2stopgap/ui.tabs.js', 'version' => 1 ), |
| 74 | + |
| 75 | + // Core functionality of extension scripts |
66 | 76 | array( 'src' => 'js/plugins/jquery.async.js', 'version' => 3 ), |
67 | 77 | array( 'src' => 'js/plugins/jquery.autoEllipsis.js', 'version' => 5 ), |
68 | 78 | array( 'src' => 'js/plugins/jquery.browser.js', 'version' => 3 ), |
— | — | @@ -82,20 +92,20 @@ |
83 | 93 | array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 1 ), |
84 | 94 | ), |
85 | 95 | 'combined' => array( |
86 | | - array( 'src' => 'js/plugins.combined.js', 'version' => 135 ), |
| 96 | + array( 'src' => 'js/plugins.combined.js', 'version' => 136 ), |
87 | 97 | ), |
88 | 98 | 'minified' => array( |
89 | | - array( 'src' => 'js/plugins.combined.min.js', 'version' => 135 ), |
| 99 | + array( 'src' => 'js/plugins.combined.min.js', 'version' => 136 ), |
90 | 100 | ), |
91 | 101 | ), |
92 | 102 | ); |
93 | | - |
| 103 | + |
94 | 104 | /* Static Functions */ |
95 | | - |
| 105 | + |
96 | 106 | public static function initialize() { |
97 | 107 | self::$doOutput = true; |
98 | 108 | } |
99 | | - |
| 109 | + |
100 | 110 | /** |
101 | 111 | * AjaxAddScript hook |
102 | 112 | * Adds scripts |
— | — | @@ -105,12 +115,12 @@ |
106 | 116 | global $wgUsabilityInitiativeResourceMode; |
107 | 117 | global $wgEnableJS2system, $wgEditToolbarRunTests; |
108 | 118 | global $wgStyleVersion; |
109 | | - |
| 119 | + |
110 | 120 | wfRunHooks( 'UsabilityInitiativeLoadModules' ); |
111 | | - |
| 121 | + |
112 | 122 | if ( !self::$doOutput ) |
113 | 123 | return true; |
114 | | - |
| 124 | + |
115 | 125 | // Default to raw |
116 | 126 | $mode = $wgUsabilityInitiativeResourceMode; // Just an alias |
117 | 127 | if ( !isset( self::$scriptFiles['base_sets'][$mode] ) ) { |
— | — | @@ -188,7 +198,7 @@ |
189 | 199 | } |
190 | 200 | return true; |
191 | 201 | } |
192 | | - |
| 202 | + |
193 | 203 | /** |
194 | 204 | * MakeGlobalVariablesScript hook |
195 | 205 | */ |
— | — | @@ -223,7 +233,7 @@ |
224 | 234 | public static function addMessages( $messages ) { |
225 | 235 | self::$messages = array_merge( self::$messages, $messages ); |
226 | 236 | } |
227 | | - |
| 237 | + |
228 | 238 | /** |
229 | 239 | * Adds variables that will be turned into global variables in JS |
230 | 240 | * @param $variables array of "name" => "value" |
— | — | @@ -231,7 +241,7 @@ |
232 | 242 | public static function addVariables( $variables ) { |
233 | 243 | self::$variables = array_merge( self::$variables, $variables ); |
234 | 244 | } |
235 | | - |
| 245 | + |
236 | 246 | /** |
237 | 247 | * Adds scripts for modules |
238 | 248 | * @param $scripts array with 'raw', 'combined' and 'minified' keys |
Index: trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.core.js |
— | — | @@ -0,0 +1,519 @@ |
| 2 | +/* |
| 3 | + * jQuery UI 1.7.1 |
| 4 | + * |
| 5 | + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
| 6 | + * Dual licensed under the MIT (MIT-LICENSE.txt) |
| 7 | + * and GPL (GPL-LICENSE.txt) licenses. |
| 8 | + * |
| 9 | + * http://docs.jquery.com/UI |
| 10 | + */ |
| 11 | +;jQuery.ui || (function($) { |
| 12 | + |
| 13 | +var _remove = $.fn.remove, |
| 14 | + isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9); |
| 15 | + |
| 16 | +//Helper functions and ui object |
| 17 | +$.ui = { |
| 18 | + version: "1.7.1", |
| 19 | + |
| 20 | + // $.ui.plugin is deprecated. Use the proxy pattern instead. |
| 21 | + plugin: { |
| 22 | + add: function(module, option, set) { |
| 23 | + var proto = $.ui[module].prototype; |
| 24 | + for(var i in set) { |
| 25 | + proto.plugins[i] = proto.plugins[i] || []; |
| 26 | + proto.plugins[i].push([option, set[i]]); |
| 27 | + } |
| 28 | + }, |
| 29 | + call: function(instance, name, args) { |
| 30 | + var set = instance.plugins[name]; |
| 31 | + if(!set || !instance.element[0].parentNode) { return; } |
| 32 | + |
| 33 | + for (var i = 0; i < set.length; i++) { |
| 34 | + if (instance.options[set[i][0]]) { |
| 35 | + set[i][1].apply(instance.element, args); |
| 36 | + } |
| 37 | + } |
| 38 | + } |
| 39 | + }, |
| 40 | + |
| 41 | + contains: function(a, b) { |
| 42 | + return document.compareDocumentPosition |
| 43 | + ? a.compareDocumentPosition(b) & 16 |
| 44 | + : a !== b && a.contains(b); |
| 45 | + }, |
| 46 | + |
| 47 | + hasScroll: function(el, a) { |
| 48 | + |
| 49 | + //If overflow is hidden, the element might have extra content, but the user wants to hide it |
| 50 | + if ($(el).css('overflow') == 'hidden') { return false; } |
| 51 | + |
| 52 | + var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop', |
| 53 | + has = false; |
| 54 | + |
| 55 | + if (el[scroll] > 0) { return true; } |
| 56 | + |
| 57 | + // TODO: determine which cases actually cause this to happen |
| 58 | + // if the element doesn't have the scroll set, see if it's possible to |
| 59 | + // set the scroll |
| 60 | + el[scroll] = 1; |
| 61 | + has = (el[scroll] > 0); |
| 62 | + el[scroll] = 0; |
| 63 | + return has; |
| 64 | + }, |
| 65 | + |
| 66 | + isOverAxis: function(x, reference, size) { |
| 67 | + //Determines when x coordinate is over "b" element axis |
| 68 | + return (x > reference) && (x < (reference + size)); |
| 69 | + }, |
| 70 | + |
| 71 | + isOver: function(y, x, top, left, height, width) { |
| 72 | + //Determines when x, y coordinates is over "b" element |
| 73 | + return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width); |
| 74 | + }, |
| 75 | + |
| 76 | + keyCode: { |
| 77 | + BACKSPACE: 8, |
| 78 | + CAPS_LOCK: 20, |
| 79 | + COMMA: 188, |
| 80 | + CONTROL: 17, |
| 81 | + DELETE: 46, |
| 82 | + DOWN: 40, |
| 83 | + END: 35, |
| 84 | + ENTER: 13, |
| 85 | + ESCAPE: 27, |
| 86 | + HOME: 36, |
| 87 | + INSERT: 45, |
| 88 | + LEFT: 37, |
| 89 | + NUMPAD_ADD: 107, |
| 90 | + NUMPAD_DECIMAL: 110, |
| 91 | + NUMPAD_DIVIDE: 111, |
| 92 | + NUMPAD_ENTER: 108, |
| 93 | + NUMPAD_MULTIPLY: 106, |
| 94 | + NUMPAD_SUBTRACT: 109, |
| 95 | + PAGE_DOWN: 34, |
| 96 | + PAGE_UP: 33, |
| 97 | + PERIOD: 190, |
| 98 | + RIGHT: 39, |
| 99 | + SHIFT: 16, |
| 100 | + SPACE: 32, |
| 101 | + TAB: 9, |
| 102 | + UP: 38 |
| 103 | + } |
| 104 | +}; |
| 105 | + |
| 106 | +// WAI-ARIA normalization |
| 107 | +if (isFF2) { |
| 108 | + var attr = $.attr, |
| 109 | + removeAttr = $.fn.removeAttr, |
| 110 | + ariaNS = "http://www.w3.org/2005/07/aaa", |
| 111 | + ariaState = /^aria-/, |
| 112 | + ariaRole = /^wairole:/; |
| 113 | + |
| 114 | + $.attr = function(elem, name, value) { |
| 115 | + var set = value !== undefined; |
| 116 | + |
| 117 | + return (name == 'role' |
| 118 | + ? (set |
| 119 | + ? attr.call(this, elem, name, "wairole:" + value) |
| 120 | + : (attr.apply(this, arguments) || "").replace(ariaRole, "")) |
| 121 | + : (ariaState.test(name) |
| 122 | + ? (set |
| 123 | + ? elem.setAttributeNS(ariaNS, |
| 124 | + name.replace(ariaState, "aaa:"), value) |
| 125 | + : attr.call(this, elem, name.replace(ariaState, "aaa:"))) |
| 126 | + : attr.apply(this, arguments))); |
| 127 | + }; |
| 128 | + |
| 129 | + $.fn.removeAttr = function(name) { |
| 130 | + return (ariaState.test(name) |
| 131 | + ? this.each(function() { |
| 132 | + this.removeAttributeNS(ariaNS, name.replace(ariaState, "")); |
| 133 | + }) : removeAttr.call(this, name)); |
| 134 | + }; |
| 135 | +} |
| 136 | + |
| 137 | +//jQuery plugins |
| 138 | +$.fn.extend({ |
| 139 | + remove: function() { |
| 140 | + // Safari has a native remove event which actually removes DOM elements, |
| 141 | + // so we have to use triggerHandler instead of trigger (#3037). |
| 142 | + $("*", this).add(this).each(function() { |
| 143 | + $(this).triggerHandler("remove"); |
| 144 | + }); |
| 145 | + return _remove.apply(this, arguments ); |
| 146 | + }, |
| 147 | + |
| 148 | + enableSelection: function() { |
| 149 | + return this |
| 150 | + .attr('unselectable', 'off') |
| 151 | + .css('MozUserSelect', '') |
| 152 | + .unbind('selectstart.ui'); |
| 153 | + }, |
| 154 | + |
| 155 | + disableSelection: function() { |
| 156 | + return this |
| 157 | + .attr('unselectable', 'on') |
| 158 | + .css('MozUserSelect', 'none') |
| 159 | + .bind('selectstart.ui', function() { return false; }); |
| 160 | + }, |
| 161 | + |
| 162 | + scrollParent: function() { |
| 163 | + var scrollParent; |
| 164 | + if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { |
| 165 | + scrollParent = this.parents().filter(function() { |
| 166 | + return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); |
| 167 | + }).eq(0); |
| 168 | + } else { |
| 169 | + scrollParent = this.parents().filter(function() { |
| 170 | + return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); |
| 171 | + }).eq(0); |
| 172 | + } |
| 173 | + |
| 174 | + return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; |
| 175 | + } |
| 176 | +}); |
| 177 | + |
| 178 | + |
| 179 | +//Additional selectors |
| 180 | +$.extend($.expr[':'], { |
| 181 | + data: function(elem, i, match) { |
| 182 | + return !!$.data(elem, match[3]); |
| 183 | + }, |
| 184 | + |
| 185 | + focusable: function(element) { |
| 186 | + var nodeName = element.nodeName.toLowerCase(), |
| 187 | + tabIndex = $.attr(element, 'tabindex'); |
| 188 | + return (/input|select|textarea|button|object/.test(nodeName) |
| 189 | + ? !element.disabled |
| 190 | + : 'a' == nodeName || 'area' == nodeName |
| 191 | + ? element.href || !isNaN(tabIndex) |
| 192 | + : !isNaN(tabIndex)) |
| 193 | + // the element and all of its ancestors must be visible |
| 194 | + // the browser may report that the area is hidden |
| 195 | + && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length; |
| 196 | + }, |
| 197 | + |
| 198 | + tabbable: function(element) { |
| 199 | + var tabIndex = $.attr(element, 'tabindex'); |
| 200 | + return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable'); |
| 201 | + } |
| 202 | +}); |
| 203 | + |
| 204 | + |
| 205 | +// $.widget is a factory to create jQuery plugins |
| 206 | +// taking some boilerplate code out of the plugin code |
| 207 | +function getter(namespace, plugin, method, args) { |
| 208 | + function getMethods(type) { |
| 209 | + var methods = $[namespace][plugin][type] || []; |
| 210 | + return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods); |
| 211 | + } |
| 212 | + |
| 213 | + var methods = getMethods('getter'); |
| 214 | + if (args.length == 1 && typeof args[0] == 'string') { |
| 215 | + methods = methods.concat(getMethods('getterSetter')); |
| 216 | + } |
| 217 | + return ($.inArray(method, methods) != -1); |
| 218 | +} |
| 219 | + |
| 220 | +$.widget = function(name, prototype) { |
| 221 | + var namespace = name.split(".")[0]; |
| 222 | + name = name.split(".")[1]; |
| 223 | + |
| 224 | + // create plugin method |
| 225 | + $.fn[name] = function(options) { |
| 226 | + var isMethodCall = (typeof options == 'string'), |
| 227 | + args = Array.prototype.slice.call(arguments, 1); |
| 228 | + |
| 229 | + // prevent calls to internal methods |
| 230 | + if (isMethodCall && options.substring(0, 1) == '_') { |
| 231 | + return this; |
| 232 | + } |
| 233 | + |
| 234 | + // handle getter methods |
| 235 | + if (isMethodCall && getter(namespace, name, options, args)) { |
| 236 | + var instance = $.data(this[0], name); |
| 237 | + return (instance ? instance[options].apply(instance, args) |
| 238 | + : undefined); |
| 239 | + } |
| 240 | + |
| 241 | + // handle initialization and non-getter methods |
| 242 | + return this.each(function() { |
| 243 | + var instance = $.data(this, name); |
| 244 | + |
| 245 | + // constructor |
| 246 | + (!instance && !isMethodCall && |
| 247 | + $.data(this, name, new $[namespace][name](this, options))._init()); |
| 248 | + |
| 249 | + // method call |
| 250 | + (instance && isMethodCall && $.isFunction(instance[options]) && |
| 251 | + instance[options].apply(instance, args)); |
| 252 | + }); |
| 253 | + }; |
| 254 | + |
| 255 | + // create widget constructor |
| 256 | + $[namespace] = $[namespace] || {}; |
| 257 | + $[namespace][name] = function(element, options) { |
| 258 | + var self = this; |
| 259 | + |
| 260 | + this.namespace = namespace; |
| 261 | + this.widgetName = name; |
| 262 | + this.widgetEventPrefix = $[namespace][name].eventPrefix || name; |
| 263 | + this.widgetBaseClass = namespace + '-' + name; |
| 264 | + |
| 265 | + this.options = $.extend({}, |
| 266 | + $.widget.defaults, |
| 267 | + $[namespace][name].defaults, |
| 268 | + $.metadata && $.metadata.get(element)[name], |
| 269 | + options); |
| 270 | + |
| 271 | + this.element = $(element) |
| 272 | + .bind('setData.' + name, function(event, key, value) { |
| 273 | + if (event.target == element) { |
| 274 | + return self._setData(key, value); |
| 275 | + } |
| 276 | + }) |
| 277 | + .bind('getData.' + name, function(event, key) { |
| 278 | + if (event.target == element) { |
| 279 | + return self._getData(key); |
| 280 | + } |
| 281 | + }) |
| 282 | + .bind('remove', function() { |
| 283 | + return self.destroy(); |
| 284 | + }); |
| 285 | + }; |
| 286 | + |
| 287 | + // add widget prototype |
| 288 | + $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype); |
| 289 | + |
| 290 | + // TODO: merge getter and getterSetter properties from widget prototype |
| 291 | + // and plugin prototype |
| 292 | + $[namespace][name].getterSetter = 'option'; |
| 293 | +}; |
| 294 | + |
| 295 | +$.widget.prototype = { |
| 296 | + _init: function() {}, |
| 297 | + destroy: function() { |
| 298 | + this.element.removeData(this.widgetName) |
| 299 | + .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled') |
| 300 | + .removeAttr('aria-disabled'); |
| 301 | + }, |
| 302 | + |
| 303 | + option: function(key, value) { |
| 304 | + var options = key, |
| 305 | + self = this; |
| 306 | + |
| 307 | + if (typeof key == "string") { |
| 308 | + if (value === undefined) { |
| 309 | + return this._getData(key); |
| 310 | + } |
| 311 | + options = {}; |
| 312 | + options[key] = value; |
| 313 | + } |
| 314 | + |
| 315 | + $.each(options, function(key, value) { |
| 316 | + self._setData(key, value); |
| 317 | + }); |
| 318 | + }, |
| 319 | + _getData: function(key) { |
| 320 | + return this.options[key]; |
| 321 | + }, |
| 322 | + _setData: function(key, value) { |
| 323 | + this.options[key] = value; |
| 324 | + |
| 325 | + if (key == 'disabled') { |
| 326 | + this.element |
| 327 | + [value ? 'addClass' : 'removeClass']( |
| 328 | + this.widgetBaseClass + '-disabled' + ' ' + |
| 329 | + this.namespace + '-state-disabled') |
| 330 | + .attr("aria-disabled", value); |
| 331 | + } |
| 332 | + }, |
| 333 | + |
| 334 | + enable: function() { |
| 335 | + this._setData('disabled', false); |
| 336 | + }, |
| 337 | + disable: function() { |
| 338 | + this._setData('disabled', true); |
| 339 | + }, |
| 340 | + |
| 341 | + _trigger: function(type, event, data) { |
| 342 | + var callback = this.options[type], |
| 343 | + eventName = (type == this.widgetEventPrefix |
| 344 | + ? type : this.widgetEventPrefix + type); |
| 345 | + |
| 346 | + event = $.Event(event); |
| 347 | + event.type = eventName; |
| 348 | + |
| 349 | + // copy original event properties over to the new event |
| 350 | + // this would happen if we could call $.event.fix instead of $.Event |
| 351 | + // but we don't have a way to force an event to be fixed multiple times |
| 352 | + if (event.originalEvent) { |
| 353 | + for (var i = $.event.props.length, prop; i;) { |
| 354 | + prop = $.event.props[--i]; |
| 355 | + event[prop] = event.originalEvent[prop]; |
| 356 | + } |
| 357 | + } |
| 358 | + |
| 359 | + this.element.trigger(event, data); |
| 360 | + |
| 361 | + return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false |
| 362 | + || event.isDefaultPrevented()); |
| 363 | + } |
| 364 | +}; |
| 365 | + |
| 366 | +$.widget.defaults = { |
| 367 | + disabled: false |
| 368 | +}; |
| 369 | + |
| 370 | + |
| 371 | +/** Mouse Interaction Plugin **/ |
| 372 | + |
| 373 | +$.ui.mouse = { |
| 374 | + _mouseInit: function() { |
| 375 | + var self = this; |
| 376 | + |
| 377 | + this.element |
| 378 | + .bind('mousedown.'+this.widgetName, function(event) { |
| 379 | + return self._mouseDown(event); |
| 380 | + }) |
| 381 | + .bind('click.'+this.widgetName, function(event) { |
| 382 | + if(self._preventClickEvent) { |
| 383 | + self._preventClickEvent = false; |
| 384 | + event.stopImmediatePropagation(); |
| 385 | + return false; |
| 386 | + } |
| 387 | + }); |
| 388 | + |
| 389 | + // Prevent text selection in IE |
| 390 | + if ($.browser.msie) { |
| 391 | + this._mouseUnselectable = this.element.attr('unselectable'); |
| 392 | + this.element.attr('unselectable', 'on'); |
| 393 | + } |
| 394 | + |
| 395 | + this.started = false; |
| 396 | + }, |
| 397 | + |
| 398 | + // TODO: make sure destroying one instance of mouse doesn't mess with |
| 399 | + // other instances of mouse |
| 400 | + _mouseDestroy: function() { |
| 401 | + this.element.unbind('.'+this.widgetName); |
| 402 | + |
| 403 | + // Restore text selection in IE |
| 404 | + ($.browser.msie |
| 405 | + && this.element.attr('unselectable', this._mouseUnselectable)); |
| 406 | + }, |
| 407 | + |
| 408 | + _mouseDown: function(event) { |
| 409 | + // don't let more than one widget handle mouseStart |
| 410 | + // TODO: figure out why we have to use originalEvent |
| 411 | + event.originalEvent = event.originalEvent || {}; |
| 412 | + if (event.originalEvent.mouseHandled) { return; } |
| 413 | + |
| 414 | + // we may have missed mouseup (out of window) |
| 415 | + (this._mouseStarted && this._mouseUp(event)); |
| 416 | + |
| 417 | + this._mouseDownEvent = event; |
| 418 | + |
| 419 | + var self = this, |
| 420 | + btnIsLeft = (event.which == 1), |
| 421 | + elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false); |
| 422 | + if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { |
| 423 | + return true; |
| 424 | + } |
| 425 | + |
| 426 | + this.mouseDelayMet = !this.options.delay; |
| 427 | + if (!this.mouseDelayMet) { |
| 428 | + this._mouseDelayTimer = setTimeout(function() { |
| 429 | + self.mouseDelayMet = true; |
| 430 | + }, this.options.delay); |
| 431 | + } |
| 432 | + |
| 433 | + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { |
| 434 | + this._mouseStarted = (this._mouseStart(event) !== false); |
| 435 | + if (!this._mouseStarted) { |
| 436 | + event.preventDefault(); |
| 437 | + return true; |
| 438 | + } |
| 439 | + } |
| 440 | + |
| 441 | + // these delegates are required to keep context |
| 442 | + this._mouseMoveDelegate = function(event) { |
| 443 | + return self._mouseMove(event); |
| 444 | + }; |
| 445 | + this._mouseUpDelegate = function(event) { |
| 446 | + return self._mouseUp(event); |
| 447 | + }; |
| 448 | + $(document) |
| 449 | + .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) |
| 450 | + .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); |
| 451 | + |
| 452 | + // preventDefault() is used to prevent the selection of text here - |
| 453 | + // however, in Safari, this causes select boxes not to be selectable |
| 454 | + // anymore, so this fix is needed |
| 455 | + ($.browser.safari || event.preventDefault()); |
| 456 | + |
| 457 | + event.originalEvent.mouseHandled = true; |
| 458 | + return true; |
| 459 | + }, |
| 460 | + |
| 461 | + _mouseMove: function(event) { |
| 462 | + // IE mouseup check - mouseup happened when mouse was out of window |
| 463 | + if ($.browser.msie && !event.button) { |
| 464 | + return this._mouseUp(event); |
| 465 | + } |
| 466 | + |
| 467 | + if (this._mouseStarted) { |
| 468 | + this._mouseDrag(event); |
| 469 | + return event.preventDefault(); |
| 470 | + } |
| 471 | + |
| 472 | + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { |
| 473 | + this._mouseStarted = |
| 474 | + (this._mouseStart(this._mouseDownEvent, event) !== false); |
| 475 | + (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); |
| 476 | + } |
| 477 | + |
| 478 | + return !this._mouseStarted; |
| 479 | + }, |
| 480 | + |
| 481 | + _mouseUp: function(event) { |
| 482 | + $(document) |
| 483 | + .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) |
| 484 | + .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); |
| 485 | + |
| 486 | + if (this._mouseStarted) { |
| 487 | + this._mouseStarted = false; |
| 488 | + this._preventClickEvent = (event.target == this._mouseDownEvent.target); |
| 489 | + this._mouseStop(event); |
| 490 | + } |
| 491 | + |
| 492 | + return false; |
| 493 | + }, |
| 494 | + |
| 495 | + _mouseDistanceMet: function(event) { |
| 496 | + return (Math.max( |
| 497 | + Math.abs(this._mouseDownEvent.pageX - event.pageX), |
| 498 | + Math.abs(this._mouseDownEvent.pageY - event.pageY) |
| 499 | + ) >= this.options.distance |
| 500 | + ); |
| 501 | + }, |
| 502 | + |
| 503 | + _mouseDelayMet: function(event) { |
| 504 | + return this.mouseDelayMet; |
| 505 | + }, |
| 506 | + |
| 507 | + // These are placeholder methods, to be overriden by extending plugin |
| 508 | + _mouseStart: function(event) {}, |
| 509 | + _mouseDrag: function(event) {}, |
| 510 | + _mouseStop: function(event) {}, |
| 511 | + _mouseCapture: function(event) { return true; } |
| 512 | +}; |
| 513 | + |
| 514 | +$.ui.mouse.defaults = { |
| 515 | + cancel: null, |
| 516 | + distance: 1, |
| 517 | + delay: 0 |
| 518 | +}; |
| 519 | + |
| 520 | +})(jQuery); |
\ No newline at end of file |
Index: trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.draggable.js |
— | — | @@ -0,0 +1,766 @@ |
| 2 | +/* |
| 3 | + * jQuery UI Draggable 1.7.1 |
| 4 | + * |
| 5 | + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
| 6 | + * Dual licensed under the MIT (MIT-LICENSE.txt) |
| 7 | + * and GPL (GPL-LICENSE.txt) licenses. |
| 8 | + * |
| 9 | + * http://docs.jquery.com/UI/Draggables |
| 10 | + * |
| 11 | + * Depends: |
| 12 | + * ui.core.js |
| 13 | + */ |
| 14 | +(function($) { |
| 15 | + |
| 16 | +$.widget("ui.draggable", $.extend({}, $.ui.mouse, { |
| 17 | + |
| 18 | + _init: function() { |
| 19 | + |
| 20 | + if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) |
| 21 | + this.element[0].style.position = 'relative'; |
| 22 | + |
| 23 | + (this.options.addClasses && this.element.addClass("ui-draggable")); |
| 24 | + (this.options.disabled && this.element.addClass("ui-draggable-disabled")); |
| 25 | + |
| 26 | + this._mouseInit(); |
| 27 | + |
| 28 | + }, |
| 29 | + |
| 30 | + destroy: function() { |
| 31 | + if(!this.element.data('draggable')) return; |
| 32 | + this.element |
| 33 | + .removeData("draggable") |
| 34 | + .unbind(".draggable") |
| 35 | + .removeClass("ui-draggable" |
| 36 | + + " ui-draggable-dragging" |
| 37 | + + " ui-draggable-disabled"); |
| 38 | + this._mouseDestroy(); |
| 39 | + }, |
| 40 | + |
| 41 | + _mouseCapture: function(event) { |
| 42 | + |
| 43 | + var o = this.options; |
| 44 | + |
| 45 | + if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) |
| 46 | + return false; |
| 47 | + |
| 48 | + //Quit if we're not on a valid handle |
| 49 | + this.handle = this._getHandle(event); |
| 50 | + if (!this.handle) |
| 51 | + return false; |
| 52 | + |
| 53 | + return true; |
| 54 | + |
| 55 | + }, |
| 56 | + |
| 57 | + _mouseStart: function(event) { |
| 58 | + |
| 59 | + var o = this.options; |
| 60 | + |
| 61 | + //Create and append the visible helper |
| 62 | + this.helper = this._createHelper(event); |
| 63 | + |
| 64 | + //Cache the helper size |
| 65 | + this._cacheHelperProportions(); |
| 66 | + |
| 67 | + //If ddmanager is used for droppables, set the global draggable |
| 68 | + if($.ui.ddmanager) |
| 69 | + $.ui.ddmanager.current = this; |
| 70 | + |
| 71 | + /* |
| 72 | + * - Position generation - |
| 73 | + * This block generates everything position related - it's the core of draggables. |
| 74 | + */ |
| 75 | + |
| 76 | + //Cache the margins of the original element |
| 77 | + this._cacheMargins(); |
| 78 | + |
| 79 | + //Store the helper's css position |
| 80 | + this.cssPosition = this.helper.css("position"); |
| 81 | + this.scrollParent = this.helper.scrollParent(); |
| 82 | + |
| 83 | + //The element's absolute position on the page minus margins |
| 84 | + this.offset = this.element.offset(); |
| 85 | + this.offset = { |
| 86 | + top: this.offset.top - this.margins.top, |
| 87 | + left: this.offset.left - this.margins.left |
| 88 | + }; |
| 89 | + |
| 90 | + $.extend(this.offset, { |
| 91 | + click: { //Where the click happened, relative to the element |
| 92 | + left: event.pageX - this.offset.left, |
| 93 | + top: event.pageY - this.offset.top |
| 94 | + }, |
| 95 | + parent: this._getParentOffset(), |
| 96 | + relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper |
| 97 | + }); |
| 98 | + |
| 99 | + //Generate the original position |
| 100 | + this.originalPosition = this._generatePosition(event); |
| 101 | + this.originalPageX = event.pageX; |
| 102 | + this.originalPageY = event.pageY; |
| 103 | + |
| 104 | + //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied |
| 105 | + if(o.cursorAt) |
| 106 | + this._adjustOffsetFromHelper(o.cursorAt); |
| 107 | + |
| 108 | + //Set a containment if given in the options |
| 109 | + if(o.containment) |
| 110 | + this._setContainment(); |
| 111 | + |
| 112 | + //Call plugins and callbacks |
| 113 | + this._trigger("start", event); |
| 114 | + |
| 115 | + //Recache the helper size |
| 116 | + this._cacheHelperProportions(); |
| 117 | + |
| 118 | + //Prepare the droppable offsets |
| 119 | + if ($.ui.ddmanager && !o.dropBehaviour) |
| 120 | + $.ui.ddmanager.prepareOffsets(this, event); |
| 121 | + |
| 122 | + this.helper.addClass("ui-draggable-dragging"); |
| 123 | + this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position |
| 124 | + return true; |
| 125 | + }, |
| 126 | + |
| 127 | + _mouseDrag: function(event, noPropagation) { |
| 128 | + |
| 129 | + //Compute the helpers position |
| 130 | + this.position = this._generatePosition(event); |
| 131 | + this.positionAbs = this._convertPositionTo("absolute"); |
| 132 | + |
| 133 | + //Call plugins and callbacks and use the resulting position if something is returned |
| 134 | + if (!noPropagation) { |
| 135 | + var ui = this._uiHash(); |
| 136 | + this._trigger('drag', event, ui); |
| 137 | + this.position = ui.position; |
| 138 | + } |
| 139 | + |
| 140 | + if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; |
| 141 | + if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; |
| 142 | + if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); |
| 143 | + |
| 144 | + return false; |
| 145 | + }, |
| 146 | + |
| 147 | + _mouseStop: function(event) { |
| 148 | + |
| 149 | + //If we are using droppables, inform the manager about the drop |
| 150 | + var dropped = false; |
| 151 | + if ($.ui.ddmanager && !this.options.dropBehaviour) |
| 152 | + dropped = $.ui.ddmanager.drop(this, event); |
| 153 | + |
| 154 | + //if a drop comes from outside (a sortable) |
| 155 | + if(this.dropped) { |
| 156 | + dropped = this.dropped; |
| 157 | + this.dropped = false; |
| 158 | + } |
| 159 | + |
| 160 | + 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))) { |
| 161 | + var self = this; |
| 162 | + $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { |
| 163 | + self._trigger("stop", event); |
| 164 | + self._clear(); |
| 165 | + }); |
| 166 | + } else { |
| 167 | + this._trigger("stop", event); |
| 168 | + this._clear(); |
| 169 | + } |
| 170 | + |
| 171 | + return false; |
| 172 | + }, |
| 173 | + |
| 174 | + _getHandle: function(event) { |
| 175 | + |
| 176 | + var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; |
| 177 | + $(this.options.handle, this.element) |
| 178 | + .find("*") |
| 179 | + .andSelf() |
| 180 | + .each(function() { |
| 181 | + if(this == event.target) handle = true; |
| 182 | + }); |
| 183 | + |
| 184 | + return handle; |
| 185 | + |
| 186 | + }, |
| 187 | + |
| 188 | + _createHelper: function(event) { |
| 189 | + |
| 190 | + var o = this.options; |
| 191 | + var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element); |
| 192 | + |
| 193 | + if(!helper.parents('body').length) |
| 194 | + helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); |
| 195 | + |
| 196 | + if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) |
| 197 | + helper.css("position", "absolute"); |
| 198 | + |
| 199 | + return helper; |
| 200 | + |
| 201 | + }, |
| 202 | + |
| 203 | + _adjustOffsetFromHelper: function(obj) { |
| 204 | + if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left; |
| 205 | + if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; |
| 206 | + if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top; |
| 207 | + if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; |
| 208 | + }, |
| 209 | + |
| 210 | + _getParentOffset: function() { |
| 211 | + |
| 212 | + //Get the offsetParent and cache its position |
| 213 | + this.offsetParent = this.helper.offsetParent(); |
| 214 | + var po = this.offsetParent.offset(); |
| 215 | + |
| 216 | + // This is a special case where we need to modify a offset calculated on start, since the following happened: |
| 217 | + // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent |
| 218 | + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that |
| 219 | + // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag |
| 220 | + if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { |
| 221 | + po.left += this.scrollParent.scrollLeft(); |
| 222 | + po.top += this.scrollParent.scrollTop(); |
| 223 | + } |
| 224 | + |
| 225 | + if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information |
| 226 | + || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix |
| 227 | + po = { top: 0, left: 0 }; |
| 228 | + |
| 229 | + return { |
| 230 | + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), |
| 231 | + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) |
| 232 | + }; |
| 233 | + |
| 234 | + }, |
| 235 | + |
| 236 | + _getRelativeOffset: function() { |
| 237 | + |
| 238 | + if(this.cssPosition == "relative") { |
| 239 | + var p = this.element.position(); |
| 240 | + return { |
| 241 | + top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), |
| 242 | + left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() |
| 243 | + }; |
| 244 | + } else { |
| 245 | + return { top: 0, left: 0 }; |
| 246 | + } |
| 247 | + |
| 248 | + }, |
| 249 | + |
| 250 | + _cacheMargins: function() { |
| 251 | + this.margins = { |
| 252 | + left: (parseInt(this.element.css("marginLeft"),10) || 0), |
| 253 | + top: (parseInt(this.element.css("marginTop"),10) || 0) |
| 254 | + }; |
| 255 | + }, |
| 256 | + |
| 257 | + _cacheHelperProportions: function() { |
| 258 | + this.helperProportions = { |
| 259 | + width: this.helper.outerWidth(), |
| 260 | + height: this.helper.outerHeight() |
| 261 | + }; |
| 262 | + }, |
| 263 | + |
| 264 | + _setContainment: function() { |
| 265 | + |
| 266 | + var o = this.options; |
| 267 | + if(o.containment == 'parent') o.containment = this.helper[0].parentNode; |
| 268 | + if(o.containment == 'document' || o.containment == 'window') this.containment = [ |
| 269 | + 0 - this.offset.relative.left - this.offset.parent.left, |
| 270 | + 0 - this.offset.relative.top - this.offset.parent.top, |
| 271 | + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, |
| 272 | + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top |
| 273 | + ]; |
| 274 | + |
| 275 | + if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { |
| 276 | + var ce = $(o.containment)[0]; if(!ce) return; |
| 277 | + var co = $(o.containment).offset(); |
| 278 | + var over = ($(ce).css("overflow") != 'hidden'); |
| 279 | + |
| 280 | + this.containment = [ |
| 281 | + co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, |
| 282 | + co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, |
| 283 | + 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, |
| 284 | + 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 |
| 285 | + ]; |
| 286 | + } else if(o.containment.constructor == Array) { |
| 287 | + this.containment = o.containment; |
| 288 | + } |
| 289 | + |
| 290 | + }, |
| 291 | + |
| 292 | + _convertPositionTo: function(d, pos) { |
| 293 | + |
| 294 | + if(!pos) pos = this.position; |
| 295 | + var mod = d == "absolute" ? 1 : -1; |
| 296 | + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); |
| 297 | + |
| 298 | + return { |
| 299 | + top: ( |
| 300 | + pos.top // The absolute mouse position |
| 301 | + + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent |
| 302 | + + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) |
| 303 | + - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) |
| 304 | + ), |
| 305 | + left: ( |
| 306 | + pos.left // The absolute mouse position |
| 307 | + + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent |
| 308 | + + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) |
| 309 | + - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) |
| 310 | + ) |
| 311 | + }; |
| 312 | + |
| 313 | + }, |
| 314 | + |
| 315 | + _generatePosition: function(event) { |
| 316 | + |
| 317 | + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); |
| 318 | + |
| 319 | + // This is another very weird special case that only happens for relative elements: |
| 320 | + // 1. If the css position is relative |
| 321 | + // 2. and the scroll parent is the document or similar to the offset parent |
| 322 | + // we have to refresh the relative offset during the scroll so there are no jumps |
| 323 | + if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { |
| 324 | + this.offset.relative = this._getRelativeOffset(); |
| 325 | + } |
| 326 | + |
| 327 | + var pageX = event.pageX; |
| 328 | + var pageY = event.pageY; |
| 329 | + |
| 330 | + /* |
| 331 | + * - Position constraining - |
| 332 | + * Constrain the position to a mix of grid, containment. |
| 333 | + */ |
| 334 | + |
| 335 | + if(this.originalPosition) { //If we are not dragging yet, we won't check for options |
| 336 | + |
| 337 | + if(this.containment) { |
| 338 | + if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; |
| 339 | + if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; |
| 340 | + if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; |
| 341 | + if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; |
| 342 | + } |
| 343 | + |
| 344 | + if(o.grid) { |
| 345 | + var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; |
| 346 | + 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; |
| 347 | + |
| 348 | + var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; |
| 349 | + 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; |
| 350 | + } |
| 351 | + |
| 352 | + } |
| 353 | + |
| 354 | + return { |
| 355 | + top: ( |
| 356 | + pageY // The absolute mouse position |
| 357 | + - this.offset.click.top // Click offset (relative to the element) |
| 358 | + - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent |
| 359 | + - this.offset.parent.top // The offsetParent's offset without borders (offset + border) |
| 360 | + + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) |
| 361 | + ), |
| 362 | + left: ( |
| 363 | + pageX // The absolute mouse position |
| 364 | + - this.offset.click.left // Click offset (relative to the element) |
| 365 | + - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent |
| 366 | + - this.offset.parent.left // The offsetParent's offset without borders (offset + border) |
| 367 | + + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) |
| 368 | + ) |
| 369 | + }; |
| 370 | + |
| 371 | + }, |
| 372 | + |
| 373 | + _clear: function() { |
| 374 | + this.helper.removeClass("ui-draggable-dragging"); |
| 375 | + if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); |
| 376 | + //if($.ui.ddmanager) $.ui.ddmanager.current = null; |
| 377 | + this.helper = null; |
| 378 | + this.cancelHelperRemoval = false; |
| 379 | + }, |
| 380 | + |
| 381 | + // From now on bulk stuff - mainly helpers |
| 382 | + |
| 383 | + _trigger: function(type, event, ui) { |
| 384 | + ui = ui || this._uiHash(); |
| 385 | + $.ui.plugin.call(this, type, [event, ui]); |
| 386 | + if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins |
| 387 | + return $.widget.prototype._trigger.call(this, type, event, ui); |
| 388 | + }, |
| 389 | + |
| 390 | + plugins: {}, |
| 391 | + |
| 392 | + _uiHash: function(event) { |
| 393 | + return { |
| 394 | + helper: this.helper, |
| 395 | + position: this.position, |
| 396 | + absolutePosition: this.positionAbs, //deprecated |
| 397 | + offset: this.positionAbs |
| 398 | + }; |
| 399 | + } |
| 400 | + |
| 401 | +})); |
| 402 | + |
| 403 | +$.extend($.ui.draggable, { |
| 404 | + version: "1.7.1", |
| 405 | + eventPrefix: "drag", |
| 406 | + defaults: { |
| 407 | + addClasses: true, |
| 408 | + appendTo: "parent", |
| 409 | + axis: false, |
| 410 | + cancel: ":input,option", |
| 411 | + connectToSortable: false, |
| 412 | + containment: false, |
| 413 | + cursor: "auto", |
| 414 | + cursorAt: false, |
| 415 | + delay: 0, |
| 416 | + distance: 1, |
| 417 | + grid: false, |
| 418 | + handle: false, |
| 419 | + helper: "original", |
| 420 | + iframeFix: false, |
| 421 | + opacity: false, |
| 422 | + refreshPositions: false, |
| 423 | + revert: false, |
| 424 | + revertDuration: 500, |
| 425 | + scope: "default", |
| 426 | + scroll: true, |
| 427 | + scrollSensitivity: 20, |
| 428 | + scrollSpeed: 20, |
| 429 | + snap: false, |
| 430 | + snapMode: "both", |
| 431 | + snapTolerance: 20, |
| 432 | + stack: false, |
| 433 | + zIndex: false |
| 434 | + } |
| 435 | +}); |
| 436 | + |
| 437 | +$.ui.plugin.add("draggable", "connectToSortable", { |
| 438 | + start: function(event, ui) { |
| 439 | + |
| 440 | + var inst = $(this).data("draggable"), o = inst.options, |
| 441 | + uiSortable = $.extend({}, ui, { item: inst.element }); |
| 442 | + inst.sortables = []; |
| 443 | + $(o.connectToSortable).each(function() { |
| 444 | + var sortable = $.data(this, 'sortable'); |
| 445 | + if (sortable && !sortable.options.disabled) { |
| 446 | + inst.sortables.push({ |
| 447 | + instance: sortable, |
| 448 | + shouldRevert: sortable.options.revert |
| 449 | + }); |
| 450 | + sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache |
| 451 | + sortable._trigger("activate", event, uiSortable); |
| 452 | + } |
| 453 | + }); |
| 454 | + |
| 455 | + }, |
| 456 | + stop: function(event, ui) { |
| 457 | + |
| 458 | + //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper |
| 459 | + var inst = $(this).data("draggable"), |
| 460 | + uiSortable = $.extend({}, ui, { item: inst.element }); |
| 461 | + |
| 462 | + $.each(inst.sortables, function() { |
| 463 | + if(this.instance.isOver) { |
| 464 | + |
| 465 | + this.instance.isOver = 0; |
| 466 | + |
| 467 | + inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance |
| 468 | + this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) |
| 469 | + |
| 470 | + //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' |
| 471 | + if(this.shouldRevert) this.instance.options.revert = true; |
| 472 | + |
| 473 | + //Trigger the stop of the sortable |
| 474 | + this.instance._mouseStop(event); |
| 475 | + |
| 476 | + this.instance.options.helper = this.instance.options._helper; |
| 477 | + |
| 478 | + //If the helper has been the original item, restore properties in the sortable |
| 479 | + if(inst.options.helper == 'original') |
| 480 | + this.instance.currentItem.css({ top: 'auto', left: 'auto' }); |
| 481 | + |
| 482 | + } else { |
| 483 | + this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance |
| 484 | + this.instance._trigger("deactivate", event, uiSortable); |
| 485 | + } |
| 486 | + |
| 487 | + }); |
| 488 | + |
| 489 | + }, |
| 490 | + drag: function(event, ui) { |
| 491 | + |
| 492 | + var inst = $(this).data("draggable"), self = this; |
| 493 | + |
| 494 | + var checkPos = function(o) { |
| 495 | + var dyClick = this.offset.click.top, dxClick = this.offset.click.left; |
| 496 | + var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; |
| 497 | + var itemHeight = o.height, itemWidth = o.width; |
| 498 | + var itemTop = o.top, itemLeft = o.left; |
| 499 | + |
| 500 | + return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); |
| 501 | + }; |
| 502 | + |
| 503 | + $.each(inst.sortables, function(i) { |
| 504 | + |
| 505 | + //Copy over some variables to allow calling the sortable's native _intersectsWith |
| 506 | + this.instance.positionAbs = inst.positionAbs; |
| 507 | + this.instance.helperProportions = inst.helperProportions; |
| 508 | + this.instance.offset.click = inst.offset.click; |
| 509 | + |
| 510 | + if(this.instance._intersectsWith(this.instance.containerCache)) { |
| 511 | + |
| 512 | + //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once |
| 513 | + if(!this.instance.isOver) { |
| 514 | + |
| 515 | + this.instance.isOver = 1; |
| 516 | + //Now we fake the start of dragging for the sortable instance, |
| 517 | + //by cloning the list group item, appending it to the sortable and using it as inst.currentItem |
| 518 | + //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) |
| 519 | + this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true); |
| 520 | + this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it |
| 521 | + this.instance.options.helper = function() { return ui.helper[0]; }; |
| 522 | + |
| 523 | + event.target = this.instance.currentItem[0]; |
| 524 | + this.instance._mouseCapture(event, true); |
| 525 | + this.instance._mouseStart(event, true, true); |
| 526 | + |
| 527 | + //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes |
| 528 | + this.instance.offset.click.top = inst.offset.click.top; |
| 529 | + this.instance.offset.click.left = inst.offset.click.left; |
| 530 | + this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; |
| 531 | + this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; |
| 532 | + |
| 533 | + inst._trigger("toSortable", event); |
| 534 | + inst.dropped = this.instance.element; //draggable revert needs that |
| 535 | + //hack so receive/update callbacks work (mostly) |
| 536 | + inst.currentItem = inst.element; |
| 537 | + this.instance.fromOutside = inst; |
| 538 | + |
| 539 | + } |
| 540 | + |
| 541 | + //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 |
| 542 | + if(this.instance.currentItem) this.instance._mouseDrag(event); |
| 543 | + |
| 544 | + } else { |
| 545 | + |
| 546 | + //If it doesn't intersect with the sortable, and it intersected before, |
| 547 | + //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval |
| 548 | + if(this.instance.isOver) { |
| 549 | + |
| 550 | + this.instance.isOver = 0; |
| 551 | + this.instance.cancelHelperRemoval = true; |
| 552 | + |
| 553 | + //Prevent reverting on this forced stop |
| 554 | + this.instance.options.revert = false; |
| 555 | + |
| 556 | + // The out event needs to be triggered independently |
| 557 | + this.instance._trigger('out', event, this.instance._uiHash(this.instance)); |
| 558 | + |
| 559 | + this.instance._mouseStop(event, true); |
| 560 | + this.instance.options.helper = this.instance.options._helper; |
| 561 | + |
| 562 | + //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size |
| 563 | + this.instance.currentItem.remove(); |
| 564 | + if(this.instance.placeholder) this.instance.placeholder.remove(); |
| 565 | + |
| 566 | + inst._trigger("fromSortable", event); |
| 567 | + inst.dropped = false; //draggable revert needs that |
| 568 | + } |
| 569 | + |
| 570 | + }; |
| 571 | + |
| 572 | + }); |
| 573 | + |
| 574 | + } |
| 575 | +}); |
| 576 | + |
| 577 | +$.ui.plugin.add("draggable", "cursor", { |
| 578 | + start: function(event, ui) { |
| 579 | + var t = $('body'), o = $(this).data('draggable').options; |
| 580 | + if (t.css("cursor")) o._cursor = t.css("cursor"); |
| 581 | + t.css("cursor", o.cursor); |
| 582 | + }, |
| 583 | + stop: function(event, ui) { |
| 584 | + var o = $(this).data('draggable').options; |
| 585 | + if (o._cursor) $('body').css("cursor", o._cursor); |
| 586 | + } |
| 587 | +}); |
| 588 | + |
| 589 | +$.ui.plugin.add("draggable", "iframeFix", { |
| 590 | + start: function(event, ui) { |
| 591 | + var o = $(this).data('draggable').options; |
| 592 | + $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { |
| 593 | + $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>') |
| 594 | + .css({ |
| 595 | + width: this.offsetWidth+"px", height: this.offsetHeight+"px", |
| 596 | + position: "absolute", opacity: "0.001", zIndex: 1000 |
| 597 | + }) |
| 598 | + .css($(this).offset()) |
| 599 | + .appendTo("body"); |
| 600 | + }); |
| 601 | + }, |
| 602 | + stop: function(event, ui) { |
| 603 | + $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers |
| 604 | + } |
| 605 | +}); |
| 606 | + |
| 607 | +$.ui.plugin.add("draggable", "opacity", { |
| 608 | + start: function(event, ui) { |
| 609 | + var t = $(ui.helper), o = $(this).data('draggable').options; |
| 610 | + if(t.css("opacity")) o._opacity = t.css("opacity"); |
| 611 | + t.css('opacity', o.opacity); |
| 612 | + }, |
| 613 | + stop: function(event, ui) { |
| 614 | + var o = $(this).data('draggable').options; |
| 615 | + if(o._opacity) $(ui.helper).css('opacity', o._opacity); |
| 616 | + } |
| 617 | +}); |
| 618 | + |
| 619 | +$.ui.plugin.add("draggable", "scroll", { |
| 620 | + start: function(event, ui) { |
| 621 | + var i = $(this).data("draggable"); |
| 622 | + if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); |
| 623 | + }, |
| 624 | + drag: function(event, ui) { |
| 625 | + |
| 626 | + var i = $(this).data("draggable"), o = i.options, scrolled = false; |
| 627 | + |
| 628 | + if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { |
| 629 | + |
| 630 | + if(!o.axis || o.axis != 'x') { |
| 631 | + if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) |
| 632 | + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; |
| 633 | + else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) |
| 634 | + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; |
| 635 | + } |
| 636 | + |
| 637 | + if(!o.axis || o.axis != 'y') { |
| 638 | + if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) |
| 639 | + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; |
| 640 | + else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) |
| 641 | + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; |
| 642 | + } |
| 643 | + |
| 644 | + } else { |
| 645 | + |
| 646 | + if(!o.axis || o.axis != 'x') { |
| 647 | + if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) |
| 648 | + scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); |
| 649 | + else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) |
| 650 | + scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); |
| 651 | + } |
| 652 | + |
| 653 | + if(!o.axis || o.axis != 'y') { |
| 654 | + if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) |
| 655 | + scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); |
| 656 | + else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) |
| 657 | + scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); |
| 658 | + } |
| 659 | + |
| 660 | + } |
| 661 | + |
| 662 | + if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) |
| 663 | + $.ui.ddmanager.prepareOffsets(i, event); |
| 664 | + |
| 665 | + } |
| 666 | +}); |
| 667 | + |
| 668 | +$.ui.plugin.add("draggable", "snap", { |
| 669 | + start: function(event, ui) { |
| 670 | + |
| 671 | + var i = $(this).data("draggable"), o = i.options; |
| 672 | + i.snapElements = []; |
| 673 | + |
| 674 | + $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { |
| 675 | + var $t = $(this); var $o = $t.offset(); |
| 676 | + if(this != i.element[0]) i.snapElements.push({ |
| 677 | + item: this, |
| 678 | + width: $t.outerWidth(), height: $t.outerHeight(), |
| 679 | + top: $o.top, left: $o.left |
| 680 | + }); |
| 681 | + }); |
| 682 | + |
| 683 | + }, |
| 684 | + drag: function(event, ui) { |
| 685 | + |
| 686 | + var inst = $(this).data("draggable"), o = inst.options; |
| 687 | + var d = o.snapTolerance; |
| 688 | + |
| 689 | + var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, |
| 690 | + y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; |
| 691 | + |
| 692 | + for (var i = inst.snapElements.length - 1; i >= 0; i--){ |
| 693 | + |
| 694 | + var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, |
| 695 | + t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; |
| 696 | + |
| 697 | + //Yes, I know, this is insane ;) |
| 698 | + if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { |
| 699 | + if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); |
| 700 | + inst.snapElements[i].snapping = false; |
| 701 | + continue; |
| 702 | + } |
| 703 | + |
| 704 | + if(o.snapMode != 'inner') { |
| 705 | + var ts = Math.abs(t - y2) <= d; |
| 706 | + var bs = Math.abs(b - y1) <= d; |
| 707 | + var ls = Math.abs(l - x2) <= d; |
| 708 | + var rs = Math.abs(r - x1) <= d; |
| 709 | + if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; |
| 710 | + if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; |
| 711 | + if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; |
| 712 | + if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; |
| 713 | + } |
| 714 | + |
| 715 | + var first = (ts || bs || ls || rs); |
| 716 | + |
| 717 | + if(o.snapMode != 'outer') { |
| 718 | + var ts = Math.abs(t - y1) <= d; |
| 719 | + var bs = Math.abs(b - y2) <= d; |
| 720 | + var ls = Math.abs(l - x1) <= d; |
| 721 | + var rs = Math.abs(r - x2) <= d; |
| 722 | + if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; |
| 723 | + if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; |
| 724 | + if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; |
| 725 | + if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; |
| 726 | + } |
| 727 | + |
| 728 | + if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) |
| 729 | + (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); |
| 730 | + inst.snapElements[i].snapping = (ts || bs || ls || rs || first); |
| 731 | + |
| 732 | + }; |
| 733 | + |
| 734 | + } |
| 735 | +}); |
| 736 | + |
| 737 | +$.ui.plugin.add("draggable", "stack", { |
| 738 | + start: function(event, ui) { |
| 739 | + |
| 740 | + var o = $(this).data("draggable").options; |
| 741 | + |
| 742 | + var group = $.makeArray($(o.stack.group)).sort(function(a,b) { |
| 743 | + return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min); |
| 744 | + }); |
| 745 | + |
| 746 | + $(group).each(function(i) { |
| 747 | + this.style.zIndex = o.stack.min + i; |
| 748 | + }); |
| 749 | + |
| 750 | + this[0].style.zIndex = o.stack.min + group.length; |
| 751 | + |
| 752 | + } |
| 753 | +}); |
| 754 | + |
| 755 | +$.ui.plugin.add("draggable", "zIndex", { |
| 756 | + start: function(event, ui) { |
| 757 | + var t = $(ui.helper), o = $(this).data("draggable").options; |
| 758 | + if(t.css("zIndex")) o._zIndex = t.css("zIndex"); |
| 759 | + t.css('zIndex', o.zIndex); |
| 760 | + }, |
| 761 | + stop: function(event, ui) { |
| 762 | + var o = $(this).data("draggable").options; |
| 763 | + if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); |
| 764 | + } |
| 765 | +}); |
| 766 | + |
| 767 | +})(jQuery); |
Index: trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.tabs.js |
— | — | @@ -0,0 +1,685 @@ |
| 2 | +/* |
| 3 | + * jQuery UI Tabs 1.7.1 |
| 4 | + * |
| 5 | + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
| 6 | + * Dual licensed under the MIT (MIT-LICENSE.txt) |
| 7 | + * and GPL (GPL-LICENSE.txt) licenses. |
| 8 | + * |
| 9 | + * http://docs.jquery.com/UI/Tabs |
| 10 | + * |
| 11 | + * Depends: |
| 12 | + * ui.core.js |
| 13 | + */ |
| 14 | +(function($) { |
| 15 | + |
| 16 | +$.widget("ui.tabs", { |
| 17 | + |
| 18 | + _init: function() { |
| 19 | + if (this.options.deselectable !== undefined) { |
| 20 | + this.options.collapsible = this.options.deselectable; |
| 21 | + } |
| 22 | + this._tabify(true); |
| 23 | + }, |
| 24 | + |
| 25 | + _setData: function(key, value) { |
| 26 | + if (key == 'selected') { |
| 27 | + if (this.options.collapsible && value == this.options.selected) { |
| 28 | + return; |
| 29 | + } |
| 30 | + this.select(value); |
| 31 | + } |
| 32 | + else { |
| 33 | + this.options[key] = value; |
| 34 | + if (key == 'deselectable') { |
| 35 | + this.options.collapsible = value; |
| 36 | + } |
| 37 | + this._tabify(); |
| 38 | + } |
| 39 | + }, |
| 40 | + |
| 41 | + _tabId: function(a) { |
| 42 | + return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') || |
| 43 | + this.options.idPrefix + $.data(a); |
| 44 | + }, |
| 45 | + |
| 46 | + _sanitizeSelector: function(hash) { |
| 47 | + return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":" |
| 48 | + }, |
| 49 | + |
| 50 | + _cookie: function() { |
| 51 | + var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + $.data(this.list[0])); |
| 52 | + return $.cookie.apply(null, [cookie].concat($.makeArray(arguments))); |
| 53 | + }, |
| 54 | + |
| 55 | + _ui: function(tab, panel) { |
| 56 | + return { |
| 57 | + tab: tab, |
| 58 | + panel: panel, |
| 59 | + index: this.anchors.index(tab) |
| 60 | + }; |
| 61 | + }, |
| 62 | + |
| 63 | + _cleanup: function() { |
| 64 | + // restore all former loading tabs labels |
| 65 | + this.lis.filter('.ui-state-processing').removeClass('ui-state-processing') |
| 66 | + .find('span:data(label.tabs)') |
| 67 | + .each(function() { |
| 68 | + var el = $(this); |
| 69 | + el.html(el.data('label.tabs')).removeData('label.tabs'); |
| 70 | + }); |
| 71 | + }, |
| 72 | + |
| 73 | + _tabify: function(init) { |
| 74 | + |
| 75 | + this.list = this.element.children('ul:first'); |
| 76 | + this.lis = $('li:has(a[href])', this.list); |
| 77 | + this.anchors = this.lis.map(function() { return $('a', this)[0]; }); |
| 78 | + this.panels = $([]); |
| 79 | + |
| 80 | + var self = this, o = this.options; |
| 81 | + |
| 82 | + var fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash |
| 83 | + this.anchors.each(function(i, a) { |
| 84 | + var href = $(a).attr('href'); |
| 85 | + |
| 86 | + // For dynamically created HTML that contains a hash as href IE < 8 expands |
| 87 | + // such href to the full page url with hash and then misinterprets tab as ajax. |
| 88 | + // Same consideration applies for an added tab with a fragment identifier |
| 89 | + // since a[href=#fragment-identifier] does unexpectedly not match. |
| 90 | + // Thus normalize href attribute... |
| 91 | + var hrefBase = href.split('#')[0], baseEl; |
| 92 | + if (hrefBase && (hrefBase === location.toString().split('#')[0] || |
| 93 | + (baseEl = $('base')[0]) && hrefBase === baseEl.href)) { |
| 94 | + href = a.hash; |
| 95 | + a.href = href; |
| 96 | + } |
| 97 | + |
| 98 | + // inline tab |
| 99 | + if (fragmentId.test(href)) { |
| 100 | + self.panels = self.panels.add(self._sanitizeSelector(href)); |
| 101 | + } |
| 102 | + |
| 103 | + // remote tab |
| 104 | + else if (href != '#') { // prevent loading the page itself if href is just "#" |
| 105 | + $.data(a, 'href.tabs', href); // required for restore on destroy |
| 106 | + |
| 107 | + // TODO until #3808 is fixed strip fragment identifier from url |
| 108 | + // (IE fails to load from such url) |
| 109 | + $.data(a, 'load.tabs', href.replace(/#.*$/, '')); // mutable data |
| 110 | + |
| 111 | + var id = self._tabId(a); |
| 112 | + a.href = '#' + id; |
| 113 | + var $panel = $('#' + id); |
| 114 | + if (!$panel.length) { |
| 115 | + $panel = $(o.panelTemplate).attr('id', id).addClass('ui-tabs-panel ui-widget-content ui-corner-bottom') |
| 116 | + .insertAfter(self.panels[i - 1] || self.list); |
| 117 | + $panel.data('destroy.tabs', true); |
| 118 | + } |
| 119 | + self.panels = self.panels.add($panel); |
| 120 | + } |
| 121 | + |
| 122 | + // invalid tab href |
| 123 | + else { |
| 124 | + o.disabled.push(i); |
| 125 | + } |
| 126 | + }); |
| 127 | + |
| 128 | + // initialization from scratch |
| 129 | + if (init) { |
| 130 | + |
| 131 | + // attach necessary classes for styling |
| 132 | + this.element.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all'); |
| 133 | + this.list.addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all'); |
| 134 | + this.lis.addClass('ui-state-default ui-corner-top'); |
| 135 | + this.panels.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom'); |
| 136 | + |
| 137 | + // Selected tab |
| 138 | + // use "selected" option or try to retrieve: |
| 139 | + // 1. from fragment identifier in url |
| 140 | + // 2. from cookie |
| 141 | + // 3. from selected class attribute on <li> |
| 142 | + if (o.selected === undefined) { |
| 143 | + if (location.hash) { |
| 144 | + this.anchors.each(function(i, a) { |
| 145 | + if (a.hash == location.hash) { |
| 146 | + o.selected = i; |
| 147 | + return false; // break |
| 148 | + } |
| 149 | + }); |
| 150 | + } |
| 151 | + if (typeof o.selected != 'number' && o.cookie) { |
| 152 | + o.selected = parseInt(self._cookie(), 10); |
| 153 | + } |
| 154 | + if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) { |
| 155 | + o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected')); |
| 156 | + } |
| 157 | + o.selected = o.selected || 0; |
| 158 | + } |
| 159 | + else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release |
| 160 | + o.selected = -1; |
| 161 | + } |
| 162 | + |
| 163 | + // sanity check - default to first tab... |
| 164 | + o.selected = ((o.selected >= 0 && this.anchors[o.selected]) || o.selected < 0) ? o.selected : 0; |
| 165 | + |
| 166 | + // Take disabling tabs via class attribute from HTML |
| 167 | + // into account and update option properly. |
| 168 | + // A selected tab cannot become disabled. |
| 169 | + o.disabled = $.unique(o.disabled.concat( |
| 170 | + $.map(this.lis.filter('.ui-state-disabled'), |
| 171 | + function(n, i) { return self.lis.index(n); } ) |
| 172 | + )).sort(); |
| 173 | + |
| 174 | + if ($.inArray(o.selected, o.disabled) != -1) { |
| 175 | + o.disabled.splice($.inArray(o.selected, o.disabled), 1); |
| 176 | + } |
| 177 | + |
| 178 | + // highlight selected tab |
| 179 | + this.panels.addClass('ui-tabs-hide'); |
| 180 | + this.lis.removeClass('ui-tabs-selected ui-state-active'); |
| 181 | + if (o.selected >= 0 && this.anchors.length) { // check for length avoids error when initializing empty list |
| 182 | + this.panels.eq(o.selected).removeClass('ui-tabs-hide'); |
| 183 | + this.lis.eq(o.selected).addClass('ui-tabs-selected ui-state-active'); |
| 184 | + |
| 185 | + // seems to be expected behavior that the show callback is fired |
| 186 | + self.element.queue("tabs", function() { |
| 187 | + self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected])); |
| 188 | + }); |
| 189 | + |
| 190 | + this.load(o.selected); |
| 191 | + } |
| 192 | + |
| 193 | + // clean up to avoid memory leaks in certain versions of IE 6 |
| 194 | + $(window).bind('unload', function() { |
| 195 | + self.lis.add(self.anchors).unbind('.tabs'); |
| 196 | + self.lis = self.anchors = self.panels = null; |
| 197 | + }); |
| 198 | + |
| 199 | + } |
| 200 | + // update selected after add/remove |
| 201 | + else { |
| 202 | + o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected')); |
| 203 | + } |
| 204 | + |
| 205 | + // update collapsible |
| 206 | + this.element[o.collapsible ? 'addClass' : 'removeClass']('ui-tabs-collapsible'); |
| 207 | + |
| 208 | + // set or update cookie after init and add/remove respectively |
| 209 | + if (o.cookie) { |
| 210 | + this._cookie(o.selected, o.cookie); |
| 211 | + } |
| 212 | + |
| 213 | + // disable tabs |
| 214 | + for (var i = 0, li; (li = this.lis[i]); i++) { |
| 215 | + $(li)[$.inArray(i, o.disabled) != -1 && |
| 216 | + !$(li).hasClass('ui-tabs-selected') ? 'addClass' : 'removeClass']('ui-state-disabled'); |
| 217 | + } |
| 218 | + |
| 219 | + // reset cache if switching from cached to not cached |
| 220 | + if (o.cache === false) { |
| 221 | + this.anchors.removeData('cache.tabs'); |
| 222 | + } |
| 223 | + |
| 224 | + // remove all handlers before, tabify may run on existing tabs after add or option change |
| 225 | + this.lis.add(this.anchors).unbind('.tabs'); |
| 226 | + |
| 227 | + if (o.event != 'mouseover') { |
| 228 | + var addState = function(state, el) { |
| 229 | + if (el.is(':not(.ui-state-disabled)')) { |
| 230 | + el.addClass('ui-state-' + state); |
| 231 | + } |
| 232 | + }; |
| 233 | + var removeState = function(state, el) { |
| 234 | + el.removeClass('ui-state-' + state); |
| 235 | + }; |
| 236 | + this.lis.bind('mouseover.tabs', function() { |
| 237 | + addState('hover', $(this)); |
| 238 | + }); |
| 239 | + this.lis.bind('mouseout.tabs', function() { |
| 240 | + removeState('hover', $(this)); |
| 241 | + }); |
| 242 | + this.anchors.bind('focus.tabs', function() { |
| 243 | + addState('focus', $(this).closest('li')); |
| 244 | + }); |
| 245 | + this.anchors.bind('blur.tabs', function() { |
| 246 | + removeState('focus', $(this).closest('li')); |
| 247 | + }); |
| 248 | + } |
| 249 | + |
| 250 | + // set up animations |
| 251 | + var hideFx, showFx; |
| 252 | + if (o.fx) { |
| 253 | + if ($.isArray(o.fx)) { |
| 254 | + hideFx = o.fx[0]; |
| 255 | + showFx = o.fx[1]; |
| 256 | + } |
| 257 | + else { |
| 258 | + hideFx = showFx = o.fx; |
| 259 | + } |
| 260 | + } |
| 261 | + |
| 262 | + // Reset certain styles left over from animation |
| 263 | + // and prevent IE's ClearType bug... |
| 264 | + function resetStyle($el, fx) { |
| 265 | + $el.css({ display: '' }); |
| 266 | + if ($.browser.msie && fx.opacity) { |
| 267 | + $el[0].style.removeAttribute('filter'); |
| 268 | + } |
| 269 | + } |
| 270 | + |
| 271 | + // Show a tab... |
| 272 | + var showTab = showFx ? |
| 273 | + function(clicked, $show) { |
| 274 | + $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active'); |
| 275 | + $show.hide().removeClass('ui-tabs-hide') // avoid flicker that way |
| 276 | + .animate(showFx, showFx.duration || 'normal', function() { |
| 277 | + resetStyle($show, showFx); |
| 278 | + self._trigger('show', null, self._ui(clicked, $show[0])); |
| 279 | + }); |
| 280 | + } : |
| 281 | + function(clicked, $show) { |
| 282 | + $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active'); |
| 283 | + $show.removeClass('ui-tabs-hide'); |
| 284 | + self._trigger('show', null, self._ui(clicked, $show[0])); |
| 285 | + }; |
| 286 | + |
| 287 | + // Hide a tab, $show is optional... |
| 288 | + var hideTab = hideFx ? |
| 289 | + function(clicked, $hide) { |
| 290 | + $hide.animate(hideFx, hideFx.duration || 'normal', function() { |
| 291 | + self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default'); |
| 292 | + $hide.addClass('ui-tabs-hide'); |
| 293 | + resetStyle($hide, hideFx); |
| 294 | + self.element.dequeue("tabs"); |
| 295 | + }); |
| 296 | + } : |
| 297 | + function(clicked, $hide, $show) { |
| 298 | + self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default'); |
| 299 | + $hide.addClass('ui-tabs-hide'); |
| 300 | + self.element.dequeue("tabs"); |
| 301 | + }; |
| 302 | + |
| 303 | + // attach tab event handler, unbind to avoid duplicates from former tabifying... |
| 304 | + this.anchors.bind(o.event + '.tabs', function() { |
| 305 | + var el = this, $li = $(this).closest('li'), $hide = self.panels.filter(':not(.ui-tabs-hide)'), |
| 306 | + $show = $(self._sanitizeSelector(this.hash)); |
| 307 | + |
| 308 | + // If tab is already selected and not collapsible or tab disabled or |
| 309 | + // or is already loading or click callback returns false stop here. |
| 310 | + // Check if click handler returns false last so that it is not executed |
| 311 | + // for a disabled or loading tab! |
| 312 | + if (($li.hasClass('ui-tabs-selected') && !o.collapsible) || |
| 313 | + $li.hasClass('ui-state-disabled') || |
| 314 | + $li.hasClass('ui-state-processing') || |
| 315 | + self._trigger('select', null, self._ui(this, $show[0])) === false) { |
| 316 | + this.blur(); |
| 317 | + return false; |
| 318 | + } |
| 319 | + |
| 320 | + o.selected = self.anchors.index(this); |
| 321 | + |
| 322 | + self.abort(); |
| 323 | + |
| 324 | + // if tab may be closed |
| 325 | + if (o.collapsible) { |
| 326 | + if ($li.hasClass('ui-tabs-selected')) { |
| 327 | + o.selected = -1; |
| 328 | + |
| 329 | + if (o.cookie) { |
| 330 | + self._cookie(o.selected, o.cookie); |
| 331 | + } |
| 332 | + |
| 333 | + self.element.queue("tabs", function() { |
| 334 | + hideTab(el, $hide); |
| 335 | + }).dequeue("tabs"); |
| 336 | + |
| 337 | + this.blur(); |
| 338 | + return false; |
| 339 | + } |
| 340 | + else if (!$hide.length) { |
| 341 | + if (o.cookie) { |
| 342 | + self._cookie(o.selected, o.cookie); |
| 343 | + } |
| 344 | + |
| 345 | + self.element.queue("tabs", function() { |
| 346 | + showTab(el, $show); |
| 347 | + }); |
| 348 | + |
| 349 | + self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 |
| 350 | + |
| 351 | + this.blur(); |
| 352 | + return false; |
| 353 | + } |
| 354 | + } |
| 355 | + |
| 356 | + if (o.cookie) { |
| 357 | + self._cookie(o.selected, o.cookie); |
| 358 | + } |
| 359 | + |
| 360 | + // show new tab |
| 361 | + if ($show.length) { |
| 362 | + if ($hide.length) { |
| 363 | + self.element.queue("tabs", function() { |
| 364 | + hideTab(el, $hide); |
| 365 | + }); |
| 366 | + } |
| 367 | + self.element.queue("tabs", function() { |
| 368 | + showTab(el, $show); |
| 369 | + }); |
| 370 | + |
| 371 | + self.load(self.anchors.index(this)); |
| 372 | + } |
| 373 | + else { |
| 374 | + throw 'jQuery UI Tabs: Mismatching fragment identifier.'; |
| 375 | + } |
| 376 | + |
| 377 | + // Prevent IE from keeping other link focussed when using the back button |
| 378 | + // and remove dotted border from clicked link. This is controlled via CSS |
| 379 | + // in modern browsers; blur() removes focus from address bar in Firefox |
| 380 | + // which can become a usability and annoying problem with tabs('rotate'). |
| 381 | + if ($.browser.msie) { |
| 382 | + this.blur(); |
| 383 | + } |
| 384 | + |
| 385 | + }); |
| 386 | + |
| 387 | + // disable click in any case |
| 388 | + this.anchors.bind('click.tabs', function(){return false;}); |
| 389 | + |
| 390 | + }, |
| 391 | + |
| 392 | + destroy: function() { |
| 393 | + var o = this.options; |
| 394 | + |
| 395 | + this.abort(); |
| 396 | + |
| 397 | + this.element.unbind('.tabs') |
| 398 | + .removeClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible') |
| 399 | + .removeData('tabs'); |
| 400 | + |
| 401 | + this.list.removeClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all'); |
| 402 | + |
| 403 | + this.anchors.each(function() { |
| 404 | + var href = $.data(this, 'href.tabs'); |
| 405 | + if (href) { |
| 406 | + this.href = href; |
| 407 | + } |
| 408 | + var $this = $(this).unbind('.tabs'); |
| 409 | + $.each(['href', 'load', 'cache'], function(i, prefix) { |
| 410 | + $this.removeData(prefix + '.tabs'); |
| 411 | + }); |
| 412 | + }); |
| 413 | + |
| 414 | + this.lis.unbind('.tabs').add(this.panels).each(function() { |
| 415 | + if ($.data(this, 'destroy.tabs')) { |
| 416 | + $(this).remove(); |
| 417 | + } |
| 418 | + else { |
| 419 | + $(this).removeClass([ |
| 420 | + 'ui-state-default', |
| 421 | + 'ui-corner-top', |
| 422 | + 'ui-tabs-selected', |
| 423 | + 'ui-state-active', |
| 424 | + 'ui-state-hover', |
| 425 | + 'ui-state-focus', |
| 426 | + 'ui-state-disabled', |
| 427 | + 'ui-tabs-panel', |
| 428 | + 'ui-widget-content', |
| 429 | + 'ui-corner-bottom', |
| 430 | + 'ui-tabs-hide' |
| 431 | + ].join(' ')); |
| 432 | + } |
| 433 | + }); |
| 434 | + |
| 435 | + if (o.cookie) { |
| 436 | + this._cookie(null, o.cookie); |
| 437 | + } |
| 438 | + }, |
| 439 | + |
| 440 | + add: function(url, label, index) { |
| 441 | + if (index === undefined) { |
| 442 | + index = this.anchors.length; // append by default |
| 443 | + } |
| 444 | + |
| 445 | + var self = this, o = this.options, |
| 446 | + $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label)), |
| 447 | + id = !url.indexOf('#') ? url.replace('#', '') : this._tabId($('a', $li)[0]); |
| 448 | + |
| 449 | + $li.addClass('ui-state-default ui-corner-top').data('destroy.tabs', true); |
| 450 | + |
| 451 | + // try to find an existing element before creating a new one |
| 452 | + var $panel = $('#' + id); |
| 453 | + if (!$panel.length) { |
| 454 | + $panel = $(o.panelTemplate).attr('id', id).data('destroy.tabs', true); |
| 455 | + } |
| 456 | + $panel.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide'); |
| 457 | + |
| 458 | + if (index >= this.lis.length) { |
| 459 | + $li.appendTo(this.list); |
| 460 | + $panel.appendTo(this.list[0].parentNode); |
| 461 | + } |
| 462 | + else { |
| 463 | + $li.insertBefore(this.lis[index]); |
| 464 | + $panel.insertBefore(this.panels[index]); |
| 465 | + } |
| 466 | + |
| 467 | + o.disabled = $.map(o.disabled, |
| 468 | + function(n, i) { return n >= index ? ++n : n; }); |
| 469 | + |
| 470 | + this._tabify(); |
| 471 | + |
| 472 | + if (this.anchors.length == 1) { // after tabify |
| 473 | + $li.addClass('ui-tabs-selected ui-state-active'); |
| 474 | + $panel.removeClass('ui-tabs-hide'); |
| 475 | + this.element.queue("tabs", function() { |
| 476 | + self._trigger('show', null, self._ui(self.anchors[0], self.panels[0])); |
| 477 | + }); |
| 478 | + |
| 479 | + this.load(0); |
| 480 | + } |
| 481 | + |
| 482 | + // callback |
| 483 | + this._trigger('add', null, this._ui(this.anchors[index], this.panels[index])); |
| 484 | + }, |
| 485 | + |
| 486 | + remove: function(index) { |
| 487 | + var o = this.options, $li = this.lis.eq(index).remove(), |
| 488 | + $panel = this.panels.eq(index).remove(); |
| 489 | + |
| 490 | + // If selected tab was removed focus tab to the right or |
| 491 | + // in case the last tab was removed the tab to the left. |
| 492 | + if ($li.hasClass('ui-tabs-selected') && this.anchors.length > 1) { |
| 493 | + this.select(index + (index + 1 < this.anchors.length ? 1 : -1)); |
| 494 | + } |
| 495 | + |
| 496 | + o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }), |
| 497 | + function(n, i) { return n >= index ? --n : n; }); |
| 498 | + |
| 499 | + this._tabify(); |
| 500 | + |
| 501 | + // callback |
| 502 | + this._trigger('remove', null, this._ui($li.find('a')[0], $panel[0])); |
| 503 | + }, |
| 504 | + |
| 505 | + enable: function(index) { |
| 506 | + var o = this.options; |
| 507 | + if ($.inArray(index, o.disabled) == -1) { |
| 508 | + return; |
| 509 | + } |
| 510 | + |
| 511 | + this.lis.eq(index).removeClass('ui-state-disabled'); |
| 512 | + o.disabled = $.grep(o.disabled, function(n, i) { return n != index; }); |
| 513 | + |
| 514 | + // callback |
| 515 | + this._trigger('enable', null, this._ui(this.anchors[index], this.panels[index])); |
| 516 | + }, |
| 517 | + |
| 518 | + disable: function(index) { |
| 519 | + var self = this, o = this.options; |
| 520 | + if (index != o.selected) { // cannot disable already selected tab |
| 521 | + this.lis.eq(index).addClass('ui-state-disabled'); |
| 522 | + |
| 523 | + o.disabled.push(index); |
| 524 | + o.disabled.sort(); |
| 525 | + |
| 526 | + // callback |
| 527 | + this._trigger('disable', null, this._ui(this.anchors[index], this.panels[index])); |
| 528 | + } |
| 529 | + }, |
| 530 | + |
| 531 | + select: function(index) { |
| 532 | + if (typeof index == 'string') { |
| 533 | + index = this.anchors.index(this.anchors.filter('[href$=' + index + ']')); |
| 534 | + } |
| 535 | + else if (index === null) { // usage of null is deprecated, TODO remove in next release |
| 536 | + index = -1; |
| 537 | + } |
| 538 | + if (index == -1 && this.options.collapsible) { |
| 539 | + index = this.options.selected; |
| 540 | + } |
| 541 | + |
| 542 | + this.anchors.eq(index).trigger(this.options.event + '.tabs'); |
| 543 | + }, |
| 544 | + |
| 545 | + load: function(index) { |
| 546 | + var self = this, o = this.options, a = this.anchors.eq(index)[0], url = $.data(a, 'load.tabs'); |
| 547 | + |
| 548 | + this.abort(); |
| 549 | + |
| 550 | + // not remote or from cache |
| 551 | + if (!url || this.element.queue("tabs").length !== 0 && $.data(a, 'cache.tabs')) { |
| 552 | + this.element.dequeue("tabs"); |
| 553 | + return; |
| 554 | + } |
| 555 | + |
| 556 | + // load remote from here on |
| 557 | + this.lis.eq(index).addClass('ui-state-processing'); |
| 558 | + |
| 559 | + if (o.spinner) { |
| 560 | + var span = $('span', a); |
| 561 | + span.data('label.tabs', span.html()).html(o.spinner); |
| 562 | + } |
| 563 | + |
| 564 | + this.xhr = $.ajax($.extend({}, o.ajaxOptions, { |
| 565 | + url: url, |
| 566 | + success: function(r, s) { |
| 567 | + $(self._sanitizeSelector(a.hash)).html(r); |
| 568 | + |
| 569 | + // take care of tab labels |
| 570 | + self._cleanup(); |
| 571 | + |
| 572 | + if (o.cache) { |
| 573 | + $.data(a, 'cache.tabs', true); // if loaded once do not load them again |
| 574 | + } |
| 575 | + |
| 576 | + // callbacks |
| 577 | + self._trigger('load', null, self._ui(self.anchors[index], self.panels[index])); |
| 578 | + try { |
| 579 | + o.ajaxOptions.success(r, s); |
| 580 | + } |
| 581 | + catch (e) {} |
| 582 | + |
| 583 | + // last, so that load event is fired before show... |
| 584 | + self.element.dequeue("tabs"); |
| 585 | + } |
| 586 | + })); |
| 587 | + }, |
| 588 | + |
| 589 | + abort: function() { |
| 590 | + // stop possibly running animations |
| 591 | + this.element.queue([]); |
| 592 | + this.panels.stop(false, true); |
| 593 | + |
| 594 | + // terminate pending requests from other tabs |
| 595 | + if (this.xhr) { |
| 596 | + this.xhr.abort(); |
| 597 | + delete this.xhr; |
| 598 | + } |
| 599 | + |
| 600 | + // take care of tab labels |
| 601 | + this._cleanup(); |
| 602 | + |
| 603 | + }, |
| 604 | + |
| 605 | + url: function(index, url) { |
| 606 | + this.anchors.eq(index).removeData('cache.tabs').data('load.tabs', url); |
| 607 | + }, |
| 608 | + |
| 609 | + length: function() { |
| 610 | + return this.anchors.length; |
| 611 | + } |
| 612 | + |
| 613 | +}); |
| 614 | + |
| 615 | +$.extend($.ui.tabs, { |
| 616 | + version: '1.7.1', |
| 617 | + getter: 'length', |
| 618 | + defaults: { |
| 619 | + ajaxOptions: null, |
| 620 | + cache: false, |
| 621 | + cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } |
| 622 | + collapsible: false, |
| 623 | + disabled: [], |
| 624 | + event: 'click', |
| 625 | + fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } |
| 626 | + idPrefix: 'ui-tabs-', |
| 627 | + panelTemplate: '<div></div>', |
| 628 | + spinner: '<em>Loading…</em>', |
| 629 | + tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>' |
| 630 | + } |
| 631 | +}); |
| 632 | + |
| 633 | +/* |
| 634 | + * Tabs Extensions |
| 635 | + */ |
| 636 | + |
| 637 | +/* |
| 638 | + * Rotate |
| 639 | + */ |
| 640 | +$.extend($.ui.tabs.prototype, { |
| 641 | + rotation: null, |
| 642 | + rotate: function(ms, continuing) { |
| 643 | + |
| 644 | + var self = this, o = this.options; |
| 645 | + |
| 646 | + var rotate = self._rotate || (self._rotate = function(e) { |
| 647 | + clearTimeout(self.rotation); |
| 648 | + self.rotation = setTimeout(function() { |
| 649 | + var t = o.selected; |
| 650 | + self.select( ++t < self.anchors.length ? t : 0 ); |
| 651 | + }, ms); |
| 652 | + |
| 653 | + if (e) { |
| 654 | + e.stopPropagation(); |
| 655 | + } |
| 656 | + }); |
| 657 | + |
| 658 | + var stop = self._unrotate || (self._unrotate = !continuing ? |
| 659 | + function(e) { |
| 660 | + if (e.clientX) { // in case of a true click |
| 661 | + self.rotate(null); |
| 662 | + } |
| 663 | + } : |
| 664 | + function(e) { |
| 665 | + t = o.selected; |
| 666 | + rotate(); |
| 667 | + }); |
| 668 | + |
| 669 | + // start rotation |
| 670 | + if (ms) { |
| 671 | + this.element.bind('tabsshow', rotate); |
| 672 | + this.anchors.bind(o.event + '.tabs', stop); |
| 673 | + rotate(); |
| 674 | + } |
| 675 | + // stop rotation |
| 676 | + else { |
| 677 | + clearTimeout(self.rotation); |
| 678 | + this.element.unbind('tabsshow', rotate); |
| 679 | + this.anchors.unbind(o.event + '.tabs', stop); |
| 680 | + delete this._rotate; |
| 681 | + delete this._unrotate; |
| 682 | + } |
| 683 | + } |
| 684 | +}); |
| 685 | + |
| 686 | +})(jQuery); |
Index: trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.datepicker.js |
— | — | @@ -0,0 +1,1630 @@ |
| 2 | +/* |
| 3 | + * jQuery UI Datepicker 1.7.1 |
| 4 | + * |
| 5 | + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
| 6 | + * Dual licensed under the MIT (MIT-LICENSE.txt) |
| 7 | + * and GPL (GPL-LICENSE.txt) licenses. |
| 8 | + * |
| 9 | + * http://docs.jquery.com/UI/Datepicker |
| 10 | + * |
| 11 | + * Depends: |
| 12 | + * ui.core.js |
| 13 | + */ |
| 14 | + |
| 15 | +(function($) { // hide the namespace |
| 16 | + |
| 17 | +$.extend($.ui, { datepicker: { version: "1.7.1" } }); |
| 18 | + |
| 19 | +var PROP_NAME = 'datepicker'; |
| 20 | + |
| 21 | +/* Date picker manager. |
| 22 | + Use the singleton instance of this class, $.datepicker, to interact with the date picker. |
| 23 | + Settings for (groups of) date pickers are maintained in an instance object, |
| 24 | + allowing multiple different settings on the same page. */ |
| 25 | + |
| 26 | +function Datepicker() { |
| 27 | + this.debug = false; // Change this to true to start debugging |
| 28 | + this._curInst = null; // The current instance in use |
| 29 | + this._keyEvent = false; // If the last event was a key event |
| 30 | + this._disabledInputs = []; // List of date picker inputs that have been disabled |
| 31 | + this._datepickerShowing = false; // True if the popup picker is showing , false if not |
| 32 | + this._inDialog = false; // True if showing within a "dialog", false if not |
| 33 | + this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division |
| 34 | + this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class |
| 35 | + this._appendClass = 'ui-datepicker-append'; // The name of the append marker class |
| 36 | + this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class |
| 37 | + this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class |
| 38 | + this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class |
| 39 | + this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class |
| 40 | + this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class |
| 41 | + this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class |
| 42 | + this.regional = []; // Available regional settings, indexed by language code |
| 43 | + this.regional[''] = { // Default regional settings |
| 44 | + closeText: 'Done', // Display text for close link |
| 45 | + prevText: 'Prev', // Display text for previous month link |
| 46 | + nextText: 'Next', // Display text for next month link |
| 47 | + currentText: 'Today', // Display text for current month link |
| 48 | + monthNames: ['January','February','March','April','May','June', |
| 49 | + 'July','August','September','October','November','December'], // Names of months for drop-down and formatting |
| 50 | + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting |
| 51 | + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting |
| 52 | + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting |
| 53 | + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday |
| 54 | + dateFormat: 'mm/dd/yy', // See format options on parseDate |
| 55 | + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... |
| 56 | + isRTL: false // True if right-to-left language, false if left-to-right |
| 57 | + }; |
| 58 | + this._defaults = { // Global defaults for all the date picker instances |
| 59 | + showOn: 'focus', // 'focus' for popup on focus, |
| 60 | + // 'button' for trigger button, or 'both' for either |
| 61 | + showAnim: 'show', // Name of jQuery animation for popup |
| 62 | + showOptions: {}, // Options for enhanced animations |
| 63 | + defaultDate: null, // Used when field is blank: actual date, |
| 64 | + // +/-number for offset from today, null for today |
| 65 | + appendText: '', // Display text following the input box, e.g. showing the format |
| 66 | + buttonText: '...', // Text for trigger button |
| 67 | + buttonImage: '', // URL for trigger button image |
| 68 | + buttonImageOnly: false, // True if the image appears alone, false if it appears on a button |
| 69 | + hideIfNoPrevNext: false, // True to hide next/previous month links |
| 70 | + // if not applicable, false to just disable them |
| 71 | + navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links |
| 72 | + gotoCurrent: false, // True if today link goes back to current selection instead |
| 73 | + changeMonth: false, // True if month can be selected directly, false if only prev/next |
| 74 | + changeYear: false, // True if year can be selected directly, false if only prev/next |
| 75 | + showMonthAfterYear: false, // True if the year select precedes month, false for month then year |
| 76 | + yearRange: '-10:+10', // Range of years to display in drop-down, |
| 77 | + // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn) |
| 78 | + showOtherMonths: false, // True to show dates in other months, false to leave blank |
| 79 | + calculateWeek: this.iso8601Week, // How to calculate the week of the year, |
| 80 | + // takes a Date and returns the number of the week for it |
| 81 | + shortYearCutoff: '+10', // Short year values < this are in the current century, |
| 82 | + // > this are in the previous century, |
| 83 | + // string value starting with '+' for current year + value |
| 84 | + minDate: null, // The earliest selectable date, or null for no limit |
| 85 | + maxDate: null, // The latest selectable date, or null for no limit |
| 86 | + duration: 'normal', // Duration of display/closure |
| 87 | + beforeShowDay: null, // Function that takes a date and returns an array with |
| 88 | + // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', |
| 89 | + // [2] = cell title (optional), e.g. $.datepicker.noWeekends |
| 90 | + beforeShow: null, // Function that takes an input field and |
| 91 | + // returns a set of custom settings for the date picker |
| 92 | + onSelect: null, // Define a callback function when a date is selected |
| 93 | + onChangeMonthYear: null, // Define a callback function when the month or year is changed |
| 94 | + onClose: null, // Define a callback function when the datepicker is closed |
| 95 | + numberOfMonths: 1, // Number of months to show at a time |
| 96 | + showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) |
| 97 | + stepMonths: 1, // Number of months to step back/forward |
| 98 | + stepBigMonths: 12, // Number of months to step back/forward for the big links |
| 99 | + altField: '', // Selector for an alternate field to store selected dates into |
| 100 | + altFormat: '', // The date format to use for the alternate field |
| 101 | + constrainInput: true, // The input is constrained by the current date format |
| 102 | + showButtonPanel: false // True to show button panel, false to not show it |
| 103 | + }; |
| 104 | + $.extend(this._defaults, this.regional['']); |
| 105 | + this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>'); |
| 106 | +} |
| 107 | + |
| 108 | +$.extend(Datepicker.prototype, { |
| 109 | + /* Class name added to elements to indicate already configured with a date picker. */ |
| 110 | + markerClassName: 'hasDatepicker', |
| 111 | + |
| 112 | + /* Debug logging (if enabled). */ |
| 113 | + log: function () { |
| 114 | + if (this.debug) |
| 115 | + console.log.apply('', arguments); |
| 116 | + }, |
| 117 | + |
| 118 | + /* Override the default settings for all instances of the date picker. |
| 119 | + @param settings object - the new settings to use as defaults (anonymous object) |
| 120 | + @return the manager object */ |
| 121 | + setDefaults: function(settings) { |
| 122 | + extendRemove(this._defaults, settings || {}); |
| 123 | + return this; |
| 124 | + }, |
| 125 | + |
| 126 | + /* Attach the date picker to a jQuery selection. |
| 127 | + @param target element - the target input field or division or span |
| 128 | + @param settings object - the new settings to use for this date picker instance (anonymous) */ |
| 129 | + _attachDatepicker: function(target, settings) { |
| 130 | + // check for settings on the control itself - in namespace 'date:' |
| 131 | + var inlineSettings = null; |
| 132 | + for (var attrName in this._defaults) { |
| 133 | + var attrValue = target.getAttribute('date:' + attrName); |
| 134 | + if (attrValue) { |
| 135 | + inlineSettings = inlineSettings || {}; |
| 136 | + try { |
| 137 | + inlineSettings[attrName] = eval(attrValue); |
| 138 | + } catch (err) { |
| 139 | + inlineSettings[attrName] = attrValue; |
| 140 | + } |
| 141 | + } |
| 142 | + } |
| 143 | + var nodeName = target.nodeName.toLowerCase(); |
| 144 | + var inline = (nodeName == 'div' || nodeName == 'span'); |
| 145 | + if (!target.id) |
| 146 | + target.id = 'dp' + (++this.uuid); |
| 147 | + var inst = this._newInst($(target), inline); |
| 148 | + inst.settings = $.extend({}, settings || {}, inlineSettings || {}); |
| 149 | + if (nodeName == 'input') { |
| 150 | + this._connectDatepicker(target, inst); |
| 151 | + } else if (inline) { |
| 152 | + this._inlineDatepicker(target, inst); |
| 153 | + } |
| 154 | + }, |
| 155 | + |
| 156 | + /* Create a new instance object. */ |
| 157 | + _newInst: function(target, inline) { |
| 158 | + var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars |
| 159 | + return {id: id, input: target, // associated target |
| 160 | + selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection |
| 161 | + drawMonth: 0, drawYear: 0, // month being drawn |
| 162 | + inline: inline, // is datepicker inline or not |
| 163 | + dpDiv: (!inline ? this.dpDiv : // presentation div |
| 164 | + $('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}; |
| 165 | + }, |
| 166 | + |
| 167 | + /* Attach the date picker to an input field. */ |
| 168 | + _connectDatepicker: function(target, inst) { |
| 169 | + var input = $(target); |
| 170 | + inst.trigger = $([]); |
| 171 | + if (input.hasClass(this.markerClassName)) |
| 172 | + return; |
| 173 | + var appendText = this._get(inst, 'appendText'); |
| 174 | + var isRTL = this._get(inst, 'isRTL'); |
| 175 | + if (appendText) |
| 176 | + input[isRTL ? 'before' : 'after']('<span class="' + this._appendClass + '">' + appendText + '</span>'); |
| 177 | + var showOn = this._get(inst, 'showOn'); |
| 178 | + if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field |
| 179 | + input.focus(this._showDatepicker); |
| 180 | + if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked |
| 181 | + var buttonText = this._get(inst, 'buttonText'); |
| 182 | + var buttonImage = this._get(inst, 'buttonImage'); |
| 183 | + inst.trigger = $(this._get(inst, 'buttonImageOnly') ? |
| 184 | + $('<img/>').addClass(this._triggerClass). |
| 185 | + attr({ src: buttonImage, alt: buttonText, title: buttonText }) : |
| 186 | + $('<button type="button"></button>').addClass(this._triggerClass). |
| 187 | + html(buttonImage == '' ? buttonText : $('<img/>').attr( |
| 188 | + { src:buttonImage, alt:buttonText, title:buttonText }))); |
| 189 | + input[isRTL ? 'before' : 'after'](inst.trigger); |
| 190 | + inst.trigger.click(function() { |
| 191 | + if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target) |
| 192 | + $.datepicker._hideDatepicker(); |
| 193 | + else |
| 194 | + $.datepicker._showDatepicker(target); |
| 195 | + return false; |
| 196 | + }); |
| 197 | + } |
| 198 | + input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress). |
| 199 | + bind("setData.datepicker", function(event, key, value) { |
| 200 | + inst.settings[key] = value; |
| 201 | + }).bind("getData.datepicker", function(event, key) { |
| 202 | + return this._get(inst, key); |
| 203 | + }); |
| 204 | + $.data(target, PROP_NAME, inst); |
| 205 | + }, |
| 206 | + |
| 207 | + /* Attach an inline date picker to a div. */ |
| 208 | + _inlineDatepicker: function(target, inst) { |
| 209 | + var divSpan = $(target); |
| 210 | + if (divSpan.hasClass(this.markerClassName)) |
| 211 | + return; |
| 212 | + divSpan.addClass(this.markerClassName).append(inst.dpDiv). |
| 213 | + bind("setData.datepicker", function(event, key, value){ |
| 214 | + inst.settings[key] = value; |
| 215 | + }).bind("getData.datepicker", function(event, key){ |
| 216 | + return this._get(inst, key); |
| 217 | + }); |
| 218 | + $.data(target, PROP_NAME, inst); |
| 219 | + this._setDate(inst, this._getDefaultDate(inst)); |
| 220 | + this._updateDatepicker(inst); |
| 221 | + this._updateAlternate(inst); |
| 222 | + }, |
| 223 | + |
| 224 | + /* Pop-up the date picker in a "dialog" box. |
| 225 | + @param input element - ignored |
| 226 | + @param dateText string - the initial date to display (in the current format) |
| 227 | + @param onSelect function - the function(dateText) to call when a date is selected |
| 228 | + @param settings object - update the dialog date picker instance's settings (anonymous object) |
| 229 | + @param pos int[2] - coordinates for the dialog's position within the screen or |
| 230 | + event - with x/y coordinates or |
| 231 | + leave empty for default (screen centre) |
| 232 | + @return the manager object */ |
| 233 | + _dialogDatepicker: function(input, dateText, onSelect, settings, pos) { |
| 234 | + var inst = this._dialogInst; // internal instance |
| 235 | + if (!inst) { |
| 236 | + var id = 'dp' + (++this.uuid); |
| 237 | + this._dialogInput = $('<input type="text" id="' + id + |
| 238 | + '" size="1" style="position: absolute; top: -100px;"/>'); |
| 239 | + this._dialogInput.keydown(this._doKeyDown); |
| 240 | + $('body').append(this._dialogInput); |
| 241 | + inst = this._dialogInst = this._newInst(this._dialogInput, false); |
| 242 | + inst.settings = {}; |
| 243 | + $.data(this._dialogInput[0], PROP_NAME, inst); |
| 244 | + } |
| 245 | + extendRemove(inst.settings, settings || {}); |
| 246 | + this._dialogInput.val(dateText); |
| 247 | + |
| 248 | + this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); |
| 249 | + if (!this._pos) { |
| 250 | + var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; |
| 251 | + var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; |
| 252 | + var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; |
| 253 | + var scrollY = document.documentElement.scrollTop || document.body.scrollTop; |
| 254 | + this._pos = // should use actual width/height below |
| 255 | + [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; |
| 256 | + } |
| 257 | + |
| 258 | + // move input on screen for focus, but hidden behind dialog |
| 259 | + this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px'); |
| 260 | + inst.settings.onSelect = onSelect; |
| 261 | + this._inDialog = true; |
| 262 | + this.dpDiv.addClass(this._dialogClass); |
| 263 | + this._showDatepicker(this._dialogInput[0]); |
| 264 | + if ($.blockUI) |
| 265 | + $.blockUI(this.dpDiv); |
| 266 | + $.data(this._dialogInput[0], PROP_NAME, inst); |
| 267 | + return this; |
| 268 | + }, |
| 269 | + |
| 270 | + /* Detach a datepicker from its control. |
| 271 | + @param target element - the target input field or division or span */ |
| 272 | + _destroyDatepicker: function(target) { |
| 273 | + var $target = $(target); |
| 274 | + var inst = $.data(target, PROP_NAME); |
| 275 | + if (!$target.hasClass(this.markerClassName)) { |
| 276 | + return; |
| 277 | + } |
| 278 | + var nodeName = target.nodeName.toLowerCase(); |
| 279 | + $.removeData(target, PROP_NAME); |
| 280 | + if (nodeName == 'input') { |
| 281 | + inst.trigger.remove(); |
| 282 | + $target.siblings('.' + this._appendClass).remove().end(). |
| 283 | + removeClass(this.markerClassName). |
| 284 | + unbind('focus', this._showDatepicker). |
| 285 | + unbind('keydown', this._doKeyDown). |
| 286 | + unbind('keypress', this._doKeyPress); |
| 287 | + } else if (nodeName == 'div' || nodeName == 'span') |
| 288 | + $target.removeClass(this.markerClassName).empty(); |
| 289 | + }, |
| 290 | + |
| 291 | + /* Enable the date picker to a jQuery selection. |
| 292 | + @param target element - the target input field or division or span */ |
| 293 | + _enableDatepicker: function(target) { |
| 294 | + var $target = $(target); |
| 295 | + var inst = $.data(target, PROP_NAME); |
| 296 | + if (!$target.hasClass(this.markerClassName)) { |
| 297 | + return; |
| 298 | + } |
| 299 | + var nodeName = target.nodeName.toLowerCase(); |
| 300 | + if (nodeName == 'input') { |
| 301 | + target.disabled = false; |
| 302 | + inst.trigger.filter("button"). |
| 303 | + each(function() { this.disabled = false; }).end(). |
| 304 | + filter("img"). |
| 305 | + css({opacity: '1.0', cursor: ''}); |
| 306 | + } |
| 307 | + else if (nodeName == 'div' || nodeName == 'span') { |
| 308 | + var inline = $target.children('.' + this._inlineClass); |
| 309 | + inline.children().removeClass('ui-state-disabled'); |
| 310 | + } |
| 311 | + this._disabledInputs = $.map(this._disabledInputs, |
| 312 | + function(value) { return (value == target ? null : value); }); // delete entry |
| 313 | + }, |
| 314 | + |
| 315 | + /* Disable the date picker to a jQuery selection. |
| 316 | + @param target element - the target input field or division or span */ |
| 317 | + _disableDatepicker: function(target) { |
| 318 | + var $target = $(target); |
| 319 | + var inst = $.data(target, PROP_NAME); |
| 320 | + if (!$target.hasClass(this.markerClassName)) { |
| 321 | + return; |
| 322 | + } |
| 323 | + var nodeName = target.nodeName.toLowerCase(); |
| 324 | + if (nodeName == 'input') { |
| 325 | + target.disabled = true; |
| 326 | + inst.trigger.filter("button"). |
| 327 | + each(function() { this.disabled = true; }).end(). |
| 328 | + filter("img"). |
| 329 | + css({opacity: '0.5', cursor: 'default'}); |
| 330 | + } |
| 331 | + else if (nodeName == 'div' || nodeName == 'span') { |
| 332 | + var inline = $target.children('.' + this._inlineClass); |
| 333 | + inline.children().addClass('ui-state-disabled'); |
| 334 | + } |
| 335 | + this._disabledInputs = $.map(this._disabledInputs, |
| 336 | + function(value) { return (value == target ? null : value); }); // delete entry |
| 337 | + this._disabledInputs[this._disabledInputs.length] = target; |
| 338 | + }, |
| 339 | + |
| 340 | + /* Is the first field in a jQuery collection disabled as a datepicker? |
| 341 | + @param target element - the target input field or division or span |
| 342 | + @return boolean - true if disabled, false if enabled */ |
| 343 | + _isDisabledDatepicker: function(target) { |
| 344 | + if (!target) { |
| 345 | + return false; |
| 346 | + } |
| 347 | + for (var i = 0; i < this._disabledInputs.length; i++) { |
| 348 | + if (this._disabledInputs[i] == target) |
| 349 | + return true; |
| 350 | + } |
| 351 | + return false; |
| 352 | + }, |
| 353 | + |
| 354 | + /* Retrieve the instance data for the target control. |
| 355 | + @param target element - the target input field or division or span |
| 356 | + @return object - the associated instance data |
| 357 | + @throws error if a jQuery problem getting data */ |
| 358 | + _getInst: function(target) { |
| 359 | + try { |
| 360 | + return $.data(target, PROP_NAME); |
| 361 | + } |
| 362 | + catch (err) { |
| 363 | + throw 'Missing instance data for this datepicker'; |
| 364 | + } |
| 365 | + }, |
| 366 | + |
| 367 | + /* Update the settings for a date picker attached to an input field or division. |
| 368 | + @param target element - the target input field or division or span |
| 369 | + @param name object - the new settings to update or |
| 370 | + string - the name of the setting to change or |
| 371 | + @param value any - the new value for the setting (omit if above is an object) */ |
| 372 | + _optionDatepicker: function(target, name, value) { |
| 373 | + var settings = name || {}; |
| 374 | + if (typeof name == 'string') { |
| 375 | + settings = {}; |
| 376 | + settings[name] = value; |
| 377 | + } |
| 378 | + var inst = this._getInst(target); |
| 379 | + if (inst) { |
| 380 | + if (this._curInst == inst) { |
| 381 | + this._hideDatepicker(null); |
| 382 | + } |
| 383 | + extendRemove(inst.settings, settings); |
| 384 | + var date = new Date(); |
| 385 | + extendRemove(inst, {rangeStart: null, // start of range |
| 386 | + endDay: null, endMonth: null, endYear: null, // end of range |
| 387 | + selectedDay: date.getDate(), selectedMonth: date.getMonth(), |
| 388 | + selectedYear: date.getFullYear(), // starting point |
| 389 | + currentDay: date.getDate(), currentMonth: date.getMonth(), |
| 390 | + currentYear: date.getFullYear(), // current selection |
| 391 | + drawMonth: date.getMonth(), drawYear: date.getFullYear()}); // month being drawn |
| 392 | + this._updateDatepicker(inst); |
| 393 | + } |
| 394 | + }, |
| 395 | + |
| 396 | + // change method deprecated |
| 397 | + _changeDatepicker: function(target, name, value) { |
| 398 | + this._optionDatepicker(target, name, value); |
| 399 | + }, |
| 400 | + |
| 401 | + /* Redraw the date picker attached to an input field or division. |
| 402 | + @param target element - the target input field or division or span */ |
| 403 | + _refreshDatepicker: function(target) { |
| 404 | + var inst = this._getInst(target); |
| 405 | + if (inst) { |
| 406 | + this._updateDatepicker(inst); |
| 407 | + } |
| 408 | + }, |
| 409 | + |
| 410 | + /* Set the dates for a jQuery selection. |
| 411 | + @param target element - the target input field or division or span |
| 412 | + @param date Date - the new date |
| 413 | + @param endDate Date - the new end date for a range (optional) */ |
| 414 | + _setDateDatepicker: function(target, date, endDate) { |
| 415 | + var inst = this._getInst(target); |
| 416 | + if (inst) { |
| 417 | + this._setDate(inst, date, endDate); |
| 418 | + this._updateDatepicker(inst); |
| 419 | + this._updateAlternate(inst); |
| 420 | + } |
| 421 | + }, |
| 422 | + |
| 423 | + /* Get the date(s) for the first entry in a jQuery selection. |
| 424 | + @param target element - the target input field or division or span |
| 425 | + @return Date - the current date or |
| 426 | + Date[2] - the current dates for a range */ |
| 427 | + _getDateDatepicker: function(target) { |
| 428 | + var inst = this._getInst(target); |
| 429 | + if (inst && !inst.inline) |
| 430 | + this._setDateFromField(inst); |
| 431 | + return (inst ? this._getDate(inst) : null); |
| 432 | + }, |
| 433 | + |
| 434 | + /* Handle keystrokes. */ |
| 435 | + _doKeyDown: function(event) { |
| 436 | + var inst = $.datepicker._getInst(event.target); |
| 437 | + var handled = true; |
| 438 | + var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); |
| 439 | + inst._keyEvent = true; |
| 440 | + if ($.datepicker._datepickerShowing) |
| 441 | + switch (event.keyCode) { |
| 442 | + case 9: $.datepicker._hideDatepicker(null, ''); |
| 443 | + break; // hide on tab out |
| 444 | + case 13: var sel = $('td.' + $.datepicker._dayOverClass + |
| 445 | + ', td.' + $.datepicker._currentClass, inst.dpDiv); |
| 446 | + if (sel[0]) |
| 447 | + $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); |
| 448 | + else |
| 449 | + $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration')); |
| 450 | + return false; // don't submit the form |
| 451 | + break; // select the value on enter |
| 452 | + case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration')); |
| 453 | + break; // hide on escape |
| 454 | + case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? |
| 455 | + -$.datepicker._get(inst, 'stepBigMonths') : |
| 456 | + -$.datepicker._get(inst, 'stepMonths')), 'M'); |
| 457 | + break; // previous month/year on page up/+ ctrl |
| 458 | + case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? |
| 459 | + +$.datepicker._get(inst, 'stepBigMonths') : |
| 460 | + +$.datepicker._get(inst, 'stepMonths')), 'M'); |
| 461 | + break; // next month/year on page down/+ ctrl |
| 462 | + case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); |
| 463 | + handled = event.ctrlKey || event.metaKey; |
| 464 | + break; // clear on ctrl or command +end |
| 465 | + case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); |
| 466 | + handled = event.ctrlKey || event.metaKey; |
| 467 | + break; // current on ctrl or command +home |
| 468 | + case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); |
| 469 | + handled = event.ctrlKey || event.metaKey; |
| 470 | + // -1 day on ctrl or command +left |
| 471 | + if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? |
| 472 | + -$.datepicker._get(inst, 'stepBigMonths') : |
| 473 | + -$.datepicker._get(inst, 'stepMonths')), 'M'); |
| 474 | + // next month/year on alt +left on Mac |
| 475 | + break; |
| 476 | + case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); |
| 477 | + handled = event.ctrlKey || event.metaKey; |
| 478 | + break; // -1 week on ctrl or command +up |
| 479 | + case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); |
| 480 | + handled = event.ctrlKey || event.metaKey; |
| 481 | + // +1 day on ctrl or command +right |
| 482 | + if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? |
| 483 | + +$.datepicker._get(inst, 'stepBigMonths') : |
| 484 | + +$.datepicker._get(inst, 'stepMonths')), 'M'); |
| 485 | + // next month/year on alt +right |
| 486 | + break; |
| 487 | + case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); |
| 488 | + handled = event.ctrlKey || event.metaKey; |
| 489 | + break; // +1 week on ctrl or command +down |
| 490 | + default: handled = false; |
| 491 | + } |
| 492 | + else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home |
| 493 | + $.datepicker._showDatepicker(this); |
| 494 | + else { |
| 495 | + handled = false; |
| 496 | + } |
| 497 | + if (handled) { |
| 498 | + event.preventDefault(); |
| 499 | + event.stopPropagation(); |
| 500 | + } |
| 501 | + }, |
| 502 | + |
| 503 | + /* Filter entered characters - based on date format. */ |
| 504 | + _doKeyPress: function(event) { |
| 505 | + var inst = $.datepicker._getInst(event.target); |
| 506 | + if ($.datepicker._get(inst, 'constrainInput')) { |
| 507 | + var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); |
| 508 | + var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); |
| 509 | + return event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); |
| 510 | + } |
| 511 | + }, |
| 512 | + |
| 513 | + /* Pop-up the date picker for a given input field. |
| 514 | + @param input element - the input field attached to the date picker or |
| 515 | + event - if triggered by focus */ |
| 516 | + _showDatepicker: function(input) { |
| 517 | + input = input.target || input; |
| 518 | + if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger |
| 519 | + input = $('input', input.parentNode)[0]; |
| 520 | + if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here |
| 521 | + return; |
| 522 | + var inst = $.datepicker._getInst(input); |
| 523 | + var beforeShow = $.datepicker._get(inst, 'beforeShow'); |
| 524 | + extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {})); |
| 525 | + $.datepicker._hideDatepicker(null, ''); |
| 526 | + $.datepicker._lastInput = input; |
| 527 | + $.datepicker._setDateFromField(inst); |
| 528 | + if ($.datepicker._inDialog) // hide cursor |
| 529 | + input.value = ''; |
| 530 | + if (!$.datepicker._pos) { // position below input |
| 531 | + $.datepicker._pos = $.datepicker._findPos(input); |
| 532 | + $.datepicker._pos[1] += input.offsetHeight; // add the height |
| 533 | + } |
| 534 | + var isFixed = false; |
| 535 | + $(input).parents().each(function() { |
| 536 | + isFixed |= $(this).css('position') == 'fixed'; |
| 537 | + return !isFixed; |
| 538 | + }); |
| 539 | + if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled |
| 540 | + $.datepicker._pos[0] -= document.documentElement.scrollLeft; |
| 541 | + $.datepicker._pos[1] -= document.documentElement.scrollTop; |
| 542 | + } |
| 543 | + var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; |
| 544 | + $.datepicker._pos = null; |
| 545 | + inst.rangeStart = null; |
| 546 | + // determine sizing offscreen |
| 547 | + inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); |
| 548 | + $.datepicker._updateDatepicker(inst); |
| 549 | + // fix width for dynamic number of date pickers |
| 550 | + // and adjust position before showing |
| 551 | + offset = $.datepicker._checkOffset(inst, offset, isFixed); |
| 552 | + inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? |
| 553 | + 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', |
| 554 | + left: offset.left + 'px', top: offset.top + 'px'}); |
| 555 | + if (!inst.inline) { |
| 556 | + var showAnim = $.datepicker._get(inst, 'showAnim') || 'show'; |
| 557 | + var duration = $.datepicker._get(inst, 'duration'); |
| 558 | + var postProcess = function() { |
| 559 | + $.datepicker._datepickerShowing = true; |
| 560 | + if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems |
| 561 | + $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4, |
| 562 | + height: inst.dpDiv.height() + 4}); |
| 563 | + }; |
| 564 | + if ($.effects && $.effects[showAnim]) |
| 565 | + inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); |
| 566 | + else |
| 567 | + inst.dpDiv[showAnim](duration, postProcess); |
| 568 | + if (duration == '') |
| 569 | + postProcess(); |
| 570 | + if (inst.input[0].type != 'hidden') |
| 571 | + inst.input[0].focus(); |
| 572 | + $.datepicker._curInst = inst; |
| 573 | + } |
| 574 | + }, |
| 575 | + |
| 576 | + /* Generate the date picker content. */ |
| 577 | + _updateDatepicker: function(inst) { |
| 578 | + var dims = {width: inst.dpDiv.width() + 4, |
| 579 | + height: inst.dpDiv.height() + 4}; |
| 580 | + var self = this; |
| 581 | + inst.dpDiv.empty().append(this._generateHTML(inst)) |
| 582 | + .find('iframe.ui-datepicker-cover'). |
| 583 | + css({width: dims.width, height: dims.height}) |
| 584 | + .end() |
| 585 | + .find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a') |
| 586 | + .bind('mouseout', function(){ |
| 587 | + $(this).removeClass('ui-state-hover'); |
| 588 | + if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); |
| 589 | + if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); |
| 590 | + }) |
| 591 | + .bind('mouseover', function(){ |
| 592 | + if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) { |
| 593 | + $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); |
| 594 | + $(this).addClass('ui-state-hover'); |
| 595 | + if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); |
| 596 | + if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); |
| 597 | + } |
| 598 | + }) |
| 599 | + .end() |
| 600 | + .find('.' + this._dayOverClass + ' a') |
| 601 | + .trigger('mouseover') |
| 602 | + .end(); |
| 603 | + var numMonths = this._getNumberOfMonths(inst); |
| 604 | + var cols = numMonths[1]; |
| 605 | + var width = 17; |
| 606 | + if (cols > 1) { |
| 607 | + inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); |
| 608 | + } else { |
| 609 | + inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); |
| 610 | + } |
| 611 | + inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + |
| 612 | + 'Class']('ui-datepicker-multi'); |
| 613 | + inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + |
| 614 | + 'Class']('ui-datepicker-rtl'); |
| 615 | + if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst) |
| 616 | + $(inst.input[0]).focus(); |
| 617 | + }, |
| 618 | + |
| 619 | + /* Check positioning to remain on screen. */ |
| 620 | + _checkOffset: function(inst, offset, isFixed) { |
| 621 | + var dpWidth = inst.dpDiv.outerWidth(); |
| 622 | + var dpHeight = inst.dpDiv.outerHeight(); |
| 623 | + var inputWidth = inst.input ? inst.input.outerWidth() : 0; |
| 624 | + var inputHeight = inst.input ? inst.input.outerHeight() : 0; |
| 625 | + var viewWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) + $(document).scrollLeft(); |
| 626 | + var viewHeight = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) + $(document).scrollTop(); |
| 627 | + |
| 628 | + offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); |
| 629 | + offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; |
| 630 | + offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; |
| 631 | + |
| 632 | + // now check if datepicker is showing outside window viewport - move to a better place if so. |
| 633 | + offset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0; |
| 634 | + offset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight*2 - viewHeight) : 0; |
| 635 | + |
| 636 | + return offset; |
| 637 | + }, |
| 638 | + |
| 639 | + /* Find an object's position on the screen. */ |
| 640 | + _findPos: function(obj) { |
| 641 | + while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) { |
| 642 | + obj = obj.nextSibling; |
| 643 | + } |
| 644 | + var position = $(obj).offset(); |
| 645 | + return [position.left, position.top]; |
| 646 | + }, |
| 647 | + |
| 648 | + /* Hide the date picker from view. |
| 649 | + @param input element - the input field attached to the date picker |
| 650 | + @param duration string - the duration over which to close the date picker */ |
| 651 | + _hideDatepicker: function(input, duration) { |
| 652 | + var inst = this._curInst; |
| 653 | + if (!inst || (input && inst != $.data(input, PROP_NAME))) |
| 654 | + return; |
| 655 | + if (inst.stayOpen) |
| 656 | + this._selectDate('#' + inst.id, this._formatDate(inst, |
| 657 | + inst.currentDay, inst.currentMonth, inst.currentYear)); |
| 658 | + inst.stayOpen = false; |
| 659 | + if (this._datepickerShowing) { |
| 660 | + duration = (duration != null ? duration : this._get(inst, 'duration')); |
| 661 | + var showAnim = this._get(inst, 'showAnim'); |
| 662 | + var postProcess = function() { |
| 663 | + $.datepicker._tidyDialog(inst); |
| 664 | + }; |
| 665 | + if (duration != '' && $.effects && $.effects[showAnim]) |
| 666 | + inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), |
| 667 | + duration, postProcess); |
| 668 | + else |
| 669 | + inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' : |
| 670 | + (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess); |
| 671 | + if (duration == '') |
| 672 | + this._tidyDialog(inst); |
| 673 | + var onClose = this._get(inst, 'onClose'); |
| 674 | + if (onClose) |
| 675 | + onClose.apply((inst.input ? inst.input[0] : null), |
| 676 | + [(inst.input ? inst.input.val() : ''), inst]); // trigger custom callback |
| 677 | + this._datepickerShowing = false; |
| 678 | + this._lastInput = null; |
| 679 | + if (this._inDialog) { |
| 680 | + this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); |
| 681 | + if ($.blockUI) { |
| 682 | + $.unblockUI(); |
| 683 | + $('body').append(this.dpDiv); |
| 684 | + } |
| 685 | + } |
| 686 | + this._inDialog = false; |
| 687 | + } |
| 688 | + this._curInst = null; |
| 689 | + }, |
| 690 | + |
| 691 | + /* Tidy up after a dialog display. */ |
| 692 | + _tidyDialog: function(inst) { |
| 693 | + inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); |
| 694 | + }, |
| 695 | + |
| 696 | + /* Close date picker if clicked elsewhere. */ |
| 697 | + _checkExternalClick: function(event) { |
| 698 | + if (!$.datepicker._curInst) |
| 699 | + return; |
| 700 | + var $target = $(event.target); |
| 701 | + if (($target.parents('#' + $.datepicker._mainDivId).length == 0) && |
| 702 | + !$target.hasClass($.datepicker.markerClassName) && |
| 703 | + !$target.hasClass($.datepicker._triggerClass) && |
| 704 | + $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) |
| 705 | + $.datepicker._hideDatepicker(null, ''); |
| 706 | + }, |
| 707 | + |
| 708 | + /* Adjust one of the date sub-fields. */ |
| 709 | + _adjustDate: function(id, offset, period) { |
| 710 | + var target = $(id); |
| 711 | + var inst = this._getInst(target[0]); |
| 712 | + if (this._isDisabledDatepicker(target[0])) { |
| 713 | + return; |
| 714 | + } |
| 715 | + this._adjustInstDate(inst, offset + |
| 716 | + (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning |
| 717 | + period); |
| 718 | + this._updateDatepicker(inst); |
| 719 | + }, |
| 720 | + |
| 721 | + /* Action for current link. */ |
| 722 | + _gotoToday: function(id) { |
| 723 | + var target = $(id); |
| 724 | + var inst = this._getInst(target[0]); |
| 725 | + if (this._get(inst, 'gotoCurrent') && inst.currentDay) { |
| 726 | + inst.selectedDay = inst.currentDay; |
| 727 | + inst.drawMonth = inst.selectedMonth = inst.currentMonth; |
| 728 | + inst.drawYear = inst.selectedYear = inst.currentYear; |
| 729 | + } |
| 730 | + else { |
| 731 | + var date = new Date(); |
| 732 | + inst.selectedDay = date.getDate(); |
| 733 | + inst.drawMonth = inst.selectedMonth = date.getMonth(); |
| 734 | + inst.drawYear = inst.selectedYear = date.getFullYear(); |
| 735 | + } |
| 736 | + this._notifyChange(inst); |
| 737 | + this._adjustDate(target); |
| 738 | + }, |
| 739 | + |
| 740 | + /* Action for selecting a new month/year. */ |
| 741 | + _selectMonthYear: function(id, select, period) { |
| 742 | + var target = $(id); |
| 743 | + var inst = this._getInst(target[0]); |
| 744 | + inst._selectingMonthYear = false; |
| 745 | + inst['selected' + (period == 'M' ? 'Month' : 'Year')] = |
| 746 | + inst['draw' + (period == 'M' ? 'Month' : 'Year')] = |
| 747 | + parseInt(select.options[select.selectedIndex].value,10); |
| 748 | + this._notifyChange(inst); |
| 749 | + this._adjustDate(target); |
| 750 | + }, |
| 751 | + |
| 752 | + /* Restore input focus after not changing month/year. */ |
| 753 | + _clickMonthYear: function(id) { |
| 754 | + var target = $(id); |
| 755 | + var inst = this._getInst(target[0]); |
| 756 | + if (inst.input && inst._selectingMonthYear && !$.browser.msie) |
| 757 | + inst.input[0].focus(); |
| 758 | + inst._selectingMonthYear = !inst._selectingMonthYear; |
| 759 | + }, |
| 760 | + |
| 761 | + /* Action for selecting a day. */ |
| 762 | + _selectDay: function(id, month, year, td) { |
| 763 | + var target = $(id); |
| 764 | + if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { |
| 765 | + return; |
| 766 | + } |
| 767 | + var inst = this._getInst(target[0]); |
| 768 | + inst.selectedDay = inst.currentDay = $('a', td).html(); |
| 769 | + inst.selectedMonth = inst.currentMonth = month; |
| 770 | + inst.selectedYear = inst.currentYear = year; |
| 771 | + if (inst.stayOpen) { |
| 772 | + inst.endDay = inst.endMonth = inst.endYear = null; |
| 773 | + } |
| 774 | + this._selectDate(id, this._formatDate(inst, |
| 775 | + inst.currentDay, inst.currentMonth, inst.currentYear)); |
| 776 | + if (inst.stayOpen) { |
| 777 | + inst.rangeStart = this._daylightSavingAdjust( |
| 778 | + new Date(inst.currentYear, inst.currentMonth, inst.currentDay)); |
| 779 | + this._updateDatepicker(inst); |
| 780 | + } |
| 781 | + }, |
| 782 | + |
| 783 | + /* Erase the input field and hide the date picker. */ |
| 784 | + _clearDate: function(id) { |
| 785 | + var target = $(id); |
| 786 | + var inst = this._getInst(target[0]); |
| 787 | + inst.stayOpen = false; |
| 788 | + inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null; |
| 789 | + this._selectDate(target, ''); |
| 790 | + }, |
| 791 | + |
| 792 | + /* Update the input field with the selected date. */ |
| 793 | + _selectDate: function(id, dateStr) { |
| 794 | + var target = $(id); |
| 795 | + var inst = this._getInst(target[0]); |
| 796 | + dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); |
| 797 | + if (inst.input) |
| 798 | + inst.input.val(dateStr); |
| 799 | + this._updateAlternate(inst); |
| 800 | + var onSelect = this._get(inst, 'onSelect'); |
| 801 | + if (onSelect) |
| 802 | + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback |
| 803 | + else if (inst.input) |
| 804 | + inst.input.trigger('change'); // fire the change event |
| 805 | + if (inst.inline) |
| 806 | + this._updateDatepicker(inst); |
| 807 | + else if (!inst.stayOpen) { |
| 808 | + this._hideDatepicker(null, this._get(inst, 'duration')); |
| 809 | + this._lastInput = inst.input[0]; |
| 810 | + if (typeof(inst.input[0]) != 'object') |
| 811 | + inst.input[0].focus(); // restore focus |
| 812 | + this._lastInput = null; |
| 813 | + } |
| 814 | + }, |
| 815 | + |
| 816 | + /* Update any alternate field to synchronise with the main field. */ |
| 817 | + _updateAlternate: function(inst) { |
| 818 | + var altField = this._get(inst, 'altField'); |
| 819 | + if (altField) { // update alternate field too |
| 820 | + var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); |
| 821 | + var date = this._getDate(inst); |
| 822 | + dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); |
| 823 | + $(altField).each(function() { $(this).val(dateStr); }); |
| 824 | + } |
| 825 | + }, |
| 826 | + |
| 827 | + /* Set as beforeShowDay function to prevent selection of weekends. |
| 828 | + @param date Date - the date to customise |
| 829 | + @return [boolean, string] - is this date selectable?, what is its CSS class? */ |
| 830 | + noWeekends: function(date) { |
| 831 | + var day = date.getDay(); |
| 832 | + return [(day > 0 && day < 6), '']; |
| 833 | + }, |
| 834 | + |
| 835 | + /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. |
| 836 | + @param date Date - the date to get the week for |
| 837 | + @return number - the number of the week within the year that contains this date */ |
| 838 | + iso8601Week: function(date) { |
| 839 | + var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()); |
| 840 | + var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan |
| 841 | + var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7 |
| 842 | + firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday |
| 843 | + if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary |
| 844 | + checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year |
| 845 | + return $.datepicker.iso8601Week(checkDate); |
| 846 | + } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year |
| 847 | + firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7; |
| 848 | + if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary |
| 849 | + return 1; |
| 850 | + } |
| 851 | + } |
| 852 | + return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date |
| 853 | + }, |
| 854 | + |
| 855 | + /* Parse a string value into a date object. |
| 856 | + See formatDate below for the possible formats. |
| 857 | + |
| 858 | + @param format string - the expected format of the date |
| 859 | + @param value string - the date in the above format |
| 860 | + @param settings Object - attributes include: |
| 861 | + shortYearCutoff number - the cutoff year for determining the century (optional) |
| 862 | + dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) |
| 863 | + dayNames string[7] - names of the days from Sunday (optional) |
| 864 | + monthNamesShort string[12] - abbreviated names of the months (optional) |
| 865 | + monthNames string[12] - names of the months (optional) |
| 866 | + @return Date - the extracted date value or null if value is blank */ |
| 867 | + parseDate: function (format, value, settings) { |
| 868 | + if (format == null || value == null) |
| 869 | + throw 'Invalid arguments'; |
| 870 | + value = (typeof value == 'object' ? value.toString() : value + ''); |
| 871 | + if (value == '') |
| 872 | + return null; |
| 873 | + var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; |
| 874 | + var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; |
| 875 | + var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; |
| 876 | + var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; |
| 877 | + var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; |
| 878 | + var year = -1; |
| 879 | + var month = -1; |
| 880 | + var day = -1; |
| 881 | + var doy = -1; |
| 882 | + var literal = false; |
| 883 | + // Check whether a format character is doubled |
| 884 | + var lookAhead = function(match) { |
| 885 | + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); |
| 886 | + if (matches) |
| 887 | + iFormat++; |
| 888 | + return matches; |
| 889 | + }; |
| 890 | + // Extract a number from the string value |
| 891 | + var getNumber = function(match) { |
| 892 | + lookAhead(match); |
| 893 | + var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2))); |
| 894 | + var size = origSize; |
| 895 | + var num = 0; |
| 896 | + while (size > 0 && iValue < value.length && |
| 897 | + value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') { |
| 898 | + num = num * 10 + parseInt(value.charAt(iValue++),10); |
| 899 | + size--; |
| 900 | + } |
| 901 | + if (size == origSize) |
| 902 | + throw 'Missing number at position ' + iValue; |
| 903 | + return num; |
| 904 | + }; |
| 905 | + // Extract a name from the string value and convert to an index |
| 906 | + var getName = function(match, shortNames, longNames) { |
| 907 | + var names = (lookAhead(match) ? longNames : shortNames); |
| 908 | + var size = 0; |
| 909 | + for (var j = 0; j < names.length; j++) |
| 910 | + size = Math.max(size, names[j].length); |
| 911 | + var name = ''; |
| 912 | + var iInit = iValue; |
| 913 | + while (size > 0 && iValue < value.length) { |
| 914 | + name += value.charAt(iValue++); |
| 915 | + for (var i = 0; i < names.length; i++) |
| 916 | + if (name == names[i]) |
| 917 | + return i + 1; |
| 918 | + size--; |
| 919 | + } |
| 920 | + throw 'Unknown name at position ' + iInit; |
| 921 | + }; |
| 922 | + // Confirm that a literal character matches the string value |
| 923 | + var checkLiteral = function() { |
| 924 | + if (value.charAt(iValue) != format.charAt(iFormat)) |
| 925 | + throw 'Unexpected literal at position ' + iValue; |
| 926 | + iValue++; |
| 927 | + }; |
| 928 | + var iValue = 0; |
| 929 | + for (var iFormat = 0; iFormat < format.length; iFormat++) { |
| 930 | + if (literal) |
| 931 | + if (format.charAt(iFormat) == "'" && !lookAhead("'")) |
| 932 | + literal = false; |
| 933 | + else |
| 934 | + checkLiteral(); |
| 935 | + else |
| 936 | + switch (format.charAt(iFormat)) { |
| 937 | + case 'd': |
| 938 | + day = getNumber('d'); |
| 939 | + break; |
| 940 | + case 'D': |
| 941 | + getName('D', dayNamesShort, dayNames); |
| 942 | + break; |
| 943 | + case 'o': |
| 944 | + doy = getNumber('o'); |
| 945 | + break; |
| 946 | + case 'm': |
| 947 | + month = getNumber('m'); |
| 948 | + break; |
| 949 | + case 'M': |
| 950 | + month = getName('M', monthNamesShort, monthNames); |
| 951 | + break; |
| 952 | + case 'y': |
| 953 | + year = getNumber('y'); |
| 954 | + break; |
| 955 | + case '@': |
| 956 | + var date = new Date(getNumber('@')); |
| 957 | + year = date.getFullYear(); |
| 958 | + month = date.getMonth() + 1; |
| 959 | + day = date.getDate(); |
| 960 | + break; |
| 961 | + case "'": |
| 962 | + if (lookAhead("'")) |
| 963 | + checkLiteral(); |
| 964 | + else |
| 965 | + literal = true; |
| 966 | + break; |
| 967 | + default: |
| 968 | + checkLiteral(); |
| 969 | + } |
| 970 | + } |
| 971 | + if (year == -1) |
| 972 | + year = new Date().getFullYear(); |
| 973 | + else if (year < 100) |
| 974 | + year += new Date().getFullYear() - new Date().getFullYear() % 100 + |
| 975 | + (year <= shortYearCutoff ? 0 : -100); |
| 976 | + if (doy > -1) { |
| 977 | + month = 1; |
| 978 | + day = doy; |
| 979 | + do { |
| 980 | + var dim = this._getDaysInMonth(year, month - 1); |
| 981 | + if (day <= dim) |
| 982 | + break; |
| 983 | + month++; |
| 984 | + day -= dim; |
| 985 | + } while (true); |
| 986 | + } |
| 987 | + var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); |
| 988 | + if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) |
| 989 | + throw 'Invalid date'; // E.g. 31/02/* |
| 990 | + return date; |
| 991 | + }, |
| 992 | + |
| 993 | + /* Standard date formats. */ |
| 994 | + ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) |
| 995 | + COOKIE: 'D, dd M yy', |
| 996 | + ISO_8601: 'yy-mm-dd', |
| 997 | + RFC_822: 'D, d M y', |
| 998 | + RFC_850: 'DD, dd-M-y', |
| 999 | + RFC_1036: 'D, d M y', |
| 1000 | + RFC_1123: 'D, d M yy', |
| 1001 | + RFC_2822: 'D, d M yy', |
| 1002 | + RSS: 'D, d M y', // RFC 822 |
| 1003 | + TIMESTAMP: '@', |
| 1004 | + W3C: 'yy-mm-dd', // ISO 8601 |
| 1005 | + |
| 1006 | + /* Format a date object into a string value. |
| 1007 | + The format can be combinations of the following: |
| 1008 | + d - day of month (no leading zero) |
| 1009 | + dd - day of month (two digit) |
| 1010 | + o - day of year (no leading zeros) |
| 1011 | + oo - day of year (three digit) |
| 1012 | + D - day name short |
| 1013 | + DD - day name long |
| 1014 | + m - month of year (no leading zero) |
| 1015 | + mm - month of year (two digit) |
| 1016 | + M - month name short |
| 1017 | + MM - month name long |
| 1018 | + y - year (two digit) |
| 1019 | + yy - year (four digit) |
| 1020 | + @ - Unix timestamp (ms since 01/01/1970) |
| 1021 | + '...' - literal text |
| 1022 | + '' - single quote |
| 1023 | + |
| 1024 | + @param format string - the desired format of the date |
| 1025 | + @param date Date - the date value to format |
| 1026 | + @param settings Object - attributes include: |
| 1027 | + dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) |
| 1028 | + dayNames string[7] - names of the days from Sunday (optional) |
| 1029 | + monthNamesShort string[12] - abbreviated names of the months (optional) |
| 1030 | + monthNames string[12] - names of the months (optional) |
| 1031 | + @return string - the date in the above format */ |
| 1032 | + formatDate: function (format, date, settings) { |
| 1033 | + if (!date) |
| 1034 | + return ''; |
| 1035 | + var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; |
| 1036 | + var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; |
| 1037 | + var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; |
| 1038 | + var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; |
| 1039 | + // Check whether a format character is doubled |
| 1040 | + var lookAhead = function(match) { |
| 1041 | + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); |
| 1042 | + if (matches) |
| 1043 | + iFormat++; |
| 1044 | + return matches; |
| 1045 | + }; |
| 1046 | + // Format a number, with leading zero if necessary |
| 1047 | + var formatNumber = function(match, value, len) { |
| 1048 | + var num = '' + value; |
| 1049 | + if (lookAhead(match)) |
| 1050 | + while (num.length < len) |
| 1051 | + num = '0' + num; |
| 1052 | + return num; |
| 1053 | + }; |
| 1054 | + // Format a name, short or long as requested |
| 1055 | + var formatName = function(match, value, shortNames, longNames) { |
| 1056 | + return (lookAhead(match) ? longNames[value] : shortNames[value]); |
| 1057 | + }; |
| 1058 | + var output = ''; |
| 1059 | + var literal = false; |
| 1060 | + if (date) |
| 1061 | + for (var iFormat = 0; iFormat < format.length; iFormat++) { |
| 1062 | + if (literal) |
| 1063 | + if (format.charAt(iFormat) == "'" && !lookAhead("'")) |
| 1064 | + literal = false; |
| 1065 | + else |
| 1066 | + output += format.charAt(iFormat); |
| 1067 | + else |
| 1068 | + switch (format.charAt(iFormat)) { |
| 1069 | + case 'd': |
| 1070 | + output += formatNumber('d', date.getDate(), 2); |
| 1071 | + break; |
| 1072 | + case 'D': |
| 1073 | + output += formatName('D', date.getDay(), dayNamesShort, dayNames); |
| 1074 | + break; |
| 1075 | + case 'o': |
| 1076 | + var doy = date.getDate(); |
| 1077 | + for (var m = date.getMonth() - 1; m >= 0; m--) |
| 1078 | + doy += this._getDaysInMonth(date.getFullYear(), m); |
| 1079 | + output += formatNumber('o', doy, 3); |
| 1080 | + break; |
| 1081 | + case 'm': |
| 1082 | + output += formatNumber('m', date.getMonth() + 1, 2); |
| 1083 | + break; |
| 1084 | + case 'M': |
| 1085 | + output += formatName('M', date.getMonth(), monthNamesShort, monthNames); |
| 1086 | + break; |
| 1087 | + case 'y': |
| 1088 | + output += (lookAhead('y') ? date.getFullYear() : |
| 1089 | + (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); |
| 1090 | + break; |
| 1091 | + case '@': |
| 1092 | + output += date.getTime(); |
| 1093 | + break; |
| 1094 | + case "'": |
| 1095 | + if (lookAhead("'")) |
| 1096 | + output += "'"; |
| 1097 | + else |
| 1098 | + literal = true; |
| 1099 | + break; |
| 1100 | + default: |
| 1101 | + output += format.charAt(iFormat); |
| 1102 | + } |
| 1103 | + } |
| 1104 | + return output; |
| 1105 | + }, |
| 1106 | + |
| 1107 | + /* Extract all possible characters from the date format. */ |
| 1108 | + _possibleChars: function (format) { |
| 1109 | + var chars = ''; |
| 1110 | + var literal = false; |
| 1111 | + for (var iFormat = 0; iFormat < format.length; iFormat++) |
| 1112 | + if (literal) |
| 1113 | + if (format.charAt(iFormat) == "'" && !lookAhead("'")) |
| 1114 | + literal = false; |
| 1115 | + else |
| 1116 | + chars += format.charAt(iFormat); |
| 1117 | + else |
| 1118 | + switch (format.charAt(iFormat)) { |
| 1119 | + case 'd': case 'm': case 'y': case '@': |
| 1120 | + chars += '0123456789'; |
| 1121 | + break; |
| 1122 | + case 'D': case 'M': |
| 1123 | + return null; // Accept anything |
| 1124 | + case "'": |
| 1125 | + if (lookAhead("'")) |
| 1126 | + chars += "'"; |
| 1127 | + else |
| 1128 | + literal = true; |
| 1129 | + break; |
| 1130 | + default: |
| 1131 | + chars += format.charAt(iFormat); |
| 1132 | + } |
| 1133 | + return chars; |
| 1134 | + }, |
| 1135 | + |
| 1136 | + /* Get a setting value, defaulting if necessary. */ |
| 1137 | + _get: function(inst, name) { |
| 1138 | + return inst.settings[name] !== undefined ? |
| 1139 | + inst.settings[name] : this._defaults[name]; |
| 1140 | + }, |
| 1141 | + |
| 1142 | + /* Parse existing date and initialise date picker. */ |
| 1143 | + _setDateFromField: function(inst) { |
| 1144 | + var dateFormat = this._get(inst, 'dateFormat'); |
| 1145 | + var dates = inst.input ? inst.input.val() : null; |
| 1146 | + inst.endDay = inst.endMonth = inst.endYear = null; |
| 1147 | + var date = defaultDate = this._getDefaultDate(inst); |
| 1148 | + var settings = this._getFormatConfig(inst); |
| 1149 | + try { |
| 1150 | + date = this.parseDate(dateFormat, dates, settings) || defaultDate; |
| 1151 | + } catch (event) { |
| 1152 | + this.log(event); |
| 1153 | + date = defaultDate; |
| 1154 | + } |
| 1155 | + inst.selectedDay = date.getDate(); |
| 1156 | + inst.drawMonth = inst.selectedMonth = date.getMonth(); |
| 1157 | + inst.drawYear = inst.selectedYear = date.getFullYear(); |
| 1158 | + inst.currentDay = (dates ? date.getDate() : 0); |
| 1159 | + inst.currentMonth = (dates ? date.getMonth() : 0); |
| 1160 | + inst.currentYear = (dates ? date.getFullYear() : 0); |
| 1161 | + this._adjustInstDate(inst); |
| 1162 | + }, |
| 1163 | + |
| 1164 | + /* Retrieve the default date shown on opening. */ |
| 1165 | + _getDefaultDate: function(inst) { |
| 1166 | + var date = this._determineDate(this._get(inst, 'defaultDate'), new Date()); |
| 1167 | + var minDate = this._getMinMaxDate(inst, 'min', true); |
| 1168 | + var maxDate = this._getMinMaxDate(inst, 'max'); |
| 1169 | + date = (minDate && date < minDate ? minDate : date); |
| 1170 | + date = (maxDate && date > maxDate ? maxDate : date); |
| 1171 | + return date; |
| 1172 | + }, |
| 1173 | + |
| 1174 | + /* A date may be specified as an exact value or a relative one. */ |
| 1175 | + _determineDate: function(date, defaultDate) { |
| 1176 | + var offsetNumeric = function(offset) { |
| 1177 | + var date = new Date(); |
| 1178 | + date.setDate(date.getDate() + offset); |
| 1179 | + return date; |
| 1180 | + }; |
| 1181 | + var offsetString = function(offset, getDaysInMonth) { |
| 1182 | + var date = new Date(); |
| 1183 | + var year = date.getFullYear(); |
| 1184 | + var month = date.getMonth(); |
| 1185 | + var day = date.getDate(); |
| 1186 | + var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; |
| 1187 | + var matches = pattern.exec(offset); |
| 1188 | + while (matches) { |
| 1189 | + switch (matches[2] || 'd') { |
| 1190 | + case 'd' : case 'D' : |
| 1191 | + day += parseInt(matches[1],10); break; |
| 1192 | + case 'w' : case 'W' : |
| 1193 | + day += parseInt(matches[1],10) * 7; break; |
| 1194 | + case 'm' : case 'M' : |
| 1195 | + month += parseInt(matches[1],10); |
| 1196 | + day = Math.min(day, getDaysInMonth(year, month)); |
| 1197 | + break; |
| 1198 | + case 'y': case 'Y' : |
| 1199 | + year += parseInt(matches[1],10); |
| 1200 | + day = Math.min(day, getDaysInMonth(year, month)); |
| 1201 | + break; |
| 1202 | + } |
| 1203 | + matches = pattern.exec(offset); |
| 1204 | + } |
| 1205 | + return new Date(year, month, day); |
| 1206 | + }; |
| 1207 | + date = (date == null ? defaultDate : |
| 1208 | + (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) : |
| 1209 | + (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date))); |
| 1210 | + date = (date && date.toString() == 'Invalid Date' ? defaultDate : date); |
| 1211 | + if (date) { |
| 1212 | + date.setHours(0); |
| 1213 | + date.setMinutes(0); |
| 1214 | + date.setSeconds(0); |
| 1215 | + date.setMilliseconds(0); |
| 1216 | + } |
| 1217 | + return this._daylightSavingAdjust(date); |
| 1218 | + }, |
| 1219 | + |
| 1220 | + /* Handle switch to/from daylight saving. |
| 1221 | + Hours may be non-zero on daylight saving cut-over: |
| 1222 | + > 12 when midnight changeover, but then cannot generate |
| 1223 | + midnight datetime, so jump to 1AM, otherwise reset. |
| 1224 | + @param date (Date) the date to check |
| 1225 | + @return (Date) the corrected date */ |
| 1226 | + _daylightSavingAdjust: function(date) { |
| 1227 | + if (!date) return null; |
| 1228 | + date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); |
| 1229 | + return date; |
| 1230 | + }, |
| 1231 | + |
| 1232 | + /* Set the date(s) directly. */ |
| 1233 | + _setDate: function(inst, date, endDate) { |
| 1234 | + var clear = !(date); |
| 1235 | + var origMonth = inst.selectedMonth; |
| 1236 | + var origYear = inst.selectedYear; |
| 1237 | + date = this._determineDate(date, new Date()); |
| 1238 | + inst.selectedDay = inst.currentDay = date.getDate(); |
| 1239 | + inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth(); |
| 1240 | + inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear(); |
| 1241 | + if (origMonth != inst.selectedMonth || origYear != inst.selectedYear) |
| 1242 | + this._notifyChange(inst); |
| 1243 | + this._adjustInstDate(inst); |
| 1244 | + if (inst.input) { |
| 1245 | + inst.input.val(clear ? '' : this._formatDate(inst)); |
| 1246 | + } |
| 1247 | + }, |
| 1248 | + |
| 1249 | + /* Retrieve the date(s) directly. */ |
| 1250 | + _getDate: function(inst) { |
| 1251 | + var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : |
| 1252 | + this._daylightSavingAdjust(new Date( |
| 1253 | + inst.currentYear, inst.currentMonth, inst.currentDay))); |
| 1254 | + return startDate; |
| 1255 | + }, |
| 1256 | + |
| 1257 | + /* Generate the HTML for the current state of the date picker. */ |
| 1258 | + _generateHTML: function(inst) { |
| 1259 | + var today = new Date(); |
| 1260 | + today = this._daylightSavingAdjust( |
| 1261 | + new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time |
| 1262 | + var isRTL = this._get(inst, 'isRTL'); |
| 1263 | + var showButtonPanel = this._get(inst, 'showButtonPanel'); |
| 1264 | + var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); |
| 1265 | + var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); |
| 1266 | + var numMonths = this._getNumberOfMonths(inst); |
| 1267 | + var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); |
| 1268 | + var stepMonths = this._get(inst, 'stepMonths'); |
| 1269 | + var stepBigMonths = this._get(inst, 'stepBigMonths'); |
| 1270 | + var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); |
| 1271 | + var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : |
| 1272 | + new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); |
| 1273 | + var minDate = this._getMinMaxDate(inst, 'min', true); |
| 1274 | + var maxDate = this._getMinMaxDate(inst, 'max'); |
| 1275 | + var drawMonth = inst.drawMonth - showCurrentAtPos; |
| 1276 | + var drawYear = inst.drawYear; |
| 1277 | + if (drawMonth < 0) { |
| 1278 | + drawMonth += 12; |
| 1279 | + drawYear--; |
| 1280 | + } |
| 1281 | + if (maxDate) { |
| 1282 | + var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), |
| 1283 | + maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate())); |
| 1284 | + maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); |
| 1285 | + while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { |
| 1286 | + drawMonth--; |
| 1287 | + if (drawMonth < 0) { |
| 1288 | + drawMonth = 11; |
| 1289 | + drawYear--; |
| 1290 | + } |
| 1291 | + } |
| 1292 | + } |
| 1293 | + inst.drawMonth = drawMonth; |
| 1294 | + inst.drawYear = drawYear; |
| 1295 | + var prevText = this._get(inst, 'prevText'); |
| 1296 | + prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, |
| 1297 | + this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), |
| 1298 | + this._getFormatConfig(inst))); |
| 1299 | + var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? |
| 1300 | + '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' + |
| 1301 | + ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : |
| 1302 | + (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>')); |
| 1303 | + var nextText = this._get(inst, 'nextText'); |
| 1304 | + nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, |
| 1305 | + this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), |
| 1306 | + this._getFormatConfig(inst))); |
| 1307 | + var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? |
| 1308 | + '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' + |
| 1309 | + ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : |
| 1310 | + (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>')); |
| 1311 | + var currentText = this._get(inst, 'currentText'); |
| 1312 | + var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); |
| 1313 | + currentText = (!navigationAsDateFormat ? currentText : |
| 1314 | + this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); |
| 1315 | + var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : ''); |
| 1316 | + var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + |
| 1317 | + (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' + |
| 1318 | + '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; |
| 1319 | + var firstDay = parseInt(this._get(inst, 'firstDay'),10); |
| 1320 | + firstDay = (isNaN(firstDay) ? 0 : firstDay); |
| 1321 | + var dayNames = this._get(inst, 'dayNames'); |
| 1322 | + var dayNamesShort = this._get(inst, 'dayNamesShort'); |
| 1323 | + var dayNamesMin = this._get(inst, 'dayNamesMin'); |
| 1324 | + var monthNames = this._get(inst, 'monthNames'); |
| 1325 | + var monthNamesShort = this._get(inst, 'monthNamesShort'); |
| 1326 | + var beforeShowDay = this._get(inst, 'beforeShowDay'); |
| 1327 | + var showOtherMonths = this._get(inst, 'showOtherMonths'); |
| 1328 | + var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; |
| 1329 | + var endDate = inst.endDay ? this._daylightSavingAdjust( |
| 1330 | + new Date(inst.endYear, inst.endMonth, inst.endDay)) : currentDate; |
| 1331 | + var defaultDate = this._getDefaultDate(inst); |
| 1332 | + var html = ''; |
| 1333 | + for (var row = 0; row < numMonths[0]; row++) { |
| 1334 | + var group = ''; |
| 1335 | + for (var col = 0; col < numMonths[1]; col++) { |
| 1336 | + var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); |
| 1337 | + var cornerClass = ' ui-corner-all'; |
| 1338 | + var calender = ''; |
| 1339 | + if (isMultiMonth) { |
| 1340 | + calender += '<div class="ui-datepicker-group ui-datepicker-group-'; |
| 1341 | + switch (col) { |
| 1342 | + case 0: calender += 'first'; cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; |
| 1343 | + case numMonths[1]-1: calender += 'last'; cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; |
| 1344 | + default: calender += 'middle'; cornerClass = ''; break; |
| 1345 | + } |
| 1346 | + calender += '">'; |
| 1347 | + } |
| 1348 | + calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' + |
| 1349 | + (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + |
| 1350 | + (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + |
| 1351 | + this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, |
| 1352 | + selectedDate, row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers |
| 1353 | + '</div><table class="ui-datepicker-calendar"><thead>' + |
| 1354 | + '<tr>'; |
| 1355 | + var thead = ''; |
| 1356 | + for (var dow = 0; dow < 7; dow++) { // days of the week |
| 1357 | + var day = (dow + firstDay) % 7; |
| 1358 | + thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' + |
| 1359 | + '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>'; |
| 1360 | + } |
| 1361 | + calender += thead + '</tr></thead><tbody>'; |
| 1362 | + var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); |
| 1363 | + if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) |
| 1364 | + inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); |
| 1365 | + var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; |
| 1366 | + var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate |
| 1367 | + var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); |
| 1368 | + for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows |
| 1369 | + calender += '<tr>'; |
| 1370 | + var tbody = ''; |
| 1371 | + for (var dow = 0; dow < 7; dow++) { // create date picker days |
| 1372 | + var daySettings = (beforeShowDay ? |
| 1373 | + beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); |
| 1374 | + var otherMonth = (printDate.getMonth() != drawMonth); |
| 1375 | + var unselectable = otherMonth || !daySettings[0] || |
| 1376 | + (minDate && printDate < minDate) || (maxDate && printDate > maxDate); |
| 1377 | + tbody += '<td class="' + |
| 1378 | + ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends |
| 1379 | + (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months |
| 1380 | + ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key |
| 1381 | + (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ? |
| 1382 | + // or defaultDate is current printedDate and defaultDate is selectedDate |
| 1383 | + ' ' + this._dayOverClass : '') + // highlight selected day |
| 1384 | + (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days |
| 1385 | + (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates |
| 1386 | + (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range |
| 1387 | + ' ' + this._currentClass : '') + // highlight selected day |
| 1388 | + (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) |
| 1389 | + ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title |
| 1390 | + (unselectable ? '' : ' onclick="DP_jQuery.datepicker._selectDay(\'#' + |
| 1391 | + inst.id + '\',' + drawMonth + ',' + drawYear + ', this);return false;"') + '>' + // actions |
| 1392 | + (otherMonth ? (showOtherMonths ? printDate.getDate() : ' ') : // display for other months |
| 1393 | + (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + |
| 1394 | + (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + |
| 1395 | + (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range |
| 1396 | + ' ui-state-active' : '') + // highlight selected day |
| 1397 | + '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display for this month |
| 1398 | + printDate.setDate(printDate.getDate() + 1); |
| 1399 | + printDate = this._daylightSavingAdjust(printDate); |
| 1400 | + } |
| 1401 | + calender += tbody + '</tr>'; |
| 1402 | + } |
| 1403 | + drawMonth++; |
| 1404 | + if (drawMonth > 11) { |
| 1405 | + drawMonth = 0; |
| 1406 | + drawYear++; |
| 1407 | + } |
| 1408 | + calender += '</tbody></table>' + (isMultiMonth ? '</div>' + |
| 1409 | + ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : ''); |
| 1410 | + group += calender; |
| 1411 | + } |
| 1412 | + html += group; |
| 1413 | + } |
| 1414 | + html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ? |
| 1415 | + '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : ''); |
| 1416 | + inst._keyEvent = false; |
| 1417 | + return html; |
| 1418 | + }, |
| 1419 | + |
| 1420 | + /* Generate the month and year header. */ |
| 1421 | + _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, |
| 1422 | + selectedDate, secondary, monthNames, monthNamesShort) { |
| 1423 | + minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate); |
| 1424 | + var changeMonth = this._get(inst, 'changeMonth'); |
| 1425 | + var changeYear = this._get(inst, 'changeYear'); |
| 1426 | + var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); |
| 1427 | + var html = '<div class="ui-datepicker-title">'; |
| 1428 | + var monthHtml = ''; |
| 1429 | + // month selection |
| 1430 | + if (secondary || !changeMonth) |
| 1431 | + monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span> '; |
| 1432 | + else { |
| 1433 | + var inMinYear = (minDate && minDate.getFullYear() == drawYear); |
| 1434 | + var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); |
| 1435 | + monthHtml += '<select class="ui-datepicker-month" ' + |
| 1436 | + 'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' + |
| 1437 | + 'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + |
| 1438 | + '>'; |
| 1439 | + for (var month = 0; month < 12; month++) { |
| 1440 | + if ((!inMinYear || month >= minDate.getMonth()) && |
| 1441 | + (!inMaxYear || month <= maxDate.getMonth())) |
| 1442 | + monthHtml += '<option value="' + month + '"' + |
| 1443 | + (month == drawMonth ? ' selected="selected"' : '') + |
| 1444 | + '>' + monthNamesShort[month] + '</option>'; |
| 1445 | + } |
| 1446 | + monthHtml += '</select>'; |
| 1447 | + } |
| 1448 | + if (!showMonthAfterYear) |
| 1449 | + html += monthHtml + ((secondary || changeMonth || changeYear) && (!(changeMonth && changeYear)) ? ' ' : ''); |
| 1450 | + // year selection |
| 1451 | + if (secondary || !changeYear) |
| 1452 | + html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; |
| 1453 | + else { |
| 1454 | + // determine range of years to display |
| 1455 | + var years = this._get(inst, 'yearRange').split(':'); |
| 1456 | + var year = 0; |
| 1457 | + var endYear = 0; |
| 1458 | + if (years.length != 2) { |
| 1459 | + year = drawYear - 10; |
| 1460 | + endYear = drawYear + 10; |
| 1461 | + } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') { |
| 1462 | + year = drawYear + parseInt(years[0], 10); |
| 1463 | + endYear = drawYear + parseInt(years[1], 10); |
| 1464 | + } else { |
| 1465 | + year = parseInt(years[0], 10); |
| 1466 | + endYear = parseInt(years[1], 10); |
| 1467 | + } |
| 1468 | + year = (minDate ? Math.max(year, minDate.getFullYear()) : year); |
| 1469 | + endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); |
| 1470 | + html += '<select class="ui-datepicker-year" ' + |
| 1471 | + 'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' + |
| 1472 | + 'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + |
| 1473 | + '>'; |
| 1474 | + for (; year <= endYear; year++) { |
| 1475 | + html += '<option value="' + year + '"' + |
| 1476 | + (year == drawYear ? ' selected="selected"' : '') + |
| 1477 | + '>' + year + '</option>'; |
| 1478 | + } |
| 1479 | + html += '</select>'; |
| 1480 | + } |
| 1481 | + if (showMonthAfterYear) |
| 1482 | + html += (secondary || changeMonth || changeYear ? ' ' : '') + monthHtml; |
| 1483 | + html += '</div>'; // Close datepicker_header |
| 1484 | + return html; |
| 1485 | + }, |
| 1486 | + |
| 1487 | + /* Adjust one of the date sub-fields. */ |
| 1488 | + _adjustInstDate: function(inst, offset, period) { |
| 1489 | + var year = inst.drawYear + (period == 'Y' ? offset : 0); |
| 1490 | + var month = inst.drawMonth + (period == 'M' ? offset : 0); |
| 1491 | + var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + |
| 1492 | + (period == 'D' ? offset : 0); |
| 1493 | + var date = this._daylightSavingAdjust(new Date(year, month, day)); |
| 1494 | + // ensure it is within the bounds set |
| 1495 | + var minDate = this._getMinMaxDate(inst, 'min', true); |
| 1496 | + var maxDate = this._getMinMaxDate(inst, 'max'); |
| 1497 | + date = (minDate && date < minDate ? minDate : date); |
| 1498 | + date = (maxDate && date > maxDate ? maxDate : date); |
| 1499 | + inst.selectedDay = date.getDate(); |
| 1500 | + inst.drawMonth = inst.selectedMonth = date.getMonth(); |
| 1501 | + inst.drawYear = inst.selectedYear = date.getFullYear(); |
| 1502 | + if (period == 'M' || period == 'Y') |
| 1503 | + this._notifyChange(inst); |
| 1504 | + }, |
| 1505 | + |
| 1506 | + /* Notify change of month/year. */ |
| 1507 | + _notifyChange: function(inst) { |
| 1508 | + var onChange = this._get(inst, 'onChangeMonthYear'); |
| 1509 | + if (onChange) |
| 1510 | + onChange.apply((inst.input ? inst.input[0] : null), |
| 1511 | + [inst.selectedYear, inst.selectedMonth + 1, inst]); |
| 1512 | + }, |
| 1513 | + |
| 1514 | + /* Determine the number of months to show. */ |
| 1515 | + _getNumberOfMonths: function(inst) { |
| 1516 | + var numMonths = this._get(inst, 'numberOfMonths'); |
| 1517 | + return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); |
| 1518 | + }, |
| 1519 | + |
| 1520 | + /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */ |
| 1521 | + _getMinMaxDate: function(inst, minMax, checkRange) { |
| 1522 | + var date = this._determineDate(this._get(inst, minMax + 'Date'), null); |
| 1523 | + return (!checkRange || !inst.rangeStart ? date : |
| 1524 | + (!date || inst.rangeStart > date ? inst.rangeStart : date)); |
| 1525 | + }, |
| 1526 | + |
| 1527 | + /* Find the number of days in a given month. */ |
| 1528 | + _getDaysInMonth: function(year, month) { |
| 1529 | + return 32 - new Date(year, month, 32).getDate(); |
| 1530 | + }, |
| 1531 | + |
| 1532 | + /* Find the day of the week of the first of a month. */ |
| 1533 | + _getFirstDayOfMonth: function(year, month) { |
| 1534 | + return new Date(year, month, 1).getDay(); |
| 1535 | + }, |
| 1536 | + |
| 1537 | + /* Determines if we should allow a "next/prev" month display change. */ |
| 1538 | + _canAdjustMonth: function(inst, offset, curYear, curMonth) { |
| 1539 | + var numMonths = this._getNumberOfMonths(inst); |
| 1540 | + var date = this._daylightSavingAdjust(new Date( |
| 1541 | + curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1)); |
| 1542 | + if (offset < 0) |
| 1543 | + date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); |
| 1544 | + return this._isInRange(inst, date); |
| 1545 | + }, |
| 1546 | + |
| 1547 | + /* Is the given date in the accepted range? */ |
| 1548 | + _isInRange: function(inst, date) { |
| 1549 | + // during range selection, use minimum of selected date and range start |
| 1550 | + var newMinDate = (!inst.rangeStart ? null : this._daylightSavingAdjust( |
| 1551 | + new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay))); |
| 1552 | + newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate); |
| 1553 | + var minDate = newMinDate || this._getMinMaxDate(inst, 'min'); |
| 1554 | + var maxDate = this._getMinMaxDate(inst, 'max'); |
| 1555 | + return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate)); |
| 1556 | + }, |
| 1557 | + |
| 1558 | + /* Provide the configuration settings for formatting/parsing. */ |
| 1559 | + _getFormatConfig: function(inst) { |
| 1560 | + var shortYearCutoff = this._get(inst, 'shortYearCutoff'); |
| 1561 | + shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : |
| 1562 | + new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); |
| 1563 | + return {shortYearCutoff: shortYearCutoff, |
| 1564 | + dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), |
| 1565 | + monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; |
| 1566 | + }, |
| 1567 | + |
| 1568 | + /* Format the given date for display. */ |
| 1569 | + _formatDate: function(inst, day, month, year) { |
| 1570 | + if (!day) { |
| 1571 | + inst.currentDay = inst.selectedDay; |
| 1572 | + inst.currentMonth = inst.selectedMonth; |
| 1573 | + inst.currentYear = inst.selectedYear; |
| 1574 | + } |
| 1575 | + var date = (day ? (typeof day == 'object' ? day : |
| 1576 | + this._daylightSavingAdjust(new Date(year, month, day))) : |
| 1577 | + this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); |
| 1578 | + return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); |
| 1579 | + } |
| 1580 | +}); |
| 1581 | + |
| 1582 | +/* jQuery extend now ignores nulls! */ |
| 1583 | +function extendRemove(target, props) { |
| 1584 | + $.extend(target, props); |
| 1585 | + for (var name in props) |
| 1586 | + if (props[name] == null || props[name] == undefined) |
| 1587 | + target[name] = props[name]; |
| 1588 | + return target; |
| 1589 | +}; |
| 1590 | + |
| 1591 | +/* Determine whether an object is an array. */ |
| 1592 | +function isArray(a) { |
| 1593 | + return (a && (($.browser.safari && typeof a == 'object' && a.length) || |
| 1594 | + (a.constructor && a.constructor.toString().match(/\Array\(\)/)))); |
| 1595 | +}; |
| 1596 | + |
| 1597 | +/* Invoke the datepicker functionality. |
| 1598 | + @param options string - a command, optionally followed by additional parameters or |
| 1599 | + Object - settings for attaching new datepicker functionality |
| 1600 | + @return jQuery object */ |
| 1601 | +$.fn.datepicker = function(options){ |
| 1602 | + |
| 1603 | + /* Initialise the date picker. */ |
| 1604 | + if (!$.datepicker.initialized) { |
| 1605 | + $(document).mousedown($.datepicker._checkExternalClick). |
| 1606 | + find('body').append($.datepicker.dpDiv); |
| 1607 | + $.datepicker.initialized = true; |
| 1608 | + } |
| 1609 | + |
| 1610 | + var otherArgs = Array.prototype.slice.call(arguments, 1); |
| 1611 | + if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate')) |
| 1612 | + return $.datepicker['_' + options + 'Datepicker']. |
| 1613 | + apply($.datepicker, [this[0]].concat(otherArgs)); |
| 1614 | + return this.each(function() { |
| 1615 | + typeof options == 'string' ? |
| 1616 | + $.datepicker['_' + options + 'Datepicker']. |
| 1617 | + apply($.datepicker, [this].concat(otherArgs)) : |
| 1618 | + $.datepicker._attachDatepicker(this, options); |
| 1619 | + }); |
| 1620 | +}; |
| 1621 | + |
| 1622 | +$.datepicker = new Datepicker(); // singleton instance |
| 1623 | +$.datepicker.initialized = false; |
| 1624 | +$.datepicker.uuid = new Date().getTime(); |
| 1625 | +$.datepicker.version = "1.7.1"; |
| 1626 | + |
| 1627 | +// Workaround for #4055 |
| 1628 | +// Add another global to avoid noConflict issues with inline event handlers |
| 1629 | +window.DP_jQuery = $; |
| 1630 | + |
| 1631 | +})(jQuery); |
Index: trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.dialog.js |
— | — | @@ -0,0 +1,650 @@ |
| 2 | +/* |
| 3 | + * jQuery UI Dialog 1.7.1 |
| 4 | + * |
| 5 | + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
| 6 | + * Dual licensed under the MIT (MIT-LICENSE.txt) |
| 7 | + * and GPL (GPL-LICENSE.txt) licenses. |
| 8 | + * |
| 9 | + * http://docs.jquery.com/UI/Dialog |
| 10 | + * |
| 11 | + * Depends: |
| 12 | + * ui.core.js |
| 13 | + * ui.draggable.js |
| 14 | + * ui.resizable.js |
| 15 | + */ |
| 16 | +(function($) { |
| 17 | + |
| 18 | +var setDataSwitch = { |
| 19 | + dragStart : "start.draggable", |
| 20 | + drag : "drag.draggable", |
| 21 | + dragStop : "stop.draggable", |
| 22 | + maxHeight : "maxHeight.resizable", |
| 23 | + minHeight : "minHeight.resizable", |
| 24 | + maxWidth : "maxWidth.resizable", |
| 25 | + minWidth : "minWidth.resizable", |
| 26 | + resizeStart : "start.resizable", |
| 27 | + resize : "drag.resizable", |
| 28 | + resizeStop : "stop.resizable" |
| 29 | + }, |
| 30 | + |
| 31 | + uiDialogClasses = |
| 32 | + 'ui-dialog ' + |
| 33 | + 'ui-widget ' + |
| 34 | + 'ui-widget-content ' + |
| 35 | + 'ui-corner-all '; |
| 36 | + |
| 37 | +$.widget("ui.dialog", { |
| 38 | + |
| 39 | + _init: function() { |
| 40 | + this.originalTitle = this.element.attr('title'); |
| 41 | + |
| 42 | + var self = this, |
| 43 | + options = this.options, |
| 44 | + |
| 45 | + title = options.title || this.originalTitle || ' ', |
| 46 | + titleId = $.ui.dialog.getTitleId(this.element), |
| 47 | + |
| 48 | + uiDialog = (this.uiDialog = $('<div/>')) |
| 49 | + .appendTo(document.body) |
| 50 | + .hide() |
| 51 | + .addClass(uiDialogClasses + options.dialogClass) |
| 52 | + .css({ |
| 53 | + position: 'absolute', |
| 54 | + overflow: 'hidden', |
| 55 | + zIndex: options.zIndex |
| 56 | + }) |
| 57 | + // setting tabIndex makes the div focusable |
| 58 | + // setting outline to 0 prevents a border on focus in Mozilla |
| 59 | + .attr('tabIndex', -1).css('outline', 0).keydown(function(event) { |
| 60 | + (options.closeOnEscape && event.keyCode |
| 61 | + && event.keyCode == $.ui.keyCode.ESCAPE && self.close(event)); |
| 62 | + }) |
| 63 | + .attr({ |
| 64 | + role: 'dialog', |
| 65 | + 'aria-labelledby': titleId |
| 66 | + }) |
| 67 | + .mousedown(function(event) { |
| 68 | + self.moveToTop(false, event); |
| 69 | + }), |
| 70 | + |
| 71 | + uiDialogContent = this.element |
| 72 | + .show() |
| 73 | + .removeAttr('title') |
| 74 | + .addClass( |
| 75 | + 'ui-dialog-content ' + |
| 76 | + 'ui-widget-content') |
| 77 | + .appendTo(uiDialog), |
| 78 | + |
| 79 | + uiDialogTitlebar = (this.uiDialogTitlebar = $('<div></div>')) |
| 80 | + .addClass( |
| 81 | + 'ui-dialog-titlebar ' + |
| 82 | + 'ui-widget-header ' + |
| 83 | + 'ui-corner-all ' + |
| 84 | + 'ui-helper-clearfix' |
| 85 | + ) |
| 86 | + .prependTo(uiDialog), |
| 87 | + |
| 88 | + uiDialogTitlebarClose = $('<a href="#"/>') |
| 89 | + .addClass( |
| 90 | + 'ui-dialog-titlebar-close ' + |
| 91 | + 'ui-corner-all' |
| 92 | + ) |
| 93 | + .attr('role', 'button') |
| 94 | + .hover( |
| 95 | + function() { |
| 96 | + uiDialogTitlebarClose.addClass('ui-state-hover'); |
| 97 | + }, |
| 98 | + function() { |
| 99 | + uiDialogTitlebarClose.removeClass('ui-state-hover'); |
| 100 | + } |
| 101 | + ) |
| 102 | + .focus(function() { |
| 103 | + uiDialogTitlebarClose.addClass('ui-state-focus'); |
| 104 | + }) |
| 105 | + .blur(function() { |
| 106 | + uiDialogTitlebarClose.removeClass('ui-state-focus'); |
| 107 | + }) |
| 108 | + .mousedown(function(ev) { |
| 109 | + ev.stopPropagation(); |
| 110 | + }) |
| 111 | + .click(function(event) { |
| 112 | + self.close(event); |
| 113 | + return false; |
| 114 | + }) |
| 115 | + .appendTo(uiDialogTitlebar), |
| 116 | + |
| 117 | + uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>')) |
| 118 | + .addClass( |
| 119 | + 'ui-icon ' + |
| 120 | + 'ui-icon-closethick' |
| 121 | + ) |
| 122 | + .text(options.closeText) |
| 123 | + .appendTo(uiDialogTitlebarClose), |
| 124 | + |
| 125 | + uiDialogTitle = $('<span/>') |
| 126 | + .addClass('ui-dialog-title') |
| 127 | + .attr('id', titleId) |
| 128 | + .html(title) |
| 129 | + .prependTo(uiDialogTitlebar); |
| 130 | + |
| 131 | + uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); |
| 132 | + |
| 133 | + (options.draggable && $.fn.draggable && this._makeDraggable()); |
| 134 | + (options.resizable && $.fn.resizable && this._makeResizable()); |
| 135 | + |
| 136 | + this._createButtons(options.buttons); |
| 137 | + this._isOpen = false; |
| 138 | + |
| 139 | + (options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe()); |
| 140 | + (options.autoOpen && this.open()); |
| 141 | + |
| 142 | + }, |
| 143 | + |
| 144 | + destroy: function() { |
| 145 | + (this.overlay && this.overlay.destroy()); |
| 146 | + this.uiDialog.hide(); |
| 147 | + this.element |
| 148 | + .unbind('.dialog') |
| 149 | + .removeData('dialog') |
| 150 | + .removeClass('ui-dialog-content ui-widget-content') |
| 151 | + .hide().appendTo('body'); |
| 152 | + this.uiDialog.remove(); |
| 153 | + |
| 154 | + (this.originalTitle && this.element.attr('title', this.originalTitle)); |
| 155 | + }, |
| 156 | + |
| 157 | + close: function(event) { |
| 158 | + var self = this; |
| 159 | + |
| 160 | + if (false === self._trigger('beforeclose', event)) { |
| 161 | + return; |
| 162 | + } |
| 163 | + |
| 164 | + (self.overlay && self.overlay.destroy()); |
| 165 | + self.uiDialog.unbind('keypress.ui-dialog'); |
| 166 | + |
| 167 | + (self.options.hide |
| 168 | + ? self.uiDialog.hide(self.options.hide, function() { |
| 169 | + self._trigger('close', event); |
| 170 | + }) |
| 171 | + : self.uiDialog.hide() && self._trigger('close', event)); |
| 172 | + |
| 173 | + $.ui.dialog.overlay.resize(); |
| 174 | + |
| 175 | + self._isOpen = false; |
| 176 | + }, |
| 177 | + |
| 178 | + isOpen: function() { |
| 179 | + return this._isOpen; |
| 180 | + }, |
| 181 | + |
| 182 | + // the force parameter allows us to move modal dialogs to their correct |
| 183 | + // position on open |
| 184 | + moveToTop: function(force, event) { |
| 185 | + |
| 186 | + if ((this.options.modal && !force) |
| 187 | + || (!this.options.stack && !this.options.modal)) { |
| 188 | + return this._trigger('focus', event); |
| 189 | + } |
| 190 | + |
| 191 | + if (this.options.zIndex > $.ui.dialog.maxZ) { |
| 192 | + $.ui.dialog.maxZ = this.options.zIndex; |
| 193 | + } |
| 194 | + (this.overlay && this.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = ++$.ui.dialog.maxZ)); |
| 195 | + |
| 196 | + //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed. |
| 197 | + // http://ui.jquery.com/bugs/ticket/3193 |
| 198 | + var saveScroll = { scrollTop: this.element.attr('scrollTop'), scrollLeft: this.element.attr('scrollLeft') }; |
| 199 | + this.uiDialog.css('z-index', ++$.ui.dialog.maxZ); |
| 200 | + this.element.attr(saveScroll); |
| 201 | + this._trigger('focus', event); |
| 202 | + }, |
| 203 | + |
| 204 | + open: function() { |
| 205 | + if (this._isOpen) { return; } |
| 206 | + |
| 207 | + var options = this.options, |
| 208 | + uiDialog = this.uiDialog; |
| 209 | + |
| 210 | + this.overlay = options.modal ? new $.ui.dialog.overlay(this) : null; |
| 211 | + (uiDialog.next().length && uiDialog.appendTo('body')); |
| 212 | + this._size(); |
| 213 | + this._position(options.position); |
| 214 | + uiDialog.show(options.show); |
| 215 | + this.moveToTop(true); |
| 216 | + |
| 217 | + // prevent tabbing out of modal dialogs |
| 218 | + (options.modal && uiDialog.bind('keypress.ui-dialog', function(event) { |
| 219 | + if (event.keyCode != $.ui.keyCode.TAB) { |
| 220 | + return; |
| 221 | + } |
| 222 | + |
| 223 | + var tabbables = $(':tabbable', this), |
| 224 | + first = tabbables.filter(':first')[0], |
| 225 | + last = tabbables.filter(':last')[0]; |
| 226 | + |
| 227 | + if (event.target == last && !event.shiftKey) { |
| 228 | + setTimeout(function() { |
| 229 | + first.focus(); |
| 230 | + }, 1); |
| 231 | + } else if (event.target == first && event.shiftKey) { |
| 232 | + setTimeout(function() { |
| 233 | + last.focus(); |
| 234 | + }, 1); |
| 235 | + } |
| 236 | + })); |
| 237 | + |
| 238 | + // set focus to the first tabbable element in the content area or the first button |
| 239 | + // if there are no tabbable elements, set focus on the dialog itself |
| 240 | + $([]) |
| 241 | + .add(uiDialog.find('.ui-dialog-content :tabbable:first')) |
| 242 | + .add(uiDialog.find('.ui-dialog-buttonpane :tabbable:first')) |
| 243 | + .add(uiDialog) |
| 244 | + .filter(':first') |
| 245 | + .focus(); |
| 246 | + |
| 247 | + this._trigger('open'); |
| 248 | + this._isOpen = true; |
| 249 | + }, |
| 250 | + |
| 251 | + _createButtons: function(buttons) { |
| 252 | + var self = this, |
| 253 | + hasButtons = false, |
| 254 | + uiDialogButtonPane = $('<div></div>') |
| 255 | + .addClass( |
| 256 | + 'ui-dialog-buttonpane ' + |
| 257 | + 'ui-widget-content ' + |
| 258 | + 'ui-helper-clearfix' |
| 259 | + ); |
| 260 | + |
| 261 | + // if we already have a button pane, remove it |
| 262 | + this.uiDialog.find('.ui-dialog-buttonpane').remove(); |
| 263 | + |
| 264 | + (typeof buttons == 'object' && buttons !== null && |
| 265 | + $.each(buttons, function() { return !(hasButtons = true); })); |
| 266 | + if (hasButtons) { |
| 267 | + $.each(buttons, function(name, fn) { |
| 268 | + $('<button type="button"></button>') |
| 269 | + .addClass( |
| 270 | + 'ui-state-default ' + |
| 271 | + 'ui-corner-all' |
| 272 | + ) |
| 273 | + .text(name) |
| 274 | + .click(function() { fn.apply(self.element[0], arguments); }) |
| 275 | + .hover( |
| 276 | + function() { |
| 277 | + $(this).addClass('ui-state-hover'); |
| 278 | + }, |
| 279 | + function() { |
| 280 | + $(this).removeClass('ui-state-hover'); |
| 281 | + } |
| 282 | + ) |
| 283 | + .focus(function() { |
| 284 | + $(this).addClass('ui-state-focus'); |
| 285 | + }) |
| 286 | + .blur(function() { |
| 287 | + $(this).removeClass('ui-state-focus'); |
| 288 | + }) |
| 289 | + .appendTo(uiDialogButtonPane); |
| 290 | + }); |
| 291 | + uiDialogButtonPane.appendTo(this.uiDialog); |
| 292 | + } |
| 293 | + }, |
| 294 | + |
| 295 | + _makeDraggable: function() { |
| 296 | + var self = this, |
| 297 | + options = this.options, |
| 298 | + heightBeforeDrag; |
| 299 | + |
| 300 | + this.uiDialog.draggable({ |
| 301 | + cancel: '.ui-dialog-content', |
| 302 | + handle: '.ui-dialog-titlebar', |
| 303 | + containment: 'document', |
| 304 | + start: function() { |
| 305 | + heightBeforeDrag = options.height; |
| 306 | + $(this).height($(this).height()).addClass("ui-dialog-dragging"); |
| 307 | + (options.dragStart && options.dragStart.apply(self.element[0], arguments)); |
| 308 | + }, |
| 309 | + drag: function() { |
| 310 | + (options.drag && options.drag.apply(self.element[0], arguments)); |
| 311 | + }, |
| 312 | + stop: function() { |
| 313 | + $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag); |
| 314 | + (options.dragStop && options.dragStop.apply(self.element[0], arguments)); |
| 315 | + $.ui.dialog.overlay.resize(); |
| 316 | + } |
| 317 | + }); |
| 318 | + }, |
| 319 | + |
| 320 | + _makeResizable: function(handles) { |
| 321 | + handles = (handles === undefined ? this.options.resizable : handles); |
| 322 | + var self = this, |
| 323 | + options = this.options, |
| 324 | + resizeHandles = typeof handles == 'string' |
| 325 | + ? handles |
| 326 | + : 'n,e,s,w,se,sw,ne,nw'; |
| 327 | + |
| 328 | + this.uiDialog.resizable({ |
| 329 | + cancel: '.ui-dialog-content', |
| 330 | + alsoResize: this.element, |
| 331 | + maxWidth: options.maxWidth, |
| 332 | + maxHeight: options.maxHeight, |
| 333 | + minWidth: options.minWidth, |
| 334 | + minHeight: options.minHeight, |
| 335 | + start: function() { |
| 336 | + $(this).addClass("ui-dialog-resizing"); |
| 337 | + (options.resizeStart && options.resizeStart.apply(self.element[0], arguments)); |
| 338 | + }, |
| 339 | + resize: function() { |
| 340 | + (options.resize && options.resize.apply(self.element[0], arguments)); |
| 341 | + }, |
| 342 | + handles: resizeHandles, |
| 343 | + stop: function() { |
| 344 | + $(this).removeClass("ui-dialog-resizing"); |
| 345 | + options.height = $(this).height(); |
| 346 | + options.width = $(this).width(); |
| 347 | + (options.resizeStop && options.resizeStop.apply(self.element[0], arguments)); |
| 348 | + $.ui.dialog.overlay.resize(); |
| 349 | + } |
| 350 | + }) |
| 351 | + .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se'); |
| 352 | + }, |
| 353 | + |
| 354 | + _position: function(pos) { |
| 355 | + var wnd = $(window), doc = $(document), |
| 356 | + pTop = doc.scrollTop(), pLeft = doc.scrollLeft(), |
| 357 | + minTop = pTop; |
| 358 | + |
| 359 | + if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) { |
| 360 | + pos = [ |
| 361 | + pos == 'right' || pos == 'left' ? pos : 'center', |
| 362 | + pos == 'top' || pos == 'bottom' ? pos : 'middle' |
| 363 | + ]; |
| 364 | + } |
| 365 | + if (pos.constructor != Array) { |
| 366 | + pos = ['center', 'middle']; |
| 367 | + } |
| 368 | + if (pos[0].constructor == Number) { |
| 369 | + pLeft += pos[0]; |
| 370 | + } else { |
| 371 | + switch (pos[0]) { |
| 372 | + case 'left': |
| 373 | + pLeft += 0; |
| 374 | + break; |
| 375 | + case 'right': |
| 376 | + pLeft += wnd.width() - this.uiDialog.outerWidth(); |
| 377 | + break; |
| 378 | + default: |
| 379 | + case 'center': |
| 380 | + pLeft += (wnd.width() - this.uiDialog.outerWidth()) / 2; |
| 381 | + } |
| 382 | + } |
| 383 | + if (pos[1].constructor == Number) { |
| 384 | + pTop += pos[1]; |
| 385 | + } else { |
| 386 | + switch (pos[1]) { |
| 387 | + case 'top': |
| 388 | + pTop += 0; |
| 389 | + break; |
| 390 | + case 'bottom': |
| 391 | + pTop += wnd.height() - this.uiDialog.outerHeight(); |
| 392 | + break; |
| 393 | + default: |
| 394 | + case 'middle': |
| 395 | + pTop += (wnd.height() - this.uiDialog.outerHeight()) / 2; |
| 396 | + } |
| 397 | + } |
| 398 | + |
| 399 | + // prevent the dialog from being too high (make sure the titlebar |
| 400 | + // is accessible) |
| 401 | + pTop = Math.max(pTop, minTop); |
| 402 | + this.uiDialog.css({top: pTop, left: pLeft}); |
| 403 | + }, |
| 404 | + |
| 405 | + _setData: function(key, value){ |
| 406 | + (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value)); |
| 407 | + switch (key) { |
| 408 | + case "buttons": |
| 409 | + this._createButtons(value); |
| 410 | + break; |
| 411 | + case "closeText": |
| 412 | + this.uiDialogTitlebarCloseText.text(value); |
| 413 | + break; |
| 414 | + case "dialogClass": |
| 415 | + this.uiDialog |
| 416 | + .removeClass(this.options.dialogClass) |
| 417 | + .addClass(uiDialogClasses + value); |
| 418 | + break; |
| 419 | + case "draggable": |
| 420 | + (value |
| 421 | + ? this._makeDraggable() |
| 422 | + : this.uiDialog.draggable('destroy')); |
| 423 | + break; |
| 424 | + case "height": |
| 425 | + this.uiDialog.height(value); |
| 426 | + break; |
| 427 | + case "position": |
| 428 | + this._position(value); |
| 429 | + break; |
| 430 | + case "resizable": |
| 431 | + var uiDialog = this.uiDialog, |
| 432 | + isResizable = this.uiDialog.is(':data(resizable)'); |
| 433 | + |
| 434 | + // currently resizable, becoming non-resizable |
| 435 | + (isResizable && !value && uiDialog.resizable('destroy')); |
| 436 | + |
| 437 | + // currently resizable, changing handles |
| 438 | + (isResizable && typeof value == 'string' && |
| 439 | + uiDialog.resizable('option', 'handles', value)); |
| 440 | + |
| 441 | + // currently non-resizable, becoming resizable |
| 442 | + (isResizable || this._makeResizable(value)); |
| 443 | + break; |
| 444 | + case "title": |
| 445 | + $(".ui-dialog-title", this.uiDialogTitlebar).html(value || ' '); |
| 446 | + break; |
| 447 | + case "width": |
| 448 | + this.uiDialog.width(value); |
| 449 | + break; |
| 450 | + } |
| 451 | + |
| 452 | + $.widget.prototype._setData.apply(this, arguments); |
| 453 | + }, |
| 454 | + |
| 455 | + _size: function() { |
| 456 | + /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content |
| 457 | + * divs will both have width and height set, so we need to reset them |
| 458 | + */ |
| 459 | + var options = this.options; |
| 460 | + |
| 461 | + // reset content sizing |
| 462 | + this.element.css({ |
| 463 | + height: 0, |
| 464 | + minHeight: 0, |
| 465 | + width: 'auto' |
| 466 | + }); |
| 467 | + |
| 468 | + // reset wrapper sizing |
| 469 | + // determine the height of all the non-content elements |
| 470 | + var nonContentHeight = this.uiDialog.css({ |
| 471 | + height: 'auto', |
| 472 | + width: options.width |
| 473 | + }) |
| 474 | + .height(); |
| 475 | + |
| 476 | + this.element |
| 477 | + .css({ |
| 478 | + minHeight: Math.max(options.minHeight - nonContentHeight, 0), |
| 479 | + height: options.height == 'auto' |
| 480 | + ? 'auto' |
| 481 | + : Math.max(options.height - nonContentHeight, 0) |
| 482 | + }); |
| 483 | + } |
| 484 | +}); |
| 485 | + |
| 486 | +$.extend($.ui.dialog, { |
| 487 | + version: "1.7.1", |
| 488 | + defaults: { |
| 489 | + autoOpen: true, |
| 490 | + bgiframe: false, |
| 491 | + buttons: {}, |
| 492 | + closeOnEscape: true, |
| 493 | + closeText: 'close', |
| 494 | + dialogClass: '', |
| 495 | + draggable: true, |
| 496 | + hide: null, |
| 497 | + height: 'auto', |
| 498 | + maxHeight: false, |
| 499 | + maxWidth: false, |
| 500 | + minHeight: 150, |
| 501 | + minWidth: 150, |
| 502 | + modal: false, |
| 503 | + position: 'center', |
| 504 | + resizable: true, |
| 505 | + show: null, |
| 506 | + stack: true, |
| 507 | + title: '', |
| 508 | + width: 300, |
| 509 | + zIndex: 1000 |
| 510 | + }, |
| 511 | + |
| 512 | + getter: 'isOpen', |
| 513 | + |
| 514 | + uuid: 0, |
| 515 | + maxZ: 0, |
| 516 | + |
| 517 | + getTitleId: function($el) { |
| 518 | + return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid); |
| 519 | + }, |
| 520 | + |
| 521 | + overlay: function(dialog) { |
| 522 | + this.$el = $.ui.dialog.overlay.create(dialog); |
| 523 | + } |
| 524 | +}); |
| 525 | + |
| 526 | +$.extend($.ui.dialog.overlay, { |
| 527 | + instances: [], |
| 528 | + maxZ: 0, |
| 529 | + events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','), |
| 530 | + function(event) { return event + '.dialog-overlay'; }).join(' '), |
| 531 | + create: function(dialog) { |
| 532 | + if (this.instances.length === 0) { |
| 533 | + // prevent use of anchors and inputs |
| 534 | + // we use a setTimeout in case the overlay is created from an |
| 535 | + // event that we're going to be cancelling (see #2804) |
| 536 | + setTimeout(function() { |
| 537 | + $(document).bind($.ui.dialog.overlay.events, function(event) { |
| 538 | + var dialogZ = $(event.target).parents('.ui-dialog').css('zIndex') || 0; |
| 539 | + return (dialogZ > $.ui.dialog.overlay.maxZ); |
| 540 | + }); |
| 541 | + }, 1); |
| 542 | + |
| 543 | + // allow closing by pressing the escape key |
| 544 | + $(document).bind('keydown.dialog-overlay', function(event) { |
| 545 | + (dialog.options.closeOnEscape && event.keyCode |
| 546 | + && event.keyCode == $.ui.keyCode.ESCAPE && dialog.close(event)); |
| 547 | + }); |
| 548 | + |
| 549 | + // handle window resize |
| 550 | + $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize); |
| 551 | + } |
| 552 | + |
| 553 | + var $el = $('<div></div>').appendTo(document.body) |
| 554 | + .addClass('ui-widget-overlay').css({ |
| 555 | + width: this.width(), |
| 556 | + height: this.height() |
| 557 | + }); |
| 558 | + |
| 559 | + (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe()); |
| 560 | + |
| 561 | + this.instances.push($el); |
| 562 | + return $el; |
| 563 | + }, |
| 564 | + |
| 565 | + destroy: function($el) { |
| 566 | + this.instances.splice($.inArray(this.instances, $el), 1); |
| 567 | + |
| 568 | + if (this.instances.length === 0) { |
| 569 | + $([document, window]).unbind('.dialog-overlay'); |
| 570 | + } |
| 571 | + |
| 572 | + $el.remove(); |
| 573 | + }, |
| 574 | + |
| 575 | + height: function() { |
| 576 | + // handle IE 6 |
| 577 | + if ($.browser.msie && $.browser.version < 7) { |
| 578 | + var scrollHeight = Math.max( |
| 579 | + document.documentElement.scrollHeight, |
| 580 | + document.body.scrollHeight |
| 581 | + ); |
| 582 | + var offsetHeight = Math.max( |
| 583 | + document.documentElement.offsetHeight, |
| 584 | + document.body.offsetHeight |
| 585 | + ); |
| 586 | + |
| 587 | + if (scrollHeight < offsetHeight) { |
| 588 | + return $(window).height() + 'px'; |
| 589 | + } else { |
| 590 | + return scrollHeight + 'px'; |
| 591 | + } |
| 592 | + // handle "good" browsers |
| 593 | + } else { |
| 594 | + return $(document).height() + 'px'; |
| 595 | + } |
| 596 | + }, |
| 597 | + |
| 598 | + width: function() { |
| 599 | + // handle IE 6 |
| 600 | + if ($.browser.msie && $.browser.version < 7) { |
| 601 | + var scrollWidth = Math.max( |
| 602 | + document.documentElement.scrollWidth, |
| 603 | + document.body.scrollWidth |
| 604 | + ); |
| 605 | + var offsetWidth = Math.max( |
| 606 | + document.documentElement.offsetWidth, |
| 607 | + document.body.offsetWidth |
| 608 | + ); |
| 609 | + |
| 610 | + if (scrollWidth < offsetWidth) { |
| 611 | + return $(window).width() + 'px'; |
| 612 | + } else { |
| 613 | + return scrollWidth + 'px'; |
| 614 | + } |
| 615 | + // handle "good" browsers |
| 616 | + } else { |
| 617 | + return $(document).width() + 'px'; |
| 618 | + } |
| 619 | + }, |
| 620 | + |
| 621 | + resize: function() { |
| 622 | + /* If the dialog is draggable and the user drags it past the |
| 623 | + * right edge of the window, the document becomes wider so we |
| 624 | + * need to stretch the overlay. If the user then drags the |
| 625 | + * dialog back to the left, the document will become narrower, |
| 626 | + * so we need to shrink the overlay to the appropriate size. |
| 627 | + * This is handled by shrinking the overlay before setting it |
| 628 | + * to the full document size. |
| 629 | + */ |
| 630 | + var $overlays = $([]); |
| 631 | + $.each($.ui.dialog.overlay.instances, function() { |
| 632 | + $overlays = $overlays.add(this); |
| 633 | + }); |
| 634 | + |
| 635 | + $overlays.css({ |
| 636 | + width: 0, |
| 637 | + height: 0 |
| 638 | + }).css({ |
| 639 | + width: $.ui.dialog.overlay.width(), |
| 640 | + height: $.ui.dialog.overlay.height() |
| 641 | + }); |
| 642 | + } |
| 643 | +}); |
| 644 | + |
| 645 | +$.extend($.ui.dialog.overlay.prototype, { |
| 646 | + destroy: function() { |
| 647 | + $.ui.dialog.overlay.destroy(this.$el); |
| 648 | + } |
| 649 | +}); |
| 650 | + |
| 651 | +})(jQuery); |
Index: trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.resizable.js |
— | — | @@ -0,0 +1,800 @@ |
| 2 | +/* |
| 3 | + * jQuery UI Resizable 1.7.1 |
| 4 | + * |
| 5 | + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) |
| 6 | + * Dual licensed under the MIT (MIT-LICENSE.txt) |
| 7 | + * and GPL (GPL-LICENSE.txt) licenses. |
| 8 | + * |
| 9 | + * http://docs.jquery.com/UI/Resizables |
| 10 | + * |
| 11 | + * Depends: |
| 12 | + * ui.core.js |
| 13 | + */ |
| 14 | +(function($) { |
| 15 | + |
| 16 | +$.widget("ui.resizable", $.extend({}, $.ui.mouse, { |
| 17 | + |
| 18 | + _init: function() { |
| 19 | + |
| 20 | + var self = this, o = this.options; |
| 21 | + this.element.addClass("ui-resizable"); |
| 22 | + |
| 23 | + $.extend(this, { |
| 24 | + _aspectRatio: !!(o.aspectRatio), |
| 25 | + aspectRatio: o.aspectRatio, |
| 26 | + originalElement: this.element, |
| 27 | + _proportionallyResizeElements: [], |
| 28 | + _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null |
| 29 | + }); |
| 30 | + |
| 31 | + //Wrap the element if it cannot hold child nodes |
| 32 | + if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { |
| 33 | + |
| 34 | + //Opera fix for relative positioning |
| 35 | + if (/relative/.test(this.element.css('position')) && $.browser.opera) |
| 36 | + this.element.css({ position: 'relative', top: 'auto', left: 'auto' }); |
| 37 | + |
| 38 | + //Create a wrapper element and set the wrapper to the new current internal element |
| 39 | + this.element.wrap( |
| 40 | + $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({ |
| 41 | + position: this.element.css('position'), |
| 42 | + width: this.element.outerWidth(), |
| 43 | + height: this.element.outerHeight(), |
| 44 | + top: this.element.css('top'), |
| 45 | + left: this.element.css('left') |
| 46 | + }) |
| 47 | + ); |
| 48 | + |
| 49 | + //Overwrite the original this.element |
| 50 | + this.element = this.element.parent().data( |
| 51 | + "resizable", this.element.data('resizable') |
| 52 | + ); |
| 53 | + |
| 54 | + this.elementIsWrapper = true; |
| 55 | + |
| 56 | + //Move margins to the wrapper |
| 57 | + this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); |
| 58 | + this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); |
| 59 | + |
| 60 | + //Prevent Safari textarea resize |
| 61 | + this.originalResizeStyle = this.originalElement.css('resize'); |
| 62 | + this.originalElement.css('resize', 'none'); |
| 63 | + |
| 64 | + //Push the actual element to our proportionallyResize internal array |
| 65 | + this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); |
| 66 | + |
| 67 | + // avoid IE jump (hard set the margin) |
| 68 | + this.originalElement.css({ margin: this.originalElement.css('margin') }); |
| 69 | + |
| 70 | + // fix handlers offset |
| 71 | + this._proportionallyResize(); |
| 72 | + |
| 73 | + } |
| 74 | + |
| 75 | + this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' }); |
| 76 | + if(this.handles.constructor == String) { |
| 77 | + |
| 78 | + if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; |
| 79 | + var n = this.handles.split(","); this.handles = {}; |
| 80 | + |
| 81 | + for(var i = 0; i < n.length; i++) { |
| 82 | + |
| 83 | + var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; |
| 84 | + var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); |
| 85 | + |
| 86 | + // increase zIndex of sw, se, ne, nw axis |
| 87 | + //TODO : this modifies original option |
| 88 | + if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex }); |
| 89 | + |
| 90 | + //TODO : What's going on here? |
| 91 | + if ('se' == handle) { |
| 92 | + axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); |
| 93 | + }; |
| 94 | + |
| 95 | + //Insert into internal handles object and append to element |
| 96 | + this.handles[handle] = '.ui-resizable-'+handle; |
| 97 | + this.element.append(axis); |
| 98 | + } |
| 99 | + |
| 100 | + } |
| 101 | + |
| 102 | + this._renderAxis = function(target) { |
| 103 | + |
| 104 | + target = target || this.element; |
| 105 | + |
| 106 | + for(var i in this.handles) { |
| 107 | + |
| 108 | + if(this.handles[i].constructor == String) |
| 109 | + this.handles[i] = $(this.handles[i], this.element).show(); |
| 110 | + |
| 111 | + //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) |
| 112 | + if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { |
| 113 | + |
| 114 | + var axis = $(this.handles[i], this.element), padWrapper = 0; |
| 115 | + |
| 116 | + //Checking the correct pad and border |
| 117 | + padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); |
| 118 | + |
| 119 | + //The padding type i have to apply... |
| 120 | + var padPos = [ 'padding', |
| 121 | + /ne|nw|n/.test(i) ? 'Top' : |
| 122 | + /se|sw|s/.test(i) ? 'Bottom' : |
| 123 | + /^e$/.test(i) ? 'Right' : 'Left' ].join(""); |
| 124 | + |
| 125 | + target.css(padPos, padWrapper); |
| 126 | + |
| 127 | + this._proportionallyResize(); |
| 128 | + |
| 129 | + } |
| 130 | + |
| 131 | + //TODO: What's that good for? There's not anything to be executed left |
| 132 | + if(!$(this.handles[i]).length) |
| 133 | + continue; |
| 134 | + |
| 135 | + } |
| 136 | + }; |
| 137 | + |
| 138 | + //TODO: make renderAxis a prototype function |
| 139 | + this._renderAxis(this.element); |
| 140 | + |
| 141 | + this._handles = $('.ui-resizable-handle', this.element) |
| 142 | + .disableSelection(); |
| 143 | + |
| 144 | + //Matching axis name |
| 145 | + this._handles.mouseover(function() { |
| 146 | + if (!self.resizing) { |
| 147 | + if (this.className) |
| 148 | + var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); |
| 149 | + //Axis, default = se |
| 150 | + self.axis = axis && axis[1] ? axis[1] : 'se'; |
| 151 | + } |
| 152 | + }); |
| 153 | + |
| 154 | + //If we want to auto hide the elements |
| 155 | + if (o.autoHide) { |
| 156 | + this._handles.hide(); |
| 157 | + $(this.element) |
| 158 | + .addClass("ui-resizable-autohide") |
| 159 | + .hover(function() { |
| 160 | + $(this).removeClass("ui-resizable-autohide"); |
| 161 | + self._handles.show(); |
| 162 | + }, |
| 163 | + function(){ |
| 164 | + if (!self.resizing) { |
| 165 | + $(this).addClass("ui-resizable-autohide"); |
| 166 | + self._handles.hide(); |
| 167 | + } |
| 168 | + }); |
| 169 | + } |
| 170 | + |
| 171 | + //Initialize the mouse interaction |
| 172 | + this._mouseInit(); |
| 173 | + |
| 174 | + }, |
| 175 | + |
| 176 | + destroy: function() { |
| 177 | + |
| 178 | + this._mouseDestroy(); |
| 179 | + |
| 180 | + var _destroy = function(exp) { |
| 181 | + $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") |
| 182 | + .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); |
| 183 | + }; |
| 184 | + |
| 185 | + //TODO: Unwrap at same DOM position |
| 186 | + if (this.elementIsWrapper) { |
| 187 | + _destroy(this.element); |
| 188 | + var wrapper = this.element; |
| 189 | + wrapper.parent().append( |
| 190 | + this.originalElement.css({ |
| 191 | + position: wrapper.css('position'), |
| 192 | + width: wrapper.outerWidth(), |
| 193 | + height: wrapper.outerHeight(), |
| 194 | + top: wrapper.css('top'), |
| 195 | + left: wrapper.css('left') |
| 196 | + }) |
| 197 | + ).end().remove(); |
| 198 | + } |
| 199 | + |
| 200 | + this.originalElement.css('resize', this.originalResizeStyle); |
| 201 | + _destroy(this.originalElement); |
| 202 | + |
| 203 | + }, |
| 204 | + |
| 205 | + _mouseCapture: function(event) { |
| 206 | + |
| 207 | + var handle = false; |
| 208 | + for(var i in this.handles) { |
| 209 | + if($(this.handles[i])[0] == event.target) handle = true; |
| 210 | + } |
| 211 | + |
| 212 | + return this.options.disabled || !!handle; |
| 213 | + |
| 214 | + }, |
| 215 | + |
| 216 | + _mouseStart: function(event) { |
| 217 | + |
| 218 | + var o = this.options, iniPos = this.element.position(), el = this.element; |
| 219 | + |
| 220 | + this.resizing = true; |
| 221 | + this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; |
| 222 | + |
| 223 | + // bugfix for http://dev.jquery.com/ticket/1749 |
| 224 | + if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { |
| 225 | + el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); |
| 226 | + } |
| 227 | + |
| 228 | + //Opera fixing relative position |
| 229 | + if ($.browser.opera && (/relative/).test(el.css('position'))) |
| 230 | + el.css({ position: 'relative', top: 'auto', left: 'auto' }); |
| 231 | + |
| 232 | + this._renderProxy(); |
| 233 | + |
| 234 | + var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); |
| 235 | + |
| 236 | + if (o.containment) { |
| 237 | + curleft += $(o.containment).scrollLeft() || 0; |
| 238 | + curtop += $(o.containment).scrollTop() || 0; |
| 239 | + } |
| 240 | + |
| 241 | + //Store needed variables |
| 242 | + this.offset = this.helper.offset(); |
| 243 | + this.position = { left: curleft, top: curtop }; |
| 244 | + this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; |
| 245 | + this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; |
| 246 | + this.originalPosition = { left: curleft, top: curtop }; |
| 247 | + this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; |
| 248 | + this.originalMousePosition = { left: event.pageX, top: event.pageY }; |
| 249 | + |
| 250 | + //Aspect Ratio |
| 251 | + this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); |
| 252 | + |
| 253 | + var cursor = $('.ui-resizable-' + this.axis).css('cursor'); |
| 254 | + $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); |
| 255 | + |
| 256 | + el.addClass("ui-resizable-resizing"); |
| 257 | + this._propagate("start", event); |
| 258 | + return true; |
| 259 | + }, |
| 260 | + |
| 261 | + _mouseDrag: function(event) { |
| 262 | + |
| 263 | + //Increase performance, avoid regex |
| 264 | + var el = this.helper, o = this.options, props = {}, |
| 265 | + self = this, smp = this.originalMousePosition, a = this.axis; |
| 266 | + |
| 267 | + var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; |
| 268 | + var trigger = this._change[a]; |
| 269 | + if (!trigger) return false; |
| 270 | + |
| 271 | + // Calculate the attrs that will be change |
| 272 | + var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; |
| 273 | + |
| 274 | + if (this._aspectRatio || event.shiftKey) |
| 275 | + data = this._updateRatio(data, event); |
| 276 | + |
| 277 | + data = this._respectSize(data, event); |
| 278 | + |
| 279 | + // plugins callbacks need to be called first |
| 280 | + this._propagate("resize", event); |
| 281 | + |
| 282 | + el.css({ |
| 283 | + top: this.position.top + "px", left: this.position.left + "px", |
| 284 | + width: this.size.width + "px", height: this.size.height + "px" |
| 285 | + }); |
| 286 | + |
| 287 | + if (!this._helper && this._proportionallyResizeElements.length) |
| 288 | + this._proportionallyResize(); |
| 289 | + |
| 290 | + this._updateCache(data); |
| 291 | + |
| 292 | + // calling the user callback at the end |
| 293 | + this._trigger('resize', event, this.ui()); |
| 294 | + |
| 295 | + return false; |
| 296 | + }, |
| 297 | + |
| 298 | + _mouseStop: function(event) { |
| 299 | + |
| 300 | + this.resizing = false; |
| 301 | + var o = this.options, self = this; |
| 302 | + |
| 303 | + if(this._helper) { |
| 304 | + var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), |
| 305 | + soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, |
| 306 | + soffsetw = ista ? 0 : self.sizeDiff.width; |
| 307 | + |
| 308 | + var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, |
| 309 | + left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, |
| 310 | + top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; |
| 311 | + |
| 312 | + if (!o.animate) |
| 313 | + this.element.css($.extend(s, { top: top, left: left })); |
| 314 | + |
| 315 | + self.helper.height(self.size.height); |
| 316 | + self.helper.width(self.size.width); |
| 317 | + |
| 318 | + if (this._helper && !o.animate) this._proportionallyResize(); |
| 319 | + } |
| 320 | + |
| 321 | + $('body').css('cursor', 'auto'); |
| 322 | + |
| 323 | + this.element.removeClass("ui-resizable-resizing"); |
| 324 | + |
| 325 | + this._propagate("stop", event); |
| 326 | + |
| 327 | + if (this._helper) this.helper.remove(); |
| 328 | + return false; |
| 329 | + |
| 330 | + }, |
| 331 | + |
| 332 | + _updateCache: function(data) { |
| 333 | + var o = this.options; |
| 334 | + this.offset = this.helper.offset(); |
| 335 | + if (isNumber(data.left)) this.position.left = data.left; |
| 336 | + if (isNumber(data.top)) this.position.top = data.top; |
| 337 | + if (isNumber(data.height)) this.size.height = data.height; |
| 338 | + if (isNumber(data.width)) this.size.width = data.width; |
| 339 | + }, |
| 340 | + |
| 341 | + _updateRatio: function(data, event) { |
| 342 | + |
| 343 | + var o = this.options, cpos = this.position, csize = this.size, a = this.axis; |
| 344 | + |
| 345 | + if (data.height) data.width = (csize.height * this.aspectRatio); |
| 346 | + else if (data.width) data.height = (csize.width / this.aspectRatio); |
| 347 | + |
| 348 | + if (a == 'sw') { |
| 349 | + data.left = cpos.left + (csize.width - data.width); |
| 350 | + data.top = null; |
| 351 | + } |
| 352 | + if (a == 'nw') { |
| 353 | + data.top = cpos.top + (csize.height - data.height); |
| 354 | + data.left = cpos.left + (csize.width - data.width); |
| 355 | + } |
| 356 | + |
| 357 | + return data; |
| 358 | + }, |
| 359 | + |
| 360 | + _respectSize: function(data, event) { |
| 361 | + |
| 362 | + var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, |
| 363 | + ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), |
| 364 | + isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); |
| 365 | + |
| 366 | + if (isminw) data.width = o.minWidth; |
| 367 | + if (isminh) data.height = o.minHeight; |
| 368 | + if (ismaxw) data.width = o.maxWidth; |
| 369 | + if (ismaxh) data.height = o.maxHeight; |
| 370 | + |
| 371 | + var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; |
| 372 | + var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); |
| 373 | + |
| 374 | + if (isminw && cw) data.left = dw - o.minWidth; |
| 375 | + if (ismaxw && cw) data.left = dw - o.maxWidth; |
| 376 | + if (isminh && ch) data.top = dh - o.minHeight; |
| 377 | + if (ismaxh && ch) data.top = dh - o.maxHeight; |
| 378 | + |
| 379 | + // fixing jump error on top/left - bug #2330 |
| 380 | + var isNotwh = !data.width && !data.height; |
| 381 | + if (isNotwh && !data.left && data.top) data.top = null; |
| 382 | + else if (isNotwh && !data.top && data.left) data.left = null; |
| 383 | + |
| 384 | + return data; |
| 385 | + }, |
| 386 | + |
| 387 | + _proportionallyResize: function() { |
| 388 | + |
| 389 | + var o = this.options; |
| 390 | + if (!this._proportionallyResizeElements.length) return; |
| 391 | + var element = this.helper || this.element; |
| 392 | + |
| 393 | + for (var i=0; i < this._proportionallyResizeElements.length; i++) { |
| 394 | + |
| 395 | + var prel = this._proportionallyResizeElements[i]; |
| 396 | + |
| 397 | + if (!this.borderDif) { |
| 398 | + var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], |
| 399 | + p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; |
| 400 | + |
| 401 | + this.borderDif = $.map(b, function(v, i) { |
| 402 | + var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; |
| 403 | + return border + padding; |
| 404 | + }); |
| 405 | + } |
| 406 | + |
| 407 | + if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length))) |
| 408 | + continue; |
| 409 | + |
| 410 | + prel.css({ |
| 411 | + height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, |
| 412 | + width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 |
| 413 | + }); |
| 414 | + |
| 415 | + }; |
| 416 | + |
| 417 | + }, |
| 418 | + |
| 419 | + _renderProxy: function() { |
| 420 | + |
| 421 | + var el = this.element, o = this.options; |
| 422 | + this.elementOffset = el.offset(); |
| 423 | + |
| 424 | + if(this._helper) { |
| 425 | + |
| 426 | + this.helper = this.helper || $('<div style="overflow:hidden;"></div>'); |
| 427 | + |
| 428 | + // fix ie6 offset TODO: This seems broken |
| 429 | + var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0), |
| 430 | + pxyoffset = ( ie6 ? 2 : -1 ); |
| 431 | + |
| 432 | + this.helper.addClass(this._helper).css({ |
| 433 | + width: this.element.outerWidth() + pxyoffset, |
| 434 | + height: this.element.outerHeight() + pxyoffset, |
| 435 | + position: 'absolute', |
| 436 | + left: this.elementOffset.left - ie6offset +'px', |
| 437 | + top: this.elementOffset.top - ie6offset +'px', |
| 438 | + zIndex: ++o.zIndex //TODO: Don't modify option |
| 439 | + }); |
| 440 | + |
| 441 | + this.helper |
| 442 | + .appendTo("body") |
| 443 | + .disableSelection(); |
| 444 | + |
| 445 | + } else { |
| 446 | + this.helper = this.element; |
| 447 | + } |
| 448 | + |
| 449 | + }, |
| 450 | + |
| 451 | + _change: { |
| 452 | + e: function(event, dx, dy) { |
| 453 | + return { width: this.originalSize.width + dx }; |
| 454 | + }, |
| 455 | + w: function(event, dx, dy) { |
| 456 | + var o = this.options, cs = this.originalSize, sp = this.originalPosition; |
| 457 | + return { left: sp.left + dx, width: cs.width - dx }; |
| 458 | + }, |
| 459 | + n: function(event, dx, dy) { |
| 460 | + var o = this.options, cs = this.originalSize, sp = this.originalPosition; |
| 461 | + return { top: sp.top + dy, height: cs.height - dy }; |
| 462 | + }, |
| 463 | + s: function(event, dx, dy) { |
| 464 | + return { height: this.originalSize.height + dy }; |
| 465 | + }, |
| 466 | + se: function(event, dx, dy) { |
| 467 | + return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); |
| 468 | + }, |
| 469 | + sw: function(event, dx, dy) { |
| 470 | + return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); |
| 471 | + }, |
| 472 | + ne: function(event, dx, dy) { |
| 473 | + return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); |
| 474 | + }, |
| 475 | + nw: function(event, dx, dy) { |
| 476 | + return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); |
| 477 | + } |
| 478 | + }, |
| 479 | + |
| 480 | + _propagate: function(n, event) { |
| 481 | + $.ui.plugin.call(this, n, [event, this.ui()]); |
| 482 | + (n != "resize" && this._trigger(n, event, this.ui())); |
| 483 | + }, |
| 484 | + |
| 485 | + plugins: {}, |
| 486 | + |
| 487 | + ui: function() { |
| 488 | + return { |
| 489 | + originalElement: this.originalElement, |
| 490 | + element: this.element, |
| 491 | + helper: this.helper, |
| 492 | + position: this.position, |
| 493 | + size: this.size, |
| 494 | + originalSize: this.originalSize, |
| 495 | + originalPosition: this.originalPosition |
| 496 | + }; |
| 497 | + } |
| 498 | + |
| 499 | +})); |
| 500 | + |
| 501 | +$.extend($.ui.resizable, { |
| 502 | + version: "1.7.1", |
| 503 | + eventPrefix: "resize", |
| 504 | + defaults: { |
| 505 | + alsoResize: false, |
| 506 | + animate: false, |
| 507 | + animateDuration: "slow", |
| 508 | + animateEasing: "swing", |
| 509 | + aspectRatio: false, |
| 510 | + autoHide: false, |
| 511 | + cancel: ":input,option", |
| 512 | + containment: false, |
| 513 | + delay: 0, |
| 514 | + distance: 1, |
| 515 | + ghost: false, |
| 516 | + grid: false, |
| 517 | + handles: "e,s,se", |
| 518 | + helper: false, |
| 519 | + maxHeight: null, |
| 520 | + maxWidth: null, |
| 521 | + minHeight: 10, |
| 522 | + minWidth: 10, |
| 523 | + zIndex: 1000 |
| 524 | + } |
| 525 | +}); |
| 526 | + |
| 527 | +/* |
| 528 | + * Resizable Extensions |
| 529 | + */ |
| 530 | + |
| 531 | +$.ui.plugin.add("resizable", "alsoResize", { |
| 532 | + |
| 533 | + start: function(event, ui) { |
| 534 | + |
| 535 | + var self = $(this).data("resizable"), o = self.options; |
| 536 | + |
| 537 | + _store = function(exp) { |
| 538 | + $(exp).each(function() { |
| 539 | + $(this).data("resizable-alsoresize", { |
| 540 | + width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10), |
| 541 | + left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10) |
| 542 | + }); |
| 543 | + }); |
| 544 | + }; |
| 545 | + |
| 546 | + if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { |
| 547 | + if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } |
| 548 | + else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); } |
| 549 | + }else{ |
| 550 | + _store(o.alsoResize); |
| 551 | + } |
| 552 | + }, |
| 553 | + |
| 554 | + resize: function(event, ui){ |
| 555 | + var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition; |
| 556 | + |
| 557 | + var delta = { |
| 558 | + height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0, |
| 559 | + top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 |
| 560 | + }, |
| 561 | + |
| 562 | + _alsoResize = function(exp, c) { |
| 563 | + $(exp).each(function() { |
| 564 | + var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left']; |
| 565 | + |
| 566 | + $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) { |
| 567 | + var sum = (start[prop]||0) + (delta[prop]||0); |
| 568 | + if (sum && sum >= 0) |
| 569 | + style[prop] = sum || null; |
| 570 | + }); |
| 571 | + |
| 572 | + //Opera fixing relative position |
| 573 | + if (/relative/.test(el.css('position')) && $.browser.opera) { |
| 574 | + self._revertToRelativePosition = true; |
| 575 | + el.css({ position: 'absolute', top: 'auto', left: 'auto' }); |
| 576 | + } |
| 577 | + |
| 578 | + el.css(style); |
| 579 | + }); |
| 580 | + }; |
| 581 | + |
| 582 | + if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { |
| 583 | + $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); }); |
| 584 | + }else{ |
| 585 | + _alsoResize(o.alsoResize); |
| 586 | + } |
| 587 | + }, |
| 588 | + |
| 589 | + stop: function(event, ui){ |
| 590 | + var self = $(this).data("resizable"); |
| 591 | + |
| 592 | + //Opera fixing relative position |
| 593 | + if (self._revertToRelativePosition && $.browser.opera) { |
| 594 | + self._revertToRelativePosition = false; |
| 595 | + el.css({ position: 'relative' }); |
| 596 | + } |
| 597 | + |
| 598 | + $(this).removeData("resizable-alsoresize-start"); |
| 599 | + } |
| 600 | +}); |
| 601 | + |
| 602 | +$.ui.plugin.add("resizable", "animate", { |
| 603 | + |
| 604 | + stop: function(event, ui) { |
| 605 | + var self = $(this).data("resizable"), o = self.options; |
| 606 | + |
| 607 | + var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), |
| 608 | + soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, |
| 609 | + soffsetw = ista ? 0 : self.sizeDiff.width; |
| 610 | + |
| 611 | + var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, |
| 612 | + left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, |
| 613 | + top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; |
| 614 | + |
| 615 | + self.element.animate( |
| 616 | + $.extend(style, top && left ? { top: top, left: left } : {}), { |
| 617 | + duration: o.animateDuration, |
| 618 | + easing: o.animateEasing, |
| 619 | + step: function() { |
| 620 | + |
| 621 | + var data = { |
| 622 | + width: parseInt(self.element.css('width'), 10), |
| 623 | + height: parseInt(self.element.css('height'), 10), |
| 624 | + top: parseInt(self.element.css('top'), 10), |
| 625 | + left: parseInt(self.element.css('left'), 10) |
| 626 | + }; |
| 627 | + |
| 628 | + if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); |
| 629 | + |
| 630 | + // propagating resize, and updating values for each animation step |
| 631 | + self._updateCache(data); |
| 632 | + self._propagate("resize", event); |
| 633 | + |
| 634 | + } |
| 635 | + } |
| 636 | + ); |
| 637 | + } |
| 638 | + |
| 639 | +}); |
| 640 | + |
| 641 | +$.ui.plugin.add("resizable", "containment", { |
| 642 | + |
| 643 | + start: function(event, ui) { |
| 644 | + var self = $(this).data("resizable"), o = self.options, el = self.element; |
| 645 | + var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; |
| 646 | + if (!ce) return; |
| 647 | + |
| 648 | + self.containerElement = $(ce); |
| 649 | + |
| 650 | + if (/document/.test(oc) || oc == document) { |
| 651 | + self.containerOffset = { left: 0, top: 0 }; |
| 652 | + self.containerPosition = { left: 0, top: 0 }; |
| 653 | + |
| 654 | + self.parentData = { |
| 655 | + element: $(document), left: 0, top: 0, |
| 656 | + width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight |
| 657 | + }; |
| 658 | + } |
| 659 | + |
| 660 | + // i'm a node, so compute top, left, right, bottom |
| 661 | + else { |
| 662 | + var element = $(ce), p = []; |
| 663 | + $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); |
| 664 | + |
| 665 | + self.containerOffset = element.offset(); |
| 666 | + self.containerPosition = element.position(); |
| 667 | + self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; |
| 668 | + |
| 669 | + var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width, |
| 670 | + width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); |
| 671 | + |
| 672 | + self.parentData = { |
| 673 | + element: ce, left: co.left, top: co.top, width: width, height: height |
| 674 | + }; |
| 675 | + } |
| 676 | + }, |
| 677 | + |
| 678 | + resize: function(event, ui) { |
| 679 | + var self = $(this).data("resizable"), o = self.options, |
| 680 | + ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position, |
| 681 | + pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement; |
| 682 | + |
| 683 | + if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; |
| 684 | + |
| 685 | + if (cp.left < (self._helper ? co.left : 0)) { |
| 686 | + self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left)); |
| 687 | + if (pRatio) self.size.height = self.size.width / o.aspectRatio; |
| 688 | + self.position.left = o.helper ? co.left : 0; |
| 689 | + } |
| 690 | + |
| 691 | + if (cp.top < (self._helper ? co.top : 0)) { |
| 692 | + self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top); |
| 693 | + if (pRatio) self.size.width = self.size.height * o.aspectRatio; |
| 694 | + self.position.top = self._helper ? co.top : 0; |
| 695 | + } |
| 696 | + |
| 697 | + self.offset.left = self.parentData.left+self.position.left; |
| 698 | + self.offset.top = self.parentData.top+self.position.top; |
| 699 | + |
| 700 | + var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ), |
| 701 | + hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height ); |
| 702 | + |
| 703 | + var isParent = self.containerElement.get(0) == self.element.parent().get(0), |
| 704 | + isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position')); |
| 705 | + |
| 706 | + if(isParent && isOffsetRelative) woset -= self.parentData.left; |
| 707 | + |
| 708 | + if (woset + self.size.width >= self.parentData.width) { |
| 709 | + self.size.width = self.parentData.width - woset; |
| 710 | + if (pRatio) self.size.height = self.size.width / self.aspectRatio; |
| 711 | + } |
| 712 | + |
| 713 | + if (hoset + self.size.height >= self.parentData.height) { |
| 714 | + self.size.height = self.parentData.height - hoset; |
| 715 | + if (pRatio) self.size.width = self.size.height * self.aspectRatio; |
| 716 | + } |
| 717 | + }, |
| 718 | + |
| 719 | + stop: function(event, ui){ |
| 720 | + var self = $(this).data("resizable"), o = self.options, cp = self.position, |
| 721 | + co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement; |
| 722 | + |
| 723 | + var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height; |
| 724 | + |
| 725 | + if (self._helper && !o.animate && (/relative/).test(ce.css('position'))) |
| 726 | + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); |
| 727 | + |
| 728 | + if (self._helper && !o.animate && (/static/).test(ce.css('position'))) |
| 729 | + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); |
| 730 | + |
| 731 | + } |
| 732 | +}); |
| 733 | + |
| 734 | +$.ui.plugin.add("resizable", "ghost", { |
| 735 | + |
| 736 | + start: function(event, ui) { |
| 737 | + |
| 738 | + var self = $(this).data("resizable"), o = self.options, cs = self.size; |
| 739 | + |
| 740 | + self.ghost = self.originalElement.clone(); |
| 741 | + self.ghost |
| 742 | + .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) |
| 743 | + .addClass('ui-resizable-ghost') |
| 744 | + .addClass(typeof o.ghost == 'string' ? o.ghost : ''); |
| 745 | + |
| 746 | + self.ghost.appendTo(self.helper); |
| 747 | + |
| 748 | + }, |
| 749 | + |
| 750 | + resize: function(event, ui){ |
| 751 | + var self = $(this).data("resizable"), o = self.options; |
| 752 | + if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width }); |
| 753 | + }, |
| 754 | + |
| 755 | + stop: function(event, ui){ |
| 756 | + var self = $(this).data("resizable"), o = self.options; |
| 757 | + if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0)); |
| 758 | + } |
| 759 | + |
| 760 | +}); |
| 761 | + |
| 762 | +$.ui.plugin.add("resizable", "grid", { |
| 763 | + |
| 764 | + resize: function(event, ui) { |
| 765 | + var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey; |
| 766 | + o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; |
| 767 | + var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); |
| 768 | + |
| 769 | + if (/^(se|s|e)$/.test(a)) { |
| 770 | + self.size.width = os.width + ox; |
| 771 | + self.size.height = os.height + oy; |
| 772 | + } |
| 773 | + else if (/^(ne)$/.test(a)) { |
| 774 | + self.size.width = os.width + ox; |
| 775 | + self.size.height = os.height + oy; |
| 776 | + self.position.top = op.top - oy; |
| 777 | + } |
| 778 | + else if (/^(sw)$/.test(a)) { |
| 779 | + self.size.width = os.width + ox; |
| 780 | + self.size.height = os.height + oy; |
| 781 | + self.position.left = op.left - ox; |
| 782 | + } |
| 783 | + else { |
| 784 | + self.size.width = os.width + ox; |
| 785 | + self.size.height = os.height + oy; |
| 786 | + self.position.top = op.top - oy; |
| 787 | + self.position.left = op.left - ox; |
| 788 | + } |
| 789 | + } |
| 790 | + |
| 791 | +}); |
| 792 | + |
| 793 | +var num = function(v) { |
| 794 | + return parseInt(v, 10) || 0; |
| 795 | +}; |
| 796 | + |
| 797 | +var isNumber = function(value) { |
| 798 | + return !isNaN(parseInt(value, 10)); |
| 799 | +}; |
| 800 | + |
| 801 | +})(jQuery); |
Index: trunk/extensions/UsabilityInitiative/Makefile |
— | — | @@ -12,6 +12,12 @@ |
13 | 13 | css/wikiEditor.preview.css |
14 | 14 | |
15 | 15 | PLUGINS := \ |
| 16 | + js/js2stopgap/ui.core.js\ |
| 17 | + js/js2stopgap/ui.datepicker.js\ |
| 18 | + js/js2stopgap/ui.dialog.js\ |
| 19 | + js/js2stopgap/ui.draggable.js\ |
| 20 | + js/js2stopgap/ui.resizable.js\ |
| 21 | + js/js2stopgap/ui.tabs.js\ |
16 | 22 | js/plugins/jquery.async.js\ |
17 | 23 | js/plugins/jquery.autoEllipsis.js\ |
18 | 24 | js/plugins/jquery.browser.js\ |
Property changes on: trunk/extensions/UsabilityInitiative |
___________________________________________________________________ |
Name: svn:ignore |
19 | 25 | - jsmin |
20 | 26 | + jsmin |
.project |