@globalpayments/vega 2.28.0 → 2.28.1

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 (33) hide show
  1. package/dist/cjs/{string-input-formatter-slimmer-fcfa5bb7.js → string-input-formatter-slimmer-79272527.js} +8 -13
  2. package/dist/cjs/vega-calendar_3.cjs.entry.js +30 -4
  3. package/dist/cjs/vega-date-picker_2.cjs.entry.js +1 -1
  4. package/dist/cjs/vega-env-manager-23b8b23c.js +2 -2
  5. package/dist/cjs/vega-input.cjs.entry.js +2 -3
  6. package/dist/collection/components/vega-calendar/slimmers/common/helpers/repeat-pattern/calendar-event-daily-repeat-pattern.js +7 -1
  7. package/dist/collection/components/vega-calendar/slimmers/common/helpers/repeat-pattern/calendar-event-monthly-repeat-pattern.js +7 -1
  8. package/dist/collection/components/vega-calendar/slimmers/common/helpers/repeat-pattern/calendar-event-weekly-repeat-pattern.js +9 -1
  9. package/dist/collection/components/vega-calendar/slimmers/common/helpers/repeat-pattern/calendar-event-yearly-repeat-pattern.js +7 -1
  10. package/dist/collection/components/vega-calendar/slimmers/common/helpers/test/calendar-event-repeat-pattern-factory.test.js +56 -0
  11. package/dist/collection/helpers/formatter/string-formatter/number-thousand-comma-strategy.js +1 -2
  12. package/dist/collection/helpers/formatter/test/string-formatter/number-thousand-comma-mask-strategy.test.js +8 -0
  13. package/dist/collection/helpers/slimmers/string-input-formatter-slimmer.js +8 -13
  14. package/dist/collection/helpers/slimmers/test/string-input-formatter-slimmer.test.js +32 -20
  15. package/dist/collection/utils/spec-utils.js +28 -0
  16. package/dist/collection/utils/test-utils.js +21 -0
  17. package/dist/esm/{string-input-formatter-slimmer-bfe3f5e5.js → string-input-formatter-slimmer-fc23bc9f.js} +8 -13
  18. package/dist/esm/vega-calendar_3.entry.js +30 -4
  19. package/dist/esm/vega-date-picker_2.entry.js +1 -1
  20. package/dist/esm/vega-env-manager-8f8dc473.js +2 -2
  21. package/dist/esm/vega-input.entry.js +2 -3
  22. package/dist/types/utils/spec-utils.d.ts +8 -0
  23. package/dist/types/utils/test-utils.d.ts +10 -0
  24. package/dist/vega/{p-1b901368.entry.js → p-128fbe13.entry.js} +1 -1
  25. package/dist/vega/p-5f377954.js +1 -1
  26. package/dist/vega/p-8843226a.entry.js +1 -0
  27. package/dist/vega/p-a10074a8.entry.js +1 -0
  28. package/dist/vega/p-a46329bb.js +1 -0
  29. package/dist/vega/vega.esm.js +1 -1
  30. package/package.json +1 -1
  31. package/dist/vega/p-a19ae233.entry.js +0 -1
  32. package/dist/vega/p-db120a1e.js +0 -1
  33. package/dist/vega/p-e0410974.entry.js +0 -1
@@ -220,7 +220,10 @@ class StringInputFormatterSlimmer extends globalSlimmerRegistry.VegaSlimmer {
220
220
  const rawValue = target.value;
221
221
  const caretPosition = target.selectionStart; // selectionStart is nullable, link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectionstart
222
222
  if (this.inputFormatStrategy) {
223
- const maskedValue = this.inputFormatStrategy.format(rawValue, caretPosition);
223
+ const maskedValue = this.inputFormatStrategy.format(rawValue,
224
+ // Paste input is difference with type input, it can set much characters at one time,
225
+ // so we should make caretPosition as undefined to format all value.
226
+ e.inputType === 'insertFromPaste' ? null : caretPosition);
224
227
  this.updateInputValue(rawValue, maskedValue);
225
228
  this.updateInputCaretPosition(rawValue, caretPosition);
226
229
  }
@@ -231,12 +234,8 @@ class StringInputFormatterSlimmer extends globalSlimmerRegistry.VegaSlimmer {
231
234
  * @param {ClipboardEvent} e - paste event
232
235
  */
233
236
  this.onPaste = (e) => {
234
- var _a;
235
- e.preventDefault();
236
- const rawValue = ((_a = e.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text')) || '';
237
- if (this.inputFormatStrategy) {
238
- const maskedValue = this.inputFormatStrategy.format(rawValue);
239
- this.updateInputValue(rawValue, maskedValue);
237
+ if (this.disableCopyPaste) {
238
+ e.preventDefault();
240
239
  }
241
240
  };
242
241
  }
@@ -253,9 +252,7 @@ class StringInputFormatterSlimmer extends globalSlimmerRegistry.VegaSlimmer {
253
252
  this.onInit();
254
253
  if (this.inputFormatStrategy) {
255
254
  this.inputElement.addEventListener('input', this.onKeyDown, { capture: true });
256
- if (!this.disableCopyPaste) {
257
- this.inputElement.addEventListener('paste', this.onPaste, { capture: true });
258
- }
255
+ this.inputElement.addEventListener('paste', this.onPaste, { capture: true });
259
256
  }
260
257
  if (this.blurFormatStrategy) {
261
258
  this.inputElement.addEventListener('blur', this.onBlur, { capture: true });
@@ -270,9 +267,7 @@ class StringInputFormatterSlimmer extends globalSlimmerRegistry.VegaSlimmer {
270
267
  if (this.inputElement) {
271
268
  if (this.inputFormatStrategy) {
272
269
  this.inputElement.removeEventListener('input', this.onKeyDown, { capture: true });
273
- if (!this.disableCopyPaste) {
274
- this.inputElement.removeEventListener('paste', this.onPaste, { capture: true });
275
- }
270
+ this.inputElement.removeEventListener('paste', this.onPaste, { capture: true });
276
271
  }
277
272
  if (this.blurFormatStrategy) {
278
273
  this.inputElement.removeEventListener('blur', this.onBlur, { capture: true });
@@ -1690,7 +1690,13 @@ class CalendarEventDailyRepeatPattern extends CalendarEventBaseRepeatPattern {
1690
1690
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
1691
1691
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
1692
1692
  while (nextMatchDate && nextMatchDate.toDate() < endDate.toDate()) {
1693
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1693
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1694
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
1695
+ if (newNextMatchDate && newNextMatchDate.toDate() <= nextMatchDate.toDate()) {
1696
+ this.cache.pop();
1697
+ break;
1698
+ }
1699
+ nextMatchDate = newNextMatchDate;
1694
1700
  if (typeof this.count === 'number' && this.cache.length >= this.count) {
1695
1701
  break;
1696
1702
  }
@@ -1762,7 +1768,13 @@ class CalendarEventMonthlyRepeatPattern extends CalendarEventBaseRepeatPattern {
1762
1768
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
1763
1769
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
1764
1770
  while (nextMatchDate && nextMatchDate.toDate() < endDate.toDate()) {
1765
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1771
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1772
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
1773
+ if (newNextMatchDate && newNextMatchDate.toDate() <= nextMatchDate.toDate()) {
1774
+ this.cache.pop();
1775
+ break;
1776
+ }
1777
+ nextMatchDate = newNextMatchDate;
1766
1778
  if (typeof this.count === 'number' && this.cache.length >= this.count) {
1767
1779
  break;
1768
1780
  }
@@ -1866,7 +1878,15 @@ class CalendarEventWeeklyRepeatPattern extends CalendarEventBaseRepeatPattern {
1866
1878
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
1867
1879
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
1868
1880
  while (nextMatchDate && nextMatchDate[0].toDate() < endDate.toDate()) {
1869
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1881
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1882
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
1883
+ if (newNextMatchDate &&
1884
+ newNextMatchDate[0] &&
1885
+ newNextMatchDate[0].toDate() <= nextMatchDate[0].toDate()) {
1886
+ this.cache.pop();
1887
+ break;
1888
+ }
1889
+ nextMatchDate = newNextMatchDate;
1870
1890
  if (typeof this.count === 'number' && this.getValidCache().length >= this.count) {
1871
1891
  break;
1872
1892
  }
@@ -2013,7 +2033,13 @@ class CalendarEventYearlyRepeatPattern extends CalendarEventBaseRepeatPattern {
2013
2033
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
2014
2034
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
2015
2035
  while (nextMatchDate && nextMatchDate.toDate() < endDate.toDate()) {
2016
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
2036
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
2037
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
2038
+ if (newNextMatchDate && newNextMatchDate.toDate() <= nextMatchDate.toDate()) {
2039
+ this.cache.pop();
2040
+ break;
2041
+ }
2042
+ nextMatchDate = newNextMatchDate;
2017
2043
  if (typeof this.count === 'number' && this.cache.length >= this.count) {
2018
2044
  break;
2019
2045
  }
@@ -17,7 +17,7 @@ const index$1 = require('./index-5792390b.js');
17
17
  const internalVegaZIndexManager = require('./internal-vega-z-index-manager-23051df4.js');
18
18
  const staticSubjectTitle = require('./static-subject-title-3599787e.js');
19
19
  const changeManager = require('./change-manager-a297e4d2.js');
20
- const stringInputFormatterSlimmer = require('./string-input-formatter-slimmer-fcfa5bb7.js');
20
+ const stringInputFormatterSlimmer = require('./string-input-formatter-slimmer-79272527.js');
21
21
  const elementAppenderSlimmer = require('./element-appender-slimmer-bf5ecbd8.js');
22
22
  const keyboardManagerSlimmer = require('./keyboard-manager-slimmer-8e2d4b5d.js');
23
23
  const componentLoadRequired = require('./component-load-required-16d76afa.js');
@@ -11,9 +11,9 @@ exports.FrameworkEnum = void 0;
11
11
  /** The VegaEnvManager class manages vega environment parameters. */
12
12
  class VegaEnvManager {
13
13
  constructor() {
14
- // The `2.28.0` will be replaced to a version string when running publish script.
14
+ // The `2.28.1` will be replaced to a version string when running publish script.
15
15
  // eslint-disable-next-line @typescript-eslint/no-magic-numbers
16
- this.vegaVersion = '2.28.0';
16
+ this.vegaVersion = '2.28.1';
17
17
  this.framework = exports.FrameworkEnum.VanillaJs;
18
18
  }
19
19
  /**
@@ -17,7 +17,7 @@ const eventEmitSlimmer = require('./event-emit-slimmer-8f51adaa.js');
17
17
  const vegaEventId = require('./vega-event-id-e40ac8f0.js');
18
18
  const staticSubjectTitle = require('./static-subject-title-3599787e.js');
19
19
  const changeManager = require('./change-manager-a297e4d2.js');
20
- const stringInputFormatterSlimmer = require('./string-input-formatter-slimmer-fcfa5bb7.js');
20
+ const stringInputFormatterSlimmer = require('./string-input-formatter-slimmer-79272527.js');
21
21
  const typeGuard = require('./type-guard-a07b353b.js');
22
22
  const domNodeSubjectObserverFactory = require('./dom-node-subject-observer-factory-2e41340d.js');
23
23
  require('./number-459031f7.js');
@@ -445,9 +445,8 @@ class NumberThousandCommaStrategy extends NumberMaskStrategy {
445
445
  if (!input.length)
446
446
  return input;
447
447
  const inputValue = input.replace(/[^\d.-]/g, '');
448
- const { precision } = this.maskConfig;
449
448
  const pointIndex = inputValue.indexOf('.');
450
- const decimals = precision && inputValue.length > 1 && pointIndex >= 1 ? inputValue.slice(pointIndex) : '';
449
+ const decimals = inputValue.length > 1 && pointIndex >= 1 ? inputValue.slice(pointIndex) : '';
451
450
  const numValue = Number(inputValue.split('.')[0]);
452
451
  if (!isNaN(numValue) && numValue <= Number.MAX_SAFE_INTEGER) {
453
452
  return numValue.toLocaleString('en-US') + decimals;
@@ -34,7 +34,13 @@ export class CalendarEventDailyRepeatPattern extends CalendarEventBaseRepeatPatt
34
34
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
35
35
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
36
36
  while (nextMatchDate && nextMatchDate.toDate() < endDate.toDate()) {
37
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
37
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
38
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
39
+ if (newNextMatchDate && newNextMatchDate.toDate() <= nextMatchDate.toDate()) {
40
+ this.cache.pop();
41
+ break;
42
+ }
43
+ nextMatchDate = newNextMatchDate;
38
44
  if (typeof this.count === 'number' && this.cache.length >= this.count) {
39
45
  break;
40
46
  }
@@ -37,7 +37,13 @@ export class CalendarEventMonthlyRepeatPattern extends CalendarEventBaseRepeatPa
37
37
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
38
38
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
39
39
  while (nextMatchDate && nextMatchDate.toDate() < endDate.toDate()) {
40
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
40
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
41
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
42
+ if (newNextMatchDate && newNextMatchDate.toDate() <= nextMatchDate.toDate()) {
43
+ this.cache.pop();
44
+ break;
45
+ }
46
+ nextMatchDate = newNextMatchDate;
41
47
  if (typeof this.count === 'number' && this.cache.length >= this.count) {
42
48
  break;
43
49
  }
@@ -53,7 +53,15 @@ export class CalendarEventWeeklyRepeatPattern extends CalendarEventBaseRepeatPat
53
53
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
54
54
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
55
55
  while (nextMatchDate && nextMatchDate[0].toDate() < endDate.toDate()) {
56
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
56
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
57
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
58
+ if (newNextMatchDate &&
59
+ newNextMatchDate[0] &&
60
+ newNextMatchDate[0].toDate() <= nextMatchDate[0].toDate()) {
61
+ this.cache.pop();
62
+ break;
63
+ }
64
+ nextMatchDate = newNextMatchDate;
57
65
  if (typeof this.count === 'number' && this.getValidCache().length >= this.count) {
58
66
  break;
59
67
  }
@@ -38,7 +38,13 @@ export class CalendarEventYearlyRepeatPattern extends CalendarEventBaseRepeatPat
38
38
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
39
39
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
40
40
  while (nextMatchDate && nextMatchDate.toDate() < endDate.toDate()) {
41
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
41
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
42
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
43
+ if (newNextMatchDate && newNextMatchDate.toDate() <= nextMatchDate.toDate()) {
44
+ this.cache.pop();
45
+ break;
46
+ }
47
+ nextMatchDate = newNextMatchDate;
42
48
  if (typeof this.count === 'number' && this.cache.length >= this.count) {
43
49
  break;
44
50
  }
@@ -102,4 +102,60 @@ describe('calendarEventRepeatPatternFactory', () => {
102
102
  const dayPeriod = new DayPeriod(new CalendarDate(2024, 8, 1));
103
103
  expect(pattern['isSeriesInPeriod'](new CalendarDate(2024, 7, 31), 3, dayPeriod)).toBeTruthy();
104
104
  });
105
+ it('dailyPattern#generateRepeatDateCacheUntilEndDate boundary testing', () => {
106
+ const pattern = calendarEventRepeatPatternFactory.getPattern(new Date(2024, 0, 1), {
107
+ frequency: 'daily',
108
+ interval: 1,
109
+ until: '01/04/2024',
110
+ });
111
+ spyOn(CalendarDate, 'from').and.callFake(function (item) {
112
+ return item.getDate() === 3
113
+ ? new CalendarDate(item.getFullYear(), 1, 1)
114
+ : new CalendarDate(item.getFullYear(), item.getMonth() + 1, item.getDate());
115
+ });
116
+ pattern['generateRepeatDateCacheUntilEndDate'](CalendarDate.from(new Date(2024, 1, 1)));
117
+ expect(pattern['cache'].length).toEqual(2);
118
+ });
119
+ it('monthlyPattern#generateRepeatDateCacheUntilEndDate boundary testing', () => {
120
+ const pattern = calendarEventRepeatPatternFactory.getPattern(new Date(2024, 0, 1), {
121
+ frequency: 'monthly',
122
+ interval: 1,
123
+ until: '04/03/2024',
124
+ });
125
+ spyOn(CalendarDate, 'from').and.callFake(function (item) {
126
+ return item.getMonth() === 2
127
+ ? new CalendarDate(item.getFullYear(), 1, 1)
128
+ : new CalendarDate(item.getFullYear(), item.getMonth() + 1, item.getDate());
129
+ });
130
+ pattern['generateRepeatDateCacheUntilEndDate'](CalendarDate.from(new Date(2024, 4, 1)));
131
+ expect(pattern['cache'].length).toEqual(2);
132
+ });
133
+ it('yearlyPattern#generateRepeatDateCacheUntilEndDate boundary testing', () => {
134
+ const pattern = calendarEventRepeatPatternFactory.getPattern(new Date(2024, 0, 1), {
135
+ frequency: 'yearly',
136
+ interval: 1,
137
+ until: '03/03/2027',
138
+ });
139
+ spyOn(CalendarDate, 'from').and.callFake(function (item) {
140
+ return item.getFullYear() === 2026
141
+ ? new CalendarDate(1900, 1, 1)
142
+ : new CalendarDate(item.getFullYear(), item.getMonth() + 1, item.getDate());
143
+ });
144
+ pattern['generateRepeatDateCacheUntilEndDate'](CalendarDate.from(new Date(2028, 1, 1)));
145
+ expect(pattern['cache'].length).toEqual(2);
146
+ });
147
+ it('weeklyPattern#generateRepeatDateCacheUntilEndDate boundary testing', () => {
148
+ const pattern = calendarEventRepeatPatternFactory.getPattern(new Date(2024, 0, 1), {
149
+ frequency: 'weekly',
150
+ interval: 1,
151
+ until: '02/01/2024',
152
+ });
153
+ spyOn(CalendarDate, 'from').and.callFake(function (item) {
154
+ return item.getDate() === 15
155
+ ? new CalendarDate(item.getFullYear(), 1, 1)
156
+ : new CalendarDate(item.getFullYear(), item.getMonth() + 1, item.getDate());
157
+ });
158
+ pattern['generateRepeatDateCacheUntilEndDate'](CalendarDate.from(new Date(2024, 3, 1)));
159
+ expect(pattern['cache'].length).toEqual(2);
160
+ });
105
161
  });
@@ -57,9 +57,8 @@ export class NumberThousandCommaStrategy extends NumberMaskStrategy {
57
57
  if (!input.length)
58
58
  return input;
59
59
  const inputValue = input.replace(/[^\d.-]/g, '');
60
- const { precision } = this.maskConfig;
61
60
  const pointIndex = inputValue.indexOf('.');
62
- const decimals = precision && inputValue.length > 1 && pointIndex >= 1 ? inputValue.slice(pointIndex) : '';
61
+ const decimals = inputValue.length > 1 && pointIndex >= 1 ? inputValue.slice(pointIndex) : '';
63
62
  const numValue = Number(inputValue.split('.')[0]);
64
63
  if (!isNaN(numValue) && numValue <= Number.MAX_SAFE_INTEGER) {
65
64
  return numValue.toLocaleString('en-US') + decimals;
@@ -29,4 +29,12 @@ describe('NumberThousandCommaStrategy', () => {
29
29
  expect(numberStrategy.calculateCaretPosition('1,23', 4)).toBe(3);
30
30
  expect(numberStrategy.calculateCaretPosition('-123', 4)).toBe(4);
31
31
  });
32
+ it('format thousand comma if set property thousandComma is true and not set precision', () => {
33
+ const numberStrategy = new NumberThousandCommaStrategy({});
34
+ expect(numberStrategy.format('123')).toBe('123');
35
+ expect(numberStrategy.format('0.12345')).toBe('0.12345');
36
+ expect(numberStrategy.format('12.12')).toBe('12.12');
37
+ expect(numberStrategy.format('123456.012')).toBe('123,456.012');
38
+ expect(numberStrategy.format('-123456.012')).toBe('-123,456.012');
39
+ });
32
40
  });
@@ -57,7 +57,10 @@ export class StringInputFormatterSlimmer extends VegaSlimmer {
57
57
  const rawValue = target.value;
58
58
  const caretPosition = target.selectionStart; // selectionStart is nullable, link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectionstart
59
59
  if (this.inputFormatStrategy) {
60
- const maskedValue = this.inputFormatStrategy.format(rawValue, caretPosition);
60
+ const maskedValue = this.inputFormatStrategy.format(rawValue,
61
+ // Paste input is difference with type input, it can set much characters at one time,
62
+ // so we should make caretPosition as undefined to format all value.
63
+ e.inputType === 'insertFromPaste' ? null : caretPosition);
61
64
  this.updateInputValue(rawValue, maskedValue);
62
65
  this.updateInputCaretPosition(rawValue, caretPosition);
63
66
  }
@@ -68,12 +71,8 @@ export class StringInputFormatterSlimmer extends VegaSlimmer {
68
71
  * @param {ClipboardEvent} e - paste event
69
72
  */
70
73
  this.onPaste = (e) => {
71
- var _a;
72
- e.preventDefault();
73
- const rawValue = ((_a = e.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text')) || '';
74
- if (this.inputFormatStrategy) {
75
- const maskedValue = this.inputFormatStrategy.format(rawValue);
76
- this.updateInputValue(rawValue, maskedValue);
74
+ if (this.disableCopyPaste) {
75
+ e.preventDefault();
77
76
  }
78
77
  };
79
78
  }
@@ -90,9 +89,7 @@ export class StringInputFormatterSlimmer extends VegaSlimmer {
90
89
  this.onInit();
91
90
  if (this.inputFormatStrategy) {
92
91
  this.inputElement.addEventListener('input', this.onKeyDown, { capture: true });
93
- if (!this.disableCopyPaste) {
94
- this.inputElement.addEventListener('paste', this.onPaste, { capture: true });
95
- }
92
+ this.inputElement.addEventListener('paste', this.onPaste, { capture: true });
96
93
  }
97
94
  if (this.blurFormatStrategy) {
98
95
  this.inputElement.addEventListener('blur', this.onBlur, { capture: true });
@@ -107,9 +104,7 @@ export class StringInputFormatterSlimmer extends VegaSlimmer {
107
104
  if (this.inputElement) {
108
105
  if (this.inputFormatStrategy) {
109
106
  this.inputElement.removeEventListener('input', this.onKeyDown, { capture: true });
110
- if (!this.disableCopyPaste) {
111
- this.inputElement.removeEventListener('paste', this.onPaste, { capture: true });
112
- }
107
+ this.inputElement.removeEventListener('paste', this.onPaste, { capture: true });
113
108
  }
114
109
  if (this.blurFormatStrategy) {
115
110
  this.inputElement.removeEventListener('blur', this.onBlur, { capture: true });
@@ -9,6 +9,7 @@ import { InjectVegaSlimmer } from 'vega-slimmer/core';
9
9
  import { StringInputFormatterSlimmer } from '../string-input-formatter-slimmer';
10
10
  import { StringMaskStrategy } from '../../formatter/string-formatter/string-mask-strategy';
11
11
  import { ThousandCommaStrategy } from '../../formatter/string-formatter/thousand-comma-strategy';
12
+ import { dispatchPasteEvent } from '../../../utils/spec-utils';
12
13
  const createMockedInput = () => {
13
14
  const inputEl = document.createElement('input');
14
15
  inputEl.setSelectionRange = jest.fn();
@@ -129,21 +130,25 @@ describe('StringInputFormatterSlimmer test suite', () => {
129
130
  mockedComponent['stringFormatter']['inputRef'] = inputEl;
130
131
  mockedComponent['stringFormatter']['inputStrategy'] = stringFormatStrategy;
131
132
  mockedComponent['stringFormatter'].setup();
132
- const pasteEvent = new Event('paste');
133
- const clipboardDataMock = {
134
- getData: jest.fn().mockReturnValue('7777 is my lucky number'),
135
- };
136
- Object.defineProperty(pasteEvent, 'clipboardData', { value: clipboardDataMock });
133
+ const pasteEvent = dispatchPasteEvent(inputEl, '7777 is my lucky number');
137
134
  const preventDefaultSpy = jest.spyOn(pasteEvent, 'preventDefault');
138
- mockedComponent['stringFormatter']['onPaste'](pasteEvent);
139
- expect(preventDefaultSpy).toHaveBeenCalled();
140
- expect(clipboardDataMock.getData).toHaveBeenCalledWith('text');
141
- expect(clipboardDataMock.getData('text')).toEqual('7777 is my lucky number');
135
+ expect(preventDefaultSpy).not.toHaveBeenCalled();
142
136
  expect(inputEl.value).toEqual('(777) 7');
143
137
  jest.spyOn(inputEl, 'removeEventListener');
144
138
  mockedComponent['stringFormatter'].destroy();
145
139
  expect(inputEl.removeEventListener).toBeCalledWith('paste', expect.any(Function), { capture: true });
146
140
  });
141
+ test('should handle paste content correctly when input a valid string', () => {
142
+ const mockedComponent = new MockedComponent();
143
+ mockedComponent.host = document.createElement('input');
144
+ const stringFormatStrategy = StringMaskStrategy.PHONE_MASK;
145
+ const inputEl = createMockedInput();
146
+ mockedComponent['stringFormatter']['inputRef'] = inputEl;
147
+ mockedComponent['stringFormatter']['inputStrategy'] = stringFormatStrategy;
148
+ mockedComponent['stringFormatter'].setup();
149
+ dispatchPasteEvent(inputEl, '(777');
150
+ expect(inputEl.value).toEqual('(777');
151
+ });
147
152
  test('should not handle paste content if paste is disabled', () => {
148
153
  const mockedComponent = new MockedComponent();
149
154
  mockedComponent.host = document.createElement('input');
@@ -153,19 +158,13 @@ describe('StringInputFormatterSlimmer test suite', () => {
153
158
  mockedComponent['stringFormatter']['disableCopyPaste'] = true;
154
159
  mockedComponent['stringFormatter']['inputStrategy'] = stringFormatStrategy;
155
160
  mockedComponent['stringFormatter'].setup();
156
- const pasteEvent = new Event('paste');
157
- Object.defineProperty(pasteEvent, 'clipboardData', {
158
- value: {
159
- getData: jest.fn().mockReturnValue('7777 is my lucky number'),
160
- },
161
- });
162
- inputEl.dispatchEvent(pasteEvent);
161
+ dispatchPasteEvent(inputEl, '7777 is my lucky number');
163
162
  expect(inputEl.value).toEqual('');
164
163
  jest.spyOn(inputEl, 'addEventListener');
165
- expect(inputEl.addEventListener).not.toBeCalledWith('paste', expect.any(Function), { capture: true });
164
+ expect(inputEl.addEventListener).not.toBeCalledWith('input', expect.any(Function), { capture: true });
166
165
  jest.spyOn(inputEl, 'removeEventListener');
167
166
  mockedComponent['stringFormatter'].destroy();
168
- expect(inputEl.removeEventListener).not.toBeCalledWith('paste', expect.any(Function), {
167
+ expect(inputEl.removeEventListener).toBeCalledWith('paste', expect.any(Function), {
169
168
  capture: true,
170
169
  });
171
170
  });
@@ -177,12 +176,25 @@ describe('StringInputFormatterSlimmer test suite', () => {
177
176
  mockedComponent['stringFormatter']['inputRef'] = inputEl;
178
177
  mockedComponent['stringFormatter']['inputStrategy'] = stringFormatStrategy;
179
178
  mockedComponent['stringFormatter'].setup();
180
- const pasteEvent = new Event('paste');
181
179
  const formatSpy = jest.spyOn(stringFormatStrategy, 'format');
182
- mockedComponent['stringFormatter']['onPaste'](pasteEvent);
180
+ dispatchPasteEvent(inputEl, '');
183
181
  expect(formatSpy).toHaveBeenCalledWith('');
184
182
  expect(inputEl.value).toEqual('');
185
183
  });
184
+ test('should handle paste content with not formatted value', () => {
185
+ const mockedComponent = new MockedComponent();
186
+ mockedComponent.host = document.createElement('input');
187
+ const stringFormatStrategy = StringMaskStrategy.PHONE_MASK;
188
+ const inputEl = createMockedInput();
189
+ mockedComponent['stringFormatter']['inputRef'] = inputEl;
190
+ mockedComponent['stringFormatter']['inputStrategy'] = stringFormatStrategy;
191
+ mockedComponent['stringFormatter'].setup();
192
+ dispatchPasteEvent(inputEl,
193
+ // should pick up numbers and then to format by this input string
194
+ // eslint-disable-next-line spellcheck/spell-checker
195
+ 'nGLNBk1x1ZKVN5qfcwNpPvK9cLPiDrChJDMW0RnzDyUf2BaGSKqXMbj4ckbGmAZbH0V5Krhzv58vpALGFF8PXvqE6cdpUFJW0vApkYk82gUuf2CkPw4q92DQ7JJSacbFEdGFdRiAKfXzaHUBPQYLbkmAR8TmmSa87zPzFzBvdrYPVpQFD1DLLTPnM0WR0Qr8WGnHRF8P0K6b0d');
196
+ expect(inputEl.value).toEqual('(115) 902-4055');
197
+ });
186
198
  test('should work proper while formatter have not implement calculateCaretPosition method', () => {
187
199
  class FormatterSlimmer {
188
200
  format(input) {
@@ -166,3 +166,31 @@ export function queryVegaDropdownItem(page, itemSelector = 'vega-dropdown-item')
166
166
  const virtualScroll = dropdownBox.shadowRoot.querySelector('vega-virtual-scroll');
167
167
  return virtualScroll.shadowRoot.querySelector(itemSelector);
168
168
  }
169
+ /**
170
+ * Dispatch paste event for a element.
171
+ *
172
+ * @param {HTMLElement} element - Content editable element, such as input, textarea.
173
+ * @param {string} data - data to paste.
174
+ * @returns {ClipboardEvent} - Paste event.
175
+ */
176
+ export function dispatchPasteEvent(element, data) {
177
+ element.focus();
178
+ const pasteEvent = new Event('paste', {
179
+ bubbles: true,
180
+ cancelable: true,
181
+ });
182
+ const clipboardDataMock = {
183
+ getData: jest.fn().mockReturnValue(data),
184
+ };
185
+ Object.defineProperty(pasteEvent, 'clipboardData', { value: clipboardDataMock });
186
+ element.dispatchEvent(pasteEvent);
187
+ if (!pasteEvent.defaultPrevented) {
188
+ const inputEvent = new Event('input', { bubbles: true, cancelable: true });
189
+ Object.defineProperty(inputEvent, 'inputType', { value: 'insertFromPaste' });
190
+ Object.defineProperty(inputEvent, 'data', { value: data });
191
+ Object.defineProperty(element, 'selectionStart', { value: data.length });
192
+ element['value'] = data;
193
+ element.dispatchEvent(inputEvent);
194
+ }
195
+ return pasteEvent;
196
+ }
@@ -132,3 +132,24 @@ export function sleep(ms) {
132
132
  setTimeout(resolve, ms);
133
133
  });
134
134
  }
135
+ /* istanbul ignore next */
136
+ /**
137
+ * NOTE: This const is only for **E2E** test cases.
138
+ * This method is to assert values of two arrays are close.
139
+ *
140
+ * @param {number[]} actualValue - The actualValue.
141
+ * @param {number[]} expectedValue - The expectedValue.
142
+ * @param {number} tolerance - The value difference tolerance of two arrays.
143
+ * @returns {boolean} - the return value
144
+ */
145
+ export function ArrayComparing(actualValue, expectedValue, tolerance) {
146
+ if (actualValue.length !== expectedValue.length) {
147
+ throw new Error('Arrays must be of the same length');
148
+ }
149
+ actualValue.forEach((value, index) => {
150
+ if (Math.abs(value - expectedValue[index]) > tolerance) {
151
+ throw new Error(`actualValue: ${JSON.stringify(actualValue)} expectedValue: ${JSON.stringify(expectedValue)}`); // output values of two arrays if values are not close
152
+ }
153
+ });
154
+ return true; // values of two arrays are close
155
+ }
@@ -218,7 +218,10 @@ class StringInputFormatterSlimmer extends VegaSlimmer {
218
218
  const rawValue = target.value;
219
219
  const caretPosition = target.selectionStart; // selectionStart is nullable, link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectionstart
220
220
  if (this.inputFormatStrategy) {
221
- const maskedValue = this.inputFormatStrategy.format(rawValue, caretPosition);
221
+ const maskedValue = this.inputFormatStrategy.format(rawValue,
222
+ // Paste input is difference with type input, it can set much characters at one time,
223
+ // so we should make caretPosition as undefined to format all value.
224
+ e.inputType === 'insertFromPaste' ? null : caretPosition);
222
225
  this.updateInputValue(rawValue, maskedValue);
223
226
  this.updateInputCaretPosition(rawValue, caretPosition);
224
227
  }
@@ -229,12 +232,8 @@ class StringInputFormatterSlimmer extends VegaSlimmer {
229
232
  * @param {ClipboardEvent} e - paste event
230
233
  */
231
234
  this.onPaste = (e) => {
232
- var _a;
233
- e.preventDefault();
234
- const rawValue = ((_a = e.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text')) || '';
235
- if (this.inputFormatStrategy) {
236
- const maskedValue = this.inputFormatStrategy.format(rawValue);
237
- this.updateInputValue(rawValue, maskedValue);
235
+ if (this.disableCopyPaste) {
236
+ e.preventDefault();
238
237
  }
239
238
  };
240
239
  }
@@ -251,9 +250,7 @@ class StringInputFormatterSlimmer extends VegaSlimmer {
251
250
  this.onInit();
252
251
  if (this.inputFormatStrategy) {
253
252
  this.inputElement.addEventListener('input', this.onKeyDown, { capture: true });
254
- if (!this.disableCopyPaste) {
255
- this.inputElement.addEventListener('paste', this.onPaste, { capture: true });
256
- }
253
+ this.inputElement.addEventListener('paste', this.onPaste, { capture: true });
257
254
  }
258
255
  if (this.blurFormatStrategy) {
259
256
  this.inputElement.addEventListener('blur', this.onBlur, { capture: true });
@@ -268,9 +265,7 @@ class StringInputFormatterSlimmer extends VegaSlimmer {
268
265
  if (this.inputElement) {
269
266
  if (this.inputFormatStrategy) {
270
267
  this.inputElement.removeEventListener('input', this.onKeyDown, { capture: true });
271
- if (!this.disableCopyPaste) {
272
- this.inputElement.removeEventListener('paste', this.onPaste, { capture: true });
273
- }
268
+ this.inputElement.removeEventListener('paste', this.onPaste, { capture: true });
274
269
  }
275
270
  if (this.blurFormatStrategy) {
276
271
  this.inputElement.removeEventListener('blur', this.onBlur, { capture: true });
@@ -1686,7 +1686,13 @@ class CalendarEventDailyRepeatPattern extends CalendarEventBaseRepeatPattern {
1686
1686
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
1687
1687
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
1688
1688
  while (nextMatchDate && nextMatchDate.toDate() < endDate.toDate()) {
1689
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1689
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1690
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
1691
+ if (newNextMatchDate && newNextMatchDate.toDate() <= nextMatchDate.toDate()) {
1692
+ this.cache.pop();
1693
+ break;
1694
+ }
1695
+ nextMatchDate = newNextMatchDate;
1690
1696
  if (typeof this.count === 'number' && this.cache.length >= this.count) {
1691
1697
  break;
1692
1698
  }
@@ -1758,7 +1764,13 @@ class CalendarEventMonthlyRepeatPattern extends CalendarEventBaseRepeatPattern {
1758
1764
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
1759
1765
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
1760
1766
  while (nextMatchDate && nextMatchDate.toDate() < endDate.toDate()) {
1761
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1767
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1768
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
1769
+ if (newNextMatchDate && newNextMatchDate.toDate() <= nextMatchDate.toDate()) {
1770
+ this.cache.pop();
1771
+ break;
1772
+ }
1773
+ nextMatchDate = newNextMatchDate;
1762
1774
  if (typeof this.count === 'number' && this.cache.length >= this.count) {
1763
1775
  break;
1764
1776
  }
@@ -1862,7 +1874,15 @@ class CalendarEventWeeklyRepeatPattern extends CalendarEventBaseRepeatPattern {
1862
1874
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
1863
1875
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
1864
1876
  while (nextMatchDate && nextMatchDate[0].toDate() < endDate.toDate()) {
1865
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1877
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
1878
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
1879
+ if (newNextMatchDate &&
1880
+ newNextMatchDate[0] &&
1881
+ newNextMatchDate[0].toDate() <= nextMatchDate[0].toDate()) {
1882
+ this.cache.pop();
1883
+ break;
1884
+ }
1885
+ nextMatchDate = newNextMatchDate;
1866
1886
  if (typeof this.count === 'number' && this.getValidCache().length >= this.count) {
1867
1887
  break;
1868
1888
  }
@@ -2009,7 +2029,13 @@ class CalendarEventYearlyRepeatPattern extends CalendarEventBaseRepeatPattern {
2009
2029
  (!this.count || (typeof this.count === 'number' && this.cache.length < this.count))) {
2010
2030
  let nextMatchDate = this.getNextRepeatStartDate(lastMatchDate);
2011
2031
  while (nextMatchDate && nextMatchDate.toDate() < endDate.toDate()) {
2012
- nextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
2032
+ const newNextMatchDate = this.getNextRepeatStartDate(nextMatchDate);
2033
+ //The below if block is used to break the infinite loop when the `getNextRepeatStartDate` method return unexpected result. such as when the date is greater than a certain value, it will be returned back 1900.
2034
+ if (newNextMatchDate && newNextMatchDate.toDate() <= nextMatchDate.toDate()) {
2035
+ this.cache.pop();
2036
+ break;
2037
+ }
2038
+ nextMatchDate = newNextMatchDate;
2013
2039
  if (typeof this.count === 'number' && this.cache.length >= this.count) {
2014
2040
  break;
2015
2041
  }
@@ -13,7 +13,7 @@ import { c as createCommonjsModule } from './index-0863eec6.js';
13
13
  import { I as InternalVegaZIndexManager } from './internal-vega-z-index-manager-0553458e.js';
14
14
  import { b as FORM_ELEMENT_VALUE_CHANGE } from './static-subject-title-6987a80b.js';
15
15
  import { C as ChangeManager } from './change-manager-6a7eb88c.js';
16
- import { S as StringInputFormatterSlimmer, a as StringMaskStrategy } from './string-input-formatter-slimmer-bfe3f5e5.js';
16
+ import { S as StringInputFormatterSlimmer, a as StringMaskStrategy } from './string-input-formatter-slimmer-fc23bc9f.js';
17
17
  import { E as ElementAppenderSlimmer } from './element-appender-slimmer-1172e2ea.js';
18
18
  import { K as KeyboardManagerSlimmer } from './keyboard-manager-slimmer-8723f20f.js';
19
19
  import { C as ComponentLoadRequired } from './component-load-required-ce710ef5.js';