fomantic-ui-sass 2.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +27 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +5 -0
  5. data/CHANGELOG.md +370 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +177 -0
  9. data/Rakefile +8 -0
  10. data/app/assets/fonts/semantic-ui/brand-icons.eot +0 -0
  11. data/app/assets/fonts/semantic-ui/brand-icons.svg +1008 -0
  12. data/app/assets/fonts/semantic-ui/brand-icons.ttf +0 -0
  13. data/app/assets/fonts/semantic-ui/brand-icons.woff +0 -0
  14. data/app/assets/fonts/semantic-ui/brand-icons.woff2 +0 -0
  15. data/app/assets/fonts/semantic-ui/icons.eot +0 -0
  16. data/app/assets/fonts/semantic-ui/icons.otf +0 -0
  17. data/app/assets/fonts/semantic-ui/icons.svg +1518 -0
  18. data/app/assets/fonts/semantic-ui/icons.ttf +0 -0
  19. data/app/assets/fonts/semantic-ui/icons.woff +0 -0
  20. data/app/assets/fonts/semantic-ui/icons.woff2 +0 -0
  21. data/app/assets/fonts/semantic-ui/outline-icons.eot +0 -0
  22. data/app/assets/fonts/semantic-ui/outline-icons.svg +366 -0
  23. data/app/assets/fonts/semantic-ui/outline-icons.ttf +0 -0
  24. data/app/assets/fonts/semantic-ui/outline-icons.woff +0 -0
  25. data/app/assets/fonts/semantic-ui/outline-icons.woff2 +0 -0
  26. data/app/assets/images/semantic-ui/flags.png +0 -0
  27. data/app/assets/javascripts/semantic-ui.js +27 -0
  28. data/app/assets/javascripts/semantic-ui/accordion.js +613 -0
  29. data/app/assets/javascripts/semantic-ui/api.js +1167 -0
  30. data/app/assets/javascripts/semantic-ui/calendar.js +1476 -0
  31. data/app/assets/javascripts/semantic-ui/checkbox.js +828 -0
  32. data/app/assets/javascripts/semantic-ui/colorize.js +280 -0
  33. data/app/assets/javascripts/semantic-ui/dimmer.js +735 -0
  34. data/app/assets/javascripts/semantic-ui/dropdown.js +4030 -0
  35. data/app/assets/javascripts/semantic-ui/embed.js +706 -0
  36. data/app/assets/javascripts/semantic-ui/form.js +1707 -0
  37. data/app/assets/javascripts/semantic-ui/modal.js +1090 -0
  38. data/app/assets/javascripts/semantic-ui/nag.js +507 -0
  39. data/app/assets/javascripts/semantic-ui/popup.js +1532 -0
  40. data/app/assets/javascripts/semantic-ui/progress.js +923 -0
  41. data/app/assets/javascripts/semantic-ui/range.js +278 -0
  42. data/app/assets/javascripts/semantic-ui/rating.js +511 -0
  43. data/app/assets/javascripts/semantic-ui/search.js +1515 -0
  44. data/app/assets/javascripts/semantic-ui/shape.js +921 -0
  45. data/app/assets/javascripts/semantic-ui/sidebar.js +1033 -0
  46. data/app/assets/javascripts/semantic-ui/site.js +490 -0
  47. data/app/assets/javascripts/semantic-ui/state.js +708 -0
  48. data/app/assets/javascripts/semantic-ui/sticky.js +959 -0
  49. data/app/assets/javascripts/semantic-ui/tab.js +952 -0
  50. data/app/assets/javascripts/semantic-ui/toast.js +592 -0
  51. data/app/assets/javascripts/semantic-ui/transition.js +1106 -0
  52. data/app/assets/javascripts/semantic-ui/video.js +532 -0
  53. data/app/assets/javascripts/semantic-ui/visibility.js +1311 -0
  54. data/app/assets/javascripts/semantic-ui/visit.js +525 -0
  55. data/app/assets/stylesheets/semantic-ui.scss +5 -0
  56. data/app/assets/stylesheets/semantic-ui/collections/_all.scss +6 -0
  57. data/app/assets/stylesheets/semantic-ui/collections/_breadcrumb.scss +124 -0
  58. data/app/assets/stylesheets/semantic-ui/collections/_form.scss +1158 -0
  59. data/app/assets/stylesheets/semantic-ui/collections/_grid.scss +2093 -0
  60. data/app/assets/stylesheets/semantic-ui/collections/_menu.scss +2193 -0
  61. data/app/assets/stylesheets/semantic-ui/collections/_message.scss +606 -0
  62. data/app/assets/stylesheets/semantic-ui/collections/_table.scss +1117 -0
  63. data/app/assets/stylesheets/semantic-ui/elements/_all.scss +16 -0
  64. data/app/assets/stylesheets/semantic-ui/elements/_button.scss +4530 -0
  65. data/app/assets/stylesheets/semantic-ui/elements/_container.scss +145 -0
  66. data/app/assets/stylesheets/semantic-ui/elements/_divider.scss +259 -0
  67. data/app/assets/stylesheets/semantic-ui/elements/_flag.scss +1036 -0
  68. data/app/assets/stylesheets/semantic-ui/elements/_header.scss +762 -0
  69. data/app/assets/stylesheets/semantic-ui/elements/_icon.scss +6330 -0
  70. data/app/assets/stylesheets/semantic-ui/elements/_image.scss +310 -0
  71. data/app/assets/stylesheets/semantic-ui/elements/_input.scss +519 -0
  72. data/app/assets/stylesheets/semantic-ui/elements/_label.scss +1395 -0
  73. data/app/assets/stylesheets/semantic-ui/elements/_list.scss +959 -0
  74. data/app/assets/stylesheets/semantic-ui/elements/_loader.scss +458 -0
  75. data/app/assets/stylesheets/semantic-ui/elements/_placeholder.scss +242 -0
  76. data/app/assets/stylesheets/semantic-ui/elements/_rail.scss +152 -0
  77. data/app/assets/stylesheets/semantic-ui/elements/_reveal.scss +295 -0
  78. data/app/assets/stylesheets/semantic-ui/elements/_segment.scss +884 -0
  79. data/app/assets/stylesheets/semantic-ui/elements/_step.scss +675 -0
  80. data/app/assets/stylesheets/semantic-ui/globals/_all.scss +3 -0
  81. data/app/assets/stylesheets/semantic-ui/globals/_reset.scss +485 -0
  82. data/app/assets/stylesheets/semantic-ui/globals/_site.scss +206 -0
  83. data/app/assets/stylesheets/semantic-ui/globals/_variables.scss +4 -0
  84. data/app/assets/stylesheets/semantic-ui/modules/_accordion.scss +247 -0
  85. data/app/assets/stylesheets/semantic-ui/modules/_all.scss +20 -0
  86. data/app/assets/stylesheets/semantic-ui/modules/_calendar.scss +165 -0
  87. data/app/assets/stylesheets/semantic-ui/modules/_checkbox.scss +718 -0
  88. data/app/assets/stylesheets/semantic-ui/modules/_dimmer.scss +464 -0
  89. data/app/assets/stylesheets/semantic-ui/modules/_dropdown.scss +1745 -0
  90. data/app/assets/stylesheets/semantic-ui/modules/_embed.scss +165 -0
  91. data/app/assets/stylesheets/semantic-ui/modules/_modal.scss +646 -0
  92. data/app/assets/stylesheets/semantic-ui/modules/_nag.scss +148 -0
  93. data/app/assets/stylesheets/semantic-ui/modules/_popup.scss +789 -0
  94. data/app/assets/stylesheets/semantic-ui/modules/_progress.scss +523 -0
  95. data/app/assets/stylesheets/semantic-ui/modules/_range.scss +192 -0
  96. data/app/assets/stylesheets/semantic-ui/modules/_rating.scss +263 -0
  97. data/app/assets/stylesheets/semantic-ui/modules/_search.scss +445 -0
  98. data/app/assets/stylesheets/semantic-ui/modules/_shape.scss +154 -0
  99. data/app/assets/stylesheets/semantic-ui/modules/_sidebar.scss +626 -0
  100. data/app/assets/stylesheets/semantic-ui/modules/_sticky.scss +78 -0
  101. data/app/assets/stylesheets/semantic-ui/modules/_tab.scss +92 -0
  102. data/app/assets/stylesheets/semantic-ui/modules/_toast.scss +291 -0
  103. data/app/assets/stylesheets/semantic-ui/modules/_transition.scss +2059 -0
  104. data/app/assets/stylesheets/semantic-ui/modules/_video.scss +125 -0
  105. data/app/assets/stylesheets/semantic-ui/views/_ad.scss +275 -0
  106. data/app/assets/stylesheets/semantic-ui/views/_all.scss +6 -0
  107. data/app/assets/stylesheets/semantic-ui/views/_card.scss +1124 -0
  108. data/app/assets/stylesheets/semantic-ui/views/_comment.scss +296 -0
  109. data/app/assets/stylesheets/semantic-ui/views/_feed.scss +314 -0
  110. data/app/assets/stylesheets/semantic-ui/views/_item.scss +555 -0
  111. data/app/assets/stylesheets/semantic-ui/views/_statistic.scss +583 -0
  112. data/app/helpers/semantic_breadcrumbs_helper.rb +10 -0
  113. data/app/helpers/semantic_flash_helper.rb +22 -0
  114. data/app/helpers/semantic_icon_helper.rb +8 -0
  115. data/app/views/semantic/_breadcrumbs.html.erb +12 -0
  116. data/fomantic-ui-sass.gemspec +31 -0
  117. data/lib/fomantic-ui-sass.rb +62 -0
  118. data/lib/fomantic/ui/sass/breadcrumbs.rb +41 -0
  119. data/lib/fomantic/ui/sass/engine.rb +23 -0
  120. data/lib/fomantic/ui/sass/version.rb +8 -0
  121. data/spec/dummy/README.rdoc +28 -0
  122. data/spec/dummy/Rakefile +6 -0
  123. data/spec/dummy/app/assets/images/.keep +0 -0
  124. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  125. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  126. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  127. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  128. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  129. data/spec/dummy/app/mailers/.keep +0 -0
  130. data/spec/dummy/app/models/.keep +0 -0
  131. data/spec/dummy/app/models/concerns/.keep +0 -0
  132. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  133. data/spec/dummy/bin/bundle +3 -0
  134. data/spec/dummy/bin/rails +4 -0
  135. data/spec/dummy/bin/rake +4 -0
  136. data/spec/dummy/config.ru +4 -0
  137. data/spec/dummy/config/application.rb +28 -0
  138. data/spec/dummy/config/boot.rb +5 -0
  139. data/spec/dummy/config/environment.rb +5 -0
  140. data/spec/dummy/config/environments/development.rb +29 -0
  141. data/spec/dummy/config/environments/production.rb +80 -0
  142. data/spec/dummy/config/environments/test.rb +36 -0
  143. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  144. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  145. data/spec/dummy/config/initializers/inflections.rb +16 -0
  146. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  147. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  148. data/spec/dummy/config/initializers/session_store.rb +3 -0
  149. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  150. data/spec/dummy/config/locales/en.yml +23 -0
  151. data/spec/dummy/config/routes.rb +2 -0
  152. data/spec/dummy/lib/assets/.keep +0 -0
  153. data/spec/dummy/log/.keep +0 -0
  154. data/spec/dummy/public/404.html +58 -0
  155. data/spec/dummy/public/422.html +58 -0
  156. data/spec/dummy/public/500.html +57 -0
  157. data/spec/dummy/public/favicon.ico +0 -0
  158. data/spec/helpers/semantic_breadcrumbs_helper_spec.rb +38 -0
  159. data/spec/helpers/semantic_flash_helper_spec.rb +36 -0
  160. data/spec/helpers/semantic_icon_helper_spec.rb +48 -0
  161. data/spec/spec_helper.rb +17 -0
  162. data/tasks/converter.rb +216 -0
  163. data/templates/project/manifest.rb +29 -0
  164. data/templates/project/styles.scss +1 -0
  165. metadata +390 -0
@@ -0,0 +1,1476 @@
1
+ /*!
2
+ * # Semantic UI - Calendar
3
+ * http://github.com/semantic-org/semantic-ui/
4
+ *
5
+ *
6
+ * Released under the MIT license
7
+ * http://opensource.org/licenses/MIT
8
+ *
9
+ */
10
+
11
+ ;(function ($, window, document, undefined) {
12
+
13
+ 'use strict';
14
+
15
+ window = (typeof window != 'undefined' && window.Math == Math)
16
+ ? window
17
+ : (typeof self != 'undefined' && self.Math == Math)
18
+ ? self
19
+ : Function('return this')()
20
+ ;
21
+
22
+ $.fn.calendar = function(parameters) {
23
+ var
24
+ $allModules = $(this),
25
+
26
+ moduleSelector = $allModules.selector || '',
27
+
28
+ time = new Date().getTime(),
29
+ performance = [],
30
+
31
+ query = arguments[0],
32
+ methodInvoked = (typeof query == 'string'),
33
+ queryArguments = [].slice.call(arguments, 1),
34
+ returnedValue
35
+ ;
36
+
37
+ $allModules
38
+ .each(function () {
39
+ var
40
+ settings = ( $.isPlainObject(parameters) )
41
+ ? $.extend(true, {}, $.fn.calendar.settings, parameters)
42
+ : $.extend({}, $.fn.calendar.settings),
43
+
44
+ className = settings.className,
45
+ namespace = settings.namespace,
46
+ selector = settings.selector,
47
+ formatter = settings.formatter,
48
+ parser = settings.parser,
49
+ metadata = settings.metadata,
50
+ error = settings.error,
51
+
52
+ eventNamespace = '.' + namespace,
53
+ moduleNamespace = 'module-' + namespace,
54
+
55
+ $module = $(this),
56
+ $input = $module.find(selector.input),
57
+ $container = $module.find(selector.popup),
58
+ $activator = $module.find(selector.activator),
59
+
60
+ element = this,
61
+ instance = $module.data(moduleNamespace),
62
+
63
+ isTouch,
64
+ isTouchDown = false,
65
+ focusDateUsedForRange = false,
66
+ module
67
+ ;
68
+
69
+ module = {
70
+
71
+ initialize: function () {
72
+ module.debug('Initializing calendar for', element, $module);
73
+
74
+ isTouch = module.get.isTouch();
75
+ module.setup.config();
76
+ module.setup.popup();
77
+ module.setup.inline();
78
+ module.setup.input();
79
+ module.setup.date();
80
+ module.create.calendar();
81
+
82
+ module.bind.events();
83
+ module.instantiate();
84
+ },
85
+
86
+ instantiate: function () {
87
+ module.verbose('Storing instance of calendar');
88
+ instance = module;
89
+ $module.data(moduleNamespace, instance);
90
+ },
91
+
92
+ destroy: function () {
93
+ module.verbose('Destroying previous calendar for', element);
94
+ $module.removeData(moduleNamespace);
95
+ module.unbind.events();
96
+ },
97
+
98
+ setup: {
99
+ config: function () {
100
+ if (module.get.minDate() !== null) {
101
+ module.set.minDate($module.data(metadata.minDate));
102
+ }
103
+ if (module.get.maxDate() !== null) {
104
+ module.set.maxDate($module.data(metadata.maxDate));
105
+ }
106
+ },
107
+ popup: function () {
108
+ if (settings.inline) {
109
+ return;
110
+ }
111
+ if (!$activator.length) {
112
+ $activator = $module.children().first();
113
+ if (!$activator.length) {
114
+ return;
115
+ }
116
+ }
117
+ if ($.fn.popup === undefined) {
118
+ module.error(error.popup);
119
+ return;
120
+ }
121
+ if (!$container.length) {
122
+ //prepend the popup element to the activator's parent so that it has less chance of messing with
123
+ //the styling (eg input action button needs to be the last child to have correct border radius)
124
+ $container = $('<div/>').addClass(className.popup).prependTo($activator.parent());
125
+ }
126
+ $container.addClass(className.calendar);
127
+ var onVisible = settings.onVisible;
128
+ var onHidden = settings.onHidden;
129
+ if (!$input.length) {
130
+ //no input, $container has to handle focus/blur
131
+ $container.attr('tabindex', '0');
132
+ onVisible = function () {
133
+ module.focus();
134
+ return settings.onVisible.apply($container, arguments);
135
+ };
136
+ onHidden = function () {
137
+ module.blur();
138
+ return settings.onHidden.apply($container, arguments);
139
+ };
140
+ }
141
+ var onShow = function () {
142
+ //reset the focus date onShow
143
+ module.set.focusDate(module.get.date());
144
+ module.set.mode(settings.startMode);
145
+ return settings.onShow.apply($container, arguments);
146
+ };
147
+ var on = settings.on || ($input.length ? 'focus' : 'click');
148
+ var options = $.extend({}, settings.popupOptions, {
149
+ popup: $container,
150
+ on: on,
151
+ hoverable: on === 'hover',
152
+ onShow: onShow,
153
+ onVisible: onVisible,
154
+ onHide: settings.onHide,
155
+ onHidden: onHidden
156
+ });
157
+ module.popup(options);
158
+ },
159
+ inline: function () {
160
+ if ($activator.length && !settings.inline) {
161
+ return;
162
+ }
163
+ $container = $('<div/>').addClass(className.calendar).appendTo($module);
164
+ if (!$input.length) {
165
+ $container.attr('tabindex', '0');
166
+ }
167
+ },
168
+ input: function () {
169
+ if (settings.touchReadonly && $input.length && isTouch) {
170
+ $input.prop('readonly', true);
171
+ }
172
+ },
173
+ date: function () {
174
+ if ($input.length) {
175
+ var val = $input.val();
176
+ var date = parser.date(val, settings);
177
+ module.set.date(date, settings.formatInput, false);
178
+ }
179
+ }
180
+ },
181
+
182
+ create: {
183
+ calendar: function () {
184
+ var i, r, c, p, row, cell, pageGrid;
185
+
186
+ var mode = module.get.mode();
187
+ var today = new Date();
188
+ var date = module.get.date();
189
+ var focusDate = module.get.focusDate();
190
+ var display = focusDate || date || settings.initialDate || today;
191
+ display = module.helper.dateInRange(display);
192
+
193
+ if (!focusDate) {
194
+ focusDate = display;
195
+ module.set.focusDate(focusDate, false, false);
196
+ }
197
+
198
+ var isYear = mode === 'year';
199
+ var isMonth = mode === 'month';
200
+ var isDay = mode === 'day';
201
+ var isHour = mode === 'hour';
202
+ var isMinute = mode === 'minute';
203
+ var isTimeOnly = settings.type === 'time';
204
+
205
+ var multiMonth = Math.max(settings.multiMonth, 1);
206
+ var monthOffset = !isDay ? 0 : module.get.monthOffset();
207
+
208
+ var minute = display.getMinutes();
209
+ var hour = display.getHours();
210
+ var day = display.getDate();
211
+ var startMonth = display.getMonth() + monthOffset;
212
+ var year = display.getFullYear();
213
+
214
+ var columns = isDay ? settings.showWeekNumbers ? 8 : 7 : isHour ? 4 : 3;
215
+ var rows = isDay || isHour ? 6 : 4;
216
+ var pages = isDay ? multiMonth : 1;
217
+
218
+ var container = $container;
219
+ var tooltipPosition = container.hasClass("left") ? "right center" : "left center";
220
+ container.empty();
221
+ if (pages > 1) {
222
+ pageGrid = $('<div/>').addClass(className.grid).appendTo(container);
223
+ }
224
+
225
+ for (p = 0; p < pages; p++) {
226
+ if (pages > 1) {
227
+ var pageColumn = $('<div/>').addClass(className.column).appendTo(pageGrid);
228
+ container = pageColumn;
229
+ }
230
+
231
+ var month = startMonth + p;
232
+ var firstMonthDayColumn = (new Date(year, month, 1).getDay() - settings.firstDayOfWeek % 7 + 7) % 7;
233
+ if (!settings.constantHeight && isDay) {
234
+ var requiredCells = new Date(year, month + 1, 0).getDate() + firstMonthDayColumn;
235
+ rows = Math.ceil(requiredCells / 7);
236
+ }
237
+
238
+ var yearChange = isYear ? 10 : isMonth ? 1 : 0;
239
+ var monthChange = isDay ? 1 : 0;
240
+ var dayChange = isHour || isMinute ? 1 : 0;
241
+ var prevNextDay = isHour || isMinute ? day : 1;
242
+ var prevDate = new Date(year - yearChange, month - monthChange, prevNextDay - dayChange, hour);
243
+ var nextDate = new Date(year + yearChange, month + monthChange, prevNextDay + dayChange, hour);
244
+
245
+ var prevLast = isYear ? new Date(Math.ceil(year / 10) * 10 - 9, 0, 0) :
246
+ isMonth ? new Date(year, 0, 0) : isDay ? new Date(year, month, 0) : new Date(year, month, day, -1);
247
+ var nextFirst = isYear ? new Date(Math.ceil(year / 10) * 10 + 1, 0, 1) :
248
+ isMonth ? new Date(year + 1, 0, 1) : isDay ? new Date(year, month + 1, 1) : new Date(year, month, day + 1);
249
+
250
+ var tempMode = mode;
251
+ if (isDay && settings.showWeekNumbers){
252
+ tempMode += ' andweek';
253
+ }
254
+ var table = $('<table/>').addClass(className.table).addClass(tempMode).appendTo(container);
255
+ var textColumns = columns;
256
+ //no header for time-only mode
257
+ if (!isTimeOnly) {
258
+ var thead = $('<thead/>').appendTo(table);
259
+
260
+ row = $('<tr/>').appendTo(thead);
261
+ cell = $('<th/>').attr('colspan', '' + columns).appendTo(row);
262
+
263
+ var headerDate = isYear || isMonth ? new Date(year, 0, 1) :
264
+ isDay ? new Date(year, month, 1) : new Date(year, month, day, hour, minute);
265
+ var headerText = $('<span/>').addClass(className.link).appendTo(cell);
266
+ headerText.text(formatter.header(headerDate, mode, settings));
267
+ var newMode = isMonth ? (settings.disableYear ? 'day' : 'year') :
268
+ isDay ? (settings.disableMonth ? 'year' : 'month') : 'day';
269
+ headerText.data(metadata.mode, newMode);
270
+
271
+ if (p === 0) {
272
+ var prev = $('<span/>').addClass(className.prev).appendTo(cell);
273
+ prev.data(metadata.focusDate, prevDate);
274
+ prev.toggleClass(className.disabledCell, !module.helper.isDateInRange(prevLast, mode));
275
+ $('<i/>').addClass(className.prevIcon).appendTo(prev);
276
+ }
277
+
278
+ if (p === pages - 1) {
279
+ var next = $('<span/>').addClass(className.next).appendTo(cell);
280
+ next.data(metadata.focusDate, nextDate);
281
+ next.toggleClass(className.disabledCell, !module.helper.isDateInRange(nextFirst, mode));
282
+ $('<i/>').addClass(className.nextIcon).appendTo(next);
283
+ }
284
+ if (isDay) {
285
+ row = $('<tr/>').appendTo(thead);
286
+ if(settings.showWeekNumbers) {
287
+ cell = $('<th/>').appendTo(row);
288
+ cell.text(settings.text.weekNo);
289
+ cell.addClass(className.disabledCell);
290
+ textColumns--;
291
+ }
292
+ for (i = 0; i < textColumns; i++) {
293
+ cell = $('<th/>').appendTo(row);
294
+ cell.text(formatter.dayColumnHeader((i + settings.firstDayOfWeek) % 7, settings));
295
+ }
296
+ }
297
+ }
298
+
299
+ var tbody = $('<tbody/>').appendTo(table);
300
+ i = isYear ? Math.ceil(year / 10) * 10 - 9 : isDay ? 1 - firstMonthDayColumn : 0;
301
+ for (r = 0; r < rows; r++) {
302
+ row = $('<tr/>').appendTo(tbody);
303
+ if(isDay && settings.showWeekNumbers){
304
+ cell = $('<th/>').appendTo(row);
305
+ cell.text(module.get.weekOfYear(year,month,i+1-settings.firstDayOfWeek));
306
+ cell.addClass(className.disabledCell);
307
+ }
308
+ for (c = 0; c < textColumns; c++, i++) {
309
+ var cellDate = isYear ? new Date(i, month, 1, hour, minute) :
310
+ isMonth ? new Date(year, i, 1, hour, minute) : isDay ? new Date(year, month, i, hour, minute) :
311
+ isHour ? new Date(year, month, day, i) : new Date(year, month, day, hour, i * 5);
312
+ var cellText = isYear ? i :
313
+ isMonth ? settings.text.monthsShort[i] : isDay ? cellDate.getDate() :
314
+ formatter.time(cellDate, settings, true);
315
+ cell = $('<td/>').addClass(className.cell).appendTo(row);
316
+ cell.text(cellText);
317
+ cell.data(metadata.date, cellDate);
318
+ var adjacent = isDay && cellDate.getMonth() !== ((month + 12) % 12);
319
+ var disabled = adjacent || !module.helper.isDateInRange(cellDate, mode) || settings.isDisabled(cellDate, mode) || module.helper.isDisabled(cellDate, mode);
320
+ if (disabled) {
321
+ var disabledReason = module.helper.disabledReason(cellDate, mode);
322
+ if (disabledReason !== null) {
323
+ cell.attr("data-tooltip", disabledReason[metadata.message]);
324
+ cell.attr("data-position", tooltipPosition);
325
+ }
326
+ }
327
+ var active = module.helper.dateEqual(cellDate, date, mode);
328
+ var isToday = module.helper.dateEqual(cellDate, today, mode);
329
+ cell.toggleClass(className.adjacentCell, adjacent);
330
+ cell.toggleClass(className.disabledCell, disabled);
331
+ cell.toggleClass(className.activeCell, active && !adjacent);
332
+ if (!isHour && !isMinute) {
333
+ cell.toggleClass(className.todayCell, !adjacent && isToday);
334
+ }
335
+
336
+ // Allow for external modifications of each cell
337
+ var cellOptions = {
338
+ mode: mode,
339
+ adjacent: adjacent,
340
+ disabled: disabled,
341
+ active: active,
342
+ today: isToday
343
+ };
344
+ formatter.cell(cell, cellDate, cellOptions);
345
+
346
+ if (module.helper.dateEqual(cellDate, focusDate, mode)) {
347
+ //ensure that the focus date is exactly equal to the cell date
348
+ //so that, if selected, the correct value is set
349
+ module.set.focusDate(cellDate, false, false);
350
+ }
351
+ }
352
+ }
353
+
354
+ if (settings.today) {
355
+ var todayRow = $('<tr/>').appendTo(tbody);
356
+ var todayButton = $('<td/>').attr('colspan', '' + columns).addClass(className.today).appendTo(todayRow);
357
+ todayButton.text(formatter.today(settings));
358
+ todayButton.data(metadata.date, today);
359
+ }
360
+
361
+ module.update.focus(false, table);
362
+ }
363
+ }
364
+ },
365
+
366
+ update: {
367
+ focus: function (updateRange, container) {
368
+ container = container || $container;
369
+ var mode = module.get.mode();
370
+ var date = module.get.date();
371
+ var focusDate = module.get.focusDate();
372
+ var startDate = module.get.startDate();
373
+ var endDate = module.get.endDate();
374
+ var rangeDate = (updateRange ? focusDate : null) || date || (!isTouch ? focusDate : null);
375
+
376
+ container.find('td').each(function () {
377
+ var cell = $(this);
378
+ var cellDate = cell.data(metadata.date);
379
+ if (!cellDate) {
380
+ return;
381
+ }
382
+ var disabled = cell.hasClass(className.disabledCell);
383
+ var active = cell.hasClass(className.activeCell);
384
+ var adjacent = cell.hasClass(className.adjacentCell);
385
+ var focused = module.helper.dateEqual(cellDate, focusDate, mode);
386
+ var inRange = !rangeDate ? false :
387
+ ((!!startDate && module.helper.isDateInRange(cellDate, mode, startDate, rangeDate)) ||
388
+ (!!endDate && module.helper.isDateInRange(cellDate, mode, rangeDate, endDate)));
389
+ cell.toggleClass(className.focusCell, focused && (!isTouch || isTouchDown) && !adjacent && !disabled);
390
+ cell.toggleClass(className.rangeCell, inRange && !active && !disabled);
391
+ });
392
+ }
393
+ },
394
+
395
+ refresh: function () {
396
+ module.create.calendar();
397
+ },
398
+
399
+ bind: {
400
+ events: function () {
401
+ module.debug('Binding events');
402
+ $container.on('mousedown' + eventNamespace, module.event.mousedown);
403
+ $container.on('touchstart' + eventNamespace, module.event.mousedown);
404
+ $container.on('mouseup' + eventNamespace, module.event.mouseup);
405
+ $container.on('touchend' + eventNamespace, module.event.mouseup);
406
+ $container.on('mouseover' + eventNamespace, module.event.mouseover);
407
+ if ($input.length) {
408
+ $input.on('input' + eventNamespace, module.event.inputChange);
409
+ $input.on('focus' + eventNamespace, module.event.inputFocus);
410
+ $input.on('blur' + eventNamespace, module.event.inputBlur);
411
+ $input.on('click' + eventNamespace, module.event.inputClick);
412
+ $input.on('keydown' + eventNamespace, module.event.keydown);
413
+ } else {
414
+ $container.on('keydown' + eventNamespace, module.event.keydown);
415
+ }
416
+ }
417
+ },
418
+
419
+ unbind: {
420
+ events: function () {
421
+ module.debug('Unbinding events');
422
+ $container.off(eventNamespace);
423
+ if ($input.length) {
424
+ $input.off(eventNamespace);
425
+ }
426
+ }
427
+ },
428
+
429
+ event: {
430
+ mouseover: function (event) {
431
+ var target = $(event.target);
432
+ var date = target.data(metadata.date);
433
+ var mousedown = event.buttons === 1;
434
+ if (date) {
435
+ module.set.focusDate(date, false, true, mousedown);
436
+ }
437
+ },
438
+ mousedown: function (event) {
439
+ if ($input.length) {
440
+ //prevent the mousedown on the calendar causing the input to lose focus
441
+ event.preventDefault();
442
+ }
443
+ isTouchDown = event.type.indexOf('touch') >= 0;
444
+ var target = $(event.target);
445
+ var date = target.data(metadata.date);
446
+ if (date) {
447
+ module.set.focusDate(date, false, true, true);
448
+ }
449
+ },
450
+ mouseup: function (event) {
451
+ //ensure input has focus so that it receives keydown events for calendar navigation
452
+ module.focus();
453
+ event.preventDefault();
454
+ event.stopPropagation();
455
+ isTouchDown = false;
456
+ var target = $(event.target);
457
+ if (target.hasClass("disabled")) {
458
+ return;
459
+ }
460
+ var parent = target.parent();
461
+ if (parent.data(metadata.date) || parent.data(metadata.focusDate) || parent.data(metadata.mode)) {
462
+ //clicked on a child element, switch to parent (used when clicking directly on prev/next <i> icon element)
463
+ target = parent;
464
+ }
465
+ var date = target.data(metadata.date);
466
+ var focusDate = target.data(metadata.focusDate);
467
+ var mode = target.data(metadata.mode);
468
+ if (date) {
469
+ var forceSet = target.hasClass(className.today);
470
+ module.selectDate(date, forceSet);
471
+ }
472
+ else if (focusDate) {
473
+ module.set.focusDate(focusDate);
474
+ }
475
+ else if (mode) {
476
+ module.set.mode(mode);
477
+ }
478
+ },
479
+ keydown: function (event) {
480
+ if (event.keyCode === 27 || event.keyCode === 9) {
481
+ //esc || tab
482
+ module.popup('hide');
483
+ }
484
+
485
+ if (module.popup('is visible')) {
486
+ if (event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40) {
487
+ //arrow keys
488
+ var mode = module.get.mode();
489
+ var bigIncrement = mode === 'day' ? 7 : mode === 'hour' ? 4 : 3;
490
+ var increment = event.keyCode === 37 ? -1 : event.keyCode === 38 ? -bigIncrement : event.keyCode == 39 ? 1 : bigIncrement;
491
+ increment *= mode === 'minute' ? 5 : 1;
492
+ var focusDate = module.get.focusDate() || module.get.date() || new Date();
493
+ var year = focusDate.getFullYear() + (mode === 'year' ? increment : 0);
494
+ var month = focusDate.getMonth() + (mode === 'month' ? increment : 0);
495
+ var day = focusDate.getDate() + (mode === 'day' ? increment : 0);
496
+ var hour = focusDate.getHours() + (mode === 'hour' ? increment : 0);
497
+ var minute = focusDate.getMinutes() + (mode === 'minute' ? increment : 0);
498
+ var newFocusDate = new Date(year, month, day, hour, minute);
499
+ if (settings.type === 'time') {
500
+ newFocusDate = module.helper.mergeDateTime(focusDate, newFocusDate);
501
+ }
502
+ if (module.helper.isDateInRange(newFocusDate, mode)) {
503
+ module.set.focusDate(newFocusDate);
504
+ }
505
+ } else if (event.keyCode === 13) {
506
+ //enter
507
+ var mode = module.get.mode();
508
+ var date = module.get.focusDate();
509
+ if (date && !settings.isDisabled(date, mode) && !module.helper.isDisabled(date, mode)) {
510
+ module.selectDate(date);
511
+ }
512
+ //disable form submission:
513
+ event.preventDefault();
514
+ event.stopPropagation();
515
+ }
516
+ }
517
+
518
+ if (event.keyCode === 38 || event.keyCode === 40) {
519
+ //arrow-up || arrow-down
520
+ event.preventDefault(); //don't scroll
521
+ module.popup('show');
522
+ }
523
+ },
524
+ inputChange: function () {
525
+ var val = $input.val();
526
+ var date = parser.date(val, settings);
527
+ module.set.date(date, false);
528
+ },
529
+ inputFocus: function () {
530
+ $container.addClass(className.active);
531
+ },
532
+ inputBlur: function () {
533
+ $container.removeClass(className.active);
534
+ if (settings.formatInput) {
535
+ var date = module.get.date();
536
+ var text = formatter.datetime(date, settings);
537
+ $input.val(text);
538
+ }
539
+ },
540
+ inputClick: function () {
541
+ module.popup('show');
542
+ }
543
+ },
544
+
545
+ get: {
546
+ weekOfYear: function(weekYear,weekMonth,weekDay) {
547
+ // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
548
+ var ms1d = 864e5, // milliseconds in a day
549
+ ms7d = 7 * ms1d; // milliseconds in a week
550
+
551
+ return function() { // return a closure so constants get calculated only once
552
+ var DC3 = Date.UTC(weekYear, weekMonth, weekDay + 3) / ms1d, // an Absolute Day Number
553
+ AWN = Math.floor(DC3 / 7), // an Absolute Week Number
554
+ Wyr = new Date(AWN * ms7d).getUTCFullYear();
555
+
556
+ return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
557
+ }();
558
+ },
559
+ date: function () {
560
+ return $module.data(metadata.date) || null;
561
+ },
562
+ focusDate: function () {
563
+ return $module.data(metadata.focusDate) || null;
564
+ },
565
+ startDate: function () {
566
+ var startModule = module.get.calendarModule(settings.startCalendar);
567
+ return (startModule ? startModule.get.date() : $module.data(metadata.startDate)) || null;
568
+ },
569
+ endDate: function () {
570
+ var endModule = module.get.calendarModule(settings.endCalendar);
571
+ return (endModule ? endModule.get.date() : $module.data(metadata.endDate)) || null;
572
+ },
573
+ minDate: function() {
574
+ return $module.data(metadata.minDate) || null;
575
+ },
576
+ maxDate: function() {
577
+ return $module.data(metadata.maxDate) || null;
578
+ },
579
+ monthOffset: function () {
580
+ return $module.data(metadata.monthOffset) || 0;
581
+ },
582
+ mode: function () {
583
+ //only returns valid modes for the current settings
584
+ var mode = $module.data(metadata.mode) || settings.startMode;
585
+ var validModes = module.get.validModes();
586
+ if ($.inArray(mode, validModes) >= 0) {
587
+ return mode;
588
+ }
589
+ return settings.type === 'time' ? 'hour' :
590
+ settings.type === 'month' ? 'month' :
591
+ settings.type === 'year' ? 'year' : 'day';
592
+ },
593
+ validModes: function () {
594
+ var validModes = [];
595
+ if (settings.type !== 'time') {
596
+ if (!settings.disableYear || settings.type === 'year') {
597
+ validModes.push('year');
598
+ }
599
+ if (!(settings.disableMonth || settings.type === 'year') || settings.type === 'month') {
600
+ validModes.push('month');
601
+ }
602
+ if (settings.type.indexOf('date') >= 0) {
603
+ validModes.push('day');
604
+ }
605
+ }
606
+ if (settings.type.indexOf('time') >= 0) {
607
+ validModes.push('hour');
608
+ if (!settings.disableMinute) {
609
+ validModes.push('minute');
610
+ }
611
+ }
612
+ return validModes;
613
+ },
614
+ isTouch: function () {
615
+ try {
616
+ document.createEvent('TouchEvent');
617
+ return true;
618
+ }
619
+ catch (e) {
620
+ return false;
621
+ }
622
+ },
623
+ calendarModule: function (selector) {
624
+ if (!selector) {
625
+ return null;
626
+ }
627
+ if (!(selector instanceof $)) {
628
+ selector = $module.parent().children(selector).first();
629
+ }
630
+ //assume range related calendars are using the same namespace
631
+ return selector.data(moduleNamespace);
632
+ }
633
+ },
634
+
635
+ set: {
636
+ date: function (date, updateInput, fireChange) {
637
+ updateInput = updateInput !== false;
638
+ fireChange = fireChange !== false;
639
+ date = module.helper.sanitiseDate(date);
640
+ date = module.helper.dateInRange(date);
641
+
642
+ var mode = module.get.mode();
643
+ var text = formatter.datetime(date, settings);
644
+ if (fireChange && settings.onChange.call(element, date, text, mode) === false) {
645
+ return false;
646
+ }
647
+
648
+ module.set.focusDate(date);
649
+
650
+ if (settings.isDisabled(date, mode)) {
651
+ return false;
652
+ }
653
+
654
+ var endDate = module.get.endDate();
655
+ if (!!endDate && !!date && date > endDate) {
656
+ //selected date is greater than end date in range, so clear end date
657
+ module.set.endDate(undefined);
658
+ }
659
+ module.set.dataKeyValue(metadata.date, date);
660
+
661
+ if (updateInput && $input.length) {
662
+ $input.val(text);
663
+ }
664
+ },
665
+ startDate: function (date, refreshCalendar) {
666
+ date = module.helper.sanitiseDate(date);
667
+ var startModule = module.get.calendarModule(settings.startCalendar);
668
+ if (startModule) {
669
+ startModule.set.date(date);
670
+ }
671
+ module.set.dataKeyValue(metadata.startDate, date, refreshCalendar);
672
+ },
673
+ endDate: function (date, refreshCalendar) {
674
+ date = module.helper.sanitiseDate(date);
675
+ var endModule = module.get.calendarModule(settings.endCalendar);
676
+ if (endModule) {
677
+ endModule.set.date(date);
678
+ }
679
+ module.set.dataKeyValue(metadata.endDate, date, refreshCalendar);
680
+ },
681
+ focusDate: function (date, refreshCalendar, updateFocus, updateRange) {
682
+ date = module.helper.sanitiseDate(date);
683
+ date = module.helper.dateInRange(date);
684
+ var isDay = module.get.mode() === 'day';
685
+ var oldFocusDate = module.get.focusDate();
686
+ if (isDay && date && oldFocusDate) {
687
+ var yearDelta = date.getFullYear() - oldFocusDate.getFullYear();
688
+ var monthDelta = yearDelta * 12 + date.getMonth() - oldFocusDate.getMonth();
689
+ if (monthDelta) {
690
+ var monthOffset = module.get.monthOffset() - monthDelta;
691
+ module.set.monthOffset(monthOffset, false);
692
+ }
693
+ }
694
+ var changed = module.set.dataKeyValue(metadata.focusDate, date, refreshCalendar);
695
+ updateFocus = (updateFocus !== false && changed && refreshCalendar === false) || focusDateUsedForRange != updateRange;
696
+ focusDateUsedForRange = updateRange;
697
+ if (updateFocus) {
698
+ module.update.focus(updateRange);
699
+ }
700
+ },
701
+ minDate: function (date) {
702
+ date = module.helper.sanitiseDate(date);
703
+ if (settings.maxDate !== null && settings.maxDate <= date) {
704
+ module.verbose('Unable to set minDate variable bigger that maxDate variable', date, settings.maxDate);
705
+ } else {
706
+ module.setting('minDate', date);
707
+ module.set.dataKeyValue(metadata.minDate, date);
708
+ }
709
+ },
710
+ maxDate: function (date) {
711
+ date = module.helper.sanitiseDate(date);
712
+ if (settings.minDate !== null && settings.minDate >= date) {
713
+ module.verbose('Unable to set maxDate variable lower that minDate variable', date, settings.minDate);
714
+ } else {
715
+ module.setting('maxDate', date);
716
+ module.set.dataKeyValue(metadata.maxDate, date);
717
+ }
718
+ },
719
+ monthOffset: function (monthOffset, refreshCalendar) {
720
+ var multiMonth = Math.max(settings.multiMonth, 1);
721
+ monthOffset = Math.max(1 - multiMonth, Math.min(0, monthOffset));
722
+ module.set.dataKeyValue(metadata.monthOffset, monthOffset, refreshCalendar);
723
+ },
724
+ mode: function (mode, refreshCalendar) {
725
+ module.set.dataKeyValue(metadata.mode, mode, refreshCalendar);
726
+ },
727
+ dataKeyValue: function (key, value, refreshCalendar) {
728
+ var oldValue = $module.data(key);
729
+ var equal = oldValue === value || (oldValue <= value && oldValue >= value); //equality test for dates and string objects
730
+ if (value) {
731
+ $module.data(key, value);
732
+ } else {
733
+ $module.removeData(key);
734
+ }
735
+ refreshCalendar = refreshCalendar !== false && !equal;
736
+ if (refreshCalendar) {
737
+ module.refresh();
738
+ }
739
+ return !equal;
740
+ }
741
+ },
742
+
743
+ selectDate: function (date, forceSet) {
744
+ module.verbose('New date selection', date)
745
+ var mode = module.get.mode();
746
+ var complete = forceSet || mode === 'minute' ||
747
+ (settings.disableMinute && mode === 'hour') ||
748
+ (settings.type === 'date' && mode === 'day') ||
749
+ (settings.type === 'month' && mode === 'month') ||
750
+ (settings.type === 'year' && mode === 'year');
751
+ if (complete) {
752
+ var canceled = module.set.date(date) === false;
753
+ if (!canceled && settings.closable) {
754
+ module.popup('hide');
755
+ //if this is a range calendar, show the end date calendar popup and focus the input
756
+ var endModule = module.get.calendarModule(settings.endCalendar);
757
+ if (endModule) {
758
+ endModule.popup('show');
759
+ endModule.focus();
760
+ }
761
+ }
762
+ } else {
763
+ var newMode = mode === 'year' ? (!settings.disableMonth ? 'month' : 'day') :
764
+ mode === 'month' ? 'day' : mode === 'day' ? 'hour' : 'minute';
765
+ module.set.mode(newMode);
766
+ if (mode === 'hour' || (mode === 'day' && module.get.date())) {
767
+ //the user has chosen enough to consider a valid date/time has been chosen
768
+ module.set.date(date);
769
+ } else {
770
+ module.set.focusDate(date);
771
+ }
772
+ }
773
+ },
774
+
775
+ changeDate: function (date) {
776
+ module.set.date(date);
777
+ },
778
+
779
+ clear: function () {
780
+ module.set.date(undefined);
781
+ },
782
+
783
+ popup: function () {
784
+ return $activator.popup.apply($activator, arguments);
785
+ },
786
+
787
+ focus: function () {
788
+ if ($input.length) {
789
+ $input.focus();
790
+ } else {
791
+ $container.focus();
792
+ }
793
+ },
794
+ blur: function () {
795
+ if ($input.length) {
796
+ $input.blur();
797
+ } else {
798
+ $container.blur();
799
+ }
800
+ },
801
+
802
+ helper: {
803
+ isDisabled: function(date, mode) {
804
+ return mode === 'day' && ((settings.disabledDaysOfWeek.indexOf(date.getDay()) !== -1) || settings.disabledDates.some(function(d){
805
+ if (d instanceof Date) {
806
+ return module.helper.dateEqual(date, d, mode);
807
+ }
808
+ if (d !== null && typeof d === 'object') {
809
+ return module.helper.dateEqual(date, d[metadata.date], mode);
810
+ }
811
+ }));
812
+ },
813
+ disabledReason: function(date, mode) {
814
+ if (mode === 'day') {
815
+ for (var i = 0; i < settings.disabledDates.length; i++) {
816
+ var d = settings.disabledDates[i];
817
+ if (d !== null && typeof d === 'object' && module.helper.dateEqual(date, d[metadata.date], mode)) {
818
+ var reason = {};
819
+ reason[metadata.message] = d[metadata.message];
820
+ return reason;
821
+ }
822
+ }
823
+ }
824
+ return null;
825
+ },
826
+ sanitiseDate: function (date) {
827
+ if (!date) {
828
+ return undefined;
829
+ }
830
+ if (!(date instanceof Date)) {
831
+ date = parser.date('' + date, settings);
832
+ }
833
+ if (isNaN(date.getTime())) {
834
+ return undefined;
835
+ }
836
+ return date;
837
+ },
838
+ dateDiff: function (date1, date2, mode) {
839
+ mode = mode || 'day';
840
+ var isTimeOnly = settings.type === 'time';
841
+ var isYear = mode === 'year';
842
+ var isYearOrMonth = isYear || mode === 'month';
843
+ var isMinute = mode === 'minute';
844
+ var isHourOrMinute = isMinute || mode === 'hour';
845
+ //only care about a minute accuracy of 5
846
+ date1 = new Date(
847
+ isTimeOnly ? 2000 : date1.getFullYear(),
848
+ isTimeOnly ? 0 : isYear ? 0 : date1.getMonth(),
849
+ isTimeOnly ? 1 : isYearOrMonth ? 1 : date1.getDate(),
850
+ !isHourOrMinute ? 0 : date1.getHours(),
851
+ !isMinute ? 0 : 5 * Math.floor(date1.getMinutes() / 5));
852
+ date2 = new Date(
853
+ isTimeOnly ? 2000 : date2.getFullYear(),
854
+ isTimeOnly ? 0 : isYear ? 0 : date2.getMonth(),
855
+ isTimeOnly ? 1 : isYearOrMonth ? 1 : date2.getDate(),
856
+ !isHourOrMinute ? 0 : date2.getHours(),
857
+ !isMinute ? 0 : 5 * Math.floor(date2.getMinutes() / 5));
858
+ return date2.getTime() - date1.getTime();
859
+ },
860
+ dateEqual: function (date1, date2, mode) {
861
+ return !!date1 && !!date2 && module.helper.dateDiff(date1, date2, mode) === 0;
862
+ },
863
+ isDateInRange: function (date, mode, minDate, maxDate) {
864
+ if (!minDate && !maxDate) {
865
+ var startDate = module.get.startDate();
866
+ minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
867
+ maxDate = settings.maxDate;
868
+ }
869
+ minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), 5 * Math.ceil(minDate.getMinutes() / 5));
870
+ return !(!date ||
871
+ (minDate && module.helper.dateDiff(date, minDate, mode) > 0) ||
872
+ (maxDate && module.helper.dateDiff(maxDate, date, mode) > 0));
873
+ },
874
+ dateInRange: function (date, minDate, maxDate) {
875
+ if (!minDate && !maxDate) {
876
+ var startDate = module.get.startDate();
877
+ minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
878
+ maxDate = settings.maxDate;
879
+ }
880
+ minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), 5 * Math.ceil(minDate.getMinutes() / 5));
881
+ var isTimeOnly = settings.type === 'time';
882
+ return !date ? date :
883
+ (minDate && module.helper.dateDiff(date, minDate, 'minute') > 0) ?
884
+ (isTimeOnly ? module.helper.mergeDateTime(date, minDate) : minDate) :
885
+ (maxDate && module.helper.dateDiff(maxDate, date, 'minute') > 0) ?
886
+ (isTimeOnly ? module.helper.mergeDateTime(date, maxDate) : maxDate) :
887
+ date;
888
+ },
889
+ mergeDateTime: function (date, time) {
890
+ return (!date || !time) ? time :
891
+ new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes());
892
+ }
893
+ },
894
+
895
+ setting: function (name, value) {
896
+ module.debug('Changing setting', name, value);
897
+ if ($.isPlainObject(name)) {
898
+ $.extend(true, settings, name);
899
+ }
900
+ else if (value !== undefined) {
901
+ if ($.isPlainObject(settings[name])) {
902
+ $.extend(true, settings[name], value);
903
+ }
904
+ else {
905
+ settings[name] = value;
906
+ }
907
+ }
908
+ else {
909
+ return settings[name];
910
+ }
911
+ },
912
+ internal: function (name, value) {
913
+ if( $.isPlainObject(name) ) {
914
+ $.extend(true, module, name);
915
+ }
916
+ else if(value !== undefined) {
917
+ module[name] = value;
918
+ }
919
+ else {
920
+ return module[name];
921
+ }
922
+ },
923
+ debug: function () {
924
+ if (!settings.silent && settings.debug) {
925
+ if (settings.performance) {
926
+ module.performance.log(arguments);
927
+ }
928
+ else {
929
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
930
+ module.debug.apply(console, arguments);
931
+ }
932
+ }
933
+ },
934
+ verbose: function () {
935
+ if (!settings.silent && settings.verbose && settings.debug) {
936
+ if (settings.performance) {
937
+ module.performance.log(arguments);
938
+ }
939
+ else {
940
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
941
+ module.verbose.apply(console, arguments);
942
+ }
943
+ }
944
+ },
945
+ error: function () {
946
+ if (!settings.silent) {
947
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
948
+ module.error.apply(console, arguments);
949
+ }
950
+ },
951
+ performance: {
952
+ log: function (message) {
953
+ var
954
+ currentTime,
955
+ executionTime,
956
+ previousTime
957
+ ;
958
+ if (settings.performance) {
959
+ currentTime = new Date().getTime();
960
+ previousTime = time || currentTime;
961
+ executionTime = currentTime - previousTime;
962
+ time = currentTime;
963
+ performance.push({
964
+ 'Name': message[0],
965
+ 'Arguments': [].slice.call(message, 1) || '',
966
+ 'Element': element,
967
+ 'Execution Time': executionTime
968
+ });
969
+ }
970
+ clearTimeout(module.performance.timer);
971
+ module.performance.timer = setTimeout(module.performance.display, 500);
972
+ },
973
+ display: function () {
974
+ var
975
+ title = settings.name + ':',
976
+ totalTime = 0
977
+ ;
978
+ time = false;
979
+ clearTimeout(module.performance.timer);
980
+ $.each(performance, function (index, data) {
981
+ totalTime += data['Execution Time'];
982
+ });
983
+ title += ' ' + totalTime + 'ms';
984
+ if (moduleSelector) {
985
+ title += ' \'' + moduleSelector + '\'';
986
+ }
987
+ if ((console.group !== undefined || console.table !== undefined) && performance.length > 0) {
988
+ console.groupCollapsed(title);
989
+ if (console.table) {
990
+ console.table(performance);
991
+ }
992
+ else {
993
+ $.each(performance, function (index, data) {
994
+ console.log(data['Name'] + ': ' + data['Execution Time'] + 'ms');
995
+ });
996
+ }
997
+ console.groupEnd();
998
+ }
999
+ performance = [];
1000
+ }
1001
+ },
1002
+ invoke: function (query, passedArguments, context) {
1003
+ var
1004
+ object = instance,
1005
+ maxDepth,
1006
+ found,
1007
+ response
1008
+ ;
1009
+ passedArguments = passedArguments || queryArguments;
1010
+ context = element || context;
1011
+ if (typeof query == 'string' && object !== undefined) {
1012
+ query = query.split(/[\. ]/);
1013
+ maxDepth = query.length - 1;
1014
+ $.each(query, function (depth, value) {
1015
+ var camelCaseValue = (depth != maxDepth)
1016
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1017
+ : query
1018
+ ;
1019
+ if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) {
1020
+ object = object[camelCaseValue];
1021
+ }
1022
+ else if (object[camelCaseValue] !== undefined) {
1023
+ found = object[camelCaseValue];
1024
+ return false;
1025
+ }
1026
+ else if ($.isPlainObject(object[value]) && (depth != maxDepth)) {
1027
+ object = object[value];
1028
+ }
1029
+ else if (object[value] !== undefined) {
1030
+ found = object[value];
1031
+ return false;
1032
+ }
1033
+ else {
1034
+ module.error(error.method, query);
1035
+ return false;
1036
+ }
1037
+ });
1038
+ }
1039
+ if ($.isFunction(found)) {
1040
+ response = found.apply(context, passedArguments);
1041
+ }
1042
+ else if (found !== undefined) {
1043
+ response = found;
1044
+ }
1045
+ if ($.isArray(returnedValue)) {
1046
+ returnedValue.push(response);
1047
+ }
1048
+ else if (returnedValue !== undefined) {
1049
+ returnedValue = [returnedValue, response];
1050
+ }
1051
+ else if (response !== undefined) {
1052
+ returnedValue = response;
1053
+ }
1054
+ return found;
1055
+ }
1056
+ };
1057
+
1058
+ if (methodInvoked) {
1059
+ if (instance === undefined) {
1060
+ module.initialize();
1061
+ }
1062
+ module.invoke(query);
1063
+ }
1064
+ else {
1065
+ if (instance !== undefined) {
1066
+ instance.invoke('destroy');
1067
+ }
1068
+ module.initialize();
1069
+ }
1070
+ })
1071
+ ;
1072
+ return (returnedValue !== undefined)
1073
+ ? returnedValue
1074
+ : this
1075
+ ;
1076
+ };
1077
+
1078
+ $.fn.calendar.settings = {
1079
+
1080
+ name : 'Calendar',
1081
+ namespace : 'calendar',
1082
+
1083
+ silent: false,
1084
+ debug: false,
1085
+ verbose: false,
1086
+ performance: false,
1087
+
1088
+ type : 'datetime', // picker type, can be 'datetime', 'date', 'time', 'month', or 'year'
1089
+ firstDayOfWeek : 0, // day for first day column (0 = Sunday)
1090
+ constantHeight : true, // add rows to shorter months to keep day calendar height consistent (6 rows)
1091
+ today : false, // show a 'today/now' button at the bottom of the calendar
1092
+ closable : true, // close the popup after selecting a date/time
1093
+ monthFirst : true, // month before day when parsing/converting date from/to text
1094
+ touchReadonly : true, // set input to readonly on touch devices
1095
+ inline : false, // create the calendar inline instead of inside a popup
1096
+ on : null, // when to show the popup (defaults to 'focus' for input, 'click' for others)
1097
+ initialDate : null, // date to display initially when no date is selected (null = now)
1098
+ startMode : false, // display mode to start in, can be 'year', 'month', 'day', 'hour', 'minute' (false = 'day')
1099
+ minDate : null, // minimum date/time that can be selected, dates/times before are disabled
1100
+ maxDate : null, // maximum date/time that can be selected, dates/times after are disabled
1101
+ ampm : true, // show am/pm in time mode
1102
+ disableYear : false, // disable year selection mode
1103
+ disableMonth : false, // disable month selection mode
1104
+ disableMinute : false, // disable minute selection mode
1105
+ formatInput : true, // format the input text upon input blur and module creation
1106
+ startCalendar : null, // jquery object or selector for another calendar that represents the start date of a date range
1107
+ endCalendar : null, // jquery object or selector for another calendar that represents the end date of a date range
1108
+ multiMonth : 1, // show multiple months when in 'day' mode
1109
+ showWeekNumbers : null, // show Number of Week at the very first column of a dayView
1110
+ disabledDates : [], // specific day(s) which won't be selectable and contain additional information.
1111
+ disabledDaysOfWeek : [], // day(s) which won't be selectable(s) (0 = Sunday)
1112
+ // popup options ('popup', 'on', 'hoverable', and show/hide callbacks are overridden)
1113
+ popupOptions: {
1114
+ position: 'bottom left',
1115
+ lastResort: 'bottom left',
1116
+ prefer: 'opposite',
1117
+ hideOnScroll: false
1118
+ },
1119
+
1120
+ text: {
1121
+ days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
1122
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
1123
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
1124
+ today: 'Today',
1125
+ now: 'Now',
1126
+ am: 'AM',
1127
+ pm: 'PM',
1128
+ weekNo: 'Week'
1129
+ },
1130
+
1131
+ formatter: {
1132
+ header: function (date, mode, settings) {
1133
+ return mode === 'year' ? settings.formatter.yearHeader(date, settings) :
1134
+ mode === 'month' ? settings.formatter.monthHeader(date, settings) :
1135
+ mode === 'day' ? settings.formatter.dayHeader(date, settings) :
1136
+ mode === 'hour' ? settings.formatter.hourHeader(date, settings) :
1137
+ settings.formatter.minuteHeader(date, settings);
1138
+ },
1139
+ yearHeader: function (date, settings) {
1140
+ var decadeYear = Math.ceil(date.getFullYear() / 10) * 10;
1141
+ return (decadeYear - 9) + ' - ' + (decadeYear + 2);
1142
+ },
1143
+ monthHeader: function (date, settings) {
1144
+ return date.getFullYear();
1145
+ },
1146
+ dayHeader: function (date, settings) {
1147
+ var month = settings.text.months[date.getMonth()];
1148
+ var year = date.getFullYear();
1149
+ return month + ' ' + year;
1150
+ },
1151
+ hourHeader: function (date, settings) {
1152
+ return settings.formatter.date(date, settings);
1153
+ },
1154
+ minuteHeader: function (date, settings) {
1155
+ return settings.formatter.date(date, settings);
1156
+ },
1157
+ dayColumnHeader: function (day, settings) {
1158
+ return settings.text.days[day];
1159
+ },
1160
+ datetime: function (date, settings) {
1161
+ if (!date) {
1162
+ return '';
1163
+ }
1164
+ var day = settings.type === 'time' ? '' : settings.formatter.date(date, settings);
1165
+ var time = settings.type.indexOf('time') < 0 ? '' : settings.formatter.time(date, settings, false);
1166
+ var separator = settings.type === 'datetime' ? ' ' : '';
1167
+ return day + separator + time;
1168
+ },
1169
+ date: function (date, settings) {
1170
+ if (!date) {
1171
+ return '';
1172
+ }
1173
+ var day = date.getDate();
1174
+ var month = settings.text.months[date.getMonth()];
1175
+ var year = date.getFullYear();
1176
+ return settings.type === 'year' ? year :
1177
+ settings.type === 'month' ? month + ' ' + year :
1178
+ (settings.monthFirst ? month + ' ' + day : day + ' ' + month) + ', ' + year;
1179
+ },
1180
+ time: function (date, settings, forCalendar) {
1181
+ if (!date) {
1182
+ return '';
1183
+ }
1184
+ var hour = date.getHours();
1185
+ var minute = date.getMinutes();
1186
+ var ampm = '';
1187
+ if (settings.ampm) {
1188
+ ampm = ' ' + (hour < 12 ? settings.text.am : settings.text.pm);
1189
+ hour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
1190
+ }
1191
+ return hour + ':' + (minute < 10 ? '0' : '') + minute + ampm;
1192
+ },
1193
+ today: function (settings) {
1194
+ return settings.type === 'date' ? settings.text.today : settings.text.now;
1195
+ },
1196
+ cell: function (cell, date, cellOptions) {
1197
+ }
1198
+ },
1199
+
1200
+ parser: {
1201
+ date: function (text, settings) {
1202
+ if (!text) {
1203
+ return null;
1204
+ }
1205
+ text = ('' + text).trim().toLowerCase();
1206
+ if (text.length === 0) {
1207
+ return null;
1208
+ }
1209
+
1210
+ var i, j, k;
1211
+ var minute = -1, hour = -1, day = -1, month = -1, year = -1;
1212
+ var isAm = undefined;
1213
+
1214
+ var isTimeOnly = settings.type === 'time';
1215
+ var isDateOnly = settings.type.indexOf('time') < 0;
1216
+
1217
+ var words = text.split(settings.regExp.dateWords);
1218
+ var numbers = text.split(settings.regExp.dateNumbers);
1219
+
1220
+ if (!isDateOnly) {
1221
+ //am/pm
1222
+ isAm = $.inArray(settings.text.am.toLowerCase(), words) >= 0 ? true :
1223
+ $.inArray(settings.text.pm.toLowerCase(), words) >= 0 ? false : undefined;
1224
+
1225
+ //time with ':'
1226
+ for (i = 0; i < numbers.length; i++) {
1227
+ var number = numbers[i];
1228
+ if (number.indexOf(':') >= 0) {
1229
+ if (hour < 0 || minute < 0) {
1230
+ var parts = number.split(':');
1231
+ for (k = 0; k < Math.min(2, parts.length); k++) {
1232
+ j = parseInt(parts[k]);
1233
+ if (isNaN(j)) {
1234
+ j = 0;
1235
+ }
1236
+ if (k === 0) {
1237
+ hour = j % 24;
1238
+ } else {
1239
+ minute = j % 60;
1240
+ }
1241
+ }
1242
+ }
1243
+ numbers.splice(i, 1);
1244
+ }
1245
+ }
1246
+ }
1247
+
1248
+ if (!isTimeOnly) {
1249
+ //textual month
1250
+ for (i = 0; i < words.length; i++) {
1251
+ var word = words[i];
1252
+ if (word.length <= 0) {
1253
+ continue;
1254
+ }
1255
+ word = word.substring(0, Math.min(word.length, 3));
1256
+ for (j = 0; j < settings.text.months.length; j++) {
1257
+ var monthString = settings.text.months[j];
1258
+ monthString = monthString.substring(0, Math.min(word.length, Math.min(monthString.length, 3))).toLowerCase();
1259
+ if (monthString === word) {
1260
+ month = j + 1;
1261
+ break;
1262
+ }
1263
+ }
1264
+ if (month >= 0) {
1265
+ break;
1266
+ }
1267
+ }
1268
+
1269
+ //year > 59
1270
+ for (i = 0; i < numbers.length; i++) {
1271
+ j = parseInt(numbers[i]);
1272
+ if (isNaN(j)) {
1273
+ continue;
1274
+ }
1275
+ if (j > 59) {
1276
+ year = j;
1277
+ numbers.splice(i, 1);
1278
+ break;
1279
+ }
1280
+ }
1281
+
1282
+ //numeric month
1283
+ if (month < 0) {
1284
+ for (i = 0; i < numbers.length; i++) {
1285
+ k = i > 1 || settings.monthFirst ? i : i === 1 ? 0 : 1;
1286
+ j = parseInt(numbers[k]);
1287
+ if (isNaN(j)) {
1288
+ continue;
1289
+ }
1290
+ if (1 <= j && j <= 12) {
1291
+ month = j;
1292
+ numbers.splice(k, 1);
1293
+ break;
1294
+ }
1295
+ }
1296
+ }
1297
+
1298
+ //day
1299
+ for (i = 0; i < numbers.length; i++) {
1300
+ j = parseInt(numbers[i]);
1301
+ if (isNaN(j)) {
1302
+ continue;
1303
+ }
1304
+ if (1 <= j && j <= 31) {
1305
+ day = j;
1306
+ numbers.splice(i, 1);
1307
+ break;
1308
+ }
1309
+ }
1310
+
1311
+ //year <= 59
1312
+ if (year < 0) {
1313
+ for (i = numbers.length - 1; i >= 0; i--) {
1314
+ j = parseInt(numbers[i]);
1315
+ if (isNaN(j)) {
1316
+ continue;
1317
+ }
1318
+ if (j < 99) {
1319
+ j += 2000;
1320
+ }
1321
+ year = j;
1322
+ numbers.splice(i, 1);
1323
+ break;
1324
+ }
1325
+ }
1326
+ }
1327
+
1328
+ if (!isDateOnly) {
1329
+ //hour
1330
+ if (hour < 0) {
1331
+ for (i = 0; i < numbers.length; i++) {
1332
+ j = parseInt(numbers[i]);
1333
+ if (isNaN(j)) {
1334
+ continue;
1335
+ }
1336
+ if (0 <= j && j <= 23) {
1337
+ hour = j;
1338
+ numbers.splice(i, 1);
1339
+ break;
1340
+ }
1341
+ }
1342
+ }
1343
+
1344
+ //minute
1345
+ if (minute < 0) {
1346
+ for (i = 0; i < numbers.length; i++) {
1347
+ j = parseInt(numbers[i]);
1348
+ if (isNaN(j)) {
1349
+ continue;
1350
+ }
1351
+ if (0 <= j && j <= 59) {
1352
+ minute = j;
1353
+ numbers.splice(i, 1);
1354
+ break;
1355
+ }
1356
+ }
1357
+ }
1358
+ }
1359
+
1360
+ if (minute < 0 && hour < 0 && day < 0 && month < 0 && year < 0) {
1361
+ return null;
1362
+ }
1363
+
1364
+ if (minute < 0) {
1365
+ minute = 0;
1366
+ }
1367
+ if (hour < 0) {
1368
+ hour = 0;
1369
+ }
1370
+ if (day < 0) {
1371
+ day = 1;
1372
+ }
1373
+ if (month < 0) {
1374
+ month = 1;
1375
+ }
1376
+ if (year < 0) {
1377
+ year = new Date().getFullYear();
1378
+ }
1379
+
1380
+ if (isAm !== undefined) {
1381
+ if (isAm) {
1382
+ if (hour === 12) {
1383
+ hour = 0;
1384
+ }
1385
+ } else if (hour < 12) {
1386
+ hour += 12;
1387
+ }
1388
+ }
1389
+
1390
+ var date = new Date(year, month - 1, day, hour, minute);
1391
+ if (date.getMonth() !== month - 1 || date.getFullYear() !== year) {
1392
+ //month or year don't match up, switch to last day of the month
1393
+ date = new Date(year, month, 0, hour, minute);
1394
+ }
1395
+ return isNaN(date.getTime()) ? null : date;
1396
+ }
1397
+ },
1398
+
1399
+ // callback when date changes, return false to cancel the change
1400
+ onChange: function (date, text, mode) {
1401
+ return true;
1402
+ },
1403
+
1404
+ // callback before show animation, return false to prevent show
1405
+ onShow: function () {
1406
+ },
1407
+
1408
+ // callback after show animation
1409
+ onVisible: function () {
1410
+ },
1411
+
1412
+ // callback before hide animation, return false to prevent hide
1413
+ onHide: function () {
1414
+ },
1415
+
1416
+ // callback after hide animation
1417
+ onHidden: function () {
1418
+ },
1419
+
1420
+ // is the given date disabled?
1421
+ isDisabled: function (date, mode) {
1422
+ return false;
1423
+ },
1424
+
1425
+ selector: {
1426
+ popup: '.ui.popup',
1427
+ input: 'input',
1428
+ activator: 'input'
1429
+ },
1430
+
1431
+ regExp: {
1432
+ dateWords: /[^A-Za-z\u00C0-\u024F]+/g,
1433
+ dateNumbers: /[^\d:]+/g
1434
+ },
1435
+
1436
+ error: {
1437
+ popup: 'UI Popup, a required component is not included in this page',
1438
+ method: 'The method you called is not defined.'
1439
+ },
1440
+
1441
+ className: {
1442
+ calendar: 'calendar',
1443
+ active: 'active',
1444
+ popup: 'ui popup',
1445
+ grid: 'ui equal width grid',
1446
+ column: 'column',
1447
+ table: 'ui celled center aligned unstackable table',
1448
+ prev: 'prev link',
1449
+ next: 'next link',
1450
+ prevIcon: 'chevron left icon',
1451
+ nextIcon: 'chevron right icon',
1452
+ link: 'link',
1453
+ cell: 'link',
1454
+ disabledCell: 'disabled',
1455
+ adjacentCell: 'adjacent',
1456
+ activeCell: 'active',
1457
+ rangeCell: 'range',
1458
+ focusCell: 'focus',
1459
+ todayCell: 'today',
1460
+ today: 'today link'
1461
+ },
1462
+
1463
+ metadata: {
1464
+ date: 'date',
1465
+ focusDate: 'focusDate',
1466
+ startDate: 'startDate',
1467
+ endDate: 'endDate',
1468
+ minDate: 'minDate',
1469
+ maxDate: 'maxDate',
1470
+ mode: 'mode',
1471
+ monthOffset: 'monthOffset',
1472
+ message: 'message'
1473
+ }
1474
+ };
1475
+
1476
+ })(jQuery, window, document);