fomantic-ui-sass 2.9.0 → 2.9.2

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