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

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.
@@ -28,7 +28,6 @@ const FOCUS_END = "focusEnd";
28
28
  const CHANGE = "change";
29
29
  const defaultDateInputOptions = {
30
30
  format: "d",
31
- allowNulls: false,
32
31
  hasPlaceholder: false,
33
32
  placeholder: null,
34
33
  cycleTime: true,
@@ -56,6 +55,7 @@ const defaultDateInputOptions = {
56
55
  [CHANGE]: null
57
56
  },
58
57
  selectNearestSegmentOnFocus: false,
58
+ selectPreviousSegmentOnBackspace: false,
59
59
  enableMouseWheel: false,
60
60
  allowCaretMode: false,
61
61
  autoSwitchParts: true,
@@ -202,6 +202,7 @@ export class DateInput extends Observable {
202
202
  */
203
203
  onElementClick(e) {
204
204
  this.mouseDownStarted = false;
205
+ this.switchedPartOnPreviousKeyAction = false;
205
206
  const selection = this.selection;
206
207
  if (this.isInCaretMode()) {
207
208
  // explicitly refresh the input element value
@@ -234,12 +235,10 @@ export class DateInput extends Observable {
234
235
  */
235
236
  onElementInput(e) {
236
237
  this.triggerInput({ event: e });
237
- const keyDownEvent = this.keyDownEvent || {};
238
- const isBackspaceKey = keyDownEvent.keyCode === KeyCode.BACKSPACE || keyDownEvent.key === Key.BACKSPACE;
239
- const isDeleteKey = keyDownEvent.keyCode === KeyCode.DELETE || keyDownEvent.key === Key.DELETE;
240
238
  if (!this.element || !this.dateObject) {
241
239
  return;
242
240
  }
241
+ const switchedPartOnPreviousKeyAction = this.switchedPartOnPreviousKeyAction;
243
242
  if (this.isPasteInProgress) {
244
243
  if (this.options.allowCaretMode) {
245
244
  // pasting should leave the input with caret
@@ -250,6 +249,9 @@ export class DateInput extends Observable {
250
249
  this.isPasteInProgress = false;
251
250
  return;
252
251
  }
252
+ const keyDownEvent = this.keyDownEvent || {};
253
+ const isBackspaceKey = keyDownEvent.keyCode === KeyCode.BACKSPACE || keyDownEvent.key === Key.BACKSPACE;
254
+ const isDeleteKey = keyDownEvent.keyCode === KeyCode.DELETE || keyDownEvent.key === Key.DELETE;
253
255
  const originalInteractionMode = this.interactionMode;
254
256
  if (this.options.allowCaretMode &&
255
257
  originalInteractionMode !== DateInputInteractionMode.Caret &&
@@ -268,50 +270,36 @@ export class DateInput extends Observable {
268
270
  this.restorePreviousInputEventState();
269
271
  return;
270
272
  }
271
- const oldDateObjectValue = this.dateObject && this.dateObject.getValue();
273
+ const oldExistingDateValue = this.dateObject && this.dateObject.getValue();
274
+ const oldDateValue = this.dateObject ? this.dateObject.value : null;
272
275
  const { text: currentText, format: currentFormat } = this.dateObject.getTextAndFormat();
273
276
  this.currentFormat = currentFormat;
274
- let text = "";
277
+ let oldText = "";
275
278
  if (hasCaret) {
276
279
  if (isBackspaceKey || isDeleteKey) {
277
- text = this.previousElementValue;
280
+ oldText = this.previousElementValue;
278
281
  }
279
282
  else if (originalInteractionMode === DateInputInteractionMode.Caret) {
280
- text = this.previousElementValue;
283
+ oldText = this.previousElementValue;
281
284
  }
282
285
  else {
283
- text = currentText;
286
+ oldText = currentText;
284
287
  }
285
288
  }
286
289
  else {
287
- text = currentText;
290
+ oldText = currentText;
288
291
  }
289
292
  const newText = this.elementValue;
290
293
  let diff = approximateStringMatching({
291
- oldText: text,
294
+ oldText: oldText,
292
295
  newText: newText,
293
296
  formatPattern: this.currentFormat,
294
297
  selectionStart: this.selection.start,
295
298
  isInCaretMode: hasCaret,
296
299
  keyEvent: this.keyDownEvent
297
300
  });
298
- const currentFormatChar = this.formatStateOnKeyDown.format[this.formatStateOnKeyDown.selectionStart] || "";
299
- if (this.options.allowCaretMode && hasCaret && this.currentFormat.length !== this.elementValue.length) {
300
- if (currentFormatChar &&
301
- currentFormatChar.length > 0 &&
302
- currentFormatChar !== Constants.formatSeparator) {
303
- if (!diff || diff.length === 0) {
304
- diff = [];
305
- diff[0][0] = currentFormatChar;
306
- diff[0][1] = e.data || "";
307
- }
308
- else if (diff[0] && diff[0][0] !== Constants.formatSeparator) {
309
- if (diff[0][0] !== currentFormatChar) {
310
- diff[0][0] = currentFormatChar;
311
- diff[0][1] = e.data || "";
312
- }
313
- }
314
- }
301
+ if (diff && diff.length && diff[0] && diff[0][1] !== Constants.formatSeparator) {
302
+ this.switchedPartOnPreviousKeyAction = false;
315
303
  }
316
304
  if (hasCaret && (!diff || diff.length === 0)) {
317
305
  this.restorePreviousInputEventState();
@@ -350,104 +338,128 @@ export class DateInput extends Observable {
350
338
  switchPart = false;
351
339
  }
352
340
  this.resetSegmentValue = false;
341
+ const hasFixedFormat = this.options.format === this.currentFormat ||
342
+ // all not fixed formats are 1 symbol, e.g. "d"
343
+ (isPresent(this.options.format) && this.options.format.length > 1);
353
344
  const lastParseResult = parsePartsResults[parsePartsResults.length - 1];
354
- const lastParseResultHasNoValue = lastParseResult && !lastParseResult.value;
345
+ const lastParseResultHasNoValue = lastParseResult && !isPresent(lastParseResult.value);
355
346
  const parsingFailedOnDelete = (hasCaret && (isBackspaceKey || isDeleteKey) && lastParseResultHasNoValue);
356
347
  const resetPart = lastParseResult ? lastParseResult.resetPart : false;
357
- const hasInvalidDatePart = lastParseResult ? lastParseResult.hasInvalidDatePart : false;
358
- const hasDateValueChanged = !isEqual(oldDateObjectValue, this.dateObject.value);
348
+ const newExistingDateValue = this.dateObject.getValue();
349
+ const hasExistingDateValueChanged = !isEqual(oldExistingDateValue, newExistingDateValue);
350
+ const newDateValue = this.dateObject.value;
359
351
  let symbolForSelection;
360
352
  const currentSelection = this.selection;
361
- if (!hasCaret || parsingFailedOnDelete || resetPart) {
362
- if (resetPart) {
363
- symbolForSelection = this.currentFormat[currentSelection.start];
364
- }
365
- this.forceUpdate();
366
- }
367
- if (diff.length && diff[0][0] !== Constants.formatSeparator) {
368
- if (!hasCaret || parsingFailedOnDelete || resetPart) {
369
- if (symbolForSelection) {
370
- this.setSelection(this.selectionBySymbol(symbolForSelection));
353
+ if (hasCaret) {
354
+ const diffChar = diff && diff.length > 0 ? diff[0][0] : null;
355
+ let hasLeadingZero = this.dateObject.getLeadingZero()[diffChar];
356
+ if (diff.length && diff[0][0] !== Constants.formatSeparator) {
357
+ if (switchPart) {
358
+ this.forceUpdateWithSelection();
359
+ this.switchDateSegment(1);
371
360
  }
372
- else {
373
- if (!this.options.autoSwitchParts && diff[0][1] === Constants.formatSeparator) {
374
- // do not change the selection when a separator is pressed
375
- // this should happen only if autoSwitchKeys contains the separator explicitly
361
+ else if (resetPart) {
362
+ symbolForSelection = this.currentFormat[currentSelection.start];
363
+ if (symbolForSelection) {
364
+ this.forceUpdate();
365
+ this.setSelection(this.selectionBySymbol(symbolForSelection));
376
366
  }
377
367
  else {
368
+ this.restorePreviousInputEventState();
369
+ }
370
+ }
371
+ else if (parsingFailedOnDelete) {
372
+ this.forceUpdate();
373
+ if (diff.length && diff[0][0] !== Constants.formatSeparator) {
378
374
  this.setSelection(this.selectionBySymbol(diff[0][0]));
379
375
  }
380
376
  }
381
- }
382
- else if (hasCaret) {
383
- if ((hasDateValueChanged && isPresent(this.dateObject.getValue()) ||
384
- (!hasDateValueChanged && switchPart && isPresent(this.dateObject.getValue())))) {
385
- if (switchPart) {
386
- this.switchDateSegment(1);
377
+ else if (lastParseResultHasNoValue) {
378
+ if (e.data === "0" && hasLeadingZero) {
379
+ // do not reset element value on a leading zero
380
+ // wait for consecutive input to determine the value
387
381
  }
388
- else {
389
- if (this.options.format.length !== this.currentFormat.length &&
390
- currentFormatChar && currentFormatChar !== "y") {
391
- const elementValueLength = this.elementValue.length;
392
- this.forceUpdate();
393
- const selectionOffset = this.elementValue.length - elementValueLength;
394
- this.setSelection({
395
- start: currentSelection.start + selectionOffset,
396
- end: currentSelection.start + selectionOffset
397
- });
398
- }
382
+ else if (isPresent(oldExistingDateValue) && !isPresent(newExistingDateValue)) {
383
+ this.restorePreviousInputEventState();
399
384
  }
400
- }
401
- else {
402
- if (lastParseResultHasNoValue) {
403
- let hasLeadingZero = this.dateObject.getLeadingZero()[currentFormatChar];
404
- if (switchPart) {
405
- this.switchDateSegment(1);
406
- }
407
- else if (e.data === "0" && hasLeadingZero) {
385
+ else if (!isPresent(oldExistingDateValue) && isPresent(newExistingDateValue)) {
386
+ this.forceUpdateWithSelection();
387
+ }
388
+ else if (isPresent(oldExistingDateValue) && isPresent(newExistingDateValue)) {
389
+ if (hasExistingDateValueChanged) {
390
+ this.forceUpdateWithSelection();
408
391
  }
409
392
  else {
410
393
  this.restorePreviousInputEventState();
411
394
  }
412
395
  }
413
- }
414
- }
415
- }
416
- if (!switchPart && hasCaret && !isBackspaceKey && !isDeleteKey && !resetPart && lastParseResultHasNoValue) {
417
- if (hasDateValueChanged) {
418
- if (this.currentFormat.length === this.elementValue.length) {
419
- // if a full date is entered, do not reset it
420
- }
421
- else {
422
- // the input is not complete, not parsable or not updatable
423
- if (originalInteractionMode !== DateInputInteractionMode.Caret && hasDateValueChanged) {
396
+ else if (!isPresent(oldExistingDateValue) && !isPresent(newExistingDateValue)) {
397
+ this.forceUpdateWithSelection();
424
398
  }
425
- else if (originalInteractionMode !== DateInputInteractionMode.Caret) {
426
- symbolForSelection = this.currentFormat[currentSelection.start];
427
- this.forceUpdate();
428
- this.setSelection(this.selectionBySymbol(symbolForSelection));
399
+ else if (oldDateValue !== newDateValue) {
400
+ // this can happen on auto correct when no valid value is parsed
429
401
  }
430
- else if (!hasInvalidDatePart) {
402
+ else {
431
403
  this.restorePreviousInputEventState();
432
404
  }
433
405
  }
406
+ else if (!lastParseResultHasNoValue) {
407
+ // the user types a valid but incomplete date (e.g. year "123" with format "yyyy")
408
+ // let them continue typing, but refresh for not fixed formats
409
+ if (!hasFixedFormat) {
410
+ this.forceUpdateWithSelection();
411
+ }
412
+ }
434
413
  }
435
414
  else {
436
- let hasLeadingZero = this.dateObject.getLeadingZero()[currentFormatChar];
437
- if (e.data === "0" && hasLeadingZero) {
415
+ if (!this.options.autoSwitchParts && diff[0][1] === Constants.formatSeparator) {
416
+ // do not change the selection when a separator is pressed
417
+ // this should happen only if autoSwitchKeys contains the separator explicitly
438
418
  }
439
- else if (!hasInvalidDatePart) {
440
- this.restorePreviousInputEventState();
419
+ else {
420
+ this.setSelection(this.selectionBySymbol(diff[0][0]));
441
421
  }
442
422
  }
443
423
  }
444
- else if (this.options.autoSwitchParts && (switchPart || navigationOnly)) {
445
- if (!hasCaret) {
446
- this.switchDateSegment(1);
424
+ else if (!hasCaret) {
425
+ this.forceUpdate();
426
+ if (diff.length && diff[0][0] !== Constants.formatSeparator) {
427
+ this.setSelection(this.selectionBySymbol(diff[0][0]));
428
+ }
429
+ if (this.options.autoSwitchParts) {
430
+ if (navigationOnly) {
431
+ this.resetSegmentValue = true;
432
+ if (!switchedPartOnPreviousKeyAction) {
433
+ this.switchDateSegment(1);
434
+ }
435
+ this.switchedPartOnPreviousKeyAction = true;
436
+ }
437
+ else if (switchPart) {
438
+ this.switchDateSegment(1);
439
+ this.switchedPartOnPreviousKeyAction = true;
440
+ }
441
+ }
442
+ else {
443
+ if (lastParseResult && lastParseResult.switchToNext) {
444
+ // the value is complete and should be switched, but the "autoSwitchParts" option prevents this
445
+ // ensure that the segment value can be reset on next input
446
+ this.resetSegmentValue = true;
447
+ }
448
+ else if (navigationOnly) {
449
+ this.resetSegmentValue = true;
450
+ if (!switchedPartOnPreviousKeyAction) {
451
+ this.switchDateSegment(1);
452
+ }
453
+ this.switchedPartOnPreviousKeyAction = true;
454
+ }
455
+ }
456
+ if (isBackspaceKey && this.options.selectPreviousSegmentOnBackspace) {
457
+ // kendo angular have this UX
458
+ this.switchDateSegment(-1);
447
459
  }
448
460
  }
449
461
  this.tryTriggerValueChange({
450
- oldValue: oldDateObjectValue,
462
+ oldValue: oldExistingDateValue,
451
463
  event: e
452
464
  });
453
465
  this.triggerInputEnd({ event: e });
@@ -467,6 +479,7 @@ export class DateInput extends Observable {
467
479
  }
468
480
  this.isActive = true;
469
481
  this.interactionMode = DateInputInteractionMode.None;
482
+ this.switchedPartOnPreviousKeyAction = false;
470
483
  this.refreshElementValue();
471
484
  if (!this.mouseDownStarted) {
472
485
  this.caret(0, this.elementValue.length);
@@ -484,6 +497,7 @@ export class DateInput extends Observable {
484
497
  return;
485
498
  }
486
499
  this.interactionMode = DateInputInteractionMode.None;
500
+ this.switchedPartOnPreviousKeyAction = false;
487
501
  this.refreshElementValue();
488
502
  this.triggerBlurEnd({ event: e });
489
503
  }
@@ -503,20 +517,9 @@ export class DateInput extends Observable {
503
517
  const { start, end } = this.selection;
504
518
  this.keyDownEvent = e;
505
519
  this.previousElementValue = this.element.value;
506
- this.formatStateOnKeyDown = {
507
- format: this.currentFormat,
508
- selectionStart: start,
509
- selectionEnd: end
510
- };
511
520
  this.previousElementSelection = { start, end };
512
- const autoSwitchKeys = (this.options.autoSwitchKeys || [])
513
- .map(x => x.toString().toLowerCase().trim());
514
- if (autoSwitchKeys.indexOf(e.keyCode.toString()) >= 0 ||
515
- autoSwitchKeys.indexOf(e.keyCode) >= 0 ||
516
- autoSwitchKeys.indexOf(e.key.toLowerCase().trim()) >= 0) {
517
- const isTabKey = autoSwitchKeys.indexOf(Key.TAB.toLowerCase().trim()) >= 0 ||
518
- autoSwitchKeys.indexOf(KeyCode.TAB) >= 0 ||
519
- autoSwitchKeys.indexOf(KeyCode.TAB.toString()) >= 0;
521
+ if (this.keyEventMatchesAutoSwitchKeys(e)) {
522
+ const isTabKey = e.KeyCode === KeyCode.TAB;
520
523
  if (isTabKey) {
521
524
  const { start: selectionStart, end: selectionEnd } = this.selection;
522
525
  if (e.shiftKey && isTabKey) {
@@ -548,45 +551,33 @@ export class DateInput extends Observable {
548
551
  case KeyCode.ARROW_LEFT:
549
552
  this.switchDateSegment(-1);
550
553
  shouldPreventDefault = true;
554
+ this.switchedPartOnPreviousKeyAction = false;
551
555
  break;
552
556
  case KeyCode.ARROW_UP:
553
557
  this.modifyDateSegmentValue(step, symbol, event);
554
558
  shouldPreventDefault = true;
559
+ this.switchedPartOnPreviousKeyAction = false;
555
560
  break;
556
561
  case KeyCode.ARROW_RIGHT:
557
562
  this.switchDateSegment(1);
558
563
  shouldPreventDefault = true;
564
+ this.switchedPartOnPreviousKeyAction = false;
559
565
  break;
560
566
  case KeyCode.ARROW_DOWN:
561
567
  this.modifyDateSegmentValue(-step, symbol, event);
562
568
  shouldPreventDefault = true;
569
+ this.switchedPartOnPreviousKeyAction = false;
563
570
  break;
564
571
  case KeyCode.ENTER:
565
572
  // todo: handle "change" event
566
573
  break;
567
- case KeyCode.DELETE:
568
- case KeyCode.BACKSPACE:
569
- if (this.options.allowNulls) {
570
- const oldValue = this.dateObject.value;
571
- this.dateObject.setValue(null);
572
- this.forceUpdate();
573
- this.tryTriggerValueChange({
574
- oldValue: oldValue,
575
- event: e
576
- });
577
- }
578
- shouldPreventDefault = true;
579
- if (e.keyCode === KeyCode.BACKSPACE &&
580
- ((this.options.autoSwitchKeys || []).indexOf(KeyCode.BACKSPACE) >= 0 ||
581
- (this.options.autoSwitchKeys || []).indexOf(Key.BACKSPACE) >= 0)) {
582
- this.switchDateSegment(-1);
583
- }
584
- return;
585
574
  case Key.HOME:
586
575
  this.selectNearestSegment(0);
576
+ this.switchedPartOnPreviousKeyAction = false;
587
577
  break;
588
578
  case Key.END:
589
579
  this.selectNearestSegment(this.elementValue.length);
580
+ this.switchedPartOnPreviousKeyAction = false;
590
581
  break;
591
582
  default:
592
583
  // allow the "input" event to handle the change
@@ -675,9 +666,11 @@ export class DateInput extends Observable {
675
666
  return returnValue;
676
667
  }
677
668
  setSelection(selection) {
678
- // this._lastSelectedSymbol = this.currentFormat[selection.start];
679
669
  if (this.element && document.activeElement === this.element) {
680
670
  this.element.setSelectionRange(selection.start, selection.end);
671
+ if (selection.start !== selection.end) {
672
+ this.interactionMode = DateInputInteractionMode.Selection;
673
+ }
681
674
  }
682
675
  }
683
676
  /**
@@ -728,8 +721,7 @@ export class DateInput extends Observable {
728
721
  const selection = this.selection;
729
722
  if (this.isInCaretMode()) {
730
723
  let start = selection.start;
731
- const currentSymbol = this.currentFormat[start - (this.elementValue.length - this.currentFormat.length)] ||
732
- this.currentFormat[start];
724
+ const currentSymbol = this.currentFormat[start - 1];
733
725
  let symbol = "";
734
726
  let symbolCandidate = "";
735
727
  if (offset < 0) {
@@ -903,6 +895,19 @@ export class DateInput extends Observable {
903
895
  this.setTextAndFormat();
904
896
  this.refreshElementValue();
905
897
  }
898
+ /**
899
+ * @hidden
900
+ */
901
+ forceUpdateWithSelection() {
902
+ const { start, end } = this.selection;
903
+ const elementValueLength = this.elementValue.length;
904
+ this.forceUpdate();
905
+ const selectionOffset = this.elementValue.length - elementValueLength;
906
+ this.setSelection({
907
+ start: start + selectionOffset,
908
+ end: end + selectionOffset
909
+ });
910
+ }
906
911
  /**
907
912
  * @hidden
908
913
  */
@@ -1084,4 +1089,18 @@ export class DateInput extends Observable {
1084
1089
  }, options));
1085
1090
  return dateObject;
1086
1091
  }
1092
+ /* tslint:enable:align */
1093
+ /**
1094
+ * @hidden
1095
+ */
1096
+ keyEventMatchesAutoSwitchKeys(keyObject) {
1097
+ const autoSwitchKeys = (this.options.autoSwitchKeys || [])
1098
+ .map(x => x.toString().toLowerCase().trim());
1099
+ if (autoSwitchKeys.indexOf(keyObject.keyCode.toString()) >= 0 ||
1100
+ autoSwitchKeys.indexOf(keyObject.keyCode) >= 0 ||
1101
+ autoSwitchKeys.indexOf(keyObject.key.toLowerCase().trim()) >= 0) {
1102
+ return true;
1103
+ }
1104
+ return false;
1105
+ }
1087
1106
  }
@@ -67,8 +67,8 @@ export const approximateStringMatching = ({ oldText, newText, formatPattern, sel
67
67
  return [[symbol, newSegmentText[selectionStart - 1]]];
68
68
  }
69
69
  /* Handle the entering of a space or a separator for navigating to the next item. */
70
- if ((!isInCaretMode && newSegmentText[newSegmentText.length - 1] === ' ') ||
71
- (!isInCaretMode && newSegmentText[newSegmentText.length - 1] === oldTextSeparator)) {
70
+ if ((newSegmentText[newSegmentText.length - 1] === ' ') ||
71
+ (newSegmentText[newSegmentText.length - 1] === oldTextSeparator)) {
72
72
  return [[formatPattern[selectionStart - 1], Constants.formatSeparator]];
73
73
  }
74
74
  /* Handle typing over a correctly selected part. */
@@ -533,7 +533,6 @@ var DateObject = /** @class */ (function () {
533
533
  * @hidden
534
534
  */
535
535
  DateObject.prototype.parsePart = function (_a) {
536
- var _b;
537
536
  var symbol = _a.symbol, currentChar = _a.currentChar, resetSegmentValue = _a.resetSegmentValue, cycleSegmentValue = _a.cycleSegmentValue, rawInputValue = _a.rawTextValue, isDeleting = _a.isDeleting, originalFormat = _a.originalFormat;
538
537
  var isInCaretMode = !cycleSegmentValue;
539
538
  var dateParts = this.dateFormatString(this.value, this.format);
@@ -578,7 +577,7 @@ var DateObject = /** @class */ (function () {
578
577
  .some(function (x) { return x.pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD; });
579
578
  var parseResult = {
580
579
  value: null,
581
- switchPart: false,
580
+ switchToNext: false,
582
581
  resetPart: shouldResetPart,
583
582
  hasInvalidDatePart: false
584
583
  };
@@ -601,8 +600,7 @@ var DateObject = /** @class */ (function () {
601
600
  this.resetLeadingZero();
602
601
  this.setExisting(symbol, false);
603
602
  this.resetInvalidDateSymbol(symbol);
604
- // return extend(parseResult, { value: null, switchToNext: false });
605
- return { value: null, switchToNext: false };
603
+ return utils_2.extend(parseResult, { value: null, switchToNext: false });
606
604
  }
607
605
  }
608
606
  var baseDate = this.intl.formatDate(this.value, this.format, this.localeId);
@@ -625,21 +623,13 @@ var DateObject = /** @class */ (function () {
625
623
  var datePartStartIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).indexOf(symbol);
626
624
  var datePartEndIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).lastIndexOf(symbol);
627
625
  var segmentLength = datePartEndIndex - datePartStartIndex + 1;
628
- var processedSegmentCharsCount = 0;
629
626
  var formatToTextLengthDiff = originalFormat.length - rawInputValue.length;
630
627
  if (isInCaretMode || (!isInCaretMode && !this.autoCorrectParts)) {
631
628
  for (var i = 0; i < baseDate.length; i++) {
632
629
  if (baseFormat[i] === symbol) {
633
630
  var existing = this.getExisting(symbol);
634
631
  current += existing ? baseDate[i] : '0';
635
- if (isDeleting) {
636
- // when deleting, process (segmentLength - 1) chars
637
- if (processedSegmentCharsCount < segmentLength - 1) {
638
- datePartText += rawInputValue[i] || "";
639
- }
640
- processedSegmentCharsCount++;
641
- }
642
- else if (formatToTextLengthDiff > 0) {
632
+ if (formatToTextLengthDiff > 0) {
643
633
  if (datePartText.length + formatToTextLengthDiff < segmentLength) {
644
634
  datePartText += rawInputValue[i] || "";
645
635
  }
@@ -663,18 +653,13 @@ var DateObject = /** @class */ (function () {
663
653
  datePartText += currentChar;
664
654
  }
665
655
  else if (!isDeleting && originalFormat.length > rawInputValue.length) {
666
- var lengthDiff = originalFormat.length - rawInputValue.length;
667
- var trimmedDatePartText = datePartText.substr(0, datePartText.length - lengthDiff);
668
- if (trimmedDatePartText && trimmedDatePartText.length > 0) {
669
- datePartText = trimmedDatePartText;
670
- }
656
+ // let the parsing to determine if the incomplete value is valid
671
657
  }
672
658
  if (datePartText.length > segmentLength) {
673
659
  return utils_2.extend(parseResult, { value: null, switchToNext: false });
674
660
  }
675
661
  }
676
662
  if (!hasFixedFormat || (hasFixedFormat && !this.autoCorrectParts)) {
677
- processedSegmentCharsCount = 0;
678
663
  current = "";
679
664
  datePartText = "";
680
665
  prefix = "";
@@ -684,14 +669,7 @@ var DateObject = /** @class */ (function () {
684
669
  if (originalFormat[i] === symbol) {
685
670
  var existing = this.getExisting(symbol);
686
671
  current += existing ? baseDate[i] || "" : '0';
687
- if (isDeleting) {
688
- // when deleting, process (segmentLength - 1) chars
689
- if (processedSegmentCharsCount < segmentLength - 1) {
690
- datePartText += rawInputValue[i] || "";
691
- }
692
- processedSegmentCharsCount++;
693
- }
694
- else if (formatToTextLengthDiff > 0) {
672
+ if (formatToTextLengthDiff > 0) {
695
673
  if (datePartText.length + formatToTextLengthDiff < segmentLength) {
696
674
  datePartText += rawInputValue[i] || "";
697
675
  }
@@ -715,7 +693,6 @@ var DateObject = /** @class */ (function () {
715
693
  }
716
694
  if (!isInCaretMode) {
717
695
  if (this.autoCorrectParts) {
718
- processedSegmentCharsCount = 0;
719
696
  current = "";
720
697
  datePartText = "";
721
698
  prefix = "";
@@ -760,6 +737,7 @@ var DateObject = /** @class */ (function () {
760
737
  }
761
738
  var partPattern = this.partPattern(dateParts.partMap, symbol);
762
739
  var patternValue = partPattern ? partPattern.pattern : null;
740
+ var patternLength = this.patternLength(patternValue) || patternValue.length;
763
741
  if (isInCaretMode) {
764
742
  if (isDeleting && !datePartText) {
765
743
  this.setExisting(symbol, false);
@@ -781,11 +759,13 @@ var DateObject = /** @class */ (function () {
781
759
  if (isInCaretMode || !this.autoCorrectParts) {
782
760
  tryParse = false;
783
761
  middle = utils_1.unpadZero(middle);
784
- middle = utils_1.padZero(segmentLength - middle.length) + middle;
762
+ // middle = padZero(segmentLength - middle.length) + middle;
763
+ middle = utils_1.padZero(patternLength - middle.length) + middle;
785
764
  }
786
765
  var middleNumber = parseInt(middle, 10);
787
766
  var candidateDateString = prefix + middle + suffix;
788
767
  parsedDate = this.intl.parseDate(candidateDateString, this.format, this.localeId);
768
+ var autoCorrectedPrefixAndSuffix = false;
789
769
  if (isInCaretMode && !utils_2.isValidDate(parsedDate)) {
790
770
  // if part of the date is not available, e.g. "d"
791
771
  // but an expanded format like "F" is used
@@ -796,6 +776,7 @@ var DateObject = /** @class */ (function () {
796
776
  // as "EEEE, February..." is not parsable
797
777
  if (this.autoCorrectParts) {
798
778
  parsedDate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
779
+ autoCorrectedPrefixAndSuffix = true;
799
780
  }
800
781
  }
801
782
  var isCurrentCharParsable = !isNaN(parseInt(currentChar, 10)) || (isInCaretMode && isDeleting && currentChar === "");
@@ -822,10 +803,22 @@ var DateObject = /** @class */ (function () {
822
803
  if ((isInCaretMode && utils_2.isValidDate(parsedDate)) || (!isInCaretMode && parsedDate)) {
823
804
  // move to next segment if the part will overflow with next char
824
805
  // when start from empty date (01, then 010), padded zeros should be trimmed
825
- var peekValue = this.peek(middle, patternValue);
826
- var peekDateString = "" + prefix + peekValue + suffix;
827
- var peekDate = this.intl.parseDate(peekDateString, this.format, this.localeId);
828
- var switchToNext = peekDate === null || (leadingZero[symbol] && patternValue.length <= middle.length) || false;
806
+ var peekedValue = this.peek(middle, patternValue);
807
+ var peekedDateString = autoCorrectedPrefixAndSuffix ?
808
+ "" + basePrefix + peekedValue + baseSuffix :
809
+ "" + prefix + peekedValue + suffix;
810
+ var peekedDate = this.intl.parseDate(peekedDateString, this.format, this.localeId);
811
+ var leadingZeroOffset = (this.leadingZero || {})[symbol] || 0;
812
+ var patternSatisfied = (leadingZeroOffset + utils_1.unpadZero(middle).length) >= patternLength;
813
+ var switchToNext = peekedDate === null ||
814
+ (leadingZero[symbol] ?
815
+ patternValue.length <= middle.length :
816
+ patternSatisfied);
817
+ // console.log("peeek: " + peekedDate);
818
+ // console.log("lead : " + (leadingZero[symbol] && patternValue.length <= middle.length ));
819
+ // console.log("pat s: " + patternSatisfied);
820
+ // console.log("middl: " + middle);
821
+ // console.log("pater: " + patternValue);
829
822
  if (this.shouldNormalizeCentury()) {
830
823
  parsedDate = this.normalizeCentury(parsedDate);
831
824
  }
@@ -851,24 +844,6 @@ var DateObject = /** @class */ (function () {
851
844
  this.markDatePartsAsExisting();
852
845
  }
853
846
  }
854
- if (isInCaretMode && switchToNext) {
855
- if (symbol === "M") {
856
- var datePartValue = utils_2.parseToInt(datePartText);
857
- if (datePartValue >= 2 || datePartText.length >= 2) {
858
- switchToNext = true;
859
- }
860
- else {
861
- switchToNext = false;
862
- }
863
- }
864
- else {
865
- switchToNext = switchToNext ?
866
- hasFixedFormat ?
867
- datePartText.length === segmentLength :
868
- datePartText.length > segmentLength :
869
- switchToNext;
870
- }
871
- }
872
847
  return utils_2.extend(parseResult, { value: this.value, switchToNext: switchToNext });
873
848
  }
874
849
  }
@@ -888,7 +863,6 @@ var DateObject = /** @class */ (function () {
888
863
  }
889
864
  }
890
865
  if (isZeroCurrentChar) {
891
- this.leadingZero = !this.isAbbrMonth(dateParts.partMap, symbol) ? (_b = {}, _b[symbol] = true, _b) : null;
892
866
  this.setExisting(symbol, false);
893
867
  }
894
868
  if (!this.autoCorrectParts) {