fomantic-ui-sass 2.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);