@progress/kendo-dateinputs-common 0.1.0 → 0.2.0-dev.202301061353

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 (55) hide show
  1. package/README.md +34 -3
  2. package/dist/cdn/js/kendo-dateinputs-common.js +1 -0
  3. package/dist/cdn/main.js +1 -1
  4. package/dist/es/common/constants.js +6 -0
  5. package/dist/es/common/dateobject.js +1159 -0
  6. package/dist/es/common/key.js +16 -0
  7. package/dist/es/common/keycode.js +16 -0
  8. package/dist/es/common/mask.js +8 -0
  9. package/dist/es/common/observable.js +32 -0
  10. package/dist/es/common/utils.js +128 -0
  11. package/dist/es/dateinput/dateinput.js +1011 -0
  12. package/dist/es/dateinput/interaction-mode.js +6 -0
  13. package/dist/es/dateinput/utils.js +93 -0
  14. package/dist/es/main.js +1 -1
  15. package/dist/es2015/common/constants.js +6 -0
  16. package/dist/es2015/common/dateobject.js +1137 -0
  17. package/dist/es2015/common/key.js +16 -0
  18. package/dist/es2015/common/keycode.js +16 -0
  19. package/dist/es2015/common/mask.js +6 -0
  20. package/dist/es2015/common/observable.js +29 -0
  21. package/dist/es2015/common/utils.js +117 -0
  22. package/dist/es2015/dateinput/dateinput.js +969 -0
  23. package/dist/es2015/dateinput/interaction-mode.js +6 -0
  24. package/dist/es2015/dateinput/utils.js +92 -0
  25. package/dist/es2015/main.js +1 -1
  26. package/dist/npm/common/constants.d.ts +6 -0
  27. package/dist/npm/common/constants.js +8 -0
  28. package/dist/npm/common/dateobject.d.ts +172 -0
  29. package/dist/npm/common/dateobject.js +1161 -0
  30. package/dist/npm/common/key.d.ts +16 -0
  31. package/dist/npm/common/key.js +18 -0
  32. package/dist/npm/common/keycode.d.ts +16 -0
  33. package/dist/npm/common/keycode.js +18 -0
  34. package/dist/npm/common/mask.d.ts +4 -0
  35. package/dist/npm/common/mask.js +10 -0
  36. package/dist/npm/common/observable.d.ts +9 -0
  37. package/dist/npm/common/observable.js +34 -0
  38. package/dist/npm/common/utils.d.ts +60 -0
  39. package/dist/npm/common/utils.js +130 -0
  40. package/dist/npm/dateinput/dateinput.d.ts +204 -0
  41. package/dist/npm/dateinput/dateinput.js +1013 -0
  42. package/dist/npm/dateinput/interaction-mode.d.ts +5 -0
  43. package/dist/npm/dateinput/interaction-mode.js +8 -0
  44. package/dist/npm/dateinput/utils.d.ts +27 -0
  45. package/dist/npm/dateinput/utils.js +95 -0
  46. package/dist/npm/main.d.ts +1 -1
  47. package/dist/npm/main.js +2 -2
  48. package/dist/systemjs/kendo-dateinputs-common.js +1 -0
  49. package/package.json +10 -8
  50. package/dist/cdn/js/kendo-typescript-package-base.js +0 -1
  51. package/dist/es/my-class.js +0 -15
  52. package/dist/es2015/my-class.js +0 -11
  53. package/dist/npm/my-class.d.ts +0 -9
  54. package/dist/npm/my-class.js +0 -17
  55. package/dist/systemjs/kendo-typescript-package-base.js +0 -1
@@ -0,0 +1,1013 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var tslib_1 = require("tslib");
4
+ var _a;
5
+ var dateobject_1 = require("../common/dateobject");
6
+ var utils_1 = require("./utils");
7
+ var keycode_1 = require("../common/keycode");
8
+ var key_1 = require("../common/key");
9
+ var utils_2 = require("../common/utils");
10
+ var observable_1 = require("../common/observable");
11
+ var interaction_mode_1 = require("./interaction-mode");
12
+ var kendo_date_math_1 = require("@progress/kendo-date-math");
13
+ var constants_1 = require("../common/constants");
14
+ var DEFAULT_SEGMENT_STEP = 1;
15
+ var DRAG_START = "dragStart";
16
+ var DROP = "drop";
17
+ var TOUCH_START = "touchstart";
18
+ var MOUSE_DOWN = "mousedown";
19
+ var MOUSE_UP = "mouseup";
20
+ var CLICK = "click";
21
+ var INPUT = "input";
22
+ var KEY_DOWN = "keydown";
23
+ var FOCUS = "focus";
24
+ var BLUR = "blur";
25
+ var PASTE = "paste";
26
+ var MOUSE_SCROLL = "DOMMouseScroll";
27
+ var MOUSE_WHEEL = "mousewheel";
28
+ var VALUE_CHANGE = "valueChange";
29
+ var INPUT_END = "inputEnd";
30
+ var BLUR_END = "blurEnd";
31
+ var FOCUS_END = "focusEnd";
32
+ var CHANGE = "change";
33
+ var defaultDateInputOptions = {
34
+ format: "d",
35
+ allowNulls: false,
36
+ placeholder: null,
37
+ cycleTime: true,
38
+ locale: null,
39
+ steps: {
40
+ millisecond: DEFAULT_SEGMENT_STEP,
41
+ second: DEFAULT_SEGMENT_STEP,
42
+ minute: DEFAULT_SEGMENT_STEP,
43
+ hour: DEFAULT_SEGMENT_STEP,
44
+ day: DEFAULT_SEGMENT_STEP,
45
+ month: DEFAULT_SEGMENT_STEP,
46
+ year: DEFAULT_SEGMENT_STEP
47
+ },
48
+ formatPlaceholder: null,
49
+ events: (_a = {},
50
+ _a[VALUE_CHANGE] = null,
51
+ _a[INPUT] = null,
52
+ _a[INPUT_END] = null,
53
+ _a[FOCUS] = null,
54
+ _a[FOCUS_END] = null,
55
+ _a[BLUR] = null,
56
+ _a[BLUR_END] = null,
57
+ _a[KEY_DOWN] = null,
58
+ _a[MOUSE_WHEEL] = null,
59
+ _a[CHANGE] = null,
60
+ _a),
61
+ selectNearestSegmentOnFocus: false,
62
+ enableMouseWheel: false,
63
+ allowCaretMode: false,
64
+ autoSwitchParts: true,
65
+ autoSwitchKeys: [],
66
+ twoDigitYearMax: constants_1.Constants.twoDigitYearMax,
67
+ autoCorrectParts: true
68
+ };
69
+ var DateInput = /** @class */ (function (_super) {
70
+ tslib_1.__extends(DateInput, _super);
71
+ function DateInput(element, options) {
72
+ var _this = _super.call(this, options) || this;
73
+ _this.dateObject = null;
74
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
75
+ // @ts-ignore
76
+ _this.currentText = '';
77
+ _this.currentFormat = '';
78
+ _this.interactionMode = interaction_mode_1.DateInputInteractionMode.None;
79
+ _this.localeId = constants_1.Constants.defaultLocaleId;
80
+ _this.init(element, options);
81
+ return _this;
82
+ }
83
+ Object.defineProperty(DateInput.prototype, "value", {
84
+ get: function () {
85
+ return this.dateObject && this.dateObject.getValue();
86
+ },
87
+ enumerable: true,
88
+ configurable: true
89
+ });
90
+ DateInput.prototype.init = function (element, options) {
91
+ var dateValue = utils_2.isDate(this.options.value) ? kendo_date_math_1.cloneDate(this.options.value) : new Date(options.formattedValue);
92
+ if (!utils_2.isDate(dateValue)) {
93
+ dateValue = null;
94
+ }
95
+ this.element = element;
96
+ // this.element._kendoWidget = this;
97
+ this.options = utils_2.extend({}, defaultDateInputOptions, options);
98
+ this.intl = this.options.intlService;
99
+ this.formatPlaceholder = this.options.formatPlaceholder ? this.options.formatPlaceholder : 'formatPattern';
100
+ this.dateObject = this.createDateObject();
101
+ this.dateObject.setValue(dateValue);
102
+ this.setTextAndFormat();
103
+ this.bindEvents();
104
+ this.resetSegmentValue = true;
105
+ this.forceUpdate();
106
+ };
107
+ DateInput.prototype.destroy = function () {
108
+ this.unbindEvents();
109
+ this.dateObject = null;
110
+ _super.prototype.destroy.call(this);
111
+ };
112
+ DateInput.prototype.bindEvents = function () {
113
+ this.onElementDragStart = this.onElementDragStart.bind(this);
114
+ this.element.addEventListener(DRAG_START, this.onElementDragStart);
115
+ this.onElementDrop = this.onElementDrop.bind(this);
116
+ this.element.addEventListener(DROP, this.onElementDrop);
117
+ this.onElementClick = this.onElementClick.bind(this);
118
+ this.element.addEventListener(CLICK, this.onElementClick);
119
+ this.onElementMouseDown = this.onElementMouseDown.bind(this);
120
+ this.element.addEventListener(MOUSE_DOWN, this.onElementMouseDown);
121
+ this.element.addEventListener(TOUCH_START, this.onElementMouseDown);
122
+ this.onElementMouseUp = this.onElementMouseUp.bind(this);
123
+ this.element.addEventListener(MOUSE_UP, this.onElementMouseUp);
124
+ this.onElementInput = this.onElementInput.bind(this);
125
+ this.element.addEventListener(INPUT, this.onElementInput);
126
+ this.onElementKeyDown = this.onElementKeyDown.bind(this);
127
+ this.element.addEventListener(KEY_DOWN, this.onElementKeyDown);
128
+ this.onElementFocus = this.onElementFocus.bind(this);
129
+ this.element.addEventListener(FOCUS, this.onElementFocus);
130
+ this.onElementBlur = this.onElementBlur.bind(this);
131
+ this.element.addEventListener(BLUR, this.onElementBlur);
132
+ this.onElementChange = this.onElementChange.bind(this);
133
+ this.element.addEventListener(CHANGE, this.onElementChange);
134
+ this.onElementPaste = this.onElementPaste.bind(this);
135
+ this.element.addEventListener(PASTE, this.onElementPaste);
136
+ this.onElementMouseWheel = this.onElementMouseWheel.bind(this);
137
+ this.element.addEventListener(MOUSE_SCROLL, this.onElementMouseWheel);
138
+ this.element.addEventListener(MOUSE_WHEEL, this.onElementMouseWheel);
139
+ };
140
+ DateInput.prototype.unbindEvents = function () {
141
+ this.element.removeEventListener(DRAG_START, this.onElementDragStart);
142
+ this.element.removeEventListener(DROP, this.onElementDrop);
143
+ this.element.removeEventListener(TOUCH_START, this.onElementMouseDown);
144
+ this.element.removeEventListener(MOUSE_DOWN, this.onElementMouseDown);
145
+ this.element.removeEventListener(MOUSE_UP, this.onElementMouseUp);
146
+ this.element.removeEventListener(CLICK, this.onElementClick);
147
+ this.element.removeEventListener(INPUT, this.onElementInput);
148
+ this.element.removeEventListener(KEY_DOWN, this.onElementKeyDown);
149
+ this.element.removeEventListener(FOCUS, this.onElementFocus);
150
+ this.element.removeEventListener(BLUR, this.onElementBlur);
151
+ this.element.removeEventListener(CHANGE, this.onElementChange);
152
+ this.element.removeEventListener(PASTE, this.onElementPaste);
153
+ this.element.removeEventListener(MOUSE_SCROLL, this.onElementMouseWheel);
154
+ this.element.removeEventListener(MOUSE_WHEEL, this.onElementMouseWheel);
155
+ };
156
+ DateInput.prototype.setOptions = function (options, refresh) {
157
+ if (refresh === void 0) { refresh = false; }
158
+ this.options = utils_2.extend(this.options, options);
159
+ if (refresh) {
160
+ this.destroy();
161
+ this.init(this.element, options);
162
+ }
163
+ };
164
+ /**
165
+ * @hidden
166
+ */
167
+ DateInput.prototype.resetLocale = function () {
168
+ this.unbindEvents();
169
+ this.init(this.element, this.options);
170
+ };
171
+ /**
172
+ * @hidden
173
+ */
174
+ DateInput.prototype.isInCaretMode = function () {
175
+ return this.interactionMode === interaction_mode_1.DateInputInteractionMode.Caret;
176
+ };
177
+ DateInput.prototype.focus = function () {
178
+ this.element.focus();
179
+ if (this.options.selectNearestSegmentOnFocus) {
180
+ this.selectNearestSegment(0);
181
+ }
182
+ };
183
+ /**
184
+ * @hidden
185
+ */
186
+ DateInput.prototype.onElementDragStart = function (e) {
187
+ e.preventDefault();
188
+ };
189
+ /**
190
+ * @hidden
191
+ */
192
+ DateInput.prototype.onElementDrop = function (e) {
193
+ e.preventDefault();
194
+ };
195
+ /**
196
+ * @hidden
197
+ */
198
+ DateInput.prototype.onElementMouseDown = function () {
199
+ this.mouseDownStarted = true;
200
+ this.focusedPriorToMouseDown = this.isActive;
201
+ };
202
+ /**
203
+ * @hidden
204
+ */
205
+ DateInput.prototype.onElementMouseUp = function (e) {
206
+ this.mouseDownStarted = false;
207
+ e.preventDefault();
208
+ };
209
+ /**
210
+ * @hidden
211
+ */
212
+ DateInput.prototype.onElementClick = function (e) {
213
+ this.mouseDownStarted = false;
214
+ var selection = this.selection;
215
+ if (this.isInCaretMode()) {
216
+ // explicitly refresh the input element value
217
+ // caret mode can change the number of symbols in the element
218
+ // thus clicking on a segment can result in incorrect selection
219
+ this.forceUpdate();
220
+ }
221
+ if (e.detail === 3) {
222
+ // when 3 clicks occur, leave the native event to handle the change
223
+ // this results in selecting the whole element value
224
+ }
225
+ else {
226
+ if (this.isActive && this.options.selectNearestSegmentOnFocus) {
227
+ var selectionPresent = this.element.selectionStart !== this.element.selectionEnd;
228
+ var placeholderToggled = utils_2.isPresent(this.options.placeholder) &&
229
+ !this.dateObject.hasValue() &&
230
+ !this.focusedPriorToMouseDown;
231
+ // focus first segment if the user hasn't selected something during mousedown and if the placeholder was just toggled
232
+ var selectFirstSegment = !selectionPresent && placeholderToggled;
233
+ var index = selectFirstSegment ? 0 : this.caret()[0];
234
+ this.selectNearestSegment(index);
235
+ }
236
+ else {
237
+ this.setSelection(this.selectionByIndex(selection.start));
238
+ }
239
+ }
240
+ };
241
+ /**
242
+ * @hidden
243
+ */
244
+ DateInput.prototype.onElementInput = function (e) {
245
+ this.triggerInput({ event: e });
246
+ var keyDownEvent = this.keyDownEvent || {};
247
+ var isBackspaceKey = keyDownEvent.keyCode === keycode_1.KeyCode.BACKSPACE || keyDownEvent.key === key_1.Key.BACKSPACE;
248
+ var isDeleteKey = keyDownEvent.keyCode === keycode_1.KeyCode.DELETE || keyDownEvent.key === key_1.Key.DELETE;
249
+ if (!this.element || !this.dateObject) {
250
+ return;
251
+ }
252
+ if (this.isPasteInProgress) {
253
+ if (this.options.allowCaretMode) {
254
+ // pasting should leave the input with caret
255
+ // thus allow direct input instead of selection mode
256
+ this.resetSegmentValue = false;
257
+ }
258
+ this.updateOnPaste(e);
259
+ this.isPasteInProgress = false;
260
+ return;
261
+ }
262
+ var originalInteractionMode = this.interactionMode;
263
+ if (this.options.allowCaretMode &&
264
+ originalInteractionMode !== interaction_mode_1.DateInputInteractionMode.Caret &&
265
+ !isDeleteKey && !isBackspaceKey) {
266
+ this.resetSegmentValue = true;
267
+ }
268
+ if (this.options.allowCaretMode) {
269
+ this.interactionMode = interaction_mode_1.DateInputInteractionMode.Caret;
270
+ }
271
+ else {
272
+ this.interactionMode = interaction_mode_1.DateInputInteractionMode.Selection;
273
+ }
274
+ var hasCaret = this.isInCaretMode();
275
+ if (hasCaret && this.keyDownEvent.key === key_1.Key.SPACE) {
276
+ // do not allow custom "holes" in the date segments
277
+ this.setPreviousInputEventState(this.keyDownEvent);
278
+ return;
279
+ }
280
+ var oldDateObjectValue = this.dateObject && this.dateObject.getValue();
281
+ var _a = this.dateObject.getTextAndFormat(), currentText = _a.text, currentFormat = _a.format;
282
+ this.currentFormat = currentFormat;
283
+ var text = hasCaret && (isBackspaceKey || isDeleteKey) ? this.previousElementValue : currentText;
284
+ var diff = utils_1.approximateStringMatching({
285
+ oldText: text,
286
+ newText: this.element.value,
287
+ formatPattern: this.currentFormat,
288
+ selectionStart: this.selection.start,
289
+ isInCaretMode: hasCaret,
290
+ keyEvent: this.keyDownEvent
291
+ });
292
+ if (hasCaret && (!diff || diff.length === 0)) {
293
+ this.setPreviousInputEventState(this.keyDownEvent);
294
+ return;
295
+ }
296
+ else if (hasCaret && diff.length === 1) {
297
+ if (!diff[0] || !diff[0][0]) {
298
+ this.setPreviousInputEventState(this.keyDownEvent);
299
+ return;
300
+ }
301
+ else if (hasCaret && diff[0] &&
302
+ (diff[0][0] === constants_1.Constants.formatSeparator || diff[0][1] === constants_1.Constants.formatSeparator)) {
303
+ this.setPreviousInputEventState(this.keyDownEvent);
304
+ return;
305
+ }
306
+ }
307
+ var navigationOnly = (diff.length === 1 && diff[0][1] === constants_1.Constants.formatSeparator);
308
+ var parsePartsResults = [];
309
+ var switchPart = false;
310
+ if (!navigationOnly) {
311
+ for (var i = 0; i < diff.length; i++) {
312
+ var parsePartResult = this.dateObject.parsePart({
313
+ symbol: diff[i][0],
314
+ currentChar: diff[i][1],
315
+ resetSegmentValue: this.resetSegmentValue,
316
+ cycleSegmentValue: !this.isInCaretMode(),
317
+ rawTextValue: this.element.value,
318
+ isDeleting: isBackspaceKey || isDeleteKey
319
+ });
320
+ parsePartsResults.push(parsePartResult);
321
+ switchPart = parsePartResult.switchToNext;
322
+ }
323
+ }
324
+ if (!this.options.autoSwitchParts) {
325
+ switchPart = false;
326
+ }
327
+ this.resetSegmentValue = false;
328
+ var lastParseResult = parsePartsResults[parsePartsResults.length - 1];
329
+ var lastParseResultHasNoValue = lastParseResult && !lastParseResult.value;
330
+ var parsingFailedOnDelete = (hasCaret && (isBackspaceKey || isDeleteKey) && lastParseResultHasNoValue);
331
+ var resetPart = lastParseResult ? lastParseResult.resetPart : false;
332
+ var hasDateValueChanged = !kendo_date_math_1.isEqual(oldDateObjectValue, this.dateObject.value);
333
+ var symbolForSelection;
334
+ var currentSelection = this.selection;
335
+ if (!hasCaret || parsingFailedOnDelete || resetPart) {
336
+ if (resetPart) {
337
+ symbolForSelection = this.currentFormat[currentSelection.start];
338
+ }
339
+ this.forceUpdate();
340
+ }
341
+ if (diff.length && diff[0][0] !== constants_1.Constants.formatSeparator) {
342
+ if (!hasCaret || parsingFailedOnDelete || resetPart) {
343
+ if (symbolForSelection) {
344
+ this.setSelection(this.selectionBySymbol(symbolForSelection));
345
+ }
346
+ else {
347
+ if (!this.options.autoSwitchParts && diff[0][1] === constants_1.Constants.formatSeparator) {
348
+ // do not change the selection when a separator is pressed
349
+ // this should happen only if autoSwitchKeys contains the separator explicitly
350
+ }
351
+ else {
352
+ this.setSelection(this.selectionBySymbol(diff[0][0]));
353
+ }
354
+ }
355
+ }
356
+ }
357
+ if (!switchPart && hasCaret && !isBackspaceKey && !isDeleteKey && !resetPart && lastParseResultHasNoValue) {
358
+ if (hasDateValueChanged) {
359
+ if (this.currentFormat.length === this.elementValue.length) {
360
+ // if a full date is entered, do not reset it
361
+ }
362
+ else {
363
+ // the input is not complete, not parsable or not updatable
364
+ if (hasCaret && originalInteractionMode !== interaction_mode_1.DateInputInteractionMode.Caret && hasDateValueChanged) {
365
+ }
366
+ else if (hasCaret && originalInteractionMode !== interaction_mode_1.DateInputInteractionMode.Caret) {
367
+ symbolForSelection = this.currentFormat[currentSelection.start];
368
+ this.forceUpdate();
369
+ this.setSelection(this.selectionBySymbol(symbolForSelection));
370
+ }
371
+ else {
372
+ this.setPreviousInputEventState(this.keyDownEvent);
373
+ }
374
+ }
375
+ }
376
+ }
377
+ else if (this.options.autoSwitchParts && (switchPart || navigationOnly)) {
378
+ if (!hasCaret) {
379
+ this.switchDateSegment(1);
380
+ }
381
+ }
382
+ this.tryTriggerValueChange({
383
+ oldValue: oldDateObjectValue,
384
+ event: e
385
+ });
386
+ this.triggerInputEnd({ event: e });
387
+ };
388
+ /**
389
+ * @hidden
390
+ */
391
+ DateInput.prototype.onElementFocus = function (e) {
392
+ if (this.triggerFocus({ event: e })) {
393
+ return;
394
+ }
395
+ this.isActive = true;
396
+ this.interactionMode = interaction_mode_1.DateInputInteractionMode.None;
397
+ this.refreshElementValue();
398
+ if (!this.mouseDownStarted) {
399
+ this.caret(0, this.elementValue.length);
400
+ }
401
+ this.mouseDownStarted = false;
402
+ this.triggerFocusEnd({ event: e });
403
+ };
404
+ /**
405
+ * @hidden
406
+ */
407
+ DateInput.prototype.onElementBlur = function (e) {
408
+ this.resetSegmentValue = true;
409
+ this.isActive = false;
410
+ if (this.triggerBlur({ event: e })) {
411
+ return;
412
+ }
413
+ this.interactionMode = interaction_mode_1.DateInputInteractionMode.None;
414
+ this.refreshElementValue();
415
+ this.triggerBlurEnd({ event: e });
416
+ };
417
+ /**
418
+ * @hidden
419
+ */
420
+ DateInput.prototype.onElementChange = function (e) {
421
+ this.triggerChange({ event: e });
422
+ };
423
+ /**
424
+ * @hidden
425
+ */
426
+ DateInput.prototype.onElementKeyDown = function (e) {
427
+ if (this.triggerKeyDown({ event: e })) {
428
+ return;
429
+ }
430
+ this.keyDownEvent = e;
431
+ this.previousElementValue = this.element.value;
432
+ var autoSwitchKeys = (this.options.autoSwitchKeys || [])
433
+ .map(function (x) { return x.toString().toLowerCase().trim(); });
434
+ if (autoSwitchKeys.indexOf(e.keyCode.toString()) >= 0 ||
435
+ autoSwitchKeys.indexOf(e.keyCode) >= 0 ||
436
+ autoSwitchKeys.indexOf(e.key.toLowerCase().trim()) >= 0) {
437
+ var isTabKey = autoSwitchKeys.indexOf(key_1.Key.TAB.toLowerCase().trim()) >= 0 ||
438
+ autoSwitchKeys.indexOf(keycode_1.KeyCode.TAB) >= 0 ||
439
+ autoSwitchKeys.indexOf(keycode_1.KeyCode.TAB.toString()) >= 0;
440
+ if (isTabKey) {
441
+ var _a = this.selection, selectionStart = _a.start, selectionEnd = _a.end;
442
+ if (e.shiftKey && isTabKey) {
443
+ this.switchDateSegment(-1);
444
+ }
445
+ else {
446
+ this.switchDateSegment(1);
447
+ }
448
+ if (selectionStart !== this.selection.start || selectionEnd !== this.selection.end) {
449
+ // when the selection changes, prevent the default Tab behavior
450
+ e.preventDefault();
451
+ return;
452
+ }
453
+ }
454
+ else {
455
+ // do not allow the "input" event to be triggered
456
+ e.preventDefault();
457
+ this.switchDateSegment(1);
458
+ return;
459
+ }
460
+ }
461
+ var symbol = this.currentFormat[this.selection.start];
462
+ var step = this.getStepFromSymbol(symbol);
463
+ var shouldPreventDefault = false;
464
+ if (e.altKey || e.ctrlKey || e.metaKey || e.keyCode === keycode_1.KeyCode.TAB) {
465
+ return;
466
+ }
467
+ switch (e.keyCode) {
468
+ case keycode_1.KeyCode.ARROW_LEFT:
469
+ this.switchDateSegment(-1);
470
+ shouldPreventDefault = true;
471
+ break;
472
+ case keycode_1.KeyCode.ARROW_UP:
473
+ this.modifyDateSegmentValue(step, symbol, event);
474
+ shouldPreventDefault = true;
475
+ break;
476
+ case keycode_1.KeyCode.ARROW_RIGHT:
477
+ this.switchDateSegment(1);
478
+ shouldPreventDefault = true;
479
+ break;
480
+ case keycode_1.KeyCode.ARROW_DOWN:
481
+ this.modifyDateSegmentValue(-step, symbol, event);
482
+ shouldPreventDefault = true;
483
+ break;
484
+ case keycode_1.KeyCode.ENTER:
485
+ // todo: handle "change" event
486
+ break;
487
+ case keycode_1.KeyCode.DELETE:
488
+ case keycode_1.KeyCode.BACKSPACE:
489
+ if (this.options.allowNulls) {
490
+ var oldValue = this.dateObject.value;
491
+ this.dateObject.setValue(null);
492
+ this.forceUpdate();
493
+ this.tryTriggerValueChange({
494
+ oldValue: oldValue,
495
+ event: e
496
+ });
497
+ }
498
+ shouldPreventDefault = true;
499
+ if (e.keyCode === keycode_1.KeyCode.BACKSPACE &&
500
+ ((this.options.autoSwitchKeys || []).indexOf(keycode_1.KeyCode.BACKSPACE) >= 0 ||
501
+ (this.options.autoSwitchKeys || []).indexOf(key_1.Key.BACKSPACE) >= 0)) {
502
+ this.switchDateSegment(-1);
503
+ }
504
+ return;
505
+ case key_1.Key.HOME:
506
+ this.selectNearestSegment(0);
507
+ break;
508
+ case key_1.Key.END:
509
+ this.selectNearestSegment(this.elementValue.length);
510
+ break;
511
+ default:
512
+ // allow the "input" event to handle the change
513
+ return;
514
+ }
515
+ if (shouldPreventDefault) {
516
+ e.preventDefault();
517
+ }
518
+ };
519
+ /**
520
+ * @hidden
521
+ */
522
+ DateInput.prototype.onElementPaste = function () {
523
+ this.isPasteInProgress = true;
524
+ };
525
+ /**
526
+ * @hidden
527
+ */
528
+ DateInput.prototype.onElementMouseWheel = function (e) {
529
+ if (!this.options.enableMouseWheel || this.triggerMouseWheel({ event: e })) {
530
+ return;
531
+ }
532
+ if (!this.isActive) {
533
+ return;
534
+ }
535
+ var event = e;
536
+ if (event.shiftKey) {
537
+ this.switchDateSegment((event.wheelDelta || -event.detail) > 0 ? -1 : 1);
538
+ }
539
+ else {
540
+ this.modifyDateSegmentValue((event.wheelDelta || -event.detail) > 0 ? 1 : -1);
541
+ }
542
+ event.returnValue = false;
543
+ if (event.preventDefault) {
544
+ event.preventDefault();
545
+ }
546
+ if (event.stopPropagation) {
547
+ event.stopPropagation();
548
+ }
549
+ };
550
+ DateInput.prototype.updateOnPaste = function (e) {
551
+ var value = this.intl.parseDate(this.elementValue, this.inputFormat) || this.value;
552
+ if (utils_2.isPresent(value) && this.dateObject.shouldNormalizeCentury()) {
553
+ value = this.dateObject.normalizeCentury(value);
554
+ }
555
+ var oldDateObjectValue = this.dateObject && this.dateObject.getValue();
556
+ this.writeValue(value);
557
+ this.tryTriggerValueChange({
558
+ oldValue: oldDateObjectValue,
559
+ event: e
560
+ });
561
+ };
562
+ Object.defineProperty(DateInput.prototype, "elementValue", {
563
+ get: function () {
564
+ return (this.element || {}).value || '';
565
+ },
566
+ enumerable: true,
567
+ configurable: true
568
+ });
569
+ Object.defineProperty(DateInput.prototype, "inputFormat", {
570
+ get: function () {
571
+ if (!this.options.format) {
572
+ return constants_1.Constants.defaultDateFormat;
573
+ }
574
+ if (typeof this.options.format === 'string') {
575
+ return this.options.format;
576
+ }
577
+ else {
578
+ return this.options.format.inputFormat;
579
+ }
580
+ },
581
+ enumerable: true,
582
+ configurable: true
583
+ });
584
+ Object.defineProperty(DateInput.prototype, "displayFormat", {
585
+ get: function () {
586
+ if (!this.options.format) {
587
+ return constants_1.Constants.defaultDateFormat;
588
+ }
589
+ if (typeof this.options.format === 'string') {
590
+ return this.options.format;
591
+ }
592
+ else {
593
+ return this.options.format.displayFormat;
594
+ }
595
+ },
596
+ enumerable: true,
597
+ configurable: true
598
+ });
599
+ Object.defineProperty(DateInput.prototype, "selection", {
600
+ get: function () {
601
+ var returnValue = { start: 0, end: 0 };
602
+ if (this.element !== null && this.element.selectionStart !== undefined) {
603
+ returnValue = {
604
+ start: this.element.selectionStart,
605
+ end: this.element.selectionEnd
606
+ };
607
+ }
608
+ return returnValue;
609
+ },
610
+ enumerable: true,
611
+ configurable: true
612
+ });
613
+ DateInput.prototype.setSelection = function (selection) {
614
+ // this._lastSelectedSymbol = this.currentFormat[selection.start];
615
+ if (this.element && document.activeElement === this.element) {
616
+ this.element.setSelectionRange(selection.start, selection.end);
617
+ }
618
+ };
619
+ /**
620
+ * @hidden
621
+ */
622
+ DateInput.prototype.selectionBySymbol = function (symbol) {
623
+ var start = -1;
624
+ var end = 0;
625
+ for (var i = 0; i < this.currentFormat.length; i++) {
626
+ if (this.currentFormat[i] === symbol) {
627
+ end = i + 1;
628
+ if (start === -1) {
629
+ start = i;
630
+ }
631
+ }
632
+ }
633
+ if (start < 0) {
634
+ start = 0;
635
+ }
636
+ return { start: start, end: end };
637
+ };
638
+ /**
639
+ * @hidden
640
+ */
641
+ DateInput.prototype.selectionByIndex = function (index) {
642
+ var selection = { start: index, end: index };
643
+ for (var i = index, j = index - 1; i < this.currentFormat.length || j >= 0; i++, j--) {
644
+ if (i < this.currentFormat.length && this.currentFormat[i] !== constants_1.Constants.formatSeparator) {
645
+ selection = this.selectionBySymbol(this.currentFormat[i]);
646
+ break;
647
+ }
648
+ if (j >= 0 && this.currentFormat[j] !== constants_1.Constants.formatSeparator) {
649
+ selection = this.selectionBySymbol(this.currentFormat[j]);
650
+ break;
651
+ }
652
+ }
653
+ return selection;
654
+ };
655
+ DateInput.prototype.switchDateSegment = function (offset) {
656
+ var selection = this.selection;
657
+ if (this.isInCaretMode()) {
658
+ var start = selection.start;
659
+ var closestNonSeparatorSymbol = this.currentFormat[start];
660
+ for (var i = start; i >= 0; i--) {
661
+ closestNonSeparatorSymbol = this.currentFormat[i];
662
+ if (closestNonSeparatorSymbol !== constants_1.Constants.formatSeparator) {
663
+ start = i;
664
+ break;
665
+ }
666
+ }
667
+ var symbol = void 0;
668
+ for (var i = start; i < this.currentFormat.length; i++) {
669
+ symbol = this.currentFormat[i];
670
+ if (symbol !== constants_1.Constants.formatSeparator) {
671
+ break;
672
+ }
673
+ }
674
+ if (symbol) {
675
+ this.forceUpdate();
676
+ this.setSelection(this.selectionBySymbol(symbol));
677
+ }
678
+ }
679
+ var _a = this.selection, selectionStart = _a.start, selectionEnd = _a.end;
680
+ if (selectionStart < selectionEnd &&
681
+ this.currentFormat[selectionStart] !== this.currentFormat[selectionEnd - 1]) {
682
+ this.setSelection(this.selectionByIndex(offset > 0 ? selectionStart : selectionEnd - 1));
683
+ this.resetSegmentValue = true;
684
+ return;
685
+ }
686
+ var previousFormatSymbol = this.currentFormat[selectionStart];
687
+ var a = selectionStart + offset;
688
+ while (a > 0 && a < this.currentFormat.length) {
689
+ if (this.currentFormat[a] !== previousFormatSymbol &&
690
+ this.currentFormat[a] !== constants_1.Constants.formatSeparator) {
691
+ break;
692
+ }
693
+ a += offset;
694
+ }
695
+ if (this.currentFormat[a] === constants_1.Constants.formatSeparator) {
696
+ // no known symbol is found
697
+ return;
698
+ }
699
+ var b = a;
700
+ while (b >= 0 && b < this.currentFormat.length) {
701
+ if (this.currentFormat[b] !== this.currentFormat[a]) {
702
+ break;
703
+ }
704
+ b += offset;
705
+ }
706
+ if (a > b && (b + 1 !== selectionStart || a + 1 !== selectionEnd)) {
707
+ this.setSelection({ start: b + 1, end: a + 1 });
708
+ this.resetSegmentValue = true;
709
+ }
710
+ else if (a < b && (a !== selectionStart || b !== selectionEnd)) {
711
+ this.setSelection({ start: a, end: b });
712
+ this.resetSegmentValue = true;
713
+ }
714
+ };
715
+ DateInput.prototype.modifyDateSegmentValue = function (offset, symbol, event) {
716
+ if (symbol === void 0) { symbol = ""; }
717
+ if (event === void 0) { event = {}; }
718
+ if (!this.dateObject) {
719
+ return;
720
+ }
721
+ var oldValue = this.value;
722
+ var step = DEFAULT_SEGMENT_STEP * offset;
723
+ var caret = this.caret();
724
+ symbol = symbol || this.currentFormat[caret[0]];
725
+ if (symbol === "S" && !this.options.steps.millisecond) {
726
+ var msDigits = utils_2.millisecondDigitsInFormat(this.inputFormat);
727
+ step = utils_2.millisecondStepFor(msDigits);
728
+ }
729
+ this.dateObject.modifyPart(symbol, step);
730
+ this.tryTriggerValueChange({
731
+ oldValue: oldValue,
732
+ event: event
733
+ });
734
+ this.forceUpdate();
735
+ this.setSelection(this.selectionBySymbol(symbol));
736
+ };
737
+ /**
738
+ * @hidden
739
+ */
740
+ DateInput.prototype.tryTriggerValueChange = function (args) {
741
+ if (args === void 0) { args = { oldValue: null, event: {} }; }
742
+ if (!kendo_date_math_1.isEqual(this.value, args.oldValue)) {
743
+ return this.triggerValueChange(args);
744
+ }
745
+ };
746
+ /**
747
+ * @hidden
748
+ */
749
+ DateInput.prototype.triggerValueChange = function (args) {
750
+ if (args === void 0) { args = { oldValue: null, event: {} }; }
751
+ return this.trigger(VALUE_CHANGE, utils_2.extend(args, {
752
+ value: this.value
753
+ }));
754
+ };
755
+ /**
756
+ * @hidden
757
+ */
758
+ DateInput.prototype.triggerInput = function (args) {
759
+ if (args === void 0) { args = { event: {} }; }
760
+ return this.trigger(INPUT, utils_2.extend(args, {
761
+ value: this.value
762
+ }));
763
+ };
764
+ /**
765
+ * @hidden
766
+ */
767
+ DateInput.prototype.triggerInputEnd = function (args) {
768
+ if (args === void 0) { args = { event: {} }; }
769
+ return this.trigger(INPUT_END, utils_2.extend(args, {
770
+ value: this.value
771
+ }));
772
+ };
773
+ /**
774
+ * @hidden
775
+ */
776
+ DateInput.prototype.triggerFocus = function (args) {
777
+ if (args === void 0) { args = { event: {} }; }
778
+ return this.trigger(FOCUS, utils_2.extend({}, args));
779
+ };
780
+ /**
781
+ * @hidden
782
+ */
783
+ DateInput.prototype.triggerFocusEnd = function (args) {
784
+ if (args === void 0) { args = { event: {} }; }
785
+ return this.trigger(FOCUS_END, utils_2.extend({}, args));
786
+ };
787
+ /**
788
+ * @hidden
789
+ */
790
+ DateInput.prototype.triggerBlur = function (args) {
791
+ if (args === void 0) { args = { event: {} }; }
792
+ return this.trigger(BLUR, utils_2.extend({}, args));
793
+ };
794
+ /**
795
+ * @hidden
796
+ */
797
+ DateInput.prototype.triggerBlurEnd = function (args) {
798
+ if (args === void 0) { args = { event: {} }; }
799
+ return this.trigger(BLUR_END, utils_2.extend({}, args));
800
+ };
801
+ /**
802
+ * @hidden
803
+ */
804
+ DateInput.prototype.triggerChange = function (args) {
805
+ if (args === void 0) { args = { event: {} }; }
806
+ return this.trigger(CHANGE, utils_2.extend(args, {
807
+ value: this.value
808
+ }));
809
+ };
810
+ /**
811
+ * @hidden
812
+ */
813
+ DateInput.prototype.triggerKeyDown = function (args) {
814
+ if (args === void 0) { args = { event: {} }; }
815
+ return this.trigger(KEY_DOWN, utils_2.extend({}, args));
816
+ };
817
+ /**
818
+ * @hidden
819
+ */
820
+ DateInput.prototype.triggerMouseWheel = function (args) {
821
+ if (args === void 0) { args = { event: {} }; }
822
+ return this.trigger(MOUSE_WHEEL, utils_2.extend({}, args));
823
+ };
824
+ /**
825
+ * @hidden
826
+ */
827
+ DateInput.prototype.forceUpdate = function () {
828
+ this.setTextAndFormat();
829
+ this.refreshElementValue();
830
+ };
831
+ /**
832
+ * @hidden
833
+ */
834
+ DateInput.prototype.setTextAndFormat = function () {
835
+ var _a = this.dateObject.getTextAndFormat(), currentText = _a.text, currentFormat = _a.format;
836
+ this.currentFormat = currentFormat;
837
+ this.currentText = currentText;
838
+ };
839
+ /**
840
+ * @hidden
841
+ */
842
+ DateInput.prototype.setElementValue = function (value) {
843
+ this.previousElementValue = this.element.value;
844
+ this.element.value = value;
845
+ };
846
+ /**
847
+ * @hidden
848
+ */
849
+ DateInput.prototype.getStepFromSymbol = function (symbol) {
850
+ /* eslint-disable no-fallthrough */
851
+ switch (symbol) {
852
+ case "S":
853
+ return Number(this.options.steps.millisecond);
854
+ case "s":
855
+ return Number(this.options.steps.second);
856
+ case "m":
857
+ return Number(this.options.steps.minute);
858
+ // represents hour as value from 01 through 12
859
+ case "h":
860
+ // represents hour as value from 01 through 23
861
+ case "H":
862
+ return Number(this.options.steps.hour);
863
+ case "M":
864
+ return Number(this.options.steps.month);
865
+ // there is no 'D' format specifier for day
866
+ case "d":
867
+ // used for formats such as "EEEE, MMMM d, yyyy",
868
+ // where "EEEE" stands for full name of the day e.g. Monday
869
+ case "E":
870
+ return Number(this.options.steps.day);
871
+ // there is no 'Y' format specifier for year
872
+ case "y":
873
+ return Number(this.options.steps.year);
874
+ default:
875
+ return DEFAULT_SEGMENT_STEP;
876
+ }
877
+ /* eslint-enable no-fallthrough */
878
+ };
879
+ DateInput.prototype.setPreviousInputEventState = function (keyDownEvent) {
880
+ var _a = this.selection, selectionStart = _a.start, selectionEnd = _a.end;
881
+ var selectionOffset = -1;
882
+ if (keyDownEvent.keyCode === keycode_1.KeyCode.BACKSPACE) {
883
+ selectionOffset = 1;
884
+ }
885
+ else if (keyDownEvent.keyCode === keycode_1.KeyCode.DELETE) {
886
+ selectionOffset = 0;
887
+ }
888
+ else if (keyDownEvent.keyCode === keycode_1.KeyCode.SPACE) {
889
+ selectionOffset = -1;
890
+ }
891
+ else {
892
+ selectionOffset = -1;
893
+ }
894
+ this.setElementValue(this.previousElementValue || '');
895
+ this.setSelection({ start: selectionStart + selectionOffset, end: selectionEnd + selectionOffset });
896
+ };
897
+ DateInput.prototype.writeValue = function (value) {
898
+ this.verifyValue(value);
899
+ this.dateObject = this.getDateObject(value);
900
+ this.refreshElementValue();
901
+ };
902
+ DateInput.prototype.verifyValue = function (value) {
903
+ if (value && !utils_2.isDate(value)) {
904
+ throw new Error("The 'value' should be a valid JavaScript Date instance.");
905
+ }
906
+ };
907
+ DateInput.prototype.refreshElementValue = function () {
908
+ var start = this.caret()[0];
909
+ var element = this.element;
910
+ var format = this.isActive ? this.inputFormat : this.displayFormat;
911
+ var _a = this.dateObject.getTextAndFormat(format), currentText = _a.text, currentFormat = _a.format;
912
+ this.currentFormat = currentFormat;
913
+ this.currentText = currentText;
914
+ var showPlaceholder = !this.isActive &&
915
+ utils_2.isPresent(this.options.placeholder) &&
916
+ !this.dateObject.hasValue();
917
+ if (utils_2.isPresent(this.options.placeholder)) {
918
+ element.placeholder = this.options.placeholder;
919
+ }
920
+ var newElementValue = !showPlaceholder ? currentText : "";
921
+ this.setElementValue(newElementValue);
922
+ if (this.isActive && !this.options.allowCaretMode && this.options.selectNearestSegmentOnFocus) {
923
+ this.selectNearestSegment(start);
924
+ }
925
+ };
926
+ /**
927
+ * @hidden
928
+ */
929
+ DateInput.prototype.caret = function (start, end) {
930
+ if (end === void 0) { end = start; }
931
+ var isPosition = start !== undefined;
932
+ var returnValue = [start, start];
933
+ var element = this.element;
934
+ if (isPosition && (this.options.disabled || this.options.readonly)) {
935
+ return undefined;
936
+ }
937
+ try {
938
+ if (element.selectionStart !== undefined) {
939
+ if (isPosition) {
940
+ if (utils_2.isDocumentAvailable() && document.activeElement !== element) {
941
+ element.focus();
942
+ }
943
+ element.setSelectionRange(start, end);
944
+ }
945
+ returnValue = [element.selectionStart, element.selectionEnd];
946
+ }
947
+ }
948
+ catch (e) {
949
+ returnValue = [];
950
+ }
951
+ return returnValue;
952
+ };
953
+ DateInput.prototype.selectNearestSegment = function (index) {
954
+ // Finds the nearest (in both directions) known part.
955
+ for (var i = index, j = index - 1; i < this.currentFormat.length || j >= 0; i++, j--) {
956
+ if (i < this.currentFormat.length && this.currentFormat[i] !== "_") {
957
+ this.selectDateSegment(this.currentFormat[i]);
958
+ return;
959
+ }
960
+ if (j >= 0 && this.currentFormat[j] !== "_") {
961
+ this.selectDateSegment(this.currentFormat[j]);
962
+ return;
963
+ }
964
+ }
965
+ };
966
+ DateInput.prototype.selectDateSegment = function (symbol) {
967
+ var begin = -1;
968
+ var end = 0;
969
+ for (var i = 0; i < this.currentFormat.length; i++) {
970
+ if (this.currentFormat[i] === symbol) {
971
+ end = i + 1;
972
+ if (begin === -1) {
973
+ begin = i;
974
+ }
975
+ }
976
+ }
977
+ if (begin < 0) {
978
+ begin = 0;
979
+ }
980
+ this.caret(0, 0);
981
+ this.caret(begin, end);
982
+ };
983
+ /**
984
+ * @hidden
985
+ */
986
+ DateInput.prototype.getDateObject = function (value) {
987
+ var leadingZero = ((this.dateObject || {}) || null).leadingZero;
988
+ var dateObject = this.createDateObject({
989
+ value: value
990
+ });
991
+ dateObject.setLeadingZero(this.isActive ? leadingZero : null);
992
+ return dateObject;
993
+ };
994
+ /* tslint:disable:align */
995
+ /**
996
+ * @hidden
997
+ */
998
+ DateInput.prototype.createDateObject = function (options) {
999
+ if (options === void 0) { options = {}; }
1000
+ var dateObject = new dateobject_1.DateObject(utils_2.extend({
1001
+ intlService: this.intl,
1002
+ formatPlaceholder: this.formatPlaceholder,
1003
+ format: this.inputFormat,
1004
+ localeId: this.localeId,
1005
+ cycleTime: this.options.cycleTime,
1006
+ twoDigitYearMax: this.options.twoDigitYearMax,
1007
+ autoCorrectParts: this.options.autoCorrectParts
1008
+ }, options));
1009
+ return dateObject;
1010
+ };
1011
+ return DateInput;
1012
+ }(observable_1.Observable));
1013
+ exports.DateInput = DateInput;