@progress/kendo-dateinputs-common 0.2.0-dev.202301231327 → 0.2.0-dev.202301260838

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.
@@ -30,7 +30,6 @@ var FOCUS_END = "focusEnd";
30
30
  var CHANGE = "change";
31
31
  var defaultDateInputOptions = {
32
32
  format: "d",
33
- allowNulls: false,
34
33
  hasPlaceholder: false,
35
34
  placeholder: null,
36
35
  cycleTime: true,
@@ -58,6 +57,7 @@ var defaultDateInputOptions = {
58
57
  _a[CHANGE] = null,
59
58
  _a),
60
59
  selectNearestSegmentOnFocus: false,
60
+ selectPreviousSegmentOnBackspace: false,
61
61
  enableMouseWheel: false,
62
62
  allowCaretMode: false,
63
63
  autoSwitchParts: true,
@@ -211,6 +211,7 @@ var DateInput = /** @class */ (function (_super) {
211
211
  */
212
212
  DateInput.prototype.onElementClick = function (e) {
213
213
  this.mouseDownStarted = false;
214
+ this.switchedPartOnPreviousKeyAction = false;
214
215
  var selection = this.selection;
215
216
  if (this.isInCaretMode()) {
216
217
  // explicitly refresh the input element value
@@ -243,12 +244,10 @@ var DateInput = /** @class */ (function (_super) {
243
244
  */
244
245
  DateInput.prototype.onElementInput = function (e) {
245
246
  this.triggerInput({ event: e });
246
- var keyDownEvent = this.keyDownEvent || {};
247
- var isBackspaceKey = keyDownEvent.keyCode === KeyCode.BACKSPACE || keyDownEvent.key === Key.BACKSPACE;
248
- var isDeleteKey = keyDownEvent.keyCode === KeyCode.DELETE || keyDownEvent.key === Key.DELETE;
249
247
  if (!this.element || !this.dateObject) {
250
248
  return;
251
249
  }
250
+ var switchedPartOnPreviousKeyAction = this.switchedPartOnPreviousKeyAction;
252
251
  if (this.isPasteInProgress) {
253
252
  if (this.options.allowCaretMode) {
254
253
  // pasting should leave the input with caret
@@ -259,6 +258,9 @@ var DateInput = /** @class */ (function (_super) {
259
258
  this.isPasteInProgress = false;
260
259
  return;
261
260
  }
261
+ var keyDownEvent = this.keyDownEvent || {};
262
+ var isBackspaceKey = keyDownEvent.keyCode === KeyCode.BACKSPACE || keyDownEvent.key === Key.BACKSPACE;
263
+ var isDeleteKey = keyDownEvent.keyCode === KeyCode.DELETE || keyDownEvent.key === Key.DELETE;
262
264
  var originalInteractionMode = this.interactionMode;
263
265
  if (this.options.allowCaretMode &&
264
266
  originalInteractionMode !== DateInputInteractionMode.Caret &&
@@ -277,50 +279,36 @@ var DateInput = /** @class */ (function (_super) {
277
279
  this.restorePreviousInputEventState();
278
280
  return;
279
281
  }
280
- var oldDateObjectValue = this.dateObject && this.dateObject.getValue();
282
+ var oldExistingDateValue = this.dateObject && this.dateObject.getValue();
283
+ var oldDateValue = this.dateObject ? this.dateObject.value : null;
281
284
  var _a = this.dateObject.getTextAndFormat(), currentText = _a.text, currentFormat = _a.format;
282
285
  this.currentFormat = currentFormat;
283
- var text = "";
286
+ var oldText = "";
284
287
  if (hasCaret) {
285
288
  if (isBackspaceKey || isDeleteKey) {
286
- text = this.previousElementValue;
289
+ oldText = this.previousElementValue;
287
290
  }
288
291
  else if (originalInteractionMode === DateInputInteractionMode.Caret) {
289
- text = this.previousElementValue;
292
+ oldText = this.previousElementValue;
290
293
  }
291
294
  else {
292
- text = currentText;
295
+ oldText = currentText;
293
296
  }
294
297
  }
295
298
  else {
296
- text = currentText;
299
+ oldText = currentText;
297
300
  }
298
301
  var newText = this.elementValue;
299
302
  var diff = approximateStringMatching({
300
- oldText: text,
303
+ oldText: oldText,
301
304
  newText: newText,
302
305
  formatPattern: this.currentFormat,
303
306
  selectionStart: this.selection.start,
304
307
  isInCaretMode: hasCaret,
305
308
  keyEvent: this.keyDownEvent
306
309
  });
307
- var currentFormatChar = this.formatStateOnKeyDown.format[this.formatStateOnKeyDown.selectionStart] || "";
308
- if (this.options.allowCaretMode && hasCaret && this.currentFormat.length !== this.elementValue.length) {
309
- if (currentFormatChar &&
310
- currentFormatChar.length > 0 &&
311
- currentFormatChar !== Constants.formatSeparator) {
312
- if (!diff || diff.length === 0) {
313
- diff = [];
314
- diff[0][0] = currentFormatChar;
315
- diff[0][1] = e.data || "";
316
- }
317
- else if (diff[0] && diff[0][0] !== Constants.formatSeparator) {
318
- if (diff[0][0] !== currentFormatChar) {
319
- diff[0][0] = currentFormatChar;
320
- diff[0][1] = e.data || "";
321
- }
322
- }
323
- }
310
+ if (diff && diff.length && diff[0] && diff[0][1] !== Constants.formatSeparator) {
311
+ this.switchedPartOnPreviousKeyAction = false;
324
312
  }
325
313
  if (hasCaret && (!diff || diff.length === 0)) {
326
314
  this.restorePreviousInputEventState();
@@ -359,104 +347,128 @@ var DateInput = /** @class */ (function (_super) {
359
347
  switchPart = false;
360
348
  }
361
349
  this.resetSegmentValue = false;
350
+ var hasFixedFormat = this.options.format === this.currentFormat ||
351
+ // all not fixed formats are 1 symbol, e.g. "d"
352
+ (isPresent(this.options.format) && this.options.format.length > 1);
362
353
  var lastParseResult = parsePartsResults[parsePartsResults.length - 1];
363
- var lastParseResultHasNoValue = lastParseResult && !lastParseResult.value;
354
+ var lastParseResultHasNoValue = lastParseResult && !isPresent(lastParseResult.value);
364
355
  var parsingFailedOnDelete = (hasCaret && (isBackspaceKey || isDeleteKey) && lastParseResultHasNoValue);
365
356
  var resetPart = lastParseResult ? lastParseResult.resetPart : false;
366
- var hasInvalidDatePart = lastParseResult ? lastParseResult.hasInvalidDatePart : false;
367
- var hasDateValueChanged = !isEqual(oldDateObjectValue, this.dateObject.value);
357
+ var newExistingDateValue = this.dateObject.getValue();
358
+ var hasExistingDateValueChanged = !isEqual(oldExistingDateValue, newExistingDateValue);
359
+ var newDateValue = this.dateObject.value;
368
360
  var symbolForSelection;
369
361
  var currentSelection = this.selection;
370
- if (!hasCaret || parsingFailedOnDelete || resetPart) {
371
- if (resetPart) {
372
- symbolForSelection = this.currentFormat[currentSelection.start];
373
- }
374
- this.forceUpdate();
375
- }
376
- if (diff.length && diff[0][0] !== Constants.formatSeparator) {
377
- if (!hasCaret || parsingFailedOnDelete || resetPart) {
378
- if (symbolForSelection) {
379
- this.setSelection(this.selectionBySymbol(symbolForSelection));
362
+ if (hasCaret) {
363
+ var diffChar = diff && diff.length > 0 ? diff[0][0] : null;
364
+ var hasLeadingZero = this.dateObject.getLeadingZero()[diffChar];
365
+ if (diff.length && diff[0][0] !== Constants.formatSeparator) {
366
+ if (switchPart) {
367
+ this.forceUpdateWithSelection();
368
+ this.switchDateSegment(1);
380
369
  }
381
- else {
382
- if (!this.options.autoSwitchParts && diff[0][1] === Constants.formatSeparator) {
383
- // do not change the selection when a separator is pressed
384
- // this should happen only if autoSwitchKeys contains the separator explicitly
370
+ else if (resetPart) {
371
+ symbolForSelection = this.currentFormat[currentSelection.start];
372
+ if (symbolForSelection) {
373
+ this.forceUpdate();
374
+ this.setSelection(this.selectionBySymbol(symbolForSelection));
385
375
  }
386
376
  else {
377
+ this.restorePreviousInputEventState();
378
+ }
379
+ }
380
+ else if (parsingFailedOnDelete) {
381
+ this.forceUpdate();
382
+ if (diff.length && diff[0][0] !== Constants.formatSeparator) {
387
383
  this.setSelection(this.selectionBySymbol(diff[0][0]));
388
384
  }
389
385
  }
390
- }
391
- else if (hasCaret) {
392
- if ((hasDateValueChanged && isPresent(this.dateObject.getValue()) ||
393
- (!hasDateValueChanged && switchPart && isPresent(this.dateObject.getValue())))) {
394
- if (switchPart) {
395
- this.switchDateSegment(1);
386
+ else if (lastParseResultHasNoValue) {
387
+ if (e.data === "0" && hasLeadingZero) {
388
+ // do not reset element value on a leading zero
389
+ // wait for consecutive input to determine the value
396
390
  }
397
- else {
398
- if (this.options.format.length !== this.currentFormat.length &&
399
- currentFormatChar && currentFormatChar !== "y") {
400
- var elementValueLength = this.elementValue.length;
401
- this.forceUpdate();
402
- var selectionOffset = this.elementValue.length - elementValueLength;
403
- this.setSelection({
404
- start: currentSelection.start + selectionOffset,
405
- end: currentSelection.start + selectionOffset
406
- });
407
- }
391
+ else if (isPresent(oldExistingDateValue) && !isPresent(newExistingDateValue)) {
392
+ this.restorePreviousInputEventState();
408
393
  }
409
- }
410
- else {
411
- if (lastParseResultHasNoValue) {
412
- var hasLeadingZero = this.dateObject.getLeadingZero()[currentFormatChar];
413
- if (switchPart) {
414
- this.switchDateSegment(1);
415
- }
416
- else if (e.data === "0" && hasLeadingZero) {
394
+ else if (!isPresent(oldExistingDateValue) && isPresent(newExistingDateValue)) {
395
+ this.forceUpdateWithSelection();
396
+ }
397
+ else if (isPresent(oldExistingDateValue) && isPresent(newExistingDateValue)) {
398
+ if (hasExistingDateValueChanged) {
399
+ this.forceUpdateWithSelection();
417
400
  }
418
401
  else {
419
402
  this.restorePreviousInputEventState();
420
403
  }
421
404
  }
422
- }
423
- }
424
- }
425
- if (!switchPart && hasCaret && !isBackspaceKey && !isDeleteKey && !resetPart && lastParseResultHasNoValue) {
426
- if (hasDateValueChanged) {
427
- if (this.currentFormat.length === this.elementValue.length) {
428
- // if a full date is entered, do not reset it
429
- }
430
- else {
431
- // the input is not complete, not parsable or not updatable
432
- if (originalInteractionMode !== DateInputInteractionMode.Caret && hasDateValueChanged) {
405
+ else if (!isPresent(oldExistingDateValue) && !isPresent(newExistingDateValue)) {
406
+ this.forceUpdateWithSelection();
433
407
  }
434
- else if (originalInteractionMode !== DateInputInteractionMode.Caret) {
435
- symbolForSelection = this.currentFormat[currentSelection.start];
436
- this.forceUpdate();
437
- this.setSelection(this.selectionBySymbol(symbolForSelection));
408
+ else if (oldDateValue !== newDateValue) {
409
+ // this can happen on auto correct when no valid value is parsed
438
410
  }
439
- else if (!hasInvalidDatePart) {
411
+ else {
440
412
  this.restorePreviousInputEventState();
441
413
  }
442
414
  }
415
+ else if (!lastParseResultHasNoValue) {
416
+ // the user types a valid but incomplete date (e.g. year "123" with format "yyyy")
417
+ // let them continue typing, but refresh for not fixed formats
418
+ if (!hasFixedFormat) {
419
+ this.forceUpdateWithSelection();
420
+ }
421
+ }
443
422
  }
444
423
  else {
445
- var hasLeadingZero = this.dateObject.getLeadingZero()[currentFormatChar];
446
- if (e.data === "0" && hasLeadingZero) {
424
+ if (!this.options.autoSwitchParts && diff[0][1] === Constants.formatSeparator) {
425
+ // do not change the selection when a separator is pressed
426
+ // this should happen only if autoSwitchKeys contains the separator explicitly
447
427
  }
448
- else if (!hasInvalidDatePart) {
449
- this.restorePreviousInputEventState();
428
+ else {
429
+ this.setSelection(this.selectionBySymbol(diff[0][0]));
450
430
  }
451
431
  }
452
432
  }
453
- else if (this.options.autoSwitchParts && (switchPart || navigationOnly)) {
454
- if (!hasCaret) {
455
- this.switchDateSegment(1);
433
+ else if (!hasCaret) {
434
+ this.forceUpdate();
435
+ if (diff.length && diff[0][0] !== Constants.formatSeparator) {
436
+ this.setSelection(this.selectionBySymbol(diff[0][0]));
437
+ }
438
+ if (this.options.autoSwitchParts) {
439
+ if (navigationOnly) {
440
+ this.resetSegmentValue = true;
441
+ if (!switchedPartOnPreviousKeyAction) {
442
+ this.switchDateSegment(1);
443
+ }
444
+ this.switchedPartOnPreviousKeyAction = true;
445
+ }
446
+ else if (switchPart) {
447
+ this.switchDateSegment(1);
448
+ this.switchedPartOnPreviousKeyAction = true;
449
+ }
450
+ }
451
+ else {
452
+ if (lastParseResult && lastParseResult.switchToNext) {
453
+ // the value is complete and should be switched, but the "autoSwitchParts" option prevents this
454
+ // ensure that the segment value can be reset on next input
455
+ this.resetSegmentValue = true;
456
+ }
457
+ else if (navigationOnly) {
458
+ this.resetSegmentValue = true;
459
+ if (!switchedPartOnPreviousKeyAction) {
460
+ this.switchDateSegment(1);
461
+ }
462
+ this.switchedPartOnPreviousKeyAction = true;
463
+ }
464
+ }
465
+ if (isBackspaceKey && this.options.selectPreviousSegmentOnBackspace) {
466
+ // kendo angular have this UX
467
+ this.switchDateSegment(-1);
456
468
  }
457
469
  }
458
470
  this.tryTriggerValueChange({
459
- oldValue: oldDateObjectValue,
471
+ oldValue: oldExistingDateValue,
460
472
  event: e
461
473
  });
462
474
  this.triggerInputEnd({ event: e });
@@ -476,6 +488,7 @@ var DateInput = /** @class */ (function (_super) {
476
488
  }
477
489
  this.isActive = true;
478
490
  this.interactionMode = DateInputInteractionMode.None;
491
+ this.switchedPartOnPreviousKeyAction = false;
479
492
  this.refreshElementValue();
480
493
  if (!this.mouseDownStarted) {
481
494
  this.caret(0, this.elementValue.length);
@@ -493,6 +506,7 @@ var DateInput = /** @class */ (function (_super) {
493
506
  return;
494
507
  }
495
508
  this.interactionMode = DateInputInteractionMode.None;
509
+ this.switchedPartOnPreviousKeyAction = false;
496
510
  this.refreshElementValue();
497
511
  this.triggerBlurEnd({ event: e });
498
512
  };
@@ -512,20 +526,9 @@ var DateInput = /** @class */ (function (_super) {
512
526
  var _a = this.selection, start = _a.start, end = _a.end;
513
527
  this.keyDownEvent = e;
514
528
  this.previousElementValue = this.element.value;
515
- this.formatStateOnKeyDown = {
516
- format: this.currentFormat,
517
- selectionStart: start,
518
- selectionEnd: end
519
- };
520
529
  this.previousElementSelection = { start: start, end: end };
521
- var autoSwitchKeys = (this.options.autoSwitchKeys || [])
522
- .map(function (x) { return x.toString().toLowerCase().trim(); });
523
- if (autoSwitchKeys.indexOf(e.keyCode.toString()) >= 0 ||
524
- autoSwitchKeys.indexOf(e.keyCode) >= 0 ||
525
- autoSwitchKeys.indexOf(e.key.toLowerCase().trim()) >= 0) {
526
- var isTabKey = autoSwitchKeys.indexOf(Key.TAB.toLowerCase().trim()) >= 0 ||
527
- autoSwitchKeys.indexOf(KeyCode.TAB) >= 0 ||
528
- autoSwitchKeys.indexOf(KeyCode.TAB.toString()) >= 0;
530
+ if (this.keyEventMatchesAutoSwitchKeys(e)) {
531
+ var isTabKey = e.KeyCode === KeyCode.TAB;
529
532
  if (isTabKey) {
530
533
  var _b = this.selection, selectionStart = _b.start, selectionEnd = _b.end;
531
534
  if (e.shiftKey && isTabKey) {
@@ -557,45 +560,33 @@ var DateInput = /** @class */ (function (_super) {
557
560
  case KeyCode.ARROW_LEFT:
558
561
  this.switchDateSegment(-1);
559
562
  shouldPreventDefault = true;
563
+ this.switchedPartOnPreviousKeyAction = false;
560
564
  break;
561
565
  case KeyCode.ARROW_UP:
562
566
  this.modifyDateSegmentValue(step, symbol, event);
563
567
  shouldPreventDefault = true;
568
+ this.switchedPartOnPreviousKeyAction = false;
564
569
  break;
565
570
  case KeyCode.ARROW_RIGHT:
566
571
  this.switchDateSegment(1);
567
572
  shouldPreventDefault = true;
573
+ this.switchedPartOnPreviousKeyAction = false;
568
574
  break;
569
575
  case KeyCode.ARROW_DOWN:
570
576
  this.modifyDateSegmentValue(-step, symbol, event);
571
577
  shouldPreventDefault = true;
578
+ this.switchedPartOnPreviousKeyAction = false;
572
579
  break;
573
580
  case KeyCode.ENTER:
574
581
  // todo: handle "change" event
575
582
  break;
576
- case KeyCode.DELETE:
577
- case KeyCode.BACKSPACE:
578
- if (this.options.allowNulls) {
579
- var oldValue = this.dateObject.value;
580
- this.dateObject.setValue(null);
581
- this.forceUpdate();
582
- this.tryTriggerValueChange({
583
- oldValue: oldValue,
584
- event: e
585
- });
586
- }
587
- shouldPreventDefault = true;
588
- if (e.keyCode === KeyCode.BACKSPACE &&
589
- ((this.options.autoSwitchKeys || []).indexOf(KeyCode.BACKSPACE) >= 0 ||
590
- (this.options.autoSwitchKeys || []).indexOf(Key.BACKSPACE) >= 0)) {
591
- this.switchDateSegment(-1);
592
- }
593
- return;
594
583
  case Key.HOME:
595
584
  this.selectNearestSegment(0);
585
+ this.switchedPartOnPreviousKeyAction = false;
596
586
  break;
597
587
  case Key.END:
598
588
  this.selectNearestSegment(this.elementValue.length);
589
+ this.switchedPartOnPreviousKeyAction = false;
599
590
  break;
600
591
  default:
601
592
  // allow the "input" event to handle the change
@@ -700,9 +691,11 @@ var DateInput = /** @class */ (function (_super) {
700
691
  configurable: true
701
692
  });
702
693
  DateInput.prototype.setSelection = function (selection) {
703
- // this._lastSelectedSymbol = this.currentFormat[selection.start];
704
694
  if (this.element && document.activeElement === this.element) {
705
695
  this.element.setSelectionRange(selection.start, selection.end);
696
+ if (selection.start !== selection.end) {
697
+ this.interactionMode = DateInputInteractionMode.Selection;
698
+ }
706
699
  }
707
700
  };
708
701
  /**
@@ -753,8 +746,7 @@ var DateInput = /** @class */ (function (_super) {
753
746
  var selection = this.selection;
754
747
  if (this.isInCaretMode()) {
755
748
  var start = selection.start;
756
- var currentSymbol = this.currentFormat[start - (this.elementValue.length - this.currentFormat.length)] ||
757
- this.currentFormat[start];
749
+ var currentSymbol = this.currentFormat[start - 1];
758
750
  var symbol = "";
759
751
  var symbolCandidate = "";
760
752
  if (offset < 0) {
@@ -941,6 +933,19 @@ var DateInput = /** @class */ (function (_super) {
941
933
  this.setTextAndFormat();
942
934
  this.refreshElementValue();
943
935
  };
936
+ /**
937
+ * @hidden
938
+ */
939
+ DateInput.prototype.forceUpdateWithSelection = function () {
940
+ var _a = this.selection, start = _a.start, end = _a.end;
941
+ var elementValueLength = this.elementValue.length;
942
+ this.forceUpdate();
943
+ var selectionOffset = this.elementValue.length - elementValueLength;
944
+ this.setSelection({
945
+ start: start + selectionOffset,
946
+ end: end + selectionOffset
947
+ });
948
+ };
944
949
  /**
945
950
  * @hidden
946
951
  */
@@ -1124,6 +1129,20 @@ var DateInput = /** @class */ (function (_super) {
1124
1129
  }, options));
1125
1130
  return dateObject;
1126
1131
  };
1132
+ /* tslint:enable:align */
1133
+ /**
1134
+ * @hidden
1135
+ */
1136
+ DateInput.prototype.keyEventMatchesAutoSwitchKeys = function (keyObject) {
1137
+ var autoSwitchKeys = (this.options.autoSwitchKeys || [])
1138
+ .map(function (x) { return x.toString().toLowerCase().trim(); });
1139
+ if (autoSwitchKeys.indexOf(keyObject.keyCode.toString()) >= 0 ||
1140
+ autoSwitchKeys.indexOf(keyObject.keyCode) >= 0 ||
1141
+ autoSwitchKeys.indexOf(keyObject.key.toLowerCase().trim()) >= 0) {
1142
+ return true;
1143
+ }
1144
+ return false;
1145
+ };
1127
1146
  return DateInput;
1128
1147
  }(Observable));
1129
1148
  export { DateInput };
@@ -68,8 +68,8 @@ export var approximateStringMatching = function (_a) {
68
68
  return [[symbol, newSegmentText[selectionStart - 1]]];
69
69
  }
70
70
  /* Handle the entering of a space or a separator for navigating to the next item. */
71
- if ((!isInCaretMode && newSegmentText[newSegmentText.length - 1] === ' ') ||
72
- (!isInCaretMode && newSegmentText[newSegmentText.length - 1] === oldTextSeparator)) {
71
+ if ((newSegmentText[newSegmentText.length - 1] === ' ') ||
72
+ (newSegmentText[newSegmentText.length - 1] === oldTextSeparator)) {
73
73
  return [[formatPattern[selectionStart - 1], Constants.formatSeparator]];
74
74
  }
75
75
  /* Handle typing over a correctly selected part. */
@@ -561,7 +561,7 @@ export class DateObject {
561
561
  .some(x => x.pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD);
562
562
  let parseResult = {
563
563
  value: null,
564
- switchPart: false,
564
+ switchToNext: false,
565
565
  resetPart: shouldResetPart,
566
566
  hasInvalidDatePart: false
567
567
  };
@@ -584,8 +584,7 @@ export class DateObject {
584
584
  this.resetLeadingZero();
585
585
  this.setExisting(symbol, false);
586
586
  this.resetInvalidDateSymbol(symbol);
587
- // return extend(parseResult, { value: null, switchToNext: false });
588
- return { value: null, switchToNext: false };
587
+ return extend(parseResult, { value: null, switchToNext: false });
589
588
  }
590
589
  }
591
590
  const baseDate = this.intl.formatDate(this.value, this.format, this.localeId);
@@ -608,21 +607,13 @@ export class DateObject {
608
607
  const datePartStartIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).indexOf(symbol);
609
608
  const datePartEndIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).lastIndexOf(symbol);
610
609
  const segmentLength = datePartEndIndex - datePartStartIndex + 1;
611
- let processedSegmentCharsCount = 0;
612
610
  let formatToTextLengthDiff = originalFormat.length - rawInputValue.length;
613
611
  if (isInCaretMode || (!isInCaretMode && !this.autoCorrectParts)) {
614
612
  for (let i = 0; i < baseDate.length; i++) {
615
613
  if (baseFormat[i] === symbol) {
616
614
  const existing = this.getExisting(symbol);
617
615
  current += existing ? baseDate[i] : '0';
618
- if (isDeleting) {
619
- // when deleting, process (segmentLength - 1) chars
620
- if (processedSegmentCharsCount < segmentLength - 1) {
621
- datePartText += rawInputValue[i] || "";
622
- }
623
- processedSegmentCharsCount++;
624
- }
625
- else if (formatToTextLengthDiff > 0) {
616
+ if (formatToTextLengthDiff > 0) {
626
617
  if (datePartText.length + formatToTextLengthDiff < segmentLength) {
627
618
  datePartText += rawInputValue[i] || "";
628
619
  }
@@ -646,18 +637,13 @@ export class DateObject {
646
637
  datePartText += currentChar;
647
638
  }
648
639
  else if (!isDeleting && originalFormat.length > rawInputValue.length) {
649
- const lengthDiff = originalFormat.length - rawInputValue.length;
650
- const trimmedDatePartText = datePartText.substr(0, datePartText.length - lengthDiff);
651
- if (trimmedDatePartText && trimmedDatePartText.length > 0) {
652
- datePartText = trimmedDatePartText;
653
- }
640
+ // let the parsing to determine if the incomplete value is valid
654
641
  }
655
642
  if (datePartText.length > segmentLength) {
656
643
  return extend(parseResult, { value: null, switchToNext: false });
657
644
  }
658
645
  }
659
646
  if (!hasFixedFormat || (hasFixedFormat && !this.autoCorrectParts)) {
660
- processedSegmentCharsCount = 0;
661
647
  current = "";
662
648
  datePartText = "";
663
649
  prefix = "";
@@ -667,14 +653,7 @@ export class DateObject {
667
653
  if (originalFormat[i] === symbol) {
668
654
  const existing = this.getExisting(symbol);
669
655
  current += existing ? baseDate[i] || "" : '0';
670
- if (isDeleting) {
671
- // when deleting, process (segmentLength - 1) chars
672
- if (processedSegmentCharsCount < segmentLength - 1) {
673
- datePartText += rawInputValue[i] || "";
674
- }
675
- processedSegmentCharsCount++;
676
- }
677
- else if (formatToTextLengthDiff > 0) {
656
+ if (formatToTextLengthDiff > 0) {
678
657
  if (datePartText.length + formatToTextLengthDiff < segmentLength) {
679
658
  datePartText += rawInputValue[i] || "";
680
659
  }
@@ -698,7 +677,6 @@ export class DateObject {
698
677
  }
699
678
  if (!isInCaretMode) {
700
679
  if (this.autoCorrectParts) {
701
- processedSegmentCharsCount = 0;
702
680
  current = "";
703
681
  datePartText = "";
704
682
  prefix = "";
@@ -743,6 +721,7 @@ export class DateObject {
743
721
  }
744
722
  const partPattern = this.partPattern(dateParts.partMap, symbol);
745
723
  const patternValue = partPattern ? partPattern.pattern : null;
724
+ const patternLength = this.patternLength(patternValue) || patternValue.length;
746
725
  if (isInCaretMode) {
747
726
  if (isDeleting && !datePartText) {
748
727
  this.setExisting(symbol, false);
@@ -764,11 +743,13 @@ export class DateObject {
764
743
  if (isInCaretMode || !this.autoCorrectParts) {
765
744
  tryParse = false;
766
745
  middle = unpadZero(middle);
767
- middle = padZero(segmentLength - middle.length) + middle;
746
+ // middle = padZero(segmentLength - middle.length) + middle;
747
+ middle = padZero(patternLength - middle.length) + middle;
768
748
  }
769
749
  let middleNumber = parseInt(middle, 10);
770
750
  const candidateDateString = prefix + middle + suffix;
771
751
  parsedDate = this.intl.parseDate(candidateDateString, this.format, this.localeId);
752
+ let autoCorrectedPrefixAndSuffix = false;
772
753
  if (isInCaretMode && !isValidDate(parsedDate)) {
773
754
  // if part of the date is not available, e.g. "d"
774
755
  // but an expanded format like "F" is used
@@ -779,6 +760,7 @@ export class DateObject {
779
760
  // as "EEEE, February..." is not parsable
780
761
  if (this.autoCorrectParts) {
781
762
  parsedDate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
763
+ autoCorrectedPrefixAndSuffix = true;
782
764
  }
783
765
  }
784
766
  const isCurrentCharParsable = !isNaN(parseInt(currentChar, 10)) || (isInCaretMode && isDeleting && currentChar === "");
@@ -805,10 +787,22 @@ export class DateObject {
805
787
  if ((isInCaretMode && isValidDate(parsedDate)) || (!isInCaretMode && parsedDate)) {
806
788
  // move to next segment if the part will overflow with next char
807
789
  // when start from empty date (01, then 010), padded zeros should be trimmed
808
- const peekValue = this.peek(middle, patternValue);
809
- const peekDateString = `${prefix}${peekValue}${suffix}`;
810
- const peekDate = this.intl.parseDate(peekDateString, this.format, this.localeId);
811
- let switchToNext = peekDate === null || (leadingZero[symbol] && patternValue.length <= middle.length) || false;
790
+ const peekedValue = this.peek(middle, patternValue);
791
+ const peekedDateString = autoCorrectedPrefixAndSuffix ?
792
+ `${basePrefix}${peekedValue}${baseSuffix}` :
793
+ `${prefix}${peekedValue}${suffix}`;
794
+ const peekedDate = this.intl.parseDate(peekedDateString, this.format, this.localeId);
795
+ const leadingZeroOffset = (this.leadingZero || {})[symbol] || 0;
796
+ const patternSatisfied = (leadingZeroOffset + unpadZero(middle).length) >= patternLength;
797
+ let switchToNext = peekedDate === null ||
798
+ (leadingZero[symbol] ?
799
+ patternValue.length <= middle.length :
800
+ patternSatisfied);
801
+ // console.log("peeek: " + peekedDate);
802
+ // console.log("lead : " + (leadingZero[symbol] && patternValue.length <= middle.length ));
803
+ // console.log("pat s: " + patternSatisfied);
804
+ // console.log("middl: " + middle);
805
+ // console.log("pater: " + patternValue);
812
806
  if (this.shouldNormalizeCentury()) {
813
807
  parsedDate = this.normalizeCentury(parsedDate);
814
808
  }
@@ -834,24 +828,6 @@ export class DateObject {
834
828
  this.markDatePartsAsExisting();
835
829
  }
836
830
  }
837
- if (isInCaretMode && switchToNext) {
838
- if (symbol === "M") {
839
- const datePartValue = parseToInt(datePartText);
840
- if (datePartValue >= 2 || datePartText.length >= 2) {
841
- switchToNext = true;
842
- }
843
- else {
844
- switchToNext = false;
845
- }
846
- }
847
- else {
848
- switchToNext = switchToNext ?
849
- hasFixedFormat ?
850
- datePartText.length === segmentLength :
851
- datePartText.length > segmentLength :
852
- switchToNext;
853
- }
854
- }
855
831
  return extend(parseResult, { value: this.value, switchToNext: switchToNext });
856
832
  }
857
833
  }
@@ -871,7 +847,6 @@ export class DateObject {
871
847
  }
872
848
  }
873
849
  if (isZeroCurrentChar) {
874
- this.leadingZero = !this.isAbbrMonth(dateParts.partMap, symbol) ? { [symbol]: true } : null;
875
850
  this.setExisting(symbol, false);
876
851
  }
877
852
  if (!this.autoCorrectParts) {