r60858 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r60857‎ | r60858 | r60859 >
Date:23:13, 8 January 2010
Author:dale
Status:deferred (Comments)
Tags:
Comment:
* removed jquery.ui stuff from "core" moved into the base_sets of UsabilityInitiative
* "core scripts" of mwEmbed do not include jquery ui
* So jquery.ui should be stored in a local extension folder until we merge in "js2" ( which includes jquery.ui )

* sill need to commit updated min files *
Modified paths:
  • /trunk/extensions/UsabilityInitiative (modified) (history)
  • /trunk/extensions/UsabilityInitiative/Makefile (modified) (history)
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2stopgap (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.core.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.datepicker.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.dialog.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.draggable.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.resizable.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2stopgap/ui.tabs.js (added) (history)
  • /trunk/phase3/js2/js2stopgap.js (modified) (history)

Diff [purge]

Index: trunk/phase3/js2/js2stopgap.js
@@ -4374,5083 +4374,7 @@
43754375
43764376 });
43774377 })();
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($) {
43884378
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 || '&nbsp;',
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 || '&nbsp;');
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&#8230;</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() : '&#xa0;') : // 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)) ? '&#xa0;' : '');
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 ? '&#xa0;' : '') + 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);
94554379 /* JavaScript for MediaWIki JS2 */
94564380
94574381 /**
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -9,7 +9,7 @@
1010 class UsabilityInitiativeHooks {
1111
1212 /* Static Members */
13 -
 13+
1414 private static $doOutput = false;
1515 private static $messages = array();
1616 private static $variables = array();
@@ -62,6 +62,16 @@
6363 // Core functionality of extension
6464 'base_sets' => array(
6565 '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
6676 array( 'src' => 'js/plugins/jquery.async.js', 'version' => 3 ),
6777 array( 'src' => 'js/plugins/jquery.autoEllipsis.js', 'version' => 5 ),
6878 array( 'src' => 'js/plugins/jquery.browser.js', 'version' => 3 ),
@@ -82,20 +92,20 @@
8393 array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 1 ),
8494 ),
8595 'combined' => array(
86 - array( 'src' => 'js/plugins.combined.js', 'version' => 135 ),
 96+ array( 'src' => 'js/plugins.combined.js', 'version' => 136 ),
8797 ),
8898 'minified' => array(
89 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 135 ),
 99+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 136 ),
90100 ),
91101 ),
92102 );
93 -
 103+
94104 /* Static Functions */
95 -
 105+
96106 public static function initialize() {
97107 self::$doOutput = true;
98108 }
99 -
 109+
100110 /**
101111 * AjaxAddScript hook
102112 * Adds scripts
@@ -105,12 +115,12 @@
106116 global $wgUsabilityInitiativeResourceMode;
107117 global $wgEnableJS2system, $wgEditToolbarRunTests;
108118 global $wgStyleVersion;
109 -
 119+
110120 wfRunHooks( 'UsabilityInitiativeLoadModules' );
111 -
 121+
112122 if ( !self::$doOutput )
113123 return true;
114 -
 124+
115125 // Default to raw
116126 $mode = $wgUsabilityInitiativeResourceMode; // Just an alias
117127 if ( !isset( self::$scriptFiles['base_sets'][$mode] ) ) {
@@ -188,7 +198,7 @@
189199 }
190200 return true;
191201 }
192 -
 202+
193203 /**
194204 * MakeGlobalVariablesScript hook
195205 */
@@ -223,7 +233,7 @@
224234 public static function addMessages( $messages ) {
225235 self::$messages = array_merge( self::$messages, $messages );
226236 }
227 -
 237+
228238 /**
229239 * Adds variables that will be turned into global variables in JS
230240 * @param $variables array of "name" => "value"
@@ -231,7 +241,7 @@
232242 public static function addVariables( $variables ) {
233243 self::$variables = array_merge( self::$variables, $variables );
234244 }
235 -
 245+
236246 /**
237247 * Adds scripts for modules
238248 * @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&#8230;</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() : '&#xa0;') : // 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)) ? '&#xa0;' : '');
 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 ? '&#xa0;' : '') + 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 || '&nbsp;',
 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 || '&nbsp;');
 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 @@
1313 css/wikiEditor.preview.css
1414
1515 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\
1622 js/plugins/jquery.async.js\
1723 js/plugins/jquery.autoEllipsis.js\
1824 js/plugins/jquery.browser.js\
Property changes on: trunk/extensions/UsabilityInitiative
___________________________________________________________________
Name: svn:ignore
1925 - jsmin
2026 + jsmin
.project

Follow-up revisions

RevisionCommit summaryAuthorDate
r60861UsabilityInitiative: Recombine and minifiy for r60858catrope15:05, 9 January 2010

Comments

#Comment by Tim Starling (talk | contribs)   06:25, 21 January 2010

What's the point of this exactly? What does mwEmbed have to do with anything?

#Comment by Platonides (talk | contribs)   14:52, 29 January 2010

Warning: The 'charCode' property of a keyup event should not be used. The value is meaningless. on the _doKeyPress function.

#Comment by Mdale (talk | contribs)   18:06, 29 January 2010

that is an upstream UI Datepicker issue. But we can remove it since I have noticed that charCode is undefined warning from time to time.

Status & tagging log