fomantic-ui-sass 2.8.8.1 → 2.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/app/assets/fonts/semantic-ui/Lato-Bold.woff +0 -0
  4. data/app/assets/fonts/semantic-ui/Lato-Bold.woff2 +0 -0
  5. data/app/assets/fonts/semantic-ui/Lato-BoldItalic.woff +0 -0
  6. data/app/assets/fonts/semantic-ui/Lato-BoldItalic.woff2 +0 -0
  7. data/app/assets/fonts/semantic-ui/Lato-Italic.woff +0 -0
  8. data/app/assets/fonts/semantic-ui/Lato-Italic.woff2 +0 -0
  9. data/app/assets/fonts/semantic-ui/Lato-Regular.woff +0 -0
  10. data/app/assets/fonts/semantic-ui/Lato-Regular.woff2 +0 -0
  11. data/app/assets/fonts/semantic-ui/LatoLatin-Bold.woff +0 -0
  12. data/app/assets/fonts/semantic-ui/LatoLatin-Bold.woff2 +0 -0
  13. data/app/assets/fonts/semantic-ui/LatoLatin-BoldItalic.woff +0 -0
  14. data/app/assets/fonts/semantic-ui/LatoLatin-BoldItalic.woff2 +0 -0
  15. data/app/assets/fonts/semantic-ui/LatoLatin-Italic.woff +0 -0
  16. data/app/assets/fonts/semantic-ui/LatoLatin-Italic.woff2 +0 -0
  17. data/app/assets/fonts/semantic-ui/LatoLatin-Regular.woff +0 -0
  18. data/app/assets/fonts/semantic-ui/LatoLatin-Regular.woff2 +0 -0
  19. data/app/assets/fonts/semantic-ui/brand-icons.eot +0 -0
  20. data/app/assets/fonts/semantic-ui/brand-icons.svg +41 -6
  21. data/app/assets/fonts/semantic-ui/brand-icons.ttf +0 -0
  22. data/app/assets/fonts/semantic-ui/brand-icons.woff +0 -0
  23. data/app/assets/fonts/semantic-ui/brand-icons.woff2 +0 -0
  24. data/app/assets/fonts/semantic-ui/icons.eot +0 -0
  25. data/app/assets/fonts/semantic-ui/icons.svg +245 -7
  26. data/app/assets/fonts/semantic-ui/icons.ttf +0 -0
  27. data/app/assets/fonts/semantic-ui/icons.woff +0 -0
  28. data/app/assets/fonts/semantic-ui/icons.woff2 +0 -0
  29. data/app/assets/fonts/semantic-ui/outline-icons.eot +0 -0
  30. data/app/assets/fonts/semantic-ui/outline-icons.svg +2 -2
  31. data/app/assets/fonts/semantic-ui/outline-icons.ttf +0 -0
  32. data/app/assets/fonts/semantic-ui/outline-icons.woff +0 -0
  33. data/app/assets/fonts/semantic-ui/outline-icons.woff2 +0 -0
  34. data/app/assets/javascripts/semantic-ui/accordion.js +569 -590
  35. data/app/assets/javascripts/semantic-ui/api.js +1153 -1116
  36. data/app/assets/javascripts/semantic-ui/calendar.js +1941 -1698
  37. data/app/assets/javascripts/semantic-ui/checkbox.js +862 -854
  38. data/app/assets/javascripts/semantic-ui/dimmer.js +697 -713
  39. data/app/assets/javascripts/semantic-ui/dropdown.js +4196 -4192
  40. data/app/assets/javascripts/semantic-ui/embed.js +646 -672
  41. data/app/assets/javascripts/semantic-ui/flyout.js +1579 -0
  42. data/app/assets/javascripts/semantic-ui/form.js +2024 -2000
  43. data/app/assets/javascripts/semantic-ui/modal.js +1546 -1384
  44. data/app/assets/javascripts/semantic-ui/nag.js +521 -527
  45. data/app/assets/javascripts/semantic-ui/popup.js +1457 -1463
  46. data/app/assets/javascripts/semantic-ui/progress.js +970 -995
  47. data/app/assets/javascripts/semantic-ui/rating.js +508 -520
  48. data/app/assets/javascripts/semantic-ui/search.js +1521 -1508
  49. data/app/assets/javascripts/semantic-ui/shape.js +784 -811
  50. data/app/assets/javascripts/semantic-ui/sidebar.js +1061 -1002
  51. data/app/assets/javascripts/semantic-ui/site.js +437 -477
  52. data/app/assets/javascripts/semantic-ui/slider.js +1311 -1297
  53. data/app/assets/javascripts/semantic-ui/state.js +639 -658
  54. data/app/assets/javascripts/semantic-ui/sticky.js +848 -891
  55. data/app/assets/javascripts/semantic-ui/tab.js +895 -941
  56. data/app/assets/javascripts/semantic-ui/toast.js +911 -851
  57. data/app/assets/javascripts/semantic-ui/transition.js +1049 -1073
  58. data/app/assets/javascripts/semantic-ui/visibility.js +1214 -1246
  59. data/app/assets/stylesheets/semantic-ui/collections/_breadcrumb.scss +7 -7
  60. data/app/assets/stylesheets/semantic-ui/collections/_form.scss +389 -407
  61. data/app/assets/stylesheets/semantic-ui/collections/_grid.scss +203 -345
  62. data/app/assets/stylesheets/semantic-ui/collections/_menu.scss +372 -501
  63. data/app/assets/stylesheets/semantic-ui/collections/_message.scss +154 -226
  64. data/app/assets/stylesheets/semantic-ui/collections/_table.scss +2065 -880
  65. data/app/assets/stylesheets/semantic-ui/elements/_button.scss +867 -1232
  66. data/app/assets/stylesheets/semantic-ui/elements/_container.scss +101 -6
  67. data/app/assets/stylesheets/semantic-ui/elements/_divider.scss +75 -93
  68. data/app/assets/stylesheets/semantic-ui/elements/_emoji.scss +11148 -9190
  69. data/app/assets/stylesheets/semantic-ui/elements/_flag.scss +1037 -929
  70. data/app/assets/stylesheets/semantic-ui/elements/_header.scss +124 -146
  71. data/app/assets/stylesheets/semantic-ui/elements/_icon.scss +2728 -2759
  72. data/app/assets/stylesheets/semantic-ui/elements/_image.scss +41 -65
  73. data/app/assets/stylesheets/semantic-ui/elements/_input.scss +982 -163
  74. data/app/assets/stylesheets/semantic-ui/elements/_label.scss +432 -479
  75. data/app/assets/stylesheets/semantic-ui/elements/_list.scss +80 -101
  76. data/app/assets/stylesheets/semantic-ui/elements/_loader.scss +452 -540
  77. data/app/assets/stylesheets/semantic-ui/elements/_placeholder.scss +56 -76
  78. data/app/assets/stylesheets/semantic-ui/elements/_rail.scss +17 -22
  79. data/app/assets/stylesheets/semantic-ui/elements/_reveal.scss +46 -85
  80. data/app/assets/stylesheets/semantic-ui/elements/_segment.scss +263 -255
  81. data/app/assets/stylesheets/semantic-ui/elements/_step.scss +106 -179
  82. data/app/assets/stylesheets/semantic-ui/elements/_text.scss +33 -33
  83. data/app/assets/stylesheets/semantic-ui/globals/_reset.scss +14 -18
  84. data/app/assets/stylesheets/semantic-ui/globals/_site.scss +132 -48
  85. data/app/assets/stylesheets/semantic-ui/modules/_accordion.scss +196 -74
  86. data/app/assets/stylesheets/semantic-ui/modules/_calendar.scss +43 -29
  87. data/app/assets/stylesheets/semantic-ui/modules/_checkbox.scss +210 -280
  88. data/app/assets/stylesheets/semantic-ui/modules/_dimmer.scss +78 -182
  89. data/app/assets/stylesheets/semantic-ui/modules/_dropdown.scss +339 -423
  90. data/app/assets/stylesheets/semantic-ui/modules/_embed.scss +24 -35
  91. data/app/assets/stylesheets/semantic-ui/modules/_flyout.scss +546 -0
  92. data/app/assets/stylesheets/semantic-ui/modules/_modal.scss +150 -153
  93. data/app/assets/stylesheets/semantic-ui/modules/_nag.scss +55 -65
  94. data/app/assets/stylesheets/semantic-ui/modules/_popup.scss +530 -310
  95. data/app/assets/stylesheets/semantic-ui/modules/_progress.scss +108 -213
  96. data/app/assets/stylesheets/semantic-ui/modules/_rating.scss +88 -168
  97. data/app/assets/stylesheets/semantic-ui/modules/_search.scss +73 -102
  98. data/app/assets/stylesheets/semantic-ui/modules/_shape.scss +16 -32
  99. data/app/assets/stylesheets/semantic-ui/modules/_sidebar.scss +126 -215
  100. data/app/assets/stylesheets/semantic-ui/modules/_slider.scss +110 -138
  101. data/app/assets/stylesheets/semantic-ui/modules/_sticky.scss +3 -7
  102. data/app/assets/stylesheets/semantic-ui/modules/_tab.scss +16 -20
  103. data/app/assets/stylesheets/semantic-ui/modules/_toast.scss +111 -141
  104. data/app/assets/stylesheets/semantic-ui/modules/_transition.scss +371 -1282
  105. data/app/assets/stylesheets/semantic-ui/views/_ad.scss +39 -50
  106. data/app/assets/stylesheets/semantic-ui/views/_card.scss +949 -458
  107. data/app/assets/stylesheets/semantic-ui/views/_comment.scss +44 -62
  108. data/app/assets/stylesheets/semantic-ui/views/_feed.scss +50 -72
  109. data/app/assets/stylesheets/semantic-ui/views/_item.scss +89 -136
  110. data/app/assets/stylesheets/semantic-ui/views/_statistic.scss +78 -119
  111. data/lib/fomantic/ui/sass/version.rb +2 -2
  112. data/tasks/converter.rb +1 -1
  113. metadata +21 -3
@@ -1,1772 +1,2015 @@
1
1
  /*!
2
2
  * # Fomantic-UI - Calendar
3
- * http://github.com/fomantic/Fomantic-UI/
3
+ * https://github.com/fomantic/Fomantic-UI/
4
4
  *
5
5
  *
6
6
  * Released under the MIT license
7
- * http://opensource.org/licenses/MIT
7
+ * https://opensource.org/licenses/MIT
8
8
  *
9
9
  */
10
10
 
11
- ;(function ($, window, document, undefined) {
12
-
13
- 'use strict';
14
-
15
- $.isFunction = $.isFunction || function(obj) {
16
- return typeof obj === "function" && typeof obj.nodeType !== "number";
17
- };
18
-
19
- window = (typeof window != 'undefined' && window.Math == Math)
20
- ? window
21
- : (typeof self != 'undefined' && self.Math == Math)
22
- ? self
23
- : Function('return this')()
24
- ;
25
-
26
- $.fn.calendar = function(parameters) {
27
- var
28
- $allModules = $(this),
29
-
30
- moduleSelector = $allModules.selector || '',
31
-
32
- time = new Date().getTime(),
33
- performance = [],
34
-
35
- query = arguments[0],
36
- methodInvoked = (typeof query == 'string'),
37
- queryArguments = [].slice.call(arguments, 1),
38
- returnedValue,
39
- timeGapTable = {
40
- '5': {'row': 4, 'column': 3 },
41
- '10': {'row': 3, 'column': 2 },
42
- '15': {'row': 2, 'column': 2 },
43
- '20': {'row': 3, 'column': 1 },
44
- '30': {'row': 2, 'column': 1 }
45
- },
46
- numberText = ['','one','two','three','four','five','six','seven','eight']
47
- ;
48
-
49
- $allModules
50
- .each(function () {
51
- var
52
- settings = ( $.isPlainObject(parameters) )
53
- ? $.extend(true, {}, $.fn.calendar.settings, parameters)
54
- : $.extend({}, $.fn.calendar.settings),
55
-
56
- className = settings.className,
57
- namespace = settings.namespace,
58
- selector = settings.selector,
59
- formatter = settings.formatter,
60
- parser = settings.parser,
61
- metadata = settings.metadata,
62
- timeGap = timeGapTable[settings.minTimeGap],
63
- error = settings.error,
64
-
65
- eventNamespace = '.' + namespace,
66
- moduleNamespace = 'module-' + namespace,
67
-
68
- $module = $(this),
69
- $input = $module.find(selector.input),
70
- $container = $module.find(selector.popup),
71
- $activator = $module.find(selector.activator),
72
-
73
- element = this,
74
- instance = $module.data(moduleNamespace),
75
-
76
- isTouch,
77
- isTouchDown = false,
78
- isInverted = $module.hasClass(className.inverted),
79
- focusDateUsedForRange = false,
80
- selectionComplete = false,
81
- classObserver,
82
- module
83
- ;
84
-
85
- module = {
86
-
87
- initialize: function () {
88
- module.debug('Initializing calendar for', element, $module);
89
-
90
- isTouch = module.get.isTouch();
91
- module.setup.config();
92
- module.setup.popup();
93
- module.setup.inline();
94
- module.setup.input();
95
- module.setup.date();
96
- module.create.calendar();
97
-
98
- module.bind.events();
99
- module.observeChanges();
100
- module.instantiate();
101
- },
102
-
103
- instantiate: function () {
104
- module.verbose('Storing instance of calendar');
105
- instance = module;
106
- $module.data(moduleNamespace, instance);
107
- },
108
-
109
- destroy: function () {
110
- module.verbose('Destroying previous calendar for', element);
111
- $module.removeData(moduleNamespace);
112
- module.unbind.events();
113
- module.disconnect.classObserver();
114
- },
11
+ (function ($, window, document) {
12
+ 'use strict';
115
13
 
116
- setup: {
117
- config: function () {
118
- if (module.get.minDate() !== null) {
119
- module.set.minDate($module.data(metadata.minDate));
120
- }
121
- if (module.get.maxDate() !== null) {
122
- module.set.maxDate($module.data(metadata.maxDate));
123
- }
124
- module.setting('type', module.get.type());
125
- module.setting('on', settings.on || ($input.length ? 'focus' : 'click'));
126
- },
127
- popup: function () {
128
- if (settings.inline) {
129
- return;
130
- }
131
- if (!$activator.length) {
132
- $activator = $module.children().first();
133
- if (!$activator.length) {
134
- return;
135
- }
136
- }
137
- if ($.fn.popup === undefined) {
138
- module.error(error.popup);
139
- return;
140
- }
141
- if (!$container.length) {
142
- //prepend the popup element to the activator's parent so that it has less chance of messing with
143
- //the styling (eg input action button needs to be the last child to have correct border radius)
144
- var $activatorParent = $activator.parent(),
145
- domPositionFunction = $activatorParent.closest(selector.append).length !== 0 ? 'appendTo' : 'prependTo';
146
- $container = $('<div/>').addClass(className.popup)[domPositionFunction]($activatorParent);
147
- }
148
- $container.addClass(className.calendar);
149
- if(isInverted){
150
- $container.addClass(className.inverted);
151
- }
152
- var onVisible = function () {
153
- module.refreshTooltips();
154
- return settings.onVisible.apply($container, arguments);
155
- };
156
- var onHidden = settings.onHidden;
157
- if (!$input.length) {
158
- //no input, $container has to handle focus/blur
159
- $container.attr('tabindex', '0');
160
- onVisible = function () {
161
- module.refreshTooltips();
162
- module.focus();
163
- return settings.onVisible.apply($container, arguments);
164
- };
165
- onHidden = function () {
166
- module.blur();
167
- return settings.onHidden.apply($container, arguments);
168
- };
169
- }
170
- var onShow = function () {
171
- //reset the focus date onShow
172
- module.set.focusDate(module.get.date());
173
- module.set.mode(module.get.validatedMode(settings.startMode));
174
- return settings.onShow.apply($container, arguments);
175
- };
176
- var on = module.setting('on');
177
- var options = $.extend({}, settings.popupOptions, {
178
- popup: $container,
179
- on: on,
180
- hoverable: on === 'hover',
181
- closable: on === 'click',
182
- onShow: onShow,
183
- onVisible: onVisible,
184
- onHide: settings.onHide,
185
- onHidden: onHidden
186
- });
187
- module.popup(options);
188
- },
189
- inline: function () {
190
- if ($activator.length && !settings.inline) {
191
- return;
192
- }
193
- settings.inline = true;
194
- $container = $('<div/>').addClass(className.calendar).appendTo($module);
195
- if (!$input.length) {
196
- $container.attr('tabindex', '0');
197
- }
198
- },
199
- input: function () {
200
- if (settings.touchReadonly && $input.length && isTouch) {
201
- $input.prop('readonly', true);
202
- }
203
- module.check.disabled();
204
- },
205
- date: function () {
206
- var date;
207
- if (settings.initialDate) {
208
- date = parser.date(settings.initialDate, settings);
209
- } else if ($module.data(metadata.date) !== undefined) {
210
- date = parser.date($module.data(metadata.date), settings);
211
- } else if ($input.length) {
212
- date = parser.date($input.val(), settings);
213
- }
214
- module.set.date(date, settings.formatInput, false);
215
- module.set.mode(module.get.mode(), false);
216
- }
217
- },
14
+ function isFunction(obj) {
15
+ return typeof obj === 'function' && typeof obj.nodeType !== 'number';
16
+ }
218
17
 
219
- trigger: {
220
- change: function() {
18
+ window = window !== undefined && window.Math === Math
19
+ ? window
20
+ : globalThis;
21
+
22
+ $.fn.calendar = function (parameters) {
23
+ var
24
+ $allModules = $(this),
25
+ $document = $(document),
26
+
27
+ moduleSelector = $allModules.selector || '',
28
+
29
+ time = Date.now(),
30
+ performance = [],
31
+
32
+ query = arguments[0],
33
+ methodInvoked = typeof query === 'string',
34
+ queryArguments = [].slice.call(arguments, 1),
35
+ returnedValue,
36
+ timeGapTable = {
37
+ 5: { row: 4, column: 3 },
38
+ 10: { row: 3, column: 2 },
39
+ 15: { row: 2, column: 2 },
40
+ 20: { row: 3, column: 1 },
41
+ 30: { row: 2, column: 1 },
42
+ },
43
+ numberText = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']
44
+ ;
45
+
46
+ $allModules.each(function () {
221
47
  var
222
- inputElement = $input[0]
48
+ settings = $.isPlainObject(parameters)
49
+ ? $.extend(true, {}, $.fn.calendar.settings, parameters)
50
+ : $.extend({}, $.fn.calendar.settings),
51
+
52
+ className = settings.className,
53
+ namespace = settings.namespace,
54
+ selector = settings.selector,
55
+ formatter = settings.formatter,
56
+ parser = settings.parser,
57
+ metadata = settings.metadata,
58
+ timeGap = timeGapTable[settings.minTimeGap],
59
+ error = settings.error,
60
+
61
+ eventNamespace = '.' + namespace,
62
+ moduleNamespace = 'module-' + namespace,
63
+
64
+ $module = $(this),
65
+ $input = $module.find(selector.input),
66
+ $activator = $module.find(selector.activator),
67
+
68
+ element = this,
69
+ instance = $module.data(moduleNamespace),
70
+ $container = instance && instance.popupId ? $document.find('#' + instance.popupId) : $module.find(selector.popup),
71
+
72
+ isTouch,
73
+ isTouchDown = false,
74
+ isInverted = $module.hasClass(className.inverted),
75
+ focusDateUsedForRange = false,
76
+ selectionComplete = false,
77
+ classObserver,
78
+ module
223
79
  ;
224
- if(inputElement) {
225
- var events = document.createEvent('HTMLEvents');
226
- module.verbose('Triggering native change event');
227
- events.initEvent('change', true, false);
228
- inputElement.dispatchEvent(events);
229
- }
230
- }
231
- },
232
80
 
233
- create: {
234
- calendar: function () {
235
- var i, r, c, p, row, cell, pageGrid;
81
+ module = {
82
+
83
+ initialize: function () {
84
+ module.debug('Initializing calendar for', element, $module);
85
+
86
+ isTouch = module.get.isTouch();
87
+ module.setup.config();
88
+ module.setup.popup();
89
+ module.setup.inline();
90
+ module.setup.input();
91
+ module.setup.date();
92
+ module.create.calendar();
93
+
94
+ module.bind.events();
95
+ module.observeChanges();
96
+ module.instantiate();
97
+ },
98
+
99
+ instantiate: function () {
100
+ module.verbose('Storing instance of calendar');
101
+ instance = module;
102
+ $module.data(moduleNamespace, instance);
103
+ },
104
+
105
+ destroy: function () {
106
+ module.verbose('Destroying previous calendar for', element);
107
+ $module.removeData(moduleNamespace);
108
+ module.unbind.events();
109
+ module.disconnect.classObserver();
110
+ },
111
+
112
+ setup: {
113
+ config: function () {
114
+ if (module.get.minDate() !== null) {
115
+ module.set.minDate($module.data(metadata.minDate));
116
+ }
117
+ if (module.get.maxDate() !== null) {
118
+ module.set.maxDate($module.data(metadata.maxDate));
119
+ }
120
+ module.setting('type', module.get.type());
121
+ module.setting('on', settings.on || 'click');
122
+ },
123
+ popup: function () {
124
+ if (settings.inline) {
125
+ return;
126
+ }
127
+ if ($activator.length === 0) {
128
+ $activator = $module.children().first();
129
+ if ($activator.length === 0) {
130
+ return;
131
+ }
132
+ }
133
+ if ($.fn.popup === undefined) {
134
+ module.error(error.popup);
236
135
 
237
- var
238
- mode = module.get.mode(),
239
- today = new Date(),
240
- date = module.get.date(),
241
- focusDate = module.get.focusDate(),
242
- display = module.helper.dateInRange(focusDate || date || settings.initialDate || today)
243
- ;
136
+ return;
137
+ }
138
+ if ($container.length === 0) {
139
+ if (settings.context) {
140
+ module.popupId = namespace + '_popup_' + (Math.random().toString(16) + '000000000').slice(2, 10);
141
+ $container = $('<div/>', { id: module.popupId }).addClass(className.popup).appendTo($document.find(settings.context));
142
+ } else {
143
+ // prepend the popup element to the activator's parent so that it has less chance of messing with
144
+ // the styling (eg input action button needs to be the last child to have correct border radius)
145
+ var
146
+ $activatorParent = $activator.parent(),
147
+ domPositionFunction = $activatorParent.closest(selector.append).length > 0 ? 'appendTo' : 'prependTo'
148
+ ;
149
+ $container = $('<div/>').addClass(className.popup)[domPositionFunction]($activatorParent);
150
+ }
151
+ }
152
+ $container.addClass(className.calendar);
153
+ if (isInverted) {
154
+ $container.addClass(className.inverted);
155
+ }
156
+ var onVisible = function () {
157
+ module.refreshTooltips();
158
+
159
+ return settings.onVisible.apply($container, arguments);
160
+ };
161
+ var onHidden = function () {
162
+ module.blur();
163
+
164
+ return settings.onHidden.apply($container, arguments);
165
+ };
166
+ if ($input.length === 0) {
167
+ // no input, $container has to handle focus/blur
168
+ $container.attr('tabindex', '0');
169
+ onVisible = function () {
170
+ module.refreshTooltips();
171
+ module.focus();
172
+
173
+ return settings.onVisible.apply($container, arguments);
174
+ };
175
+ }
176
+ var onShow = function () {
177
+ // reset the focus date onShow
178
+ module.set.focusDate(module.get.date());
179
+ module.set.mode(module.get.validatedMode(settings.startMode));
180
+
181
+ return settings.onShow.apply($container, arguments);
182
+ };
183
+ var on = module.setting('on');
184
+ var options = $.extend({}, settings.popupOptions, {
185
+ popup: $container,
186
+ movePopup: !settings.context,
187
+ on: on,
188
+ hoverable: on === 'hover',
189
+ closable: on === 'click',
190
+ onShow: onShow,
191
+ onVisible: onVisible,
192
+ onHide: settings.onHide,
193
+ onHidden: onHidden,
194
+ });
195
+ module.popup(options);
196
+ },
197
+ inline: function () {
198
+ if ($activator.length > 0 && !settings.inline) {
199
+ return;
200
+ }
201
+ settings.inline = true;
202
+ $container = $('<div/>').addClass(className.calendar).appendTo($module);
203
+ if ($input.length === 0) {
204
+ $container.attr('tabindex', '0');
205
+ }
206
+ },
207
+ input: function () {
208
+ if (settings.touchReadonly && $input.length > 0 && isTouch) {
209
+ $input.prop('readonly', true);
210
+ }
211
+ module.check.disabled();
212
+ },
213
+ date: function () {
214
+ var date;
215
+ if (settings.initialDate) {
216
+ date = parser.date(settings.initialDate, settings);
217
+ } else if ($module.data(metadata.date) !== undefined) {
218
+ date = parser.date($module.data(metadata.date), settings);
219
+ } else if ($input.length > 0) {
220
+ date = parser.date($input.val(), settings);
221
+ }
222
+ module.set.date(date, settings.formatInput, false);
223
+ module.set.mode(module.get.mode(), false);
224
+ },
225
+ },
226
+
227
+ trigger: {
228
+ change: function () {
229
+ var
230
+ inputElement = $input[0]
231
+ ;
232
+ if (inputElement) {
233
+ var events = document.createEvent('HTMLEvents');
234
+ module.verbose('Triggering native change event');
235
+ events.initEvent('change', true, false);
236
+ inputElement.dispatchEvent(events);
237
+ }
238
+ },
239
+ },
240
+
241
+ create: {
242
+ calendar: function () {
243
+ var
244
+ i,
245
+ r,
246
+ c,
247
+ p,
248
+ row,
249
+ cell,
250
+ pageGrid
251
+ ;
252
+
253
+ var
254
+ mode = module.get.mode(),
255
+ today = new Date(),
256
+ date = module.get.date(),
257
+ focusDate = module.get.focusDate(),
258
+ display = module.helper.dateInRange(focusDate || date || parser.date(settings.initialDate, settings) || today)
259
+ ;
260
+
261
+ if (!focusDate) {
262
+ focusDate = display;
263
+ module.set.focusDate(focusDate, false, false);
264
+ }
244
265
 
245
- if (!focusDate) {
246
- focusDate = display;
247
- module.set.focusDate(focusDate, false, false);
248
- }
266
+ var
267
+ isYear = mode === 'year',
268
+ isMonth = mode === 'month',
269
+ isDay = mode === 'day',
270
+ isHour = mode === 'hour',
271
+ isMinute = mode === 'minute',
272
+ isTimeOnly = settings.type === 'time'
273
+ ;
274
+
275
+ var multiMonth = Math.max(settings.multiMonth, 1);
276
+ var monthOffset = !isDay ? 0 : module.get.monthOffset();
277
+
278
+ var
279
+ minute = display.getMinutes(),
280
+ hour = display.getHours(),
281
+ day = display.getDate(),
282
+ startMonth = display.getMonth() + monthOffset,
283
+ year = display.getFullYear()
284
+ ;
285
+
286
+ var columns = isDay
287
+ ? (settings.showWeekNumbers ? 8 : 7)
288
+ : (isHour ? 4 : timeGap.column);
289
+ var rows = isDay || isHour ? 6 : timeGap.row;
290
+ var pages = isDay ? multiMonth : 1;
291
+
292
+ var container = $container;
293
+ var tooltipPosition = container.hasClass('left') ? 'right center' : 'left center';
294
+ container.empty();
295
+ if (pages > 1) {
296
+ pageGrid = $('<div/>').addClass(className.grid).appendTo(container);
297
+ }
249
298
 
250
- var
251
- isYear = mode === 'year',
252
- isMonth = mode === 'month',
253
- isDay = mode === 'day',
254
- isHour = mode === 'hour',
255
- isMinute = mode === 'minute',
256
- isTimeOnly = settings.type === 'time'
257
- ;
299
+ for (p = 0; p < pages; p++) {
300
+ if (pages > 1) {
301
+ var pageColumn = $('<div/>').addClass(className.column).appendTo(pageGrid);
302
+ container = pageColumn;
303
+ }
304
+
305
+ var month = startMonth + p;
306
+ var firstMonthDayColumn = (new Date(year, month, 1).getDay() - (settings.firstDayOfWeek % 7) + 7) % 7;
307
+ if (!settings.constantHeight && isDay) {
308
+ var requiredCells = new Date(year, month + 1, 0).getDate() + firstMonthDayColumn;
309
+ rows = Math.ceil(requiredCells / 7);
310
+ }
311
+
312
+ var
313
+ yearChange = isYear ? 10 : (isMonth ? 1 : 0),
314
+ monthChange = isDay ? 1 : 0,
315
+ dayChange = isHour || isMinute ? 1 : 0,
316
+ prevNextDay = isHour || isMinute ? day : 1,
317
+ prevDate = new Date(year - yearChange, month - monthChange, prevNextDay - dayChange, hour),
318
+ nextDate = new Date(year + yearChange, month + monthChange, prevNextDay + dayChange, hour),
319
+ prevLast = isYear
320
+ ? new Date(Math.ceil(year / 10) * 10 - 9, 0, 0)
321
+ : (isMonth
322
+ ? new Date(year, 0, 0)
323
+ : (isDay // eslint-disable-line unicorn/no-nested-ternary
324
+ ? new Date(year, month, 0)
325
+ : new Date(year, month, day, -1))),
326
+ nextFirst = isYear
327
+ ? new Date(Math.ceil(year / 10) * 10 + 1, 0, 1)
328
+ : (isMonth
329
+ ? new Date(year + 1, 0, 1)
330
+ : (isDay // eslint-disable-line unicorn/no-nested-ternary
331
+ ? new Date(year, month + 1, 1)
332
+ : new Date(year, month, day + 1)))
333
+ ;
334
+
335
+ var tempMode = mode;
336
+ if (isDay && settings.showWeekNumbers) {
337
+ tempMode += ' andweek';
338
+ }
339
+ var table = $('<table/>').addClass(className.table).addClass(tempMode).addClass(numberText[columns] + ' column')
340
+ .appendTo(container);
341
+ if (isInverted) {
342
+ table.addClass(className.inverted);
343
+ }
344
+ var textColumns = columns;
345
+ // no header for time-only mode
346
+ if (!isTimeOnly) {
347
+ var thead = $('<thead/>').appendTo(table);
348
+
349
+ row = $('<tr/>').appendTo(thead);
350
+ cell = $('<th/>').attr('colspan', '' + columns).appendTo(row);
351
+
352
+ var headerDate = isYear || isMonth
353
+ ? new Date(year, 0, 1)
354
+ : (isDay
355
+ ? new Date(year, month, 1)
356
+ : new Date(year, month, day, hour, minute));
357
+ var headerText = $('<span/>').addClass(className.link).appendTo(cell);
358
+ headerText.text(module.helper.dateFormat(formatter[mode + 'Header'], headerDate));
359
+ var newMode = isMonth
360
+ ? (settings.disableYear ? 'day' : 'year')
361
+ : (isDay
362
+ ? (settings.disableMonth ? 'year' : 'month') // eslint-disable-line unicorn/no-nested-ternary
363
+ : 'day');
364
+ headerText.data(metadata.mode, newMode);
365
+
366
+ if (p === 0) {
367
+ var prev = $('<span/>').addClass(className.prev).appendTo(cell);
368
+ prev.data(metadata.focusDate, prevDate);
369
+ prev.toggleClass(className.disabledCell, !module.helper.isDateInRange(prevLast, mode));
370
+ $('<i/>').addClass(className.prevIcon).appendTo(prev);
371
+ }
372
+
373
+ if (p === pages - 1) {
374
+ var next = $('<span/>').addClass(className.next).appendTo(cell);
375
+ next.data(metadata.focusDate, nextDate);
376
+ next.toggleClass(className.disabledCell, !module.helper.isDateInRange(nextFirst, mode));
377
+ $('<i/>').addClass(className.nextIcon).appendTo(next);
378
+ }
379
+ if (isDay) {
380
+ row = $('<tr/>').appendTo(thead);
381
+ if (settings.showWeekNumbers) {
382
+ cell = $('<th/>').appendTo(row);
383
+ cell.text(settings.text.weekNo);
384
+ cell.addClass(className.weekCell);
385
+ textColumns--;
386
+ }
387
+ for (i = 0; i < textColumns; i++) {
388
+ cell = $('<th/>').appendTo(row);
389
+ cell.text(formatter.dayColumnHeader((i + settings.firstDayOfWeek) % 7, settings));
390
+ }
391
+ }
392
+ }
393
+
394
+ var tbody = $('<tbody/>').appendTo(table);
395
+ i = isYear
396
+ ? Math.ceil(year / 10) * 10 - 9
397
+ : (isDay ? 1 - firstMonthDayColumn : 0);
398
+ for (r = 0; r < rows; r++) {
399
+ row = $('<tr/>').appendTo(tbody);
400
+ if (isDay && settings.showWeekNumbers) {
401
+ cell = $('<th/>').appendTo(row);
402
+ cell.text(module.get.weekOfYear(year, month, i + 1 - settings.firstDayOfWeek));
403
+ cell.addClass(className.weekCell);
404
+ }
405
+ for (c = 0; c < textColumns; c++, i++) {
406
+ var cellDate = isYear
407
+ ? new Date(i, month, 1, hour, minute)
408
+ : (isMonth
409
+ ? new Date(year, i, 1, hour, minute)
410
+ : (isDay // eslint-disable-line unicorn/no-nested-ternary
411
+ ? new Date(year, month, i, hour, minute)
412
+ : (isHour
413
+ ? new Date(year, month, day, i)
414
+ : new Date(year, month, day, hour, i * settings.minTimeGap))));
415
+ var cellText = isYear
416
+ ? i
417
+ : (isMonth
418
+ ? settings.text.monthsShort[i]
419
+ : (isDay // eslint-disable-line unicorn/no-nested-ternary
420
+ ? cellDate.getDate()
421
+ : module.helper.dateFormat(formatter.cellTime, cellDate)));
422
+ cell = $('<td/>').addClass(className.cell).appendTo(row);
423
+ cell.text(cellText);
424
+ cell.data(metadata.date, cellDate);
425
+ var adjacent = isDay && cellDate.getMonth() !== ((month + 12) % 12);
426
+ var disabled = (!settings.selectAdjacentDays && adjacent) || !module.helper.isDateInRange(cellDate, mode) || settings.isDisabled(cellDate, mode) || module.helper.isDisabled(cellDate, mode) || !module.helper.isEnabled(cellDate, mode);
427
+ var eventDate;
428
+ if (disabled) {
429
+ var disabledDate = module.helper.findDayAsObject(cellDate, mode, settings.disabledDates);
430
+ if (disabledDate !== null && disabledDate[metadata.message]) {
431
+ cell.attr('data-tooltip', disabledDate[metadata.message]);
432
+ cell.attr('data-position', disabledDate[metadata.position] || tooltipPosition);
433
+ if (disabledDate[metadata.inverted] || (isInverted && disabledDate[metadata.inverted] === undefined)) {
434
+ cell.attr('data-inverted', '');
435
+ }
436
+ if (disabledDate[metadata.variation]) {
437
+ cell.attr('data-variation', disabledDate[metadata.variation]);
438
+ }
439
+ }
440
+ if (mode === 'hour') {
441
+ var disabledHour = module.helper.findHourAsObject(cellDate, mode, settings.disabledHours);
442
+ if (disabledHour !== null && disabledHour[metadata.message]) {
443
+ cell.attr('data-tooltip', disabledHour[metadata.message]);
444
+ cell.attr('data-position', disabledHour[metadata.position] || tooltipPosition);
445
+ if (disabledHour[metadata.inverted] || (isInverted && disabledHour[metadata.inverted] === undefined)) {
446
+ cell.attr('data-inverted', '');
447
+ }
448
+ if (disabledHour[metadata.variation]) {
449
+ cell.attr('data-variation', disabledHour[metadata.variation]);
450
+ }
451
+ }
452
+ }
453
+ } else {
454
+ eventDate = module.helper.findDayAsObject(cellDate, mode, settings.eventDates);
455
+ if (eventDate !== null) {
456
+ cell.addClass(eventDate[metadata.class] || settings.eventClass);
457
+ if (eventDate[metadata.message]) {
458
+ cell.attr('data-tooltip', eventDate[metadata.message]);
459
+ cell.attr('data-position', eventDate[metadata.position] || tooltipPosition);
460
+ if (eventDate[metadata.inverted] || (isInverted && eventDate[metadata.inverted] === undefined)) {
461
+ cell.attr('data-inverted', '');
462
+ }
463
+ if (eventDate[metadata.variation]) {
464
+ cell.attr('data-variation', eventDate[metadata.variation]);
465
+ }
466
+ }
467
+ }
468
+ }
469
+ var active = module.helper.dateEqual(cellDate, date, mode);
470
+ var isToday = module.helper.dateEqual(cellDate, today, mode);
471
+ cell.toggleClass(className.adjacentCell, adjacent && !eventDate);
472
+ cell.toggleClass(className.disabledCell, disabled);
473
+ cell.toggleClass(className.activeCell, active && !(adjacent && disabled));
474
+ if (!isHour && !isMinute) {
475
+ cell.toggleClass(className.todayCell, !adjacent && isToday);
476
+ }
477
+
478
+ // Allow for external modifications of each cell
479
+ var cellOptions = {
480
+ mode: mode,
481
+ adjacent: adjacent,
482
+ disabled: disabled,
483
+ active: active,
484
+ today: isToday,
485
+ };
486
+ formatter.cell(cell, cellDate, cellOptions);
487
+
488
+ if (module.helper.dateEqual(cellDate, focusDate, mode)) {
489
+ // ensure that the focus date is exactly equal to the cell date
490
+ // so that, if selected, the correct value is set
491
+ module.set.focusDate(cellDate, false, false);
492
+ }
493
+ }
494
+ }
495
+
496
+ if (settings.today) {
497
+ var todayRow = $('<tr/>').appendTo(tbody);
498
+ var todayButton = $('<td/>').attr('colspan', '' + columns).addClass(className.today).appendTo(todayRow);
499
+ todayButton.text(formatter.today(settings));
500
+ todayButton.data(metadata.date, today);
501
+ }
502
+
503
+ module.update.focus(false, table);
504
+
505
+ if (settings.inline) {
506
+ module.refreshTooltips();
507
+ }
508
+ }
509
+ },
510
+ },
511
+
512
+ update: {
513
+ focus: function (updateRange, container) {
514
+ container = container || $container;
515
+ var mode = module.get.mode();
516
+ var date = module.get.date();
517
+ var focusDate = module.get.focusDate();
518
+ var startDate = module.get.startDate();
519
+ var endDate = module.get.endDate();
520
+ var rangeDate = (updateRange ? focusDate : null) || date || (!isTouch ? focusDate : null);
521
+
522
+ container.find('td').each(function () {
523
+ var $cell = $(this);
524
+ var cellDate = $cell.data(metadata.date);
525
+ if (!cellDate) {
526
+ return;
527
+ }
528
+ var disabled = $cell.hasClass(className.disabledCell);
529
+ var active = $cell.hasClass(className.activeCell);
530
+ var adjacent = $cell.hasClass(className.adjacentCell);
531
+ var focused = module.helper.dateEqual(cellDate, focusDate, mode);
532
+ var inRange = !rangeDate
533
+ ? false
534
+ : (!!startDate && module.helper.isDateInRange(cellDate, mode, startDate, rangeDate))
535
+ || (!!endDate && module.helper.isDateInRange(cellDate, mode, rangeDate, endDate));
536
+ $cell.toggleClass(className.focusCell, focused && (!isTouch || isTouchDown) && (!adjacent || (settings.selectAdjacentDays && adjacent)) && !disabled);
537
+
538
+ if (module.helper.isTodayButton($cell)) {
539
+ return;
540
+ }
541
+ $cell.toggleClass(className.rangeCell, inRange && !active && !disabled);
542
+ });
543
+ },
544
+ },
545
+
546
+ refresh: function () {
547
+ module.create.calendar();
548
+ },
549
+
550
+ refreshTooltips: function () {
551
+ var winWidth = $(window).width();
552
+ $container.find('td[data-position]').each(function () {
553
+ var $cell = $(this);
554
+ var tooltipWidth = window.getComputedStyle($cell[0], '::after').width.replace(/[^\d.]/g, '');
555
+ var tooltipPosition = $cell.attr('data-position');
556
+ // use a fallback width of 250 (calendar width) for IE/Edge (which return "auto")
557
+ var calcPosition = (winWidth - $cell.width() - (parseInt(tooltipWidth, 10) || 250)) > $cell.offset().left ? 'right' : 'left';
558
+ if (tooltipPosition.indexOf(calcPosition) === -1) {
559
+ $cell.attr('data-position', tooltipPosition.replace(/(left|right)/, calcPosition));
560
+ }
561
+ });
562
+ },
563
+
564
+ bind: {
565
+ events: function () {
566
+ module.debug('Binding events');
567
+ $container.on('mousedown' + eventNamespace, module.event.mousedown);
568
+ $container.on('touchstart' + eventNamespace, module.event.mousedown);
569
+ $container.on('mouseup' + eventNamespace, module.event.mouseup);
570
+ $container.on('touchend' + eventNamespace, module.event.mouseup);
571
+ $container.on('mouseover' + eventNamespace, module.event.mouseover);
572
+ if ($input.length > 0) {
573
+ $input.on('input' + eventNamespace, module.event.inputChange);
574
+ $input.on('focus' + eventNamespace, module.event.inputFocus);
575
+ $input.on('blur' + eventNamespace, module.event.inputBlur);
576
+ $input.on('keydown' + eventNamespace, module.event.keydown);
577
+ } else {
578
+ $container.on('keydown' + eventNamespace, module.event.keydown);
579
+ }
580
+ },
581
+ },
582
+
583
+ unbind: {
584
+ events: function () {
585
+ module.debug('Unbinding events');
586
+ $container.off(eventNamespace);
587
+ if ($input.length > 0) {
588
+ $input.off(eventNamespace);
589
+ }
590
+ },
591
+ },
592
+
593
+ event: {
594
+ mouseover: function (event) {
595
+ var target = $(event.target);
596
+ var date = target.data(metadata.date);
597
+ var mousedown = event.buttons === 1;
598
+ if (date) {
599
+ module.set.focusDate(date, false, true, mousedown);
600
+ }
601
+ },
602
+ mousedown: function (event) {
603
+ if ($input.length > 0) {
604
+ // prevent the mousedown on the calendar causing the input to lose focus
605
+ event.preventDefault();
606
+ }
607
+ isTouchDown = event.type.indexOf('touch') >= 0;
608
+ var target = $(event.target);
609
+ var date = target.data(metadata.date);
610
+ if (date) {
611
+ module.set.focusDate(date, false, true, true);
612
+ }
613
+ },
614
+ mouseup: function (event) {
615
+ // ensure input has focus so that it receives keydown events for calendar navigation
616
+ module.focus();
617
+ event.preventDefault();
618
+ event.stopPropagation();
619
+ isTouchDown = false;
620
+ var target = $(event.target);
621
+ if (target.hasClass('disabled')) {
622
+ return;
623
+ }
624
+ var parent = target.parent();
625
+ if (parent.data(metadata.date) || parent.data(metadata.focusDate) || parent.data(metadata.mode)) {
626
+ // clicked on a child element, switch to parent (used when clicking directly on prev/next <i> icon element)
627
+ target = parent;
628
+ }
629
+ var date = target.data(metadata.date);
630
+ var focusDate = target.data(metadata.focusDate);
631
+ var mode = target.data(metadata.mode);
632
+ if (date && settings.onSelect.call(element, date, module.get.mode()) !== false) {
633
+ var forceSet = target.hasClass(className.today);
634
+ module.selectDate(date, forceSet);
635
+ } else if (focusDate) {
636
+ module.set.focusDate(focusDate);
637
+ } else if (mode) {
638
+ module.set.mode(mode);
639
+ }
640
+ },
641
+ keydown: function (event) {
642
+ var keyCode = event.which;
643
+ if (keyCode === 9) {
644
+ // tab
645
+ module.popup('hide');
646
+ }
258
647
 
259
- var multiMonth = Math.max(settings.multiMonth, 1);
260
- var monthOffset = !isDay ? 0 : module.get.monthOffset();
648
+ if (module.popup('is visible')) {
649
+ var mode = module.get.mode();
650
+ switch (keyCode) {
651
+ // arrow keys
652
+ case 37:
653
+ case 38:
654
+ case 39:
655
+ case 40: {
656
+ var bigIncrement = mode === 'day'
657
+ ? 7
658
+ : (mode === 'hour'
659
+ ? 4
660
+ : (mode === 'minute' ? timeGap.column : 3)); // eslint-disable-line unicorn/no-nested-ternary
661
+ var increment = keyCode === 37
662
+ ? -1
663
+ : (keyCode === 38
664
+ ? -bigIncrement
665
+ : (keyCode === 39 ? 1 : bigIncrement)); // eslint-disable-line unicorn/no-nested-ternary
666
+ increment *= mode === 'minute' ? settings.minTimeGap : 1;
667
+ var focusDate = module.get.focusDate() || module.get.date() || new Date();
668
+ var year = focusDate.getFullYear() + (mode === 'year' ? increment : 0);
669
+ var month = focusDate.getMonth() + (mode === 'month' ? increment : 0);
670
+ var day = focusDate.getDate() + (mode === 'day' ? increment : 0);
671
+ var hour = focusDate.getHours() + (mode === 'hour' ? increment : 0);
672
+ var minute = focusDate.getMinutes() + (mode === 'minute' ? increment : 0);
673
+ var newFocusDate = new Date(year, month, day, hour, minute);
674
+ if (settings.type === 'time') {
675
+ newFocusDate = module.helper.mergeDateTime(focusDate, newFocusDate);
676
+ }
677
+ if (module.helper.isDateInRange(newFocusDate, mode)) {
678
+ module.set.focusDate(newFocusDate);
679
+ }
680
+
681
+ break;
682
+ }
683
+ // enter key
684
+ case 13: {
685
+ var date = module.get.focusDate();
686
+ if (date && !settings.isDisabled(date, mode) && !module.helper.isDisabled(date, mode) && module.helper.isEnabled(date, mode)) {
687
+ if (settings.onSelect.call(element, date, module.get.mode()) !== false) {
688
+ module.selectDate(date);
689
+ }
690
+ }
691
+ // disable form submission:
692
+ event.preventDefault();
693
+ event.stopPropagation();
694
+
695
+ break;
696
+ }
697
+ // escape key
698
+ case 27: {
699
+ module.popup('hide');
700
+ event.stopPropagation();
701
+
702
+ break;
703
+ }
704
+ }
705
+ }
261
706
 
262
- var
263
- minute = display.getMinutes(),
264
- hour = display.getHours(),
265
- day = display.getDate(),
266
- startMonth = display.getMonth() + monthOffset,
267
- year = display.getFullYear()
268
- ;
707
+ if (keyCode === 38 || keyCode === 40) {
708
+ // arrow-up || arrow-down
709
+ event.preventDefault(); // don't scroll
710
+ module.popup('show');
711
+ }
712
+ },
713
+ inputChange: function () {
714
+ var val = $input.val();
715
+ var date = parser.date(val, settings);
716
+ module.set.date(date, false);
717
+ },
718
+ inputFocus: function () {
719
+ $container.addClass(className.active);
720
+ },
721
+ inputBlur: function () {
722
+ $container.removeClass(className.active);
723
+ if (settings.formatInput) {
724
+ var date = module.get.date();
725
+ var text = module.helper.dateFormat(formatter[settings.type], date);
726
+ $input.val(text);
727
+ }
728
+ if (selectionComplete) {
729
+ module.trigger.change();
730
+ selectionComplete = false;
731
+ }
732
+ },
733
+ class: {
734
+ mutation: function (mutations) {
735
+ mutations.forEach(function (mutation) {
736
+ if (mutation.attributeName === 'class') {
737
+ module.check.disabled();
738
+ }
739
+ });
740
+ },
741
+ },
742
+ },
743
+
744
+ observeChanges: function () {
745
+ if ('MutationObserver' in window) {
746
+ classObserver = new MutationObserver(module.event.class.mutation);
747
+ module.debug('Setting up mutation observer', classObserver);
748
+ module.observe.class();
749
+ }
750
+ },
269
751
 
270
- var columns = isDay ? settings.showWeekNumbers ? 8 : 7 : isHour ? 4 : timeGap['column'];
271
- var rows = isDay || isHour ? 6 : timeGap['row'];
272
- var pages = isDay ? multiMonth : 1;
752
+ disconnect: {
753
+ classObserver: function () {
754
+ if ($input.length > 0 && classObserver) {
755
+ classObserver.disconnect();
756
+ }
757
+ },
758
+ },
759
+
760
+ observe: {
761
+ class: function () {
762
+ if ($input.length > 0 && classObserver) {
763
+ classObserver.observe($module[0], {
764
+ attributes: true,
765
+ });
766
+ }
767
+ },
768
+ },
769
+
770
+ is: {
771
+ disabled: function () {
772
+ return $module.hasClass(className.disabled);
773
+ },
774
+ },
775
+
776
+ check: {
777
+ disabled: function () {
778
+ $input.attr('tabindex', module.is.disabled() ? -1 : 0);
779
+ },
780
+ },
781
+
782
+ get: {
783
+ weekOfYear: function (weekYear, weekMonth, weekDay) {
784
+ // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
785
+ var ms1d = 24 * 3600 * 1000,
786
+ ms7d = 7 * ms1d,
787
+ DC3 = Date.UTC(weekYear, weekMonth, weekDay + 3) / ms1d, // an absolute day number
788
+ AWN = Math.floor(DC3 / 7), // an absolute week number
789
+ Wyr = new Date(AWN * ms7d).getUTCFullYear()
790
+ ;
791
+
792
+ return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
793
+ },
794
+ formattedDate: function (format, date) {
795
+ return module.helper.dateFormat(format || formatter[settings.type], date || module.get.date());
796
+ },
797
+ date: function () {
798
+ return module.helper.sanitiseDate($module.data(metadata.date)) || null;
799
+ },
800
+ inputDate: function () {
801
+ return $input.val();
802
+ },
803
+ focusDate: function () {
804
+ return $module.data(metadata.focusDate) || null;
805
+ },
806
+ startDate: function () {
807
+ var startModule = module.get.calendarModule(settings.startCalendar);
808
+
809
+ return (startModule ? startModule.get.date() : $module.data(metadata.startDate)) || null;
810
+ },
811
+ endDate: function () {
812
+ var endModule = module.get.calendarModule(settings.endCalendar);
813
+
814
+ return (endModule ? endModule.get.date() : $module.data(metadata.endDate)) || null;
815
+ },
816
+ minDate: function () {
817
+ return $module.data(metadata.minDate) || null;
818
+ },
819
+ maxDate: function () {
820
+ return $module.data(metadata.maxDate) || null;
821
+ },
822
+ monthOffset: function () {
823
+ return $module.data(metadata.monthOffset) || settings.monthOffset || 0;
824
+ },
825
+ mode: function () {
826
+ // only returns valid modes for the current settings
827
+ var mode = $module.data(metadata.mode) || settings.startMode;
828
+
829
+ return module.get.validatedMode(mode);
830
+ },
831
+ validatedMode: function (mode) {
832
+ var validModes = module.get.validModes();
833
+ if ($.inArray(mode, validModes) >= 0) {
834
+ return mode;
835
+ }
273
836
 
274
- var container = $container;
275
- var tooltipPosition = container.hasClass("left") ? "right center" : "left center";
276
- container.empty();
277
- if (pages > 1) {
278
- pageGrid = $('<div/>').addClass(className.grid).appendTo(container);
279
- }
837
+ return settings.type === 'time'
838
+ ? 'hour'
839
+ : (settings.type === 'month'
840
+ ? 'month'
841
+ : (settings.type === 'year' ? 'year' : 'day')); // eslint-disable-line unicorn/no-nested-ternary
842
+ },
843
+ type: function () {
844
+ return $module.data(metadata.type) || settings.type;
845
+ },
846
+ validModes: function () {
847
+ var validModes = [];
848
+ if (settings.type !== 'time') {
849
+ if (!settings.disableYear || settings.type === 'year') {
850
+ validModes.push('year');
851
+ }
852
+ if (!(settings.disableMonth || settings.type === 'year') || settings.type === 'month') {
853
+ validModes.push('month');
854
+ }
855
+ if (settings.type.indexOf('date') >= 0) {
856
+ validModes.push('day');
857
+ }
858
+ }
859
+ if (settings.type.indexOf('time') >= 0) {
860
+ validModes.push('hour');
861
+ if (!settings.disableMinute) {
862
+ validModes.push('minute');
863
+ }
864
+ }
280
865
 
281
- for (p = 0; p < pages; p++) {
282
- if (pages > 1) {
283
- var pageColumn = $('<div/>').addClass(className.column).appendTo(pageGrid);
284
- container = pageColumn;
285
- }
286
-
287
- var month = startMonth + p;
288
- var firstMonthDayColumn = (new Date(year, month, 1).getDay() - settings.firstDayOfWeek % 7 + 7) % 7;
289
- if (!settings.constantHeight && isDay) {
290
- var requiredCells = new Date(year, month + 1, 0).getDate() + firstMonthDayColumn;
291
- rows = Math.ceil(requiredCells / 7);
292
- }
293
-
294
- var
295
- yearChange = isYear ? 10 : isMonth ? 1 : 0,
296
- monthChange = isDay ? 1 : 0,
297
- dayChange = isHour || isMinute ? 1 : 0,
298
- prevNextDay = isHour || isMinute ? day : 1,
299
- prevDate = new Date(year - yearChange, month - monthChange, prevNextDay - dayChange, hour),
300
- nextDate = new Date(year + yearChange, month + monthChange, prevNextDay + dayChange, hour),
301
- prevLast = isYear ? new Date(Math.ceil(year / 10) * 10 - 9, 0, 0) :
302
- isMonth ? new Date(year, 0, 0) : isDay ? new Date(year, month, 0) : new Date(year, month, day, -1),
303
- nextFirst = isYear ? new Date(Math.ceil(year / 10) * 10 + 1, 0, 1) :
304
- isMonth ? new Date(year + 1, 0, 1) : isDay ? new Date(year, month + 1, 1) : new Date(year, month, day + 1)
305
- ;
306
-
307
- var tempMode = mode;
308
- if (isDay && settings.showWeekNumbers){
309
- tempMode += ' andweek';
310
- }
311
- var table = $('<table/>').addClass(className.table).addClass(tempMode).addClass(numberText[columns] + ' column').appendTo(container);
312
- if(isInverted){
313
- table.addClass(className.inverted);
314
- }
315
- var textColumns = columns;
316
- //no header for time-only mode
317
- if (!isTimeOnly) {
318
- var thead = $('<thead/>').appendTo(table);
319
-
320
- row = $('<tr/>').appendTo(thead);
321
- cell = $('<th/>').attr('colspan', '' + columns).appendTo(row);
322
-
323
- var headerDate = isYear || isMonth ? new Date(year, 0, 1) :
324
- isDay ? new Date(year, month, 1) : new Date(year, month, day, hour, minute);
325
- var headerText = $('<span/>').addClass(className.link).appendTo(cell);
326
- headerText.text(formatter.header(headerDate, mode, settings));
327
- var newMode = isMonth ? (settings.disableYear ? 'day' : 'year') :
328
- isDay ? (settings.disableMonth ? 'year' : 'month') : 'day';
329
- headerText.data(metadata.mode, newMode);
330
-
331
- if (p === 0) {
332
- var prev = $('<span/>').addClass(className.prev).appendTo(cell);
333
- prev.data(metadata.focusDate, prevDate);
334
- prev.toggleClass(className.disabledCell, !module.helper.isDateInRange(prevLast, mode));
335
- $('<i/>').addClass(className.prevIcon).appendTo(prev);
336
- }
866
+ return validModes;
867
+ },
868
+ isTouch: function () {
869
+ try {
870
+ document.createEvent('TouchEvent');
337
871
 
338
- if (p === pages - 1) {
339
- var next = $('<span/>').addClass(className.next).appendTo(cell);
340
- next.data(metadata.focusDate, nextDate);
341
- next.toggleClass(className.disabledCell, !module.helper.isDateInRange(nextFirst, mode));
342
- $('<i/>').addClass(className.nextIcon).appendTo(next);
343
- }
344
- if (isDay) {
345
- row = $('<tr/>').appendTo(thead);
346
- if(settings.showWeekNumbers) {
347
- cell = $('<th/>').appendTo(row);
348
- cell.text(settings.text.weekNo);
349
- cell.addClass(className.weekCell);
350
- textColumns--;
351
- }
352
- for (i = 0; i < textColumns; i++) {
353
- cell = $('<th/>').appendTo(row);
354
- cell.text(formatter.dayColumnHeader((i + settings.firstDayOfWeek) % 7, settings));
355
- }
356
- }
357
- }
358
-
359
- var tbody = $('<tbody/>').appendTo(table);
360
- i = isYear ? Math.ceil(year / 10) * 10 - 9 : isDay ? 1 - firstMonthDayColumn : 0;
361
- for (r = 0; r < rows; r++) {
362
- row = $('<tr/>').appendTo(tbody);
363
- if(isDay && settings.showWeekNumbers){
364
- cell = $('<th/>').appendTo(row);
365
- cell.text(module.get.weekOfYear(year,month,i+1-settings.firstDayOfWeek));
366
- cell.addClass(className.weekCell);
367
- }
368
- for (c = 0; c < textColumns; c++, i++) {
369
- var cellDate = isYear ? new Date(i, month, 1, hour, minute) :
370
- isMonth ? new Date(year, i, 1, hour, minute) : isDay ? new Date(year, month, i, hour, minute) :
371
- isHour ? new Date(year, month, day, i) : new Date(year, month, day, hour, i * settings.minTimeGap);
372
- var cellText = isYear ? i :
373
- isMonth ? settings.text.monthsShort[i] : isDay ? cellDate.getDate() :
374
- formatter.time(cellDate, settings, true);
375
- cell = $('<td/>').addClass(className.cell).appendTo(row);
376
- cell.text(cellText);
377
- cell.data(metadata.date, cellDate);
378
- var adjacent = isDay && cellDate.getMonth() !== ((month + 12) % 12);
379
- var disabled = (!settings.selectAdjacentDays && adjacent) || !module.helper.isDateInRange(cellDate, mode) || settings.isDisabled(cellDate, mode) || module.helper.isDisabled(cellDate, mode) || !module.helper.isEnabled(cellDate, mode);
380
- var eventDate;
381
- if (disabled) {
382
- var disabledDate = module.helper.findDayAsObject(cellDate, mode, settings.disabledDates);
383
- if (disabledDate !== null && disabledDate[metadata.message]) {
384
- cell.attr("data-tooltip", disabledDate[metadata.message]);
385
- cell.attr("data-position", disabledDate[metadata.position] || tooltipPosition);
386
- if(disabledDate[metadata.inverted] || (isInverted && disabledDate[metadata.inverted] === undefined)) {
387
- cell.attr("data-inverted", '');
388
- }
389
- if(disabledDate[metadata.variation]) {
390
- cell.attr("data-variation", disabledDate[metadata.variation]);
391
- }
392
- }
393
- } else {
394
- eventDate = module.helper.findDayAsObject(cellDate, mode, settings.eventDates);
395
- if (eventDate !== null) {
396
- cell.addClass(eventDate[metadata.class] || settings.eventClass);
397
- if (eventDate[metadata.message]) {
398
- cell.attr("data-tooltip", eventDate[metadata.message]);
399
- cell.attr("data-position", eventDate[metadata.position] || tooltipPosition);
400
- if(eventDate[metadata.inverted] || (isInverted && eventDate[metadata.inverted] === undefined)) {
401
- cell.attr("data-inverted", '');
402
- }
403
- if(eventDate[metadata.variation]) {
404
- cell.attr("data-variation", eventDate[metadata.variation]);
405
- }
406
- }
407
- }
408
- }
409
- var active = module.helper.dateEqual(cellDate, date, mode);
410
- var isToday = module.helper.dateEqual(cellDate, today, mode);
411
- cell.toggleClass(className.adjacentCell, adjacent && !eventDate);
412
- cell.toggleClass(className.disabledCell, disabled);
413
- cell.toggleClass(className.activeCell, active && !(adjacent && disabled));
414
- if (!isHour && !isMinute) {
415
- cell.toggleClass(className.todayCell, !adjacent && isToday);
416
- }
417
-
418
- // Allow for external modifications of each cell
419
- var cellOptions = {
420
- mode: mode,
421
- adjacent: adjacent,
422
- disabled: disabled,
423
- active: active,
424
- today: isToday
425
- };
426
- formatter.cell(cell, cellDate, cellOptions);
427
-
428
- if (module.helper.dateEqual(cellDate, focusDate, mode)) {
429
- //ensure that the focus date is exactly equal to the cell date
430
- //so that, if selected, the correct value is set
431
- module.set.focusDate(cellDate, false, false);
432
- }
433
- }
434
- }
872
+ return true;
873
+ } catch (e) {
874
+ return false;
875
+ }
876
+ },
877
+ calendarModule: function (selector) {
878
+ if (!selector) {
879
+ return null;
880
+ }
881
+ if (!(selector instanceof $)) {
882
+ selector = $document.find(selector).first();
883
+ }
435
884
 
436
- if (settings.today) {
437
- var todayRow = $('<tr/>').appendTo(tbody);
438
- var todayButton = $('<td/>').attr('colspan', '' + columns).addClass(className.today).appendTo(todayRow);
439
- todayButton.text(formatter.today(settings));
440
- todayButton.data(metadata.date, today);
441
- }
885
+ // assume range related calendars are using the same namespace
886
+ return selector.data(moduleNamespace);
887
+ },
888
+ },
442
889
 
443
- module.update.focus(false, table);
890
+ set: {
891
+ date: function (date, updateInput, fireChange) {
892
+ updateInput = updateInput !== false;
893
+ fireChange = fireChange !== false;
894
+ date = module.helper.sanitiseDate(date);
895
+ date = module.helper.dateInRange(date);
444
896
 
445
- if(settings.inline){
446
- module.refreshTooltips();
447
- }
448
- }
449
- }
450
- },
897
+ var mode = module.get.mode();
898
+ var text = module.helper.dateFormat(formatter[settings.type], date);
451
899
 
452
- update: {
453
- focus: function (updateRange, container) {
454
- container = container || $container;
455
- var mode = module.get.mode();
456
- var date = module.get.date();
457
- var focusDate = module.get.focusDate();
458
- var startDate = module.get.startDate();
459
- var endDate = module.get.endDate();
460
- var rangeDate = (updateRange ? focusDate : null) || date || (!isTouch ? focusDate : null);
461
-
462
- container.find('td').each(function () {
463
- var cell = $(this);
464
- var cellDate = cell.data(metadata.date);
465
- if (!cellDate) {
466
- return;
467
- }
468
- var disabled = cell.hasClass(className.disabledCell);
469
- var active = cell.hasClass(className.activeCell);
470
- var adjacent = cell.hasClass(className.adjacentCell);
471
- var focused = module.helper.dateEqual(cellDate, focusDate, mode);
472
- var inRange = !rangeDate ? false :
473
- ((!!startDate && module.helper.isDateInRange(cellDate, mode, startDate, rangeDate)) ||
474
- (!!endDate && module.helper.isDateInRange(cellDate, mode, rangeDate, endDate)));
475
- cell.toggleClass(className.focusCell, focused && (!isTouch || isTouchDown) && (!adjacent || (settings.selectAdjacentDays && adjacent)) && !disabled);
476
-
477
- if (module.helper.isTodayButton(cell)) {
478
- return;
479
- }
480
- cell.toggleClass(className.rangeCell, inRange && !active && !disabled);
481
- });
482
- }
483
- },
900
+ if (fireChange && settings.onBeforeChange.call(element, date, text, mode) === false) {
901
+ return false;
902
+ }
484
903
 
485
- refresh: function () {
486
- module.create.calendar();
487
- },
904
+ module.set.focusDate(date);
488
905
 
489
- refreshTooltips: function() {
490
- var winWidth = $(window).width();
491
- $container.find('td[data-position]').each(function () {
492
- var cell = $(this);
493
- var tooltipWidth = window.getComputedStyle(cell[0], ':after').width.replace(/[^0-9\.]/g,'');
494
- var tooltipPosition = cell.attr('data-position');
495
- // use a fallback width of 250 (calendar width) for IE/Edge (which return "auto")
496
- var calcPosition = (winWidth - cell.width() - (parseInt(tooltipWidth,10) || 250)) > cell.offset().left ? 'right' : 'left';
497
- if(tooltipPosition.indexOf(calcPosition) === -1) {
498
- cell.attr('data-position',tooltipPosition.replace(/(left|right)/,calcPosition));
499
- }
500
- });
501
- },
906
+ if (settings.isDisabled(date, mode)) {
907
+ return false;
908
+ }
502
909
 
503
- bind: {
504
- events: function () {
505
- module.debug('Binding events');
506
- $container.on('mousedown' + eventNamespace, module.event.mousedown);
507
- $container.on('touchstart' + eventNamespace, module.event.mousedown);
508
- $container.on('mouseup' + eventNamespace, module.event.mouseup);
509
- $container.on('touchend' + eventNamespace, module.event.mouseup);
510
- $container.on('mouseover' + eventNamespace, module.event.mouseover);
511
- if ($input.length) {
512
- $input.on('input' + eventNamespace, module.event.inputChange);
513
- $input.on('focus' + eventNamespace, module.event.inputFocus);
514
- $input.on('blur' + eventNamespace, module.event.inputBlur);
515
- $input.on('keydown' + eventNamespace, module.event.keydown);
516
- } else {
517
- $container.on('keydown' + eventNamespace, module.event.keydown);
518
- }
519
- }
520
- },
910
+ var endDate = module.get.endDate();
911
+ if (!!endDate && !!date && date > endDate) {
912
+ // selected date is greater than end date in range, so clear end date
913
+ module.set.endDate();
914
+ }
915
+ module.set.dataKeyValue(metadata.date, date);
521
916
 
522
- unbind: {
523
- events: function () {
524
- module.debug('Unbinding events');
525
- $container.off(eventNamespace);
526
- if ($input.length) {
527
- $input.off(eventNamespace);
528
- }
529
- }
530
- },
917
+ if (updateInput && $input.length > 0) {
918
+ $input.val(text);
919
+ }
531
920
 
532
- event: {
533
- mouseover: function (event) {
534
- var target = $(event.target);
535
- var date = target.data(metadata.date);
536
- var mousedown = event.buttons === 1;
537
- if (date) {
538
- module.set.focusDate(date, false, true, mousedown);
539
- }
540
- },
541
- mousedown: function (event) {
542
- if ($input.length) {
543
- //prevent the mousedown on the calendar causing the input to lose focus
544
- event.preventDefault();
545
- }
546
- isTouchDown = event.type.indexOf('touch') >= 0;
547
- var target = $(event.target);
548
- var date = target.data(metadata.date);
549
- if (date) {
550
- module.set.focusDate(date, false, true, true);
551
- }
552
- },
553
- mouseup: function (event) {
554
- //ensure input has focus so that it receives keydown events for calendar navigation
555
- module.focus();
556
- event.preventDefault();
557
- event.stopPropagation();
558
- isTouchDown = false;
559
- var target = $(event.target);
560
- if (target.hasClass("disabled")) {
561
- return;
562
- }
563
- var parent = target.parent();
564
- if (parent.data(metadata.date) || parent.data(metadata.focusDate) || parent.data(metadata.mode)) {
565
- //clicked on a child element, switch to parent (used when clicking directly on prev/next <i> icon element)
566
- target = parent;
567
- }
568
- var date = target.data(metadata.date);
569
- var focusDate = target.data(metadata.focusDate);
570
- var mode = target.data(metadata.mode);
571
- if (date && settings.onSelect.call(element, date, module.get.mode()) !== false) {
572
- var forceSet = target.hasClass(className.today);
573
- module.selectDate(date, forceSet);
574
- }
575
- else if (focusDate) {
576
- module.set.focusDate(focusDate);
577
- }
578
- else if (mode) {
579
- module.set.mode(mode);
580
- }
581
- },
582
- keydown: function (event) {
583
- var keyCode = event.which;
584
- if (keyCode === 27 || keyCode === 9) {
585
- //esc || tab
586
- module.popup('hide');
587
- }
921
+ if (fireChange) {
922
+ settings.onChange.call(element, date, text, mode);
923
+ }
924
+ },
925
+ startDate: function (date, refreshCalendar) {
926
+ date = module.helper.sanitiseDate(date);
927
+ var startModule = module.get.calendarModule(settings.startCalendar);
928
+ if (startModule) {
929
+ startModule.set.date(date);
930
+ }
931
+ module.set.dataKeyValue(metadata.startDate, date, refreshCalendar);
932
+ },
933
+ endDate: function (date, refreshCalendar) {
934
+ date = module.helper.sanitiseDate(date);
935
+ var endModule = module.get.calendarModule(settings.endCalendar);
936
+ if (endModule) {
937
+ endModule.set.date(date);
938
+ }
939
+ module.set.dataKeyValue(metadata.endDate, date, refreshCalendar);
940
+ },
941
+ focusDate: function (date, refreshCalendar, updateFocus, updateRange) {
942
+ date = module.helper.sanitiseDate(date);
943
+ date = module.helper.dateInRange(date);
944
+ var isDay = module.get.mode() === 'day';
945
+ var oldFocusDate = module.get.focusDate();
946
+ if (isDay && date && oldFocusDate) {
947
+ var yearDelta = date.getFullYear() - oldFocusDate.getFullYear();
948
+ var monthDelta = yearDelta * 12 + date.getMonth() - oldFocusDate.getMonth();
949
+ if (monthDelta) {
950
+ var monthOffset = module.get.monthOffset() - monthDelta;
951
+ module.set.monthOffset(monthOffset, false);
952
+ }
953
+ }
954
+ var changed = module.set.dataKeyValue(metadata.focusDate, date, !!date && refreshCalendar);
955
+ updateFocus = (updateFocus !== false && changed && refreshCalendar === false) || focusDateUsedForRange != updateRange;
956
+ focusDateUsedForRange = updateRange;
957
+ if (updateFocus) {
958
+ module.update.focus(updateRange);
959
+ }
960
+ },
961
+ minDate: function (date) {
962
+ date = module.helper.sanitiseDate(date);
963
+ if (settings.maxDate !== null && settings.maxDate <= date) {
964
+ module.verbose('Unable to set minDate variable bigger that maxDate variable', date, settings.maxDate);
965
+ } else {
966
+ module.setting('minDate', date);
967
+ module.set.dataKeyValue(metadata.minDate, date);
968
+ }
969
+ },
970
+ maxDate: function (date) {
971
+ date = module.helper.sanitiseDate(date);
972
+ if (settings.minDate !== null && settings.minDate >= date) {
973
+ module.verbose('Unable to set maxDate variable lower that minDate variable', date, settings.minDate);
974
+ } else {
975
+ module.setting('maxDate', date);
976
+ module.set.dataKeyValue(metadata.maxDate, date);
977
+ }
978
+ },
979
+ monthOffset: function (monthOffset, refreshCalendar) {
980
+ var multiMonth = Math.max(settings.multiMonth, 1);
981
+ monthOffset = Math.max(1 - multiMonth, Math.min(0, monthOffset));
982
+ module.set.dataKeyValue(metadata.monthOffset, monthOffset, refreshCalendar);
983
+ },
984
+ mode: function (mode, refreshCalendar) {
985
+ module.set.dataKeyValue(metadata.mode, mode, refreshCalendar);
986
+ },
987
+ dataKeyValue: function (key, value, refreshCalendar) {
988
+ var oldValue = $module.data(key);
989
+ var equal = oldValue === value || (oldValue <= value && oldValue >= value); // equality test for dates and string objects
990
+ if (value) {
991
+ $module.data(key, value);
992
+ } else {
993
+ $module.removeData(key);
994
+ }
995
+ refreshCalendar = refreshCalendar !== false && !equal;
996
+ if (refreshCalendar) {
997
+ module.refresh();
998
+ }
588
999
 
589
- if (module.popup('is visible')) {
590
- if (keyCode === 37 || keyCode === 38 || keyCode === 39 || keyCode === 40) {
591
- //arrow keys
592
- var mode = module.get.mode();
593
- var bigIncrement = mode === 'day' ? 7 : mode === 'hour' ? 4 : mode === 'minute' ? timeGap['column'] : 3;
594
- var increment = keyCode === 37 ? -1 : keyCode === 38 ? -bigIncrement : keyCode == 39 ? 1 : bigIncrement;
595
- increment *= mode === 'minute' ? settings.minTimeGap : 1;
596
- var focusDate = module.get.focusDate() || module.get.date() || new Date();
597
- var year = focusDate.getFullYear() + (mode === 'year' ? increment : 0);
598
- var month = focusDate.getMonth() + (mode === 'month' ? increment : 0);
599
- var day = focusDate.getDate() + (mode === 'day' ? increment : 0);
600
- var hour = focusDate.getHours() + (mode === 'hour' ? increment : 0);
601
- var minute = focusDate.getMinutes() + (mode === 'minute' ? increment : 0);
602
- var newFocusDate = new Date(year, month, day, hour, minute);
603
- if (settings.type === 'time') {
604
- newFocusDate = module.helper.mergeDateTime(focusDate, newFocusDate);
605
- }
606
- if (module.helper.isDateInRange(newFocusDate, mode)) {
607
- module.set.focusDate(newFocusDate);
608
- }
609
- } else if (keyCode === 13) {
610
- //enter
611
- var mode = module.get.mode();
612
- var date = module.get.focusDate();
613
- if (date && !settings.isDisabled(date, mode) && !module.helper.isDisabled(date, mode) && module.helper.isEnabled(date, mode)) {
614
- module.selectDate(date);
615
- }
616
- //disable form submission:
617
- event.preventDefault();
618
- event.stopPropagation();
619
- }
620
- }
1000
+ return !equal;
1001
+ },
1002
+ },
1003
+
1004
+ selectDate: function (date, forceSet) {
1005
+ module.verbose('New date selection', date);
1006
+ var mode = module.get.mode();
1007
+ var complete = forceSet || mode === 'minute'
1008
+ || (settings.disableMinute && mode === 'hour')
1009
+ || (settings.type === 'date' && mode === 'day')
1010
+ || (settings.type === 'month' && mode === 'month')
1011
+ || (settings.type === 'year' && mode === 'year');
1012
+ if (complete) {
1013
+ var canceled = module.set.date(date) === false;
1014
+ if (!canceled) {
1015
+ selectionComplete = true;
1016
+ if (settings.closable) {
1017
+ module.popup('hide');
1018
+ // if this is a range calendar, focus the container or input. This will open the popup from its event listeners.
1019
+ var endModule = module.get.calendarModule(settings.endCalendar);
1020
+ if (endModule) {
1021
+ endModule.refresh();
1022
+ if (endModule.setting('on') !== 'focus') {
1023
+ endModule.popup('show');
1024
+ }
1025
+ endModule.focus();
1026
+ }
1027
+ }
1028
+ }
1029
+ } else {
1030
+ var newMode = mode === 'year'
1031
+ ? (!settings.disableMonth ? 'month' : 'day')
1032
+ : (mode === 'month'
1033
+ ? 'day'
1034
+ : (mode === 'day' ? 'hour' : 'minute')); // eslint-disable-line unicorn/no-nested-ternary
1035
+ module.set.mode(newMode);
1036
+ if (mode === 'hour' || (mode === 'day' && module.get.date())) {
1037
+ // the user has chosen enough to consider a valid date/time has been chosen
1038
+ module.set.date(date, true, false);
1039
+ } else {
1040
+ module.set.focusDate(date);
1041
+ }
1042
+ }
1043
+ },
621
1044
 
622
- if (keyCode === 38 || keyCode === 40) {
623
- //arrow-up || arrow-down
624
- event.preventDefault(); //don't scroll
625
- module.popup('show');
626
- }
627
- },
628
- inputChange: function () {
629
- var val = $input.val();
630
- var date = parser.date(val, settings);
631
- module.set.date(date, false);
632
- },
633
- inputFocus: function () {
634
- $container.addClass(className.active);
635
- },
636
- inputBlur: function () {
637
- $container.removeClass(className.active);
638
- if (settings.formatInput) {
639
- var date = module.get.date();
640
- var text = formatter.datetime(date, settings);
641
- $input.val(text);
642
- }
643
- if(selectionComplete){
644
- module.trigger.change();
645
- selectionComplete = false;
646
- }
647
- },
648
- class: {
649
- mutation: function(mutations) {
650
- mutations.forEach(function(mutation) {
651
- if(mutation.attributeName === "class") {
652
- module.check.disabled();
653
- }
654
- });
655
- }
656
- }
657
- },
1045
+ changeDate: function (date) {
1046
+ module.set.date(date);
1047
+ },
658
1048
 
659
- observeChanges: function() {
660
- if('MutationObserver' in window) {
661
- classObserver = new MutationObserver(module.event.class.mutation);
662
- module.debug('Setting up mutation observer', classObserver);
663
- module.observe.class();
664
- }
665
- },
1049
+ clear: function () {
1050
+ module.set.date();
1051
+ },
666
1052
 
667
- disconnect: {
668
- classObserver: function() {
669
- if($input.length && classObserver) {
670
- classObserver.disconnect();
671
- }
672
- }
673
- },
1053
+ popup: function () {
1054
+ return $activator.popup.apply($activator, arguments);
1055
+ },
674
1056
 
675
- observe: {
676
- class: function() {
677
- if($input.length && classObserver) {
678
- classObserver.observe($module[0], {
679
- attributes : true
680
- });
681
- }
682
- }
683
- },
1057
+ focus: function () {
1058
+ if ($input.length > 0) {
1059
+ $input.trigger('focus');
1060
+ } else {
1061
+ $container.trigger('focus');
1062
+ }
1063
+ },
1064
+ blur: function () {
1065
+ if ($input.length > 0) {
1066
+ $input.trigger('blur');
1067
+ } else {
1068
+ $container.trigger('blur');
1069
+ }
1070
+ },
1071
+
1072
+ helper: {
1073
+ dateFormat: function (format, date) {
1074
+ if (!(date instanceof Date)) {
1075
+ return '';
1076
+ }
1077
+ if (typeof format === 'function') {
1078
+ return format.call(module, date, settings);
1079
+ }
1080
+
1081
+ var
1082
+ D = date.getDate(),
1083
+ M = date.getMonth(),
1084
+ Y = date.getFullYear(),
1085
+ d = date.getDay(),
1086
+ H = date.getHours(),
1087
+ m = date.getMinutes(),
1088
+ s = date.getSeconds(),
1089
+ w = module.get.weekOfYear(Y, M, D + 1 - settings.firstDayOfWeek),
1090
+ h = H % 12 || 12,
1091
+ a = H < 12 ? settings.text.am.toLowerCase() : settings.text.pm.toLowerCase(),
1092
+ tokens = {
1093
+ D: D,
1094
+ DD: ('0' + D).slice(-2),
1095
+ M: M + 1,
1096
+ MM: ('0' + (M + 1)).slice(-2),
1097
+ MMM: settings.text.monthsShort[M],
1098
+ MMMM: settings.text.months[M],
1099
+ Y: Y,
1100
+ YY: String(Y).slice(2),
1101
+ YYYY: Y,
1102
+ d: d,
1103
+ dd: settings.text.dayNamesShort[d].slice(0, 2),
1104
+ ddd: settings.text.dayNamesShort[d],
1105
+ dddd: settings.text.dayNames[d],
1106
+ h: h,
1107
+ hh: ('0' + h).slice(-2),
1108
+ H: H,
1109
+ HH: ('0' + H).slice(-2),
1110
+ m: m,
1111
+ mm: ('0' + m).slice(-2),
1112
+ s: s,
1113
+ ss: ('0' + s).slice(-2),
1114
+ a: a,
1115
+ A: a.toUpperCase(),
1116
+ S: ['th', 'st', 'nd', 'rd'][(D % 10) > 3 ? 0 : ((D % 100) - (D % 10) === 10 ? 0 : D % 10)],
1117
+ w: w,
1118
+ ww: ('0' + w).slice(-2),
1119
+ }
1120
+ ;
1121
+
1122
+ return format.replace(settings.regExp.token, function (match) {
1123
+ if (match in tokens) {
1124
+ return tokens[match];
1125
+ }
1126
+
1127
+ return match.slice(1, -1);
1128
+ });
1129
+ },
1130
+ isDisabled: function (date, mode) {
1131
+ return (mode === 'day' || mode === 'month' || mode === 'year' || mode === 'hour') && (((mode === 'day' && settings.disabledDaysOfWeek.indexOf(date.getDay()) !== -1) || settings.disabledDates.some(function (d) {
1132
+ var blocked = false;
1133
+
1134
+ if (typeof d === 'string') {
1135
+ d = module.helper.sanitiseDate(d);
1136
+ }
1137
+ if (d instanceof Date) {
1138
+ blocked = module.helper.dateEqual(date, d, mode);
1139
+ } else if (d !== null && typeof d === 'object') {
1140
+ if (d[metadata.year]) {
1141
+ if (typeof d[metadata.year] === 'number') {
1142
+ blocked = date.getFullYear() === d[metadata.year];
1143
+ } else if (Array.isArray(d[metadata.year])) {
1144
+ blocked = d[metadata.year].indexOf(date.getFullYear()) > -1;
1145
+ }
1146
+ } else if (d[metadata.month]) {
1147
+ if (typeof d[metadata.month] === 'number') {
1148
+ blocked = date.getMonth() === d[metadata.month];
1149
+ } else if (Array.isArray(d[metadata.month])) {
1150
+ blocked = d[metadata.month].indexOf(date.getMonth()) > -1;
1151
+ } else if (d[metadata.month] instanceof Date) {
1152
+ var sdate = module.helper.sanitiseDate(d[metadata.month]);
1153
+
1154
+ blocked = (date.getMonth() === sdate.getMonth()) && (date.getFullYear() === sdate.getFullYear());
1155
+ }
1156
+ } else if (d[metadata.date] && mode === 'day') {
1157
+ if (d[metadata.date] instanceof Date) {
1158
+ blocked = module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
1159
+ } else if (Array.isArray(d[metadata.date])) {
1160
+ blocked = d[metadata.date].some(function (idate) {
1161
+ return module.helper.dateEqual(date, idate, mode);
1162
+ });
1163
+ }
1164
+ }
1165
+ }
1166
+
1167
+ return blocked;
1168
+ })) || (mode === 'hour' && settings.disabledHours.some(function (d) {
1169
+ var blocked = false;
1170
+
1171
+ if (typeof d === 'string') {
1172
+ d = module.helper.sanitiseDate(d);
1173
+ }
1174
+ if (d instanceof Date) {
1175
+ blocked = module.helper.dateEqual(date, d, mode);
1176
+ } else if (typeof d === 'number') {
1177
+ blocked = date.getHours() === d;
1178
+ } else if (d !== null && typeof d === 'object') {
1179
+ if (d[metadata.date]) {
1180
+ if (d[metadata.date] instanceof Date) {
1181
+ blocked = module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]));
1182
+ } else if (Array.isArray(d[metadata.date])) {
1183
+ blocked = d[metadata.date].some(function (idate) {
1184
+ return module.helper.dateEqual(date, idate, mode);
1185
+ });
1186
+ }
1187
+ }
1188
+
1189
+ if (d[metadata.days]) {
1190
+ if (typeof d[metadata.days] === 'number') {
1191
+ blocked = date.getDay() === d[metadata.days];
1192
+ } else if (Array.isArray(d[metadata.days])) {
1193
+ blocked = d[metadata.days].indexOf(date.getDay()) > -1;
1194
+ }
1195
+ }
1196
+
1197
+ if (d[metadata.hours]) {
1198
+ if (typeof d[metadata.hours] === 'number') {
1199
+ blocked = blocked && date.getHours() === d[metadata.hours];
1200
+ } else if (Array.isArray(d[metadata.hours])) {
1201
+ blocked = blocked && d[metadata.hours].indexOf(date.getHours()) > -1;
1202
+ }
1203
+ }
1204
+ }
1205
+
1206
+ return blocked;
1207
+ })));
1208
+ },
1209
+ isEnabled: function (date, mode) {
1210
+ if (mode === 'day') {
1211
+ return settings.enabledDates.length === 0 || settings.enabledDates.some(function (d) {
1212
+ var enabled = false;
1213
+
1214
+ if (typeof d === 'string') {
1215
+ d = module.helper.sanitiseDate(d);
1216
+ }
1217
+ if (d instanceof Date) {
1218
+ enabled = module.helper.dateEqual(date, d, mode);
1219
+ } else if (d !== null && typeof d === 'object' && d[metadata.date]) {
1220
+ enabled = module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
1221
+ }
1222
+
1223
+ return enabled;
1224
+ });
1225
+ }
1226
+
1227
+ return true;
1228
+ },
1229
+ findDayAsObject: function (date, mode, dates) {
1230
+ if (mode === 'day' || mode === 'month' || mode === 'year') {
1231
+ var d;
1232
+ for (var i = 0; i < dates.length; i++) {
1233
+ d = dates[i];
1234
+ if (typeof d === 'string') {
1235
+ d = module.helper.sanitiseDate(d);
1236
+ }
1237
+ if (d instanceof Date && module.helper.dateEqual(date, d, mode)) {
1238
+ var dateObject = {};
1239
+ dateObject[metadata.date] = d;
1240
+
1241
+ return dateObject;
1242
+ }
1243
+ if (d !== null && typeof d === 'object') {
1244
+ if (d[metadata.year]) {
1245
+ if (typeof d[metadata.year] === 'number' && date.getFullYear() === d[metadata.year]) {
1246
+ return d;
1247
+ }
1248
+ if (Array.isArray(d[metadata.year])) {
1249
+ if (d[metadata.year].indexOf(date.getFullYear()) > -1) {
1250
+ return d;
1251
+ }
1252
+ }
1253
+ } else if (d[metadata.month]) {
1254
+ if (typeof d[metadata.month] === 'number' && date.getMonth() === d[metadata.month]) {
1255
+ return d;
1256
+ }
1257
+ if (Array.isArray(d[metadata.month])) {
1258
+ if (d[metadata.month].indexOf(date.getMonth()) > -1) {
1259
+ return d;
1260
+ }
1261
+ } else if (d[metadata.month] instanceof Date) {
1262
+ var sdate = module.helper.sanitiseDate(d[metadata.month]);
1263
+ if ((date.getMonth() === sdate.getMonth()) && (date.getFullYear() === sdate.getFullYear())) {
1264
+ return d;
1265
+ }
1266
+ }
1267
+ } else if (d[metadata.date] && mode === 'day') {
1268
+ if (d[metadata.date] instanceof Date && module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode)) {
1269
+ return d;
1270
+ }
1271
+ if (Array.isArray(d[metadata.date])) {
1272
+ if (d[metadata.date].some(function (idate) {
1273
+ return module.helper.dateEqual(date, idate, mode);
1274
+ })) {
1275
+ return d;
1276
+ }
1277
+ }
1278
+ }
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ return null;
1284
+ },
1285
+ findHourAsObject: function (date, mode, hours) {
1286
+ if (mode === 'hour') {
1287
+ var d;
1288
+ var hourCheck = function (date, d) {
1289
+ if (d[metadata.hours]) {
1290
+ if (typeof d[metadata.hours] === 'number' && date.getHours() === d[metadata.hours]) {
1291
+ return d;
1292
+ }
1293
+ if (Array.isArray(d[metadata.hours])) {
1294
+ if (d[metadata.hours].indexOf(date.getHours()) > -1) {
1295
+ return d;
1296
+ }
1297
+ }
1298
+ }
1299
+ };
1300
+ for (var i = 0; i < hours.length; i++) {
1301
+ d = hours[i];
1302
+ if (typeof d === 'number' && date.getHours() === d) {
1303
+ return null;
1304
+ }
1305
+ if (d !== null && typeof d === 'object') {
1306
+ if (d[metadata.days] && hourCheck(date, d)) {
1307
+ if (typeof d[metadata.days] === 'number' && date.getDay() === d[metadata.days]) {
1308
+ return d;
1309
+ }
1310
+ if (Array.isArray(d[metadata.days])) {
1311
+ if (d[metadata.days].indexOf(date.getDay()) > -1) {
1312
+ return d;
1313
+ }
1314
+ }
1315
+ } else if (d[metadata.date] && hourCheck(date, d)) {
1316
+ if (d[metadata.date] instanceof Date && module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]))) {
1317
+ return d;
1318
+ }
1319
+ if (Array.isArray(d[metadata.date])) {
1320
+ if (d[metadata.date].some(function (idate) {
1321
+ return module.helper.dateEqual(date, idate, mode);
1322
+ })) {
1323
+ return d;
1324
+ }
1325
+ }
1326
+ } else if (hourCheck(date, d)) {
1327
+ return d;
1328
+ }
1329
+ }
1330
+ }
1331
+ }
1332
+
1333
+ return null;
1334
+ },
1335
+ sanitiseDate: function (date) {
1336
+ if (!(date instanceof Date)) {
1337
+ date = parser.date('' + date, settings);
1338
+ }
1339
+ if (!date || isNaN(date.getTime())) {
1340
+ return null;
1341
+ }
1342
+
1343
+ return date;
1344
+ },
1345
+ dateDiff: function (date1, date2, mode) {
1346
+ if (!mode) {
1347
+ mode = 'day';
1348
+ }
684
1349
 
685
- is: {
686
- disabled: function() {
687
- return $module.hasClass(className.disabled);
688
- }
1350
+ var isTimeOnly = settings.type === 'time';
1351
+ var isYear = mode === 'year';
1352
+ var isYearOrMonth = isYear || mode === 'month';
1353
+ var isMinute = mode === 'minute';
1354
+ var isHourOrMinute = isMinute || mode === 'hour';
1355
+ // only care about a minute accuracy of settings.minTimeGap
1356
+ date1 = new Date(
1357
+ isTimeOnly ? 2000 : date1.getFullYear(),
1358
+ isTimeOnly ? 0 : (isYear ? 0 : date1.getMonth()),
1359
+ isTimeOnly ? 1 : (isYearOrMonth ? 1 : date1.getDate()),
1360
+ !isHourOrMinute ? 0 : date1.getHours(),
1361
+ !isMinute ? 0 : settings.minTimeGap * Math.floor(date1.getMinutes() / settings.minTimeGap)
1362
+ );
1363
+ date2 = new Date(
1364
+ isTimeOnly ? 2000 : date2.getFullYear(),
1365
+ isTimeOnly ? 0 : (isYear ? 0 : date2.getMonth()),
1366
+ isTimeOnly ? 1 : (isYearOrMonth ? 1 : date2.getDate()),
1367
+ !isHourOrMinute ? 0 : date2.getHours(),
1368
+ !isMinute ? 0 : settings.minTimeGap * Math.floor(date2.getMinutes() / settings.minTimeGap)
1369
+ );
1370
+
1371
+ return date2.getTime() - date1.getTime();
1372
+ },
1373
+ dateEqual: function (date1, date2, mode) {
1374
+ return !!date1 && !!date2 && module.helper.dateDiff(date1, date2, mode) === 0;
1375
+ },
1376
+ isDateInRange: function (date, mode, minDate, maxDate) {
1377
+ if (!minDate && !maxDate) {
1378
+ var startDate = module.get.startDate();
1379
+ minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
1380
+ maxDate = settings.maxDate;
1381
+ }
1382
+ minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
1383
+
1384
+ return !(!date
1385
+ || (minDate && module.helper.dateDiff(date, minDate, mode) > 0)
1386
+ || (maxDate && module.helper.dateDiff(maxDate, date, mode) > 0));
1387
+ },
1388
+ dateInRange: function (date, minDate, maxDate) {
1389
+ if (!minDate && !maxDate) {
1390
+ var startDate = module.get.startDate();
1391
+ minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
1392
+ maxDate = settings.maxDate;
1393
+ }
1394
+ minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
1395
+ var isTimeOnly = settings.type === 'time';
1396
+
1397
+ return !date
1398
+ ? date
1399
+ : (minDate && module.helper.dateDiff(date, minDate, 'minute') > 0
1400
+ ? (isTimeOnly ? module.helper.mergeDateTime(date, minDate) : minDate) // eslint-disable-line unicorn/no-nested-ternary
1401
+ : (maxDate && module.helper.dateDiff(maxDate, date, 'minute') > 0 // eslint-disable-line unicorn/no-nested-ternary
1402
+ ? (isTimeOnly ? module.helper.mergeDateTime(date, maxDate) : maxDate)
1403
+ : date));
1404
+ },
1405
+ mergeDateTime: function (date, time) {
1406
+ return !date || !time
1407
+ ? time
1408
+ : new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes());
1409
+ },
1410
+ isTodayButton: function (element) {
1411
+ return element.text() === settings.text.today;
1412
+ },
1413
+ },
1414
+
1415
+ setting: function (name, value) {
1416
+ module.debug('Changing setting', name, value);
1417
+ if ($.isPlainObject(name)) {
1418
+ $.extend(true, settings, name);
1419
+ } else if (value !== undefined) {
1420
+ if ($.isPlainObject(settings[name])) {
1421
+ $.extend(true, settings[name], value);
1422
+ } else {
1423
+ settings[name] = value;
1424
+ }
1425
+ } else {
1426
+ return settings[name];
1427
+ }
1428
+ },
1429
+ internal: function (name, value) {
1430
+ if ($.isPlainObject(name)) {
1431
+ $.extend(true, module, name);
1432
+ } else if (value !== undefined) {
1433
+ module[name] = value;
1434
+ } else {
1435
+ return module[name];
1436
+ }
1437
+ },
1438
+ debug: function () {
1439
+ if (!settings.silent && settings.debug) {
1440
+ if (settings.performance) {
1441
+ module.performance.log(arguments);
1442
+ } else {
1443
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1444
+ module.debug.apply(console, arguments);
1445
+ }
1446
+ }
1447
+ },
1448
+ verbose: function () {
1449
+ if (!settings.silent && settings.verbose && settings.debug) {
1450
+ if (settings.performance) {
1451
+ module.performance.log(arguments);
1452
+ } else {
1453
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1454
+ module.verbose.apply(console, arguments);
1455
+ }
1456
+ }
1457
+ },
1458
+ error: function () {
1459
+ if (!settings.silent) {
1460
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1461
+ module.error.apply(console, arguments);
1462
+ }
1463
+ },
1464
+ performance: {
1465
+ log: function (message) {
1466
+ var
1467
+ currentTime,
1468
+ executionTime,
1469
+ previousTime
1470
+ ;
1471
+ if (settings.performance) {
1472
+ currentTime = Date.now();
1473
+ previousTime = time || currentTime;
1474
+ executionTime = currentTime - previousTime;
1475
+ time = currentTime;
1476
+ performance.push({
1477
+ Name: message[0],
1478
+ Arguments: [].slice.call(message, 1) || '',
1479
+ Element: element,
1480
+ 'Execution Time': executionTime,
1481
+ });
1482
+ }
1483
+ clearTimeout(module.performance.timer);
1484
+ module.performance.timer = setTimeout(module.performance.display, 500);
1485
+ },
1486
+ display: function () {
1487
+ var
1488
+ title = settings.name + ':',
1489
+ totalTime = 0
1490
+ ;
1491
+ time = false;
1492
+ clearTimeout(module.performance.timer);
1493
+ $.each(performance, function (index, data) {
1494
+ totalTime += data['Execution Time'];
1495
+ });
1496
+ title += ' ' + totalTime + 'ms';
1497
+ if (moduleSelector) {
1498
+ title += ' \'' + moduleSelector + '\'';
1499
+ }
1500
+ if (performance.length > 0) {
1501
+ console.groupCollapsed(title);
1502
+ if (console.table) {
1503
+ console.table(performance);
1504
+ } else {
1505
+ $.each(performance, function (index, data) {
1506
+ console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
1507
+ });
1508
+ }
1509
+ console.groupEnd();
1510
+ }
1511
+ performance = [];
1512
+ },
1513
+ },
1514
+ invoke: function (query, passedArguments, context) {
1515
+ var
1516
+ object = instance,
1517
+ maxDepth,
1518
+ found,
1519
+ response
1520
+ ;
1521
+ passedArguments = passedArguments || queryArguments;
1522
+ context = context || element;
1523
+ if (typeof query === 'string' && object !== undefined) {
1524
+ query = query.split(/[ .]/);
1525
+ maxDepth = query.length - 1;
1526
+ $.each(query, function (depth, value) {
1527
+ var camelCaseValue = depth !== maxDepth
1528
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1529
+ : query
1530
+ ;
1531
+ if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
1532
+ object = object[camelCaseValue];
1533
+ } else if (object[camelCaseValue] !== undefined) {
1534
+ found = object[camelCaseValue];
1535
+
1536
+ return false;
1537
+ } else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
1538
+ object = object[value];
1539
+ } else if (object[value] !== undefined) {
1540
+ found = object[value];
1541
+
1542
+ return false;
1543
+ } else {
1544
+ module.error(error.method, query);
1545
+
1546
+ return false;
1547
+ }
1548
+ });
1549
+ }
1550
+ if (isFunction(found)) {
1551
+ response = found.apply(context, passedArguments);
1552
+ } else if (found !== undefined) {
1553
+ response = found;
1554
+ }
1555
+ if (Array.isArray(returnedValue)) {
1556
+ returnedValue.push(response);
1557
+ } else if (returnedValue !== undefined) {
1558
+ returnedValue = [returnedValue, response];
1559
+ } else if (response !== undefined) {
1560
+ returnedValue = response;
1561
+ }
1562
+
1563
+ return found;
1564
+ },
1565
+ };
1566
+
1567
+ if (methodInvoked) {
1568
+ if (instance === undefined) {
1569
+ module.initialize();
1570
+ }
1571
+ module.invoke(query);
1572
+ } else {
1573
+ if (instance !== undefined) {
1574
+ instance.invoke('destroy');
1575
+ }
1576
+ module.initialize();
1577
+ }
1578
+ });
1579
+
1580
+ return returnedValue !== undefined
1581
+ ? returnedValue
1582
+ : this;
1583
+ };
1584
+
1585
+ $.fn.calendar.settings = {
1586
+
1587
+ name: 'Calendar',
1588
+ namespace: 'calendar',
1589
+
1590
+ silent: false,
1591
+ debug: false,
1592
+ verbose: false,
1593
+ performance: true,
1594
+
1595
+ context: false,
1596
+
1597
+ type: 'datetime', // picker type, can be 'datetime', 'date', 'time', 'month', or 'year'
1598
+ firstDayOfWeek: 0, // day for first day column (0 = Sunday)
1599
+ constantHeight: true, // add rows to shorter months to keep day calendar height consistent (6 rows)
1600
+ today: false, // show a 'today/now' button at the bottom of the calendar
1601
+ closable: true, // close the popup after selecting a date/time
1602
+ monthFirst: true, // month before day when parsing date from text
1603
+ touchReadonly: true, // set input to readonly on touch devices
1604
+ inline: false, // create the calendar inline instead of inside a popup
1605
+ on: null, // when to show the popup (defaults to 'focus' for input, 'click' for others)
1606
+ initialDate: null, // date to display initially when no date is selected (null = now)
1607
+ startMode: false, // display mode to start in, can be 'year', 'month', 'day', 'hour', 'minute' (false = 'day')
1608
+ minDate: null, // minimum date/time that can be selected, dates/times before are disabled
1609
+ maxDate: null, // maximum date/time that can be selected, dates/times after are disabled
1610
+ disableYear: false, // disable year selection mode
1611
+ disableMonth: false, // disable month selection mode
1612
+ disableMinute: false, // disable minute selection mode
1613
+ formatInput: true, // format the input text upon input blur and module creation
1614
+ startCalendar: null, // jquery object or selector for another calendar that represents the start date of a date range
1615
+ endCalendar: null, // jquery object or selector for another calendar that represents the end date of a date range
1616
+ multiMonth: 1, // show multiple months when in 'day' mode
1617
+ monthOffset: 0, // position current month by offset when multimonth > 1
1618
+ minTimeGap: 5,
1619
+ showWeekNumbers: false, // show Number of Week at the very first column of a dayView
1620
+ disabledHours: [], // specific hour(s) which won't be selectable and contain additional information.
1621
+ disabledDates: [], // specific day(s) which won't be selectable and contain additional information.
1622
+ disabledDaysOfWeek: [], // day(s) which won't be selectable(s) (0 = Sunday)
1623
+ enabledDates: [], // specific day(s) which will be selectable, all other days will be disabled
1624
+ eventDates: [], // specific day(s) which will be shown in a different color and using tooltips
1625
+ centuryBreak: 60, // starting short year until 99 where it will be assumed to belong to the last century
1626
+ currentCentury: 2000, // century to be added to 2-digit years (00 to {centuryBreak}-1)
1627
+ selectAdjacentDays: false, // The calendar can show dates from adjacent month. These adjacent month dates can also be made selectable.
1628
+ // popup options ('popup', 'on', 'hoverable', and show/hide callbacks are overridden)
1629
+ popupOptions: {
1630
+ position: 'bottom left',
1631
+ lastResort: 'bottom left',
1632
+ prefer: 'opposite',
1633
+ observeChanges: false,
1634
+ hideOnScroll: false,
689
1635
  },
690
1636
 
691
- check: {
692
- disabled: function(){
693
- $input.attr('tabindex',module.is.disabled() ? -1 : 0);
694
- }
1637
+ text: {
1638
+ days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
1639
+ dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
1640
+ dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
1641
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
1642
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
1643
+ today: 'Today',
1644
+ now: 'Now',
1645
+ am: 'AM',
1646
+ pm: 'PM',
1647
+ weekNo: 'Week',
695
1648
  },
696
1649
 
697
- get: {
698
- weekOfYear: function(weekYear,weekMonth,weekDay) {
699
- // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
700
- var ms1d = 864e5, // milliseconds in a day
701
- ms7d = 7 * ms1d; // milliseconds in a week
702
-
703
- return function() { // return a closure so constants get calculated only once
704
- var DC3 = Date.UTC(weekYear, weekMonth, weekDay + 3) / ms1d, // an Absolute Day Number
705
- AWN = Math.floor(DC3 / 7), // an Absolute Week Number
706
- Wyr = new Date(AWN * ms7d).getUTCFullYear();
707
-
708
- return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
709
- }();
710
- },
711
- date: function () {
712
- return module.helper.sanitiseDate($module.data(metadata.date)) || null;
713
- },
714
- inputDate: function() {
715
- return $input.val();
716
- },
717
- focusDate: function () {
718
- return $module.data(metadata.focusDate) || null;
719
- },
720
- startDate: function () {
721
- var startModule = module.get.calendarModule(settings.startCalendar);
722
- return (startModule ? startModule.get.date() : $module.data(metadata.startDate)) || null;
723
- },
724
- endDate: function () {
725
- var endModule = module.get.calendarModule(settings.endCalendar);
726
- return (endModule ? endModule.get.date() : $module.data(metadata.endDate)) || null;
727
- },
728
- minDate: function() {
729
- return $module.data(metadata.minDate) || null;
730
- },
731
- maxDate: function() {
732
- return $module.data(metadata.maxDate) || null;
733
- },
734
- monthOffset: function () {
735
- return $module.data(metadata.monthOffset) || 0;
736
- },
737
- mode: function () {
738
- //only returns valid modes for the current settings
739
- var mode = $module.data(metadata.mode) || settings.startMode;
740
- return module.get.validatedMode(mode);
741
- },
742
- validatedMode: function(mode){
743
- var validModes = module.get.validModes();
744
- if ($.inArray(mode, validModes) >= 0) {
745
- return mode;
746
- }
747
- return settings.type === 'time' ? 'hour' :
748
- settings.type === 'month' ? 'month' :
749
- settings.type === 'year' ? 'year' : 'day';
750
- },
751
- type: function() {
752
- return $module.data(metadata.type) || settings.type;
753
- },
754
- validModes: function () {
755
- var validModes = [];
756
- if (settings.type !== 'time') {
757
- if (!settings.disableYear || settings.type === 'year') {
758
- validModes.push('year');
759
- }
760
- if (!(settings.disableMonth || settings.type === 'year') || settings.type === 'month') {
761
- validModes.push('month');
762
- }
763
- if (settings.type.indexOf('date') >= 0) {
764
- validModes.push('day');
765
- }
766
- }
767
- if (settings.type.indexOf('time') >= 0) {
768
- validModes.push('hour');
769
- if (!settings.disableMinute) {
770
- validModes.push('minute');
771
- }
772
- }
773
- return validModes;
774
- },
775
- isTouch: function () {
776
- try {
777
- document.createEvent('TouchEvent');
778
- return true;
779
- }
780
- catch (e) {
781
- return false;
782
- }
783
- },
784
- calendarModule: function (selector) {
785
- if (!selector) {
786
- return null;
787
- }
788
- if (!(selector instanceof $)) {
789
- selector = $(selector).first();
790
- }
791
- //assume range related calendars are using the same namespace
792
- return selector.data(moduleNamespace);
793
- }
1650
+ formatter: {
1651
+ yearHeader: function (date, settings) {
1652
+ var decadeYear = Math.ceil(date.getFullYear() / 10) * 10;
1653
+
1654
+ return (decadeYear - 9) + ' - ' + (decadeYear + 2);
1655
+ },
1656
+ monthHeader: 'YYYY',
1657
+ dayHeader: 'MMMM YYYY',
1658
+ hourHeader: 'MMMM D, YYYY',
1659
+ minuteHeader: 'MMMM D, YYYY',
1660
+ dayColumnHeader: function (day, settings) {
1661
+ return settings.text.days[day];
1662
+ },
1663
+ datetime: 'MMMM D, YYYY h:mm A',
1664
+ date: 'MMMM D, YYYY',
1665
+ time: 'h:mm A',
1666
+ cellTime: 'h:mm A',
1667
+ month: 'MMMM YYYY',
1668
+ year: 'YYYY',
1669
+ today: function (settings) {
1670
+ return settings.type === 'date' ? settings.text.today : settings.text.now;
1671
+ },
1672
+ cell: function (cell, date, cellOptions) {},
794
1673
  },
795
1674
 
796
- set: {
797
- date: function (date, updateInput, fireChange) {
798
- updateInput = updateInput !== false;
799
- fireChange = fireChange !== false;
800
- date = module.helper.sanitiseDate(date);
801
- date = module.helper.dateInRange(date);
1675
+ parser: {
1676
+ date: function (text, settings) {
1677
+ if (text instanceof Date) {
1678
+ return text;
1679
+ }
1680
+ if (!text) {
1681
+ return null;
1682
+ }
1683
+ text = String(text).trim().replace(/([./:-])\s+/g, '$1').replace(/\s+([./:-])/g, '$1')
1684
+ .replace(/\s+/g, ' ');
1685
+ if (text.length === 0) {
1686
+ return null;
1687
+ }
1688
+ if (/^\d{4}(?:[./-]\d{1,2}){2}$/.test(text)) {
1689
+ text = text.replace(/[./-]/g, '/') + ' 00:00:00';
1690
+ }
1691
+ // Reverse date and month in some cases
1692
+ text = settings.monthFirst || !/^\d{1,2}[./-]/.test(text) ? text : text.replace(/[./-]/g, '/').replace(/(\d+)\/(\d+)/, '$2/$1');
1693
+ var textDate = new Date(text);
1694
+ var numberOnly = text.match(/^\d+$/) !== null;
1695
+ if (!numberOnly && !isNaN(textDate.getDate())) {
1696
+ return textDate;
1697
+ }
1698
+ text = text.toLowerCase();
802
1699
 
803
- var mode = module.get.mode();
804
- var text = formatter.datetime(date, settings);
1700
+ var
1701
+ i,
1702
+ j,
1703
+ k
1704
+ ;
1705
+ var
1706
+ minute = -1,
1707
+ hour = -1,
1708
+ day = -1,
1709
+ month = -1,
1710
+ year = -1
1711
+ ;
1712
+ var isAm;
805
1713
 
806
- if (fireChange && settings.onBeforeChange.call(element, date, text, mode) === false) {
807
- return false;
808
- }
1714
+ var isTimeOnly = settings.type === 'time';
1715
+ var isDateOnly = settings.type.indexOf('time') < 0;
809
1716
 
810
- module.set.focusDate(date);
1717
+ var
1718
+ words = text.split(settings.regExp.dateWords),
1719
+ word
1720
+ ;
1721
+ var
1722
+ numbers = text.split(settings.regExp.dateNumbers),
1723
+ number
1724
+ ;
811
1725
 
812
- if (settings.isDisabled(date, mode)) {
813
- return false;
814
- }
1726
+ var parts;
1727
+ var monthString;
1728
+
1729
+ if (!isDateOnly) {
1730
+ // am/pm
1731
+ isAm = $.inArray(settings.text.am.toLowerCase(), words) >= 0
1732
+ ? true
1733
+ : ($.inArray(settings.text.pm.toLowerCase(), words) >= 0 ? false : undefined);
1734
+
1735
+ // time with ':'
1736
+ for (i = 0; i < numbers.length; i++) {
1737
+ number = numbers[i];
1738
+ if (number.indexOf(':') >= 0) {
1739
+ if (hour < 0 || minute < 0) {
1740
+ parts = number.split(':');
1741
+ for (k = 0; k < Math.min(2, parts.length); k++) {
1742
+ j = parseInt(parts[k], 10);
1743
+ if (isNaN(j)) {
1744
+ j = 0;
1745
+ }
1746
+ if (k === 0) {
1747
+ hour = j % 24;
1748
+ } else {
1749
+ minute = j % 60;
1750
+ }
1751
+ }
1752
+ }
1753
+ numbers.splice(i, 1);
1754
+ }
1755
+ }
1756
+ }
815
1757
 
816
- var endDate = module.get.endDate();
817
- if (!!endDate && !!date && date > endDate) {
818
- //selected date is greater than end date in range, so clear end date
819
- module.set.endDate(undefined);
820
- }
821
- module.set.dataKeyValue(metadata.date, date);
1758
+ if (!isTimeOnly) {
1759
+ // textual month
1760
+ for (i = 0; i < words.length; i++) {
1761
+ word = words[i];
1762
+ if (word.length <= 0) {
1763
+ continue;
1764
+ }
1765
+ for (j = 0; j < settings.text.months.length; j++) {
1766
+ monthString = settings.text.months[j];
1767
+ monthString = monthString.slice(0, word.length).toLowerCase();
1768
+ if (monthString === word) {
1769
+ month = j + 1;
1770
+
1771
+ break;
1772
+ }
1773
+ }
1774
+ if (month >= 0) {
1775
+ break;
1776
+ }
1777
+ }
822
1778
 
823
- if (updateInput && $input.length) {
824
- $input.val(text);
825
- }
1779
+ // year > settings.centuryBreak
1780
+ for (i = 0; i < numbers.length; i++) {
1781
+ j = parseInt(numbers[i], 10);
1782
+ if (isNaN(j)) {
1783
+ continue;
1784
+ }
1785
+ if (j >= settings.centuryBreak && i === numbers.length - 1) {
1786
+ if (j <= 99) {
1787
+ j += settings.currentCentury - 100;
1788
+ }
1789
+ year = j;
1790
+ numbers.splice(i, 1);
1791
+
1792
+ break;
1793
+ }
1794
+ }
826
1795
 
827
- if (fireChange) {
828
- settings.onChange.call(element, date, text, mode);
829
- }
830
- },
831
- startDate: function (date, refreshCalendar) {
832
- date = module.helper.sanitiseDate(date);
833
- var startModule = module.get.calendarModule(settings.startCalendar);
834
- if (startModule) {
835
- startModule.set.date(date);
836
- }
837
- module.set.dataKeyValue(metadata.startDate, date, refreshCalendar);
838
- },
839
- endDate: function (date, refreshCalendar) {
840
- date = module.helper.sanitiseDate(date);
841
- var endModule = module.get.calendarModule(settings.endCalendar);
842
- if (endModule) {
843
- endModule.set.date(date);
844
- }
845
- module.set.dataKeyValue(metadata.endDate, date, refreshCalendar);
846
- },
847
- focusDate: function (date, refreshCalendar, updateFocus, updateRange) {
848
- date = module.helper.sanitiseDate(date);
849
- date = module.helper.dateInRange(date);
850
- var isDay = module.get.mode() === 'day';
851
- var oldFocusDate = module.get.focusDate();
852
- if (isDay && date && oldFocusDate) {
853
- var yearDelta = date.getFullYear() - oldFocusDate.getFullYear();
854
- var monthDelta = yearDelta * 12 + date.getMonth() - oldFocusDate.getMonth();
855
- if (monthDelta) {
856
- var monthOffset = module.get.monthOffset() - monthDelta;
857
- module.set.monthOffset(monthOffset, false);
858
- }
859
- }
860
- var changed = module.set.dataKeyValue(metadata.focusDate, date, !!date && refreshCalendar);
861
- updateFocus = (updateFocus !== false && changed && refreshCalendar === false) || focusDateUsedForRange != updateRange;
862
- focusDateUsedForRange = updateRange;
863
- if (updateFocus) {
864
- module.update.focus(updateRange);
865
- }
866
- },
867
- minDate: function (date) {
868
- date = module.helper.sanitiseDate(date);
869
- if (settings.maxDate !== null && settings.maxDate <= date) {
870
- module.verbose('Unable to set minDate variable bigger that maxDate variable', date, settings.maxDate);
871
- } else {
872
- module.setting('minDate', date);
873
- module.set.dataKeyValue(metadata.minDate, date);
874
- }
875
- },
876
- maxDate: function (date) {
877
- date = module.helper.sanitiseDate(date);
878
- if (settings.minDate !== null && settings.minDate >= date) {
879
- module.verbose('Unable to set maxDate variable lower that minDate variable', date, settings.minDate);
880
- } else {
881
- module.setting('maxDate', date);
882
- module.set.dataKeyValue(metadata.maxDate, date);
883
- }
884
- },
885
- monthOffset: function (monthOffset, refreshCalendar) {
886
- var multiMonth = Math.max(settings.multiMonth, 1);
887
- monthOffset = Math.max(1 - multiMonth, Math.min(0, monthOffset));
888
- module.set.dataKeyValue(metadata.monthOffset, monthOffset, refreshCalendar);
889
- },
890
- mode: function (mode, refreshCalendar) {
891
- module.set.dataKeyValue(metadata.mode, mode, refreshCalendar);
892
- },
893
- dataKeyValue: function (key, value, refreshCalendar) {
894
- var oldValue = $module.data(key);
895
- var equal = oldValue === value || (oldValue <= value && oldValue >= value); //equality test for dates and string objects
896
- if (value) {
897
- $module.data(key, value);
898
- } else {
899
- $module.removeData(key);
900
- }
901
- refreshCalendar = refreshCalendar !== false && !equal;
902
- if (refreshCalendar) {
903
- module.refresh();
904
- }
905
- return !equal;
906
- }
907
- },
1796
+ // numeric month
1797
+ if (month < 0) {
1798
+ for (i = 0; i < numbers.length; i++) {
1799
+ k = i > 1 || settings.monthFirst
1800
+ ? i
1801
+ : (i === 1 ? 0 : 1);
1802
+ j = parseInt(numbers[k], 10);
1803
+ if (isNaN(j)) {
1804
+ continue;
1805
+ }
1806
+ if (j >= 1 && j <= 12) {
1807
+ month = j;
1808
+ numbers.splice(k, 1);
1809
+
1810
+ break;
1811
+ }
1812
+ }
1813
+ }
908
1814
 
909
- selectDate: function (date, forceSet) {
910
- module.verbose('New date selection', date);
911
- var mode = module.get.mode();
912
- var complete = forceSet || mode === 'minute' ||
913
- (settings.disableMinute && mode === 'hour') ||
914
- (settings.type === 'date' && mode === 'day') ||
915
- (settings.type === 'month' && mode === 'month') ||
916
- (settings.type === 'year' && mode === 'year');
917
- if (complete) {
918
- var canceled = module.set.date(date) === false;
919
- if (!canceled) {
920
- selectionComplete = true;
921
- if(settings.closable) {
922
- module.popup('hide');
923
- //if this is a range calendar, focus the container or input. This will open the popup from its event listeners.
924
- var endModule = module.get.calendarModule(settings.endCalendar);
925
- if (endModule) {
926
- if (endModule.setting('on') !== 'focus') {
927
- endModule.popup('show');
928
- }
929
- endModule.focus();
930
- }
931
- }
932
- }
933
- } else {
934
- var newMode = mode === 'year' ? (!settings.disableMonth ? 'month' : 'day') :
935
- mode === 'month' ? 'day' : mode === 'day' ? 'hour' : 'minute';
936
- module.set.mode(newMode);
937
- if (mode === 'hour' || (mode === 'day' && module.get.date())) {
938
- //the user has chosen enough to consider a valid date/time has been chosen
939
- module.set.date(date, true, false);
940
- } else {
941
- module.set.focusDate(date);
942
- }
943
- }
944
- },
1815
+ // day
1816
+ for (i = 0; i < numbers.length; i++) {
1817
+ j = parseInt(numbers[i], 10);
1818
+ if (isNaN(j)) {
1819
+ continue;
1820
+ }
1821
+ if (j >= 1 && j <= 31) {
1822
+ day = j;
1823
+ numbers.splice(i, 1);
945
1824
 
946
- changeDate: function (date) {
947
- module.set.date(date);
948
- },
1825
+ break;
1826
+ }
1827
+ }
949
1828
 
950
- clear: function () {
951
- module.set.date(undefined);
952
- },
1829
+ // year <= settings.centuryBreak
1830
+ if (year < 0) {
1831
+ for (i = numbers.length - 1; i >= 0; i--) {
1832
+ j = parseInt(numbers[i], 10);
1833
+ if (isNaN(j)) {
1834
+ continue;
1835
+ }
1836
+ if (j <= 99) {
1837
+ j += settings.currentCentury;
1838
+ }
1839
+ year = j;
1840
+ numbers.splice(i, 1);
1841
+
1842
+ break;
1843
+ }
1844
+ }
1845
+ }
953
1846
 
954
- popup: function () {
955
- return $activator.popup.apply($activator, arguments);
956
- },
1847
+ if (!isDateOnly) {
1848
+ // hour
1849
+ if (hour < 0) {
1850
+ for (i = 0; i < numbers.length; i++) {
1851
+ j = parseInt(numbers[i], 10);
1852
+ if (isNaN(j)) {
1853
+ continue;
1854
+ }
1855
+ if (j >= 0 && j <= 23) {
1856
+ hour = j;
1857
+ numbers.splice(i, 1);
1858
+
1859
+ break;
1860
+ }
1861
+ }
1862
+ }
957
1863
 
958
- focus: function () {
959
- if ($input.length) {
960
- $input.focus();
961
- } else {
962
- $container.focus();
963
- }
964
- },
965
- blur: function () {
966
- if ($input.length) {
967
- $input.blur();
968
- } else {
969
- $container.blur();
970
- }
971
- },
1864
+ // minute
1865
+ if (minute < 0) {
1866
+ for (i = 0; i < numbers.length; i++) {
1867
+ j = parseInt(numbers[i], 10);
1868
+ if (isNaN(j)) {
1869
+ continue;
1870
+ }
1871
+ if (j >= 0 && j <= 59) {
1872
+ minute = j;
1873
+ numbers.splice(i, 1);
1874
+
1875
+ break;
1876
+ }
1877
+ }
1878
+ }
1879
+ }
972
1880
 
973
- helper: {
974
- isDisabled: function(date, mode) {
975
- return (mode === 'day' || mode === 'month' || mode === 'year') && ((mode === 'day' && settings.disabledDaysOfWeek.indexOf(date.getDay()) !== -1) || settings.disabledDates.some(function(d){
976
- if(typeof d === 'string') {
977
- d = module.helper.sanitiseDate(d);
978
- }
979
- if (d instanceof Date) {
980
- return module.helper.dateEqual(date, d, mode);
981
- }
982
- if (d !== null && typeof d === 'object') {
983
- if (d[metadata.year]) {
984
- if (typeof d[metadata.year] === 'number') {
985
- return date.getFullYear() == d[metadata.year];
986
- } else if (Array.isArray(d[metadata.year])) {
987
- return d[metadata.year].indexOf(date.getFullYear()) > -1;
988
- }
989
- } else if (d[metadata.month]) {
990
- if (typeof d[metadata.month] === 'number') {
991
- return date.getMonth() == d[metadata.month];
992
- } else if (Array.isArray(d[metadata.month])) {
993
- return d[metadata.month].indexOf(date.getMonth()) > -1;
994
- } else if (d[metadata.month] instanceof Date) {
995
- var sdate = module.helper.sanitiseDate(d[metadata.month]);
996
- return (date.getMonth() == sdate.getMonth()) && (date.getFullYear() == sdate.getFullYear())
997
- }
998
- } else if (d[metadata.date] && mode === 'day') {
999
- if (d[metadata.date] instanceof Date) {
1000
- return module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
1001
- } else if (Array.isArray(d[metadata.date])) {
1002
- return d[metadata.date].some(function(idate) {
1003
- return module.helper.dateEqual(date, idate, mode);
1004
- });
1005
- }
1881
+ if (minute < 0 && hour < 0 && day < 0 && month < 0 && year < 0) {
1882
+ return null;
1006
1883
  }
1007
- }
1008
- }));
1009
- },
1010
- isEnabled: function(date, mode) {
1011
- if (mode === 'day') {
1012
- return settings.enabledDates.length === 0 || settings.enabledDates.some(function(d){
1013
- if(typeof d === 'string') {
1014
- d = module.helper.sanitiseDate(d);
1884
+
1885
+ if (minute < 0) {
1886
+ minute = 0;
1015
1887
  }
1016
- if (d instanceof Date) {
1017
- return module.helper.dateEqual(date, d, mode);
1888
+ if (hour < 0) {
1889
+ hour = 0;
1018
1890
  }
1019
- if (d !== null && typeof d === 'object' && d[metadata.date]) {
1020
- return module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
1891
+ if (day < 0) {
1892
+ day = 1;
1021
1893
  }
1022
- });
1023
- } else {
1024
- return true;
1025
- }
1026
- },
1027
- findDayAsObject: function(date, mode, dates) {
1028
- if (mode === 'day' || mode === 'month' || mode === 'year') {
1029
- var d;
1030
- for (var i = 0; i < dates.length; i++) {
1031
- d = dates[i];
1032
- if(typeof d === 'string') {
1033
- d = module.helper.sanitiseDate(d);
1894
+ if (month < 0) {
1895
+ month = 1;
1034
1896
  }
1035
- if (d instanceof Date && module.helper.dateEqual(date, d, mode)) {
1036
- var dateObject = {};
1037
- dateObject[metadata.date] = d;
1038
- return dateObject;
1897
+ if (year < 0) {
1898
+ year = new Date().getFullYear();
1039
1899
  }
1040
- else if (d !== null && typeof d === 'object') {
1041
- if (d[metadata.year]) {
1042
- if (typeof d[metadata.year] === 'number' && date.getFullYear() == d[metadata.year]) {
1043
- return d;
1044
- } else if (Array.isArray(d[metadata.year])) {
1045
- if (d[metadata.year].indexOf(date.getFullYear()) > -1) {
1046
- return d;
1047
- }
1048
- }
1049
- } else if (d[metadata.month]) {
1050
- if (typeof d[metadata.month] === 'number' && date.getMonth() == d[metadata.month]) {
1051
- return d;
1052
- } else if (Array.isArray(d[metadata.month])) {
1053
- if (d[metadata.month].indexOf(date.getMonth()) > -1) {
1054
- return d;
1055
- }
1056
- } else if (d[metadata.month] instanceof Date) {
1057
- var sdate = module.helper.sanitiseDate(d[metadata.month]);
1058
- if ((date.getMonth() == sdate.getMonth()) && (date.getFullYear() == sdate.getFullYear())) {
1059
- return d;
1060
- }
1061
- }
1062
- } else if (d[metadata.date] && mode === 'day') {
1063
- if (d[metadata.date] instanceof Date && module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode)) {
1064
- return d;
1065
- } else if (Array.isArray(d[metadata.date])) {
1066
- if(d[metadata.date].some(function(idate) { return module.helper.dateEqual(date, idate, mode); })) {
1067
- return d;
1068
- }
1900
+
1901
+ if (isAm !== undefined) {
1902
+ if (isAm) {
1903
+ if (hour === 12) {
1904
+ hour = 0;
1905
+ }
1906
+ } else if (hour < 12) {
1907
+ hour += 12;
1069
1908
  }
1070
- }
1071
1909
  }
1072
- }
1073
- }
1074
- return null;
1075
- },
1076
- sanitiseDate: function (date) {
1077
- if (!(date instanceof Date)) {
1078
- date = parser.date('' + date, settings);
1079
- }
1080
- if (!date || isNaN(date.getTime())) {
1081
- return null;
1082
- }
1083
- return date;
1084
- },
1085
- dateDiff: function (date1, date2, mode) {
1086
- mode = mode || 'day';
1087
- var isTimeOnly = settings.type === 'time';
1088
- var isYear = mode === 'year';
1089
- var isYearOrMonth = isYear || mode === 'month';
1090
- var isMinute = mode === 'minute';
1091
- var isHourOrMinute = isMinute || mode === 'hour';
1092
- //only care about a minute accuracy of settings.minTimeGap
1093
- date1 = new Date(
1094
- isTimeOnly ? 2000 : date1.getFullYear(),
1095
- isTimeOnly ? 0 : isYear ? 0 : date1.getMonth(),
1096
- isTimeOnly ? 1 : isYearOrMonth ? 1 : date1.getDate(),
1097
- !isHourOrMinute ? 0 : date1.getHours(),
1098
- !isMinute ? 0 : settings.minTimeGap * Math.floor(date1.getMinutes() / settings.minTimeGap));
1099
- date2 = new Date(
1100
- isTimeOnly ? 2000 : date2.getFullYear(),
1101
- isTimeOnly ? 0 : isYear ? 0 : date2.getMonth(),
1102
- isTimeOnly ? 1 : isYearOrMonth ? 1 : date2.getDate(),
1103
- !isHourOrMinute ? 0 : date2.getHours(),
1104
- !isMinute ? 0 : settings.minTimeGap * Math.floor(date2.getMinutes() / settings.minTimeGap));
1105
- return date2.getTime() - date1.getTime();
1106
- },
1107
- dateEqual: function (date1, date2, mode) {
1108
- return !!date1 && !!date2 && module.helper.dateDiff(date1, date2, mode) === 0;
1109
- },
1110
- isDateInRange: function (date, mode, minDate, maxDate) {
1111
- if (!minDate && !maxDate) {
1112
- var startDate = module.get.startDate();
1113
- minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
1114
- maxDate = settings.maxDate;
1115
- }
1116
- minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
1117
- return !(!date ||
1118
- (minDate && module.helper.dateDiff(date, minDate, mode) > 0) ||
1119
- (maxDate && module.helper.dateDiff(maxDate, date, mode) > 0));
1120
- },
1121
- dateInRange: function (date, minDate, maxDate) {
1122
- if (!minDate && !maxDate) {
1123
- var startDate = module.get.startDate();
1124
- minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
1125
- maxDate = settings.maxDate;
1126
- }
1127
- minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
1128
- var isTimeOnly = settings.type === 'time';
1129
- return !date ? date :
1130
- (minDate && module.helper.dateDiff(date, minDate, 'minute') > 0) ?
1131
- (isTimeOnly ? module.helper.mergeDateTime(date, minDate) : minDate) :
1132
- (maxDate && module.helper.dateDiff(maxDate, date, 'minute') > 0) ?
1133
- (isTimeOnly ? module.helper.mergeDateTime(date, maxDate) : maxDate) :
1134
- date;
1135
- },
1136
- mergeDateTime: function (date, time) {
1137
- return (!date || !time) ? time :
1138
- new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes());
1139
- },
1140
- isTodayButton: function(element) {
1141
- return element.text() === settings.text.today;
1142
- }
1910
+
1911
+ var date = new Date(year, month - 1, day, hour, minute);
1912
+ if (date.getMonth() !== month - 1 || date.getFullYear() !== year) {
1913
+ // month or year don't match up, switch to last day of the month
1914
+ date = new Date(year, month, 0, hour, minute);
1915
+ }
1916
+
1917
+ return isNaN(date.getTime()) ? null : date;
1918
+ },
1143
1919
  },
1144
1920
 
1145
- setting: function (name, value) {
1146
- module.debug('Changing setting', name, value);
1147
- if ($.isPlainObject(name)) {
1148
- $.extend(true, settings, name);
1149
- }
1150
- else if (value !== undefined) {
1151
- if ($.isPlainObject(settings[name])) {
1152
- $.extend(true, settings[name], value);
1153
- }
1154
- else {
1155
- settings[name] = value;
1156
- }
1157
- }
1158
- else {
1159
- return settings[name];
1160
- }
1921
+ // callback before date is changed, return false to cancel the change
1922
+ onBeforeChange: function (date, text, mode) {
1923
+ return true;
1924
+ },
1925
+
1926
+ // callback when date changes
1927
+ onChange: function (date, text, mode) {},
1928
+
1929
+ // callback before show animation, return false to prevent show
1930
+ onShow: function () {},
1931
+
1932
+ // callback after show animation
1933
+ onVisible: function () {},
1934
+
1935
+ // callback before hide animation, return false to prevent hide
1936
+ onHide: function () {},
1937
+
1938
+ // callback after hide animation
1939
+ onHidden: function () {},
1940
+
1941
+ // callback before item is selected, return false to prevent selection
1942
+ onSelect: function (date, mode) {},
1943
+
1944
+ // is the given date disabled?
1945
+ isDisabled: function (date, mode) {
1946
+ return false;
1161
1947
  },
1162
- internal: function (name, value) {
1163
- if( $.isPlainObject(name) ) {
1164
- $.extend(true, module, name);
1165
- }
1166
- else if(value !== undefined) {
1167
- module[name] = value;
1168
- }
1169
- else {
1170
- return module[name];
1171
- }
1948
+
1949
+ selector: {
1950
+ popup: '.ui.popup',
1951
+ input: 'input',
1952
+ activator: 'input',
1953
+ append: '.inline.field,.inline.fields',
1172
1954
  },
1173
- debug: function () {
1174
- if (!settings.silent && settings.debug) {
1175
- if (settings.performance) {
1176
- module.performance.log(arguments);
1177
- }
1178
- else {
1179
- module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1180
- module.debug.apply(console, arguments);
1181
- }
1182
- }
1955
+
1956
+ regExp: {
1957
+ dateWords: /[^A-Za-z\u00C0-\u024F]+/g,
1958
+ dateNumbers: /[^\d:]+/g,
1959
+ token: /d{1,4}|D{1,2}|M{1,4}|YY(?:YY)?|([Hhmsw])\1?|[ASYa]|"[^"]*"|'[^']*'/g,
1183
1960
  },
1184
- verbose: function () {
1185
- if (!settings.silent && settings.verbose && settings.debug) {
1186
- if (settings.performance) {
1187
- module.performance.log(arguments);
1188
- }
1189
- else {
1190
- module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1191
- module.verbose.apply(console, arguments);
1192
- }
1193
- }
1961
+
1962
+ error: {
1963
+ popup: 'UI Popup, a required component is not included in this page',
1964
+ method: 'The method you called is not defined.',
1194
1965
  },
1195
- error: function () {
1196
- if (!settings.silent) {
1197
- module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1198
- module.error.apply(console, arguments);
1199
- }
1966
+
1967
+ className: {
1968
+ calendar: 'calendar',
1969
+ active: 'active',
1970
+ popup: 'ui popup',
1971
+ grid: 'ui equal width grid',
1972
+ column: 'column',
1973
+ table: 'ui celled center aligned unstackable table',
1974
+ inverted: 'inverted',
1975
+ prev: 'prev link',
1976
+ next: 'next link',
1977
+ prevIcon: 'chevron left icon',
1978
+ nextIcon: 'chevron right icon',
1979
+ link: 'link',
1980
+ cell: 'link',
1981
+ disabledCell: 'disabled',
1982
+ weekCell: 'disabled',
1983
+ adjacentCell: 'adjacent',
1984
+ activeCell: 'active',
1985
+ rangeCell: 'range',
1986
+ focusCell: 'focus',
1987
+ todayCell: 'today',
1988
+ today: 'today link',
1989
+ disabled: 'disabled',
1200
1990
  },
1201
- performance: {
1202
- log: function (message) {
1203
- var
1204
- currentTime,
1205
- executionTime,
1206
- previousTime
1207
- ;
1208
- if (settings.performance) {
1209
- currentTime = new Date().getTime();
1210
- previousTime = time || currentTime;
1211
- executionTime = currentTime - previousTime;
1212
- time = currentTime;
1213
- performance.push({
1214
- 'Name': message[0],
1215
- 'Arguments': [].slice.call(message, 1) || '',
1216
- 'Element': element,
1217
- 'Execution Time': executionTime
1218
- });
1219
- }
1220
- clearTimeout(module.performance.timer);
1221
- module.performance.timer = setTimeout(module.performance.display, 500);
1222
- },
1223
- display: function () {
1224
- var
1225
- title = settings.name + ':',
1226
- totalTime = 0
1227
- ;
1228
- time = false;
1229
- clearTimeout(module.performance.timer);
1230
- $.each(performance, function (index, data) {
1231
- totalTime += data['Execution Time'];
1232
- });
1233
- title += ' ' + totalTime + 'ms';
1234
- if (moduleSelector) {
1235
- title += ' \'' + moduleSelector + '\'';
1236
- }
1237
- if ((console.group !== undefined || console.table !== undefined) && performance.length > 0) {
1238
- console.groupCollapsed(title);
1239
- if (console.table) {
1240
- console.table(performance);
1241
- }
1242
- else {
1243
- $.each(performance, function (index, data) {
1244
- console.log(data['Name'] + ': ' + data['Execution Time'] + 'ms');
1245
- });
1246
- }
1247
- console.groupEnd();
1248
- }
1249
- performance = [];
1250
- }
1991
+
1992
+ metadata: {
1993
+ date: 'date',
1994
+ focusDate: 'focusDate',
1995
+ startDate: 'startDate',
1996
+ endDate: 'endDate',
1997
+ minDate: 'minDate',
1998
+ maxDate: 'maxDate',
1999
+ mode: 'mode',
2000
+ type: 'type',
2001
+ monthOffset: 'monthOffset',
2002
+ message: 'message',
2003
+ class: 'class',
2004
+ inverted: 'inverted',
2005
+ variation: 'variation',
2006
+ position: 'position',
2007
+ month: 'month',
2008
+ year: 'year',
2009
+ hours: 'hours',
2010
+ days: 'days',
1251
2011
  },
1252
- invoke: function (query, passedArguments, context) {
1253
- var
1254
- object = instance,
1255
- maxDepth,
1256
- found,
1257
- response
1258
- ;
1259
- passedArguments = passedArguments || queryArguments;
1260
- context = element || context;
1261
- if (typeof query == 'string' && object !== undefined) {
1262
- query = query.split(/[\. ]/);
1263
- maxDepth = query.length - 1;
1264
- $.each(query, function (depth, value) {
1265
- var camelCaseValue = (depth != maxDepth)
1266
- ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1267
- : query
1268
- ;
1269
- if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) {
1270
- object = object[camelCaseValue];
1271
- }
1272
- else if (object[camelCaseValue] !== undefined) {
1273
- found = object[camelCaseValue];
1274
- return false;
1275
- }
1276
- else if ($.isPlainObject(object[value]) && (depth != maxDepth)) {
1277
- object = object[value];
1278
- }
1279
- else if (object[value] !== undefined) {
1280
- found = object[value];
1281
- return false;
1282
- }
1283
- else {
1284
- module.error(error.method, query);
1285
- return false;
1286
- }
1287
- });
1288
- }
1289
- if ($.isFunction(found)) {
1290
- response = found.apply(context, passedArguments);
1291
- }
1292
- else if (found !== undefined) {
1293
- response = found;
1294
- }
1295
- if (Array.isArray(returnedValue)) {
1296
- returnedValue.push(response);
1297
- }
1298
- else if (returnedValue !== undefined) {
1299
- returnedValue = [returnedValue, response];
1300
- }
1301
- else if (response !== undefined) {
1302
- returnedValue = response;
1303
- }
1304
- return found;
1305
- }
1306
- };
1307
-
1308
- if (methodInvoked) {
1309
- if (instance === undefined) {
1310
- module.initialize();
1311
- }
1312
- module.invoke(query);
1313
- }
1314
- else {
1315
- if (instance !== undefined) {
1316
- instance.invoke('destroy');
1317
- }
1318
- module.initialize();
1319
- }
1320
- })
1321
- ;
1322
- return (returnedValue !== undefined)
1323
- ? returnedValue
1324
- : this
1325
- ;
1326
- };
1327
-
1328
- $.fn.calendar.settings = {
1329
-
1330
- name : 'Calendar',
1331
- namespace : 'calendar',
1332
-
1333
- silent: false,
1334
- debug: false,
1335
- verbose: false,
1336
- performance: false,
1337
-
1338
- type : 'datetime', // picker type, can be 'datetime', 'date', 'time', 'month', or 'year'
1339
- firstDayOfWeek : 0, // day for first day column (0 = Sunday)
1340
- constantHeight : true, // add rows to shorter months to keep day calendar height consistent (6 rows)
1341
- today : false, // show a 'today/now' button at the bottom of the calendar
1342
- closable : true, // close the popup after selecting a date/time
1343
- monthFirst : true, // month before day when parsing/converting date from/to text
1344
- touchReadonly : true, // set input to readonly on touch devices
1345
- inline : false, // create the calendar inline instead of inside a popup
1346
- on : null, // when to show the popup (defaults to 'focus' for input, 'click' for others)
1347
- initialDate : null, // date to display initially when no date is selected (null = now)
1348
- startMode : false, // display mode to start in, can be 'year', 'month', 'day', 'hour', 'minute' (false = 'day')
1349
- minDate : null, // minimum date/time that can be selected, dates/times before are disabled
1350
- maxDate : null, // maximum date/time that can be selected, dates/times after are disabled
1351
- ampm : true, // show am/pm in time mode
1352
- disableYear : false, // disable year selection mode
1353
- disableMonth : false, // disable month selection mode
1354
- disableMinute : false, // disable minute selection mode
1355
- formatInput : true, // format the input text upon input blur and module creation
1356
- startCalendar : null, // jquery object or selector for another calendar that represents the start date of a date range
1357
- endCalendar : null, // jquery object or selector for another calendar that represents the end date of a date range
1358
- multiMonth : 1, // show multiple months when in 'day' mode
1359
- minTimeGap : 5,
1360
- showWeekNumbers : null, // show Number of Week at the very first column of a dayView
1361
- disabledDates : [], // specific day(s) which won't be selectable and contain additional information.
1362
- disabledDaysOfWeek : [], // day(s) which won't be selectable(s) (0 = Sunday)
1363
- enabledDates : [], // specific day(s) which will be selectable, all other days will be disabled
1364
- eventDates : [], // specific day(s) which will be shown in a different color and using tooltips
1365
- centuryBreak : 60, // starting short year until 99 where it will be assumed to belong to the last century
1366
- currentCentury : 2000, // century to be added to 2-digit years (00 to {centuryBreak}-1)
1367
- selectAdjacentDays : false, // The calendar can show dates from adjacent month. These adjacent month dates can also be made selectable.
1368
- // popup options ('popup', 'on', 'hoverable', and show/hide callbacks are overridden)
1369
- popupOptions: {
1370
- position: 'bottom left',
1371
- lastResort: 'bottom left',
1372
- prefer: 'opposite',
1373
- hideOnScroll: false
1374
- },
1375
-
1376
- text: {
1377
- days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
1378
- months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
1379
- monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
1380
- today: 'Today',
1381
- now: 'Now',
1382
- am: 'AM',
1383
- pm: 'PM',
1384
- weekNo: 'Week'
1385
- },
1386
-
1387
- formatter: {
1388
- header: function (date, mode, settings) {
1389
- return mode === 'year' ? settings.formatter.yearHeader(date, settings) :
1390
- mode === 'month' ? settings.formatter.monthHeader(date, settings) :
1391
- mode === 'day' ? settings.formatter.dayHeader(date, settings) :
1392
- mode === 'hour' ? settings.formatter.hourHeader(date, settings) :
1393
- settings.formatter.minuteHeader(date, settings);
1394
- },
1395
- yearHeader: function (date, settings) {
1396
- var decadeYear = Math.ceil(date.getFullYear() / 10) * 10;
1397
- return (decadeYear - 9) + ' - ' + (decadeYear + 2);
1398
- },
1399
- monthHeader: function (date, settings) {
1400
- return date.getFullYear();
1401
- },
1402
- dayHeader: function (date, settings) {
1403
- var month = settings.text.months[date.getMonth()];
1404
- var year = date.getFullYear();
1405
- return month + ' ' + year;
1406
- },
1407
- hourHeader: function (date, settings) {
1408
- return settings.formatter.date(date, settings);
1409
- },
1410
- minuteHeader: function (date, settings) {
1411
- return settings.formatter.date(date, settings);
1412
- },
1413
- dayColumnHeader: function (day, settings) {
1414
- return settings.text.days[day];
1415
- },
1416
- datetime: function (date, settings) {
1417
- if (!date) {
1418
- return '';
1419
- }
1420
- var day = settings.type === 'time' ? '' : settings.formatter.date(date, settings);
1421
- var time = settings.type.indexOf('time') < 0 ? '' : settings.formatter.time(date, settings, false);
1422
- var separator = settings.type === 'datetime' ? ' ' : '';
1423
- return day + separator + time;
1424
- },
1425
- date: function (date, settings) {
1426
- if (!date) {
1427
- return '';
1428
- }
1429
- var day = date.getDate();
1430
- var month = settings.text.months[date.getMonth()];
1431
- var year = date.getFullYear();
1432
- return settings.type === 'year' ? year :
1433
- settings.type === 'month' ? month + ' ' + year :
1434
- (settings.monthFirst ? month + ' ' + day : day + ' ' + month) + ', ' + year;
1435
- },
1436
- time: function (date, settings, forCalendar) {
1437
- if (!date) {
1438
- return '';
1439
- }
1440
- var hour = date.getHours();
1441
- var minute = date.getMinutes();
1442
- var ampm = '';
1443
- if (settings.ampm) {
1444
- ampm = ' ' + (hour < 12 ? settings.text.am : settings.text.pm);
1445
- hour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
1446
- }
1447
- return hour + ':' + (minute < 10 ? '0' : '') + minute + ampm;
1448
- },
1449
- today: function (settings) {
1450
- return settings.type === 'date' ? settings.text.today : settings.text.now;
1451
- },
1452
- cell: function (cell, date, cellOptions) {
1453
- }
1454
- },
1455
-
1456
- parser: {
1457
- date: function (text, settings) {
1458
- if (text instanceof Date) {
1459
- return text;
1460
- }
1461
- if (!text) {
1462
- return null;
1463
- }
1464
- text = String(text).trim();
1465
- if (text.length === 0) {
1466
- return null;
1467
- }
1468
- if(text.match(/^[0-9]{4}[\/\-\.][0-9]{1,2}[\/\-\.][0-9]{1,2}$/)){
1469
- text = text.replace(/[\/\-\.]/g,'/') + ' 00:00:00';
1470
- }
1471
- // Reverse date and month in some cases
1472
- text = settings.monthFirst || !text.match(/^[0-9]{1,2}[\/\-\.]/) ? text : text.replace(/[\/\-\.]/g,'/').replace(/([0-9]+)\/([0-9]+)/,'$2/$1');
1473
- var textDate = new Date(text);
1474
- var numberOnly = text.match(/^[0-9]+$/) !== null;
1475
- if(!numberOnly && !isNaN(textDate.getDate())) {
1476
- return textDate;
1477
- }
1478
- text = text.toLowerCase();
1479
-
1480
- var i, j, k;
1481
- var minute = -1, hour = -1, day = -1, month = -1, year = -1;
1482
- var isAm = undefined;
1483
-
1484
- var isTimeOnly = settings.type === 'time';
1485
- var isDateOnly = settings.type.indexOf('time') < 0;
1486
-
1487
- var words = text.split(settings.regExp.dateWords), word;
1488
- var numbers = text.split(settings.regExp.dateNumbers), number;
1489
-
1490
- var parts;
1491
- var monthString;
1492
-
1493
- if (!isDateOnly) {
1494
- //am/pm
1495
- isAm = $.inArray(settings.text.am.toLowerCase(), words) >= 0 ? true :
1496
- $.inArray(settings.text.pm.toLowerCase(), words) >= 0 ? false : undefined;
1497
-
1498
- //time with ':'
1499
- for (i = 0; i < numbers.length; i++) {
1500
- number = numbers[i];
1501
- if (number.indexOf(':') >= 0) {
1502
- if (hour < 0 || minute < 0) {
1503
- parts = number.split(':');
1504
- for (k = 0; k < Math.min(2, parts.length); k++) {
1505
- j = parseInt(parts[k]);
1506
- if (isNaN(j)) {
1507
- j = 0;
1508
- }
1509
- if (k === 0) {
1510
- hour = j % 24;
1511
- } else {
1512
- minute = j % 60;
1513
- }
1514
- }
1515
- }
1516
- numbers.splice(i, 1);
1517
- }
1518
- }
1519
- }
1520
-
1521
- if (!isTimeOnly) {
1522
- //textual month
1523
- for (i = 0; i < words.length; i++) {
1524
- word = words[i];
1525
- if (word.length <= 0) {
1526
- continue;
1527
- }
1528
- for (j = 0; j < settings.text.months.length; j++) {
1529
- monthString = settings.text.months[j];
1530
- monthString = monthString.substring(0, word.length).toLowerCase();
1531
- if (monthString === word) {
1532
- month = j + 1;
1533
- break;
1534
- }
1535
- }
1536
- if (month >= 0) {
1537
- break;
1538
- }
1539
- }
1540
-
1541
- //year > settings.centuryBreak
1542
- for (i = 0; i < numbers.length; i++) {
1543
- j = parseInt(numbers[i]);
1544
- if (isNaN(j)) {
1545
- continue;
1546
- }
1547
- if (j >= settings.centuryBreak && i === numbers.length-1) {
1548
- if (j <= 99) {
1549
- j += settings.currentCentury - 100;
1550
- }
1551
- year = j;
1552
- numbers.splice(i, 1);
1553
- break;
1554
- }
1555
- }
1556
-
1557
- //numeric month
1558
- if (month < 0) {
1559
- for (i = 0; i < numbers.length; i++) {
1560
- k = i > 1 || settings.monthFirst ? i : i === 1 ? 0 : 1;
1561
- j = parseInt(numbers[k]);
1562
- if (isNaN(j)) {
1563
- continue;
1564
- }
1565
- if (1 <= j && j <= 12) {
1566
- month = j;
1567
- numbers.splice(k, 1);
1568
- break;
1569
- }
1570
- }
1571
- }
1572
-
1573
- //day
1574
- for (i = 0; i < numbers.length; i++) {
1575
- j = parseInt(numbers[i]);
1576
- if (isNaN(j)) {
1577
- continue;
1578
- }
1579
- if (1 <= j && j <= 31) {
1580
- day = j;
1581
- numbers.splice(i, 1);
1582
- break;
1583
- }
1584
- }
1585
-
1586
- //year <= settings.centuryBreak
1587
- if (year < 0) {
1588
- for (i = numbers.length - 1; i >= 0; i--) {
1589
- j = parseInt(numbers[i]);
1590
- if (isNaN(j)) {
1591
- continue;
1592
- }
1593
- if (j <= 99) {
1594
- j += settings.currentCentury;
1595
- }
1596
- year = j;
1597
- numbers.splice(i, 1);
1598
- break;
1599
- }
1600
- }
1601
- }
1602
-
1603
- if (!isDateOnly) {
1604
- //hour
1605
- if (hour < 0) {
1606
- for (i = 0; i < numbers.length; i++) {
1607
- j = parseInt(numbers[i]);
1608
- if (isNaN(j)) {
1609
- continue;
1610
- }
1611
- if (0 <= j && j <= 23) {
1612
- hour = j;
1613
- numbers.splice(i, 1);
1614
- break;
1615
- }
1616
- }
1617
- }
1618
-
1619
- //minute
1620
- if (minute < 0) {
1621
- for (i = 0; i < numbers.length; i++) {
1622
- j = parseInt(numbers[i]);
1623
- if (isNaN(j)) {
1624
- continue;
1625
- }
1626
- if (0 <= j && j <= 59) {
1627
- minute = j;
1628
- numbers.splice(i, 1);
1629
- break;
1630
- }
1631
- }
1632
- }
1633
- }
1634
-
1635
- if (minute < 0 && hour < 0 && day < 0 && month < 0 && year < 0) {
1636
- return null;
1637
- }
1638
-
1639
- if (minute < 0) {
1640
- minute = 0;
1641
- }
1642
- if (hour < 0) {
1643
- hour = 0;
1644
- }
1645
- if (day < 0) {
1646
- day = 1;
1647
- }
1648
- if (month < 0) {
1649
- month = 1;
1650
- }
1651
- if (year < 0) {
1652
- year = new Date().getFullYear();
1653
- }
1654
-
1655
- if (isAm !== undefined) {
1656
- if (isAm) {
1657
- if (hour === 12) {
1658
- hour = 0;
1659
- }
1660
- } else if (hour < 12) {
1661
- hour += 12;
1662
- }
1663
- }
1664
-
1665
- var date = new Date(year, month - 1, day, hour, minute);
1666
- if (date.getMonth() !== month - 1 || date.getFullYear() !== year) {
1667
- //month or year don't match up, switch to last day of the month
1668
- date = new Date(year, month, 0, hour, minute);
1669
- }
1670
- return isNaN(date.getTime()) ? null : date;
1671
- }
1672
- },
1673
-
1674
- // callback before date is changed, return false to cancel the change
1675
- onBeforeChange: function (date, text, mode) {
1676
- return true;
1677
- },
1678
-
1679
- // callback when date changes
1680
- onChange: function (date, text, mode) {
1681
- },
1682
-
1683
- // callback before show animation, return false to prevent show
1684
- onShow: function () {
1685
- },
1686
-
1687
- // callback after show animation
1688
- onVisible: function () {
1689
- },
1690
-
1691
- // callback before hide animation, return false to prevent hide
1692
- onHide: function () {
1693
- },
1694
-
1695
- // callback after hide animation
1696
- onHidden: function () {
1697
- },
1698
-
1699
- // callback before item is selected, return false to prevent selection
1700
- onSelect: function (date, mode) {
1701
- },
1702
-
1703
- // is the given date disabled?
1704
- isDisabled: function (date, mode) {
1705
- return false;
1706
- },
1707
-
1708
- selector: {
1709
- popup: '.ui.popup',
1710
- input: 'input',
1711
- activator: 'input',
1712
- append: '.inline.field,.inline.fields'
1713
- },
1714
-
1715
- regExp: {
1716
- dateWords: /[^A-Za-z\u00C0-\u024F]+/g,
1717
- dateNumbers: /[^\d:]+/g
1718
- },
1719
-
1720
- error: {
1721
- popup: 'UI Popup, a required component is not included in this page',
1722
- method: 'The method you called is not defined.'
1723
- },
1724
-
1725
- className: {
1726
- calendar: 'calendar',
1727
- active: 'active',
1728
- popup: 'ui popup',
1729
- grid: 'ui equal width grid',
1730
- column: 'column',
1731
- table: 'ui celled center aligned unstackable table',
1732
- inverted: 'inverted',
1733
- prev: 'prev link',
1734
- next: 'next link',
1735
- prevIcon: 'chevron left icon',
1736
- nextIcon: 'chevron right icon',
1737
- link: 'link',
1738
- cell: 'link',
1739
- disabledCell: 'disabled',
1740
- weekCell: 'disabled',
1741
- adjacentCell: 'adjacent',
1742
- activeCell: 'active',
1743
- rangeCell: 'range',
1744
- focusCell: 'focus',
1745
- todayCell: 'today',
1746
- today: 'today link',
1747
- disabled: 'disabled'
1748
- },
1749
-
1750
- metadata: {
1751
- date: 'date',
1752
- focusDate: 'focusDate',
1753
- startDate: 'startDate',
1754
- endDate: 'endDate',
1755
- minDate: 'minDate',
1756
- maxDate: 'maxDate',
1757
- mode: 'mode',
1758
- type: 'type',
1759
- monthOffset: 'monthOffset',
1760
- message: 'message',
1761
- class: 'class',
1762
- inverted: 'inverted',
1763
- variation: 'variation',
1764
- position: 'position',
1765
- month: 'month',
1766
- year: 'year'
1767
- },
1768
-
1769
- eventClass: 'blue'
1770
- };
1771
2012
 
2013
+ eventClass: 'blue',
2014
+ };
1772
2015
  })(jQuery, window, document);