@syncfusion/ej2-inputs 30.2.6 → 31.1.17

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 (99) hide show
  1. package/dist/ej2-inputs.min.js +2 -2
  2. package/dist/ej2-inputs.umd.min.js +2 -2
  3. package/dist/ej2-inputs.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-inputs.es2015.js +1 -1
  5. package/dist/es6/ej2-inputs.es2015.js.map +1 -1
  6. package/dist/es6/ej2-inputs.es5.js +1 -1
  7. package/dist/es6/ej2-inputs.es5.js.map +1 -1
  8. package/dist/global/ej2-inputs.min.js +2 -2
  9. package/dist/global/ej2-inputs.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/dist/ts/color-picker/color-picker-model.d.ts +186 -0
  12. package/dist/ts/color-picker/color-picker.d.ts +398 -0
  13. package/dist/ts/color-picker/color-picker.ts +2209 -0
  14. package/dist/ts/color-picker/index.d.ts +5 -0
  15. package/dist/ts/color-picker/index.ts +5 -0
  16. package/dist/ts/common/index.d.ts +4 -0
  17. package/dist/ts/common/index.ts +4 -0
  18. package/dist/ts/common/signature-base.d.ts +340 -0
  19. package/dist/ts/common/signature-base.ts +1170 -0
  20. package/dist/ts/form-validator/form-validator-model.d.ts +121 -0
  21. package/dist/ts/form-validator/form-validator.d.ts +312 -0
  22. package/dist/ts/form-validator/form-validator.ts +1068 -0
  23. package/dist/ts/form-validator/index.d.ts +5 -0
  24. package/dist/ts/form-validator/index.ts +5 -0
  25. package/dist/ts/index.d.ts +18 -0
  26. package/dist/ts/index.ts +18 -0
  27. package/dist/ts/input/index.d.ts +4 -0
  28. package/dist/ts/input/index.ts +4 -0
  29. package/dist/ts/input/input.d.ts +345 -0
  30. package/dist/ts/input/input.ts +1277 -0
  31. package/dist/ts/maskedtextbox/base/index.d.ts +4 -0
  32. package/dist/ts/maskedtextbox/base/index.ts +4 -0
  33. package/dist/ts/maskedtextbox/base/mask-base.d.ts +134 -0
  34. package/dist/ts/maskedtextbox/base/mask-base.ts +1207 -0
  35. package/dist/ts/maskedtextbox/index.d.ts +5 -0
  36. package/dist/ts/maskedtextbox/index.ts +5 -0
  37. package/dist/ts/maskedtextbox/maskedtextbox/index.d.ts +5 -0
  38. package/dist/ts/maskedtextbox/maskedtextbox/index.ts +5 -0
  39. package/dist/ts/maskedtextbox/maskedtextbox/maskedtextbox-model.d.ts +167 -0
  40. package/dist/ts/maskedtextbox/maskedtextbox/maskedtextbox.d.ts +307 -0
  41. package/dist/ts/maskedtextbox/maskedtextbox/maskedtextbox.ts +709 -0
  42. package/dist/ts/numerictextbox/index.d.ts +5 -0
  43. package/dist/ts/numerictextbox/index.ts +5 -0
  44. package/dist/ts/numerictextbox/numerictextbox-model.d.ts +228 -0
  45. package/dist/ts/numerictextbox/numerictextbox.d.ts +431 -0
  46. package/dist/ts/numerictextbox/numerictextbox.ts +1672 -0
  47. package/dist/ts/otp-input/index.d.ts +5 -0
  48. package/dist/ts/otp-input/index.ts +5 -0
  49. package/dist/ts/otp-input/otp-input-model.d.ts +165 -0
  50. package/dist/ts/otp-input/otp-input.d.ts +365 -0
  51. package/dist/ts/otp-input/otp-input.ts +924 -0
  52. package/dist/ts/rating/index.d.ts +5 -0
  53. package/dist/ts/rating/index.ts +5 -0
  54. package/dist/ts/rating/rating-model.d.ts +239 -0
  55. package/dist/ts/rating/rating.d.ts +416 -0
  56. package/dist/ts/rating/rating.ts +1101 -0
  57. package/dist/ts/signature/index.d.ts +5 -0
  58. package/dist/ts/signature/index.ts +5 -0
  59. package/dist/ts/signature/signature-model.d.ts +131 -0
  60. package/dist/ts/signature/signature.d.ts +167 -0
  61. package/dist/ts/signature/signature.ts +266 -0
  62. package/dist/ts/slider/index.d.ts +5 -0
  63. package/dist/ts/slider/index.ts +5 -0
  64. package/dist/ts/slider/slider-model.d.ts +401 -0
  65. package/dist/ts/slider/slider.d.ts +721 -0
  66. package/dist/ts/slider/slider.ts +3497 -0
  67. package/dist/ts/smart-textarea/caret-helper.d.ts +17 -0
  68. package/dist/ts/smart-textarea/caret-helper.ts +95 -0
  69. package/dist/ts/smart-textarea/index.d.ts +5 -0
  70. package/dist/ts/smart-textarea/index.ts +5 -0
  71. package/dist/ts/smart-textarea/smart-textarea-model.d.ts +44 -0
  72. package/dist/ts/smart-textarea/smart-textarea.d.ts +80 -0
  73. package/dist/ts/smart-textarea/smart-textarea.ts +518 -0
  74. package/dist/ts/speech-to-text/index.d.ts +5 -0
  75. package/dist/ts/speech-to-text/index.ts +5 -0
  76. package/dist/ts/speech-to-text/speech-to-text-model.d.ts +270 -0
  77. package/dist/ts/speech-to-text/speech-to-text.d.ts +487 -0
  78. package/dist/ts/speech-to-text/speech-to-text.ts +1008 -0
  79. package/dist/ts/textarea/index.d.ts +5 -0
  80. package/dist/ts/textarea/index.ts +5 -0
  81. package/dist/ts/textarea/textarea-model.d.ts +161 -0
  82. package/dist/ts/textarea/textarea.d.ts +237 -0
  83. package/dist/ts/textarea/textarea.ts +812 -0
  84. package/dist/ts/textbox/index.d.ts +5 -0
  85. package/dist/ts/textbox/index.ts +5 -0
  86. package/dist/ts/textbox/textbox-model.d.ts +155 -0
  87. package/dist/ts/textbox/textbox.d.ts +288 -0
  88. package/dist/ts/textbox/textbox.ts +872 -0
  89. package/dist/ts/uploader/index.d.ts +5 -0
  90. package/dist/ts/uploader/index.ts +5 -0
  91. package/dist/ts/uploader/uploader-model.d.ts +555 -0
  92. package/dist/ts/uploader/uploader.d.ts +1216 -0
  93. package/dist/ts/uploader/uploader.ts +4391 -0
  94. package/package.json +62 -12
  95. package/src/input/input.js +1 -1
  96. package/styles/input/_layout.scss +0 -1
  97. package/styles/input/tailwind3.css +0 -1
  98. package/styles/tailwind3-lite.css +0 -1
  99. package/styles/tailwind3.css +0 -1
@@ -0,0 +1,1207 @@
1
+ /* eslint-disable valid-jsdoc, jsdoc/require-jsdoc, jsdoc/require-returns, jsdoc/require-param */
2
+ /**
3
+ * MaskedTextBox base module
4
+ */
5
+ import { EventHandler, isNullOrUndefined, merge, attributes, addClass, removeClass, Browser, extend } from '@syncfusion/ej2-base';
6
+ import { BaseEventArgs } from '@syncfusion/ej2-base';
7
+ import { Input } from '../../input/input';
8
+
9
+ const ERROR: string = 'e-error';
10
+ const INPUTGROUP: string = 'e-input-group';
11
+ const FLOATINPUT: string = 'e-float-input';
12
+ const UTILMASK: string = 'e-utility-mask';
13
+ const TOPLABEL: string = 'e-label-top';
14
+ const BOTTOMLABEL: string = 'e-label-bottom';
15
+
16
+ /**
17
+ * @hidden
18
+ * Built-in masking elements collection.
19
+ */
20
+ export const regularExpressions: { [key: string]: string } = {
21
+ '0': '[0-9]',
22
+ '9': '[0-9 ]',
23
+ '#': '[0-9 +-]',
24
+ 'L': '[A-Za-z]',
25
+ '?': '[A-Za-z ]',
26
+ '&': '[^\x7f ]+',
27
+ 'C': '[^\x7f]+',
28
+ 'A': '[A-Za-z0-9]',
29
+ 'a': '[A-Za-z0-9 ]'
30
+ };
31
+
32
+ interface MaskFocusEventArgs extends BaseEventArgs {
33
+ /** Returns selectionStart value as zero by default */
34
+ selectionStart?: number
35
+ /** Returns selectionEnd value depends on mask length */
36
+ selectionEnd?: number
37
+ /** Returns the original event arguments. */
38
+ event?: MouseEvent | FocusEvent | TouchEvent | KeyboardEvent
39
+ /** Returns the value of MaskedTextBox. */
40
+ value?: string
41
+ /** Returns the maskedValue of MaskedTextBox. */
42
+ maskedValue?: string
43
+ /** Returns the MaskedTextBox container element */
44
+ container?: HTMLElement
45
+ }
46
+ /**
47
+ * Generate required masking elements to the MaskedTextBox from user mask input.
48
+ *
49
+ * @hidden
50
+ */
51
+ export function createMask(): void {
52
+ attributes(this.element, {
53
+ 'role': 'textbox', 'autocomplete': 'off', 'autocapitalize': 'off',
54
+ 'spellcheck': 'false', 'aria-live': 'assertive'
55
+ });
56
+ if (this.mask) {
57
+ const splitMask: string[] = this.mask.split(']');
58
+ for (let i: number = 0; i < splitMask.length; i++) {
59
+ if (splitMask[i as number][splitMask[i as number].length - 1] === '\\') {
60
+ splitMask[i as number] = splitMask[i as number] + ']';
61
+ const splitInnerMask: string[] = splitMask[i as number].split('[');
62
+ for (let j: number = 0; j < splitInnerMask.length; j++) {
63
+ if (splitInnerMask[j as number][splitInnerMask[j as number].length - 1] === '\\') {
64
+ splitInnerMask[j as number] = splitInnerMask[j as number] + '[';
65
+ }
66
+ pushIntoRegExpCollec.call(this, splitInnerMask[j as number]);
67
+ }
68
+ } else {
69
+ const splitInnerMask: string[] = splitMask[i as number].split('[');
70
+ if (splitInnerMask.length > 1) {
71
+ let chkSpace: boolean = false;
72
+ for (let j: number = 0; j < splitInnerMask.length; j++) {
73
+ if (splitInnerMask[j as number] === '\\') {
74
+ this.customRegExpCollec.push('[');
75
+ this.hiddenMask += splitInnerMask[j as number] + '[';
76
+ } else if (splitInnerMask[j as number] === '') {
77
+ chkSpace = true;
78
+ } else if ((splitInnerMask[j as number] !== '' && chkSpace) || j === splitInnerMask.length - 1) {
79
+ this.customRegExpCollec.push('[' + splitInnerMask[j as number] + ']');
80
+ this.hiddenMask += this.promptChar;
81
+ chkSpace = false;
82
+ } else {
83
+ pushIntoRegExpCollec.call(this, splitInnerMask[j as number]);
84
+ }
85
+ }
86
+ } else {
87
+ pushIntoRegExpCollec.call(this, splitInnerMask[0]);
88
+ }
89
+ }
90
+ }
91
+ this.escapeMaskValue = this.hiddenMask;
92
+ this.promptMask = this.hiddenMask.replace(/[09?LCAa#&]/g, this.promptChar);
93
+ if (!isNullOrUndefined(this.customCharacters)) {
94
+ for (let i: number = 0; i < this.promptMask.length; i++) {
95
+ if (!isNullOrUndefined(this.customCharacters[this.promptMask[i as number]])) {
96
+ /* eslint-disable-next-line security/detect-non-literal-regexp */
97
+ this.promptMask = this.promptMask.replace(new RegExp(this.promptMask[i as number], 'g'), this.promptChar);
98
+ }
99
+ }
100
+ }
101
+ let escapeNumber: number = 0;
102
+ if (this.hiddenMask.match(new RegExp(/\\/))) {
103
+ for (let i: number = 0; i < this.hiddenMask.length; i++) {
104
+ let j: number = 0;
105
+ if (i >= 1) {
106
+ j = i;
107
+ }
108
+ escapeNumber = this.hiddenMask.length - this.promptMask.length;
109
+ j = j - escapeNumber;
110
+ if ((i > 0 && this.hiddenMask[i - 1] !== '\\') && (this.hiddenMask[i as number] === '>' ||
111
+ this.hiddenMask[i as number] === '<' || this.hiddenMask[i as number] === '|')) {
112
+ this.promptMask = this.promptMask.substring(0, j) +
113
+ this.promptMask.substring((i + 1) - escapeNumber, this.promptMask.length);
114
+ this.escapeMaskValue = this.escapeMaskValue.substring(0, j) +
115
+ this.escapeMaskValue.substring((i + 1) - escapeNumber, this.escapeMaskValue.length);
116
+ }
117
+ if (this.hiddenMask[i as number] === '\\') {
118
+ this.promptMask = this.promptMask.substring(0, j) + this.hiddenMask[i + 1] +
119
+ this.promptMask.substring((i + 2) - escapeNumber, this.promptMask.length);
120
+ this.escapeMaskValue = this.escapeMaskValue.substring(0, j) + this.escapeMaskValue[i + 1] +
121
+ this.escapeMaskValue.substring((i + 2) - escapeNumber, this.escapeMaskValue.length);
122
+ }
123
+ }
124
+ } else {
125
+ this.promptMask = this.promptMask.replace(/[>|<]/g, '');
126
+ this.escapeMaskValue = this.hiddenMask.replace(/[>|<]/g, '');
127
+ }
128
+ attributes(this.element, { 'aria-invalid': 'false' });
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Apply mask ability with masking elements to the MaskedTextBox.
134
+ *
135
+ * @hidden
136
+ */
137
+ export function applyMask(): void {
138
+ setElementValue.call(this, this.promptMask);
139
+ setMaskValue.call(this, this.value);
140
+ }
141
+
142
+ /**
143
+ * To wire required events to the MaskedTextBox.
144
+ *
145
+ * @hidden
146
+ */
147
+ export function wireEvents(): void {
148
+ EventHandler.add(this.element, 'keydown', maskInputKeyDownHandler, this);
149
+ EventHandler.add(this.element, 'keypress', maskInputKeyPressHandler, this);
150
+ EventHandler.add(this.element, 'keyup', maskInputKeyUpHandler, this);
151
+ EventHandler.add(this.element, 'input', maskInputHandler, this);
152
+ EventHandler.add(this.element, 'focus', maskInputFocusHandler, this);
153
+ EventHandler.add(this.element, 'blur', maskInputBlurHandler, this);
154
+ EventHandler.add(this.element, 'paste', maskInputPasteHandler, this);
155
+ EventHandler.add(this.element, 'cut', maskInputCutHandler, this);
156
+ EventHandler.add(this.element, 'drop', maskInputDropHandler, this);
157
+ EventHandler.add(this.element, 'mousedown', maskInputMouseDownHandler, this);
158
+ EventHandler.add(this.element, 'mouseup', maskInputMouseUpHandler, this);
159
+ if (this.enabled) {
160
+ bindClearEvent.call(this);
161
+ if (this.formElement) {
162
+ EventHandler.add(this.formElement, 'reset', resetFormHandler, this);
163
+ }
164
+ }
165
+ }
166
+
167
+ /**
168
+ * To unwire events attached to the MaskedTextBox.
169
+ *
170
+ * @hidden
171
+ */
172
+ export function unwireEvents(): void {
173
+ EventHandler.remove(this.element, 'keydown', maskInputKeyDownHandler);
174
+ EventHandler.remove(this.element, 'keypress', maskInputKeyPressHandler);
175
+ EventHandler.remove(this.element, 'keyup', maskInputKeyUpHandler);
176
+ EventHandler.remove(this.element, 'input', maskInputHandler);
177
+ EventHandler.remove(this.element, 'focus', maskInputFocusHandler);
178
+ EventHandler.remove(this.element, 'blur', maskInputBlurHandler);
179
+ EventHandler.remove(this.element, 'paste', maskInputPasteHandler);
180
+ EventHandler.remove(this.element, 'cut', maskInputCutHandler);
181
+ EventHandler.remove(this.element, 'drop', maskInputDropHandler);
182
+ EventHandler.remove(this.element, 'mousedown', maskInputMouseDownHandler);
183
+ EventHandler.remove(this.element, 'mouseup', maskInputMouseUpHandler);
184
+ if (this.formElement) {
185
+ EventHandler.remove(this.formElement, 'reset', resetFormHandler);
186
+ }
187
+ }
188
+
189
+ /**
190
+ * To bind required events to the MaskedTextBox clearButton.
191
+ *
192
+ * @hidden
193
+ */
194
+ export function bindClearEvent(): void {
195
+ if (this.showClearButton) {
196
+ EventHandler.add(this.inputObj.clearButton, 'mousedown touchstart', resetHandler, this);
197
+ }
198
+ }
199
+ function resetHandler(e?: MouseEvent): void {
200
+ e.preventDefault();
201
+ if (!this.inputObj.clearButton.classList.contains('e-clear-icon-hide') || (this.inputObj.container.classList.contains('e-static-clear'))) {
202
+ clear.call(this, e);
203
+ this.value = '';
204
+ }
205
+ }
206
+ function clear(event: MouseEvent): void {
207
+ const value: string = this.element.value;
208
+ setElementValue.call(this, this.promptMask);
209
+ this.redoCollec.unshift({
210
+ value: this.promptMask, startIndex: this.element.selectionStart, endIndex: this.element.selectionEnd
211
+ });
212
+ triggerMaskChangeEvent.call(this, event, value);
213
+ this.element.setSelectionRange(0, 0);
214
+ }
215
+ function resetFormHandler(): void {
216
+ if (this.element.tagName === 'EJS-MASKEDTEXTBOX') {
217
+ setElementValue.call(this, this.promptMask);
218
+ } else {
219
+ this.value = this.initInputValue;
220
+ }
221
+ }
222
+
223
+ /**
224
+ * To get masked value from the MaskedTextBox.
225
+ *
226
+ * @hidden
227
+ */
228
+ export function unstrippedValue(element: HTMLInputElement): string {
229
+ return element.value;
230
+ }
231
+
232
+ /**
233
+ * To extract raw value from the MaskedTextBox.
234
+ *
235
+ * @hidden
236
+ */
237
+ export function strippedValue(element: HTMLInputElement, maskValues: string): string {
238
+ let value: string = '';
239
+ let k: number = 0;
240
+ let checkMask: boolean = false;
241
+ const maskValue: string = (!isNullOrUndefined(maskValues)) ? maskValues : (!isNullOrUndefined(element) &&
242
+ !isNullOrUndefined(this)) ? element.value : maskValues;
243
+ if (maskValue !== this.promptMask) {
244
+ for (let i: number = 0; i < this.customRegExpCollec.length; i++) {
245
+ if (checkMask) {
246
+ checkMask = false;
247
+ }
248
+ if (this.customRegExpCollec[k as number] === '>' || this.customRegExpCollec[k as number] === '<' ||
249
+ this.customRegExpCollec[k as number] === '|' || this.customRegExpCollec[k as number] === '\\') {
250
+ --i;
251
+ checkMask = true;
252
+ }
253
+ if (!checkMask) {
254
+ if ((maskValue[i as number] !== this.promptChar) && (!isNullOrUndefined(this.customRegExpCollec[k as number]) &&
255
+ ((this._callPasteHandler || (!isNullOrUndefined(this.regExpCollec[this.customRegExpCollec[k as number]]) &&
256
+ !this.maskedRegExp.includes(this.customRegExpCollec[k as number]))) ||
257
+ (this.customRegExpCollec[k as number].length > 2 && this.customRegExpCollec[k as number][0] === '[' &&
258
+ this.customRegExpCollec[k as number][this.customRegExpCollec[k as number].length - 1] === ']') ||
259
+ (!isNullOrUndefined(this.customCharacters) &&
260
+ (!isNullOrUndefined(this.customCharacters[this.customRegExpCollec[k as number]]))))) && (maskValue !== '')) {
261
+ value += maskValue[i as number];
262
+ }
263
+ }
264
+ ++k;
265
+ }
266
+ }
267
+ if (this.mask === null || this.mask === '' && this.value !== undefined) {
268
+ value = maskValue;
269
+ }
270
+ return value;
271
+ }
272
+
273
+ function pushIntoRegExpCollec(value: string): void {
274
+ for (let k: number = 0; k < value.length; k++) {
275
+ this.hiddenMask += value[k as number];
276
+ if (value[k as number] !== '\\') {
277
+ this.customRegExpCollec.push(value[k as number]);
278
+ }
279
+ else if (value[k as number] === '\\' && !isNullOrUndefined(this.regExpCollec[value[k as number + 1]])) {
280
+ this.maskedRegExp.push(value[k as number + 1]);
281
+ }
282
+ }
283
+ }
284
+
285
+ export function maskInputMouseDownHandler(): void {
286
+ this.isClicked = true;
287
+ }
288
+
289
+ export function maskInputMouseUpHandler(): void {
290
+ this.isClicked = false;
291
+ }
292
+
293
+ export function maskInputFocusHandler(event: MouseEvent | FocusEvent | TouchEvent | KeyboardEvent): void {
294
+ const inputElement: HTMLInputElement = this.element;
295
+ let startIndex: number = 0;
296
+ const modelValue: string = strippedValue.call(this, inputElement);
297
+ let toAllowForward: boolean = false;
298
+ let toAllowBackward: boolean = false;
299
+ let eventArgs: MaskFocusEventArgs = {
300
+ selectionStart: inputElement.selectionStart,
301
+ event: event,
302
+ value: this.value,
303
+ maskedValue: inputElement.value,
304
+ container: !isNullOrUndefined(this.inputObj) ? this.inputObj.container : this.inputObj,
305
+ selectionEnd: inputElement.selectionEnd
306
+ };
307
+ if (!this.isClicked) {
308
+ triggerFocus.call(this, eventArgs, inputElement);
309
+ }
310
+ if (this.mask) {
311
+ if (!(!(modelValue === null || modelValue === '') || this.floatLabelType === 'Always' ||
312
+ this.placeholder === null || this.placeholder === '')) {
313
+ inputElement.value = this.promptMask;
314
+ }
315
+ setTimeout(() => {
316
+ if (inputElement.selectionStart === this.promptMask.length ||
317
+ inputElement.value[inputElement.selectionStart] === this.promptChar) {
318
+ toAllowForward = true;
319
+ } else {
320
+ for (let i: number = inputElement.selectionStart; i < this.promptMask.length; i++) {
321
+ if (inputElement.value[i as number] !== this.promptChar) {
322
+ if ((inputElement.value[i as number] !== this.promptMask[i as number])) {
323
+ toAllowForward = false;
324
+ break;
325
+ }
326
+ } else {
327
+ toAllowForward = true;
328
+ break;
329
+ }
330
+ }
331
+ }
332
+ });
333
+ setTimeout(() => {
334
+ const backSelectionStart: number = inputElement.selectionStart - 1;
335
+ if (backSelectionStart === this.promptMask.length - 1 ||
336
+ inputElement.value[backSelectionStart as number] === this.promptChar) {
337
+ toAllowBackward = true;
338
+ } else {
339
+ for (let i: number = backSelectionStart; i >= 0; i--) {
340
+ if (inputElement.value[i as number] !== this.promptChar) {
341
+ if ((inputElement.value[i as number] !== this.promptMask[i as number])) {
342
+ toAllowBackward = false;
343
+ break;
344
+ }
345
+ } else {
346
+ toAllowBackward = true;
347
+ break;
348
+ }
349
+ }
350
+ }
351
+ });
352
+ if ((this.isClicked || (this.floatLabelType !== 'Always' &&
353
+ ((modelValue === null || modelValue === '') &&
354
+ (this.placeholder !== null && this.placeholder !== ''))))) {
355
+ for (startIndex = 0; startIndex < this.promptMask.length; startIndex++) {
356
+ if (inputElement.value[startIndex as number] === this.promptChar) {
357
+ setTimeout(() => {
358
+ if (toAllowForward || toAllowBackward) {
359
+ inputElement.selectionEnd = startIndex;
360
+ inputElement.selectionStart = startIndex;
361
+ }
362
+ eventArgs = {
363
+ selectionStart: inputElement.selectionStart,
364
+ event: event,
365
+ value: this.value,
366
+ maskedValue: inputElement.value,
367
+ container: !isNullOrUndefined(this.inputObj) ? this.inputObj.container : this.inputObj,
368
+ selectionEnd: inputElement.selectionEnd
369
+ };
370
+ triggerFocus.call(this, eventArgs, inputElement);
371
+ }, 110);
372
+ break;
373
+ }
374
+ }
375
+ if (isNullOrUndefined(inputElement.value.match(escapeRegExp(this.promptChar)))) {
376
+ eventArgs = {
377
+ selectionStart: inputElement.selectionStart,
378
+ event: event,
379
+ value: this.value,
380
+ maskedValue: inputElement.value,
381
+ container: !isNullOrUndefined(this.inputObj) ? this.inputObj.container : this.inputObj,
382
+ selectionEnd: inputElement.selectionEnd
383
+ };
384
+ triggerFocus.call(this, eventArgs, inputElement);
385
+ }
386
+ this.isClicked = false;
387
+ }
388
+ }
389
+ }
390
+
391
+ export function triggerFocus(eventArgs: MaskFocusEventArgs, inputElement: HTMLInputElement): void {
392
+ this.trigger('focus', eventArgs, (eventArgs: MaskFocusEventArgs) => {
393
+ inputElement.selectionStart = eventArgs.selectionStart;
394
+ inputElement.selectionEnd = eventArgs.selectionEnd;
395
+ });
396
+ }
397
+
398
+ export function escapeRegExp(text: string): string {
399
+ return !isNullOrUndefined(text) ? text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') : text;
400
+ }
401
+
402
+ export function maskInputBlurHandler(event: MouseEvent | FocusEvent | TouchEvent | KeyboardEvent): void {
403
+ this.blurEventArgs = {
404
+ event: event,
405
+ value: this.value,
406
+ maskedValue: this.element.value,
407
+ container: !isNullOrUndefined(this.inputObj) ? this.inputObj.container : this.inputObj
408
+ };
409
+ this.trigger('blur', this.blurEventArgs);
410
+ if (this.mask) {
411
+ this.isFocus = false;
412
+ if (this.placeholder && this.element.value === this.promptMask && this.floatLabelType !== 'Always') {
413
+ setElementValue.call(this, '');
414
+ const labelElement: HTMLElement = <HTMLElement>this.element.parentNode.querySelector('.e-float-text');
415
+ if (this.floatLabelType === 'Auto' && !isNullOrUndefined(labelElement) && labelElement.classList.contains(TOPLABEL)) {
416
+ removeClass([labelElement], TOPLABEL);
417
+ }
418
+ }
419
+ }
420
+ }
421
+
422
+ function maskInputPasteHandler(event: KeyboardEvent): void {
423
+ if (this.mask && !this.readonly) {
424
+ const sIndex: number = this.element.selectionStart;
425
+ const eIndex: number = this.element.selectionEnd;
426
+ const oldValue: string = this.element.value;
427
+ setElementValue.call(this, '');
428
+ this._callPasteHandler = true;
429
+ setTimeout(
430
+ () => {
431
+ let value: string = this.element.value.replace(/ /g, '');
432
+ if (this.redoCollec.length > 0 && this.redoCollec[0].value === this.element.value) {
433
+ value = strippedValue.call(this, this.element);
434
+ }
435
+ setElementValue.call(this, oldValue);
436
+ this.element.selectionStart = sIndex;
437
+ this.element.selectionEnd = eIndex;
438
+ let i: number = 0;
439
+ this.maskKeyPress = true;
440
+ do {
441
+ validateValue.call(this, value[i as number], false, null); ++i;
442
+ } while (i < value.length);
443
+ this.maskKeyPress = false;
444
+ this._callPasteHandler = false;
445
+ if (this.element.value === oldValue) {
446
+ let i: number = 0;
447
+ this.maskKeyPress = true;
448
+ do {
449
+ validateValue.call(this, value[i as number], false, null); ++i;
450
+ } while (i < value.length);
451
+ this.maskKeyPress = false;
452
+ } else {
453
+ triggerMaskChangeEvent.call(this, event, oldValue);
454
+ }
455
+ },
456
+ 1);
457
+ }
458
+ }
459
+
460
+ function maskInputCutHandler(event: KeyboardEvent): void {
461
+ if (this.mask && !this.readonly) {
462
+ const preValue: string = this.element.value;
463
+ const sIndex: number = this.element.selectionStart;
464
+ const eIndex: number = this.element.selectionEnd;
465
+ this.undoCollec.push({ value: this.element.value, startIndex: this.element.selectionStart, endIndex: this.element.selectionEnd });
466
+ const value: string = this.element.value.substring(0, sIndex) + this.promptMask.substring(sIndex, eIndex) +
467
+ this.element.value.substring(eIndex);
468
+ setTimeout(
469
+ () => {
470
+ setElementValue.call(this, value);
471
+ this.element.selectionStart = this.element.selectionEnd = sIndex;
472
+ if (this.element.value !== preValue) {
473
+ triggerMaskChangeEvent.call(this, event, null);
474
+ }
475
+ },
476
+ 0);
477
+ }
478
+ }
479
+
480
+ export function maskInputDropHandler(event: MouseEvent): void {
481
+ event.preventDefault();
482
+ }
483
+
484
+ function maskInputHandler(event: KeyboardEvent): void {
485
+ if (Browser.isIE === true && this.element.value === '' && this.floatLabelType === 'Never') {
486
+ return;
487
+ }
488
+ const eventArgs: Object = { ctrlKey: false, keyCode: 229 };
489
+ extend(event, eventArgs);
490
+ if (this.mask) {
491
+ if (this.element.value === '') {
492
+ this.redoCollec.unshift({
493
+ value: this.promptMask, startIndex: this.element.selectionStart, endIndex: this.element.selectionEnd
494
+ });
495
+ }
496
+ if (this.element.value.length === 1) {
497
+ this.element.value = this.element.value + this.promptMask;
498
+ this.element.setSelectionRange(1, 1);
499
+ }
500
+ if ((!this._callPasteHandler && !Browser.isDevice) || this._callPasteHandler) {
501
+ removeMaskInputValues.call(this, event);
502
+ }
503
+ if (this.element.value.length > this.promptMask.length) {
504
+ const startIndex: number = this.element.selectionStart;
505
+ const addedValues: number = this.element.value.length - this.promptMask.length;
506
+ const value: string = this.element.value.substring(startIndex - addedValues, startIndex);
507
+ this.maskKeyPress = false;
508
+ let i: number = 0;
509
+ do {
510
+ validateValue.call(this, value[i as number], event.ctrlKey, event); ++i;
511
+ } while (i < value.length);
512
+ if (this.element.value !== this.preEleVal) {
513
+ triggerMaskChangeEvent.call(this, event, null);
514
+ }
515
+ }
516
+ const val: string = strippedValue.call(this, this.element);
517
+ this.prevValue = val;
518
+ this.value = val;
519
+ if (val === '') {
520
+ setElementValue.call(this, this.promptMask);
521
+ this.element.setSelectionRange(0, 0);
522
+ }
523
+ }
524
+ }
525
+
526
+ function maskInputKeyDownHandler(event: KeyboardEvent): void {
527
+ if (this.mask && !this.readonly) {
528
+ if (event.keyCode !== 229) {
529
+ if (event.ctrlKey && (event.keyCode === 89 || event.keyCode === 90)) {
530
+ event.preventDefault();
531
+ }
532
+ removeMaskInputValues.call(this, event);
533
+ }
534
+ const startValue: string = this.element.value;
535
+ if (event.ctrlKey && (event.keyCode === 89 || event.keyCode === 90)) {
536
+ let collec: { value: string; startIndex: number; endIndex: number };
537
+ if (event.keyCode === 90 && this.undoCollec.length > 0 && startValue !== this.undoCollec[this.undoCollec.length - 1].value) {
538
+ collec = this.undoCollec[this.undoCollec.length - 1];
539
+ this.redoCollec.unshift({
540
+ value: this.element.value, startIndex: this.element.selectionStart,
541
+ endIndex: this.element.selectionEnd
542
+ });
543
+ setElementValue.call(this, collec.value);
544
+ this.element.selectionStart = collec.startIndex;
545
+ this.element.selectionEnd = collec.endIndex;
546
+ this.undoCollec.splice(this.undoCollec.length - 1, 1);
547
+ } else if (event.keyCode === 89 && this.redoCollec.length > 0 && startValue !== this.redoCollec[0].value) {
548
+ collec = this.redoCollec[0];
549
+ this.undoCollec.push({
550
+ value: this.element.value, startIndex: this.element.selectionStart,
551
+ endIndex: this.element.selectionEnd
552
+ });
553
+ setElementValue.call(this, collec.value);
554
+ this.element.selectionStart = collec.startIndex;
555
+ this.element.selectionEnd = collec.endIndex;
556
+ this.redoCollec.splice(0, 1);
557
+ }
558
+ }
559
+ }
560
+ }
561
+
562
+ export function mobileRemoveFunction(): void {
563
+ let collec: { value: string; startIndex: number; endIndex: number };
564
+ const sIndex: number = this.element.selectionStart;
565
+ const eIndex: number = this.element.selectionEnd;
566
+ if (this.redoCollec.length > 0) {
567
+ collec = this.redoCollec[0];
568
+ setElementValue.call(this, collec.value);
569
+ if ((collec.startIndex - sIndex) === 1) {
570
+ this.element.selectionStart = collec.startIndex;
571
+ this.element.selectionEnd = collec.endIndex;
572
+ } else {
573
+ this.element.selectionStart = sIndex + 1;
574
+ this.element.selectionEnd = eIndex + 1;
575
+ }
576
+ } else {
577
+ setElementValue.call(this, this.promptMask);
578
+ this.element.selectionStart = this.element.selectionEnd = sIndex;
579
+ }
580
+ }
581
+
582
+ function autoFillMaskInputValues(isRemove: boolean, oldEventVal: string, event: KeyboardEvent): boolean {
583
+ if (event.type === 'input') {
584
+ isRemove = false;
585
+ oldEventVal = this.element.value;
586
+ setElementValue.call(this, this.promptMask);
587
+ setMaskValue.call(this, oldEventVal);
588
+ }
589
+ return isRemove;
590
+ }
591
+
592
+ function removeMaskInputValues(event: KeyboardEvent): void {
593
+ let isRemove: boolean = false;
594
+ let oldEventVal: string;
595
+ let isDeleted: boolean = false;
596
+ if (this.element.value.length < this.promptMask.length) {
597
+ isRemove = true;
598
+ oldEventVal = this.element.value;
599
+ isRemove = autoFillMaskInputValues.call(this, isRemove, oldEventVal, event);
600
+ mobileRemoveFunction.call(this);
601
+ }
602
+ if (this.element.value.length >= this.promptMask.length && event.type === 'input') {
603
+ isRemove = autoFillMaskInputValues.call(this, isRemove, oldEventVal, event);
604
+ }
605
+ const initStartIndex: number = this.element.selectionStart;
606
+ const initEndIndex: number = this.element.selectionEnd;
607
+ let startIndex: number = this.element.selectionStart;
608
+ const endIndex: number = this.element.selectionEnd;
609
+ const maskValue: string = this.hiddenMask.replace(/[>|\\<]/g, '');
610
+ let curMask: string = maskValue[startIndex - 1];
611
+ const deleteEndIndex: number = this.element.selectionEnd;
612
+ if (isRemove || event.keyCode === 8 || event.keyCode === 46) {
613
+ this.undoCollec.push({ value: this.element.value, startIndex: this.element.selectionStart, endIndex: endIndex });
614
+ let multipleDel: boolean = false;
615
+ const preValue: string = this.element.value;
616
+ if (startIndex > 0 || ((event.keyCode === 8 || event.keyCode === 46) && startIndex < this.element.value.length
617
+ && ((this.element.selectionEnd - startIndex) !== this.element.value.length))) {
618
+ let index: number = startIndex;
619
+ if (startIndex !== endIndex) {
620
+ startIndex = endIndex;
621
+ if (event.keyCode === 46) {
622
+ multipleDel = true;
623
+ }
624
+ } else if (event.keyCode === 46) {
625
+ ++index;
626
+ } else {
627
+ --index;
628
+ }
629
+ for (let k: number = startIndex; (event.keyCode === 8 || isRemove || multipleDel) ? k > index : k < index;
630
+ (event.keyCode === 8 || isRemove || multipleDel) ? k-- : k++) {
631
+ for (let i: number = startIndex; (event.keyCode === 8 || isRemove || multipleDel) ? i > 0 : i < this.element.value.length;
632
+ (event.keyCode === 8 || isRemove || multipleDel) ? i-- : i++) {
633
+ let sIndex: number;
634
+ if (((event.keyCode === 8 || multipleDel) && ((initStartIndex !== initEndIndex && initStartIndex !== startIndex) ||
635
+ (initStartIndex === initEndIndex))) || isRemove) {
636
+ curMask = maskValue[i - 1];
637
+ sIndex = startIndex - 1;
638
+ } else {
639
+ curMask = maskValue[i as number];
640
+ sIndex = startIndex;
641
+ ++startIndex;
642
+ }
643
+ let oldValue: string = this.element.value[sIndex as number];
644
+ if ((isNullOrUndefined(this.regExpCollec[`${curMask}`]) && (!isNullOrUndefined(this.customCharacters)
645
+ && isNullOrUndefined(this.customCharacters[`${curMask}`]))
646
+ && ((this.hiddenMask[sIndex as number] !== this.promptChar && this.customRegExpCollec[sIndex as number][0] !== '['
647
+ && this.customRegExpCollec[sIndex as number][this.customRegExpCollec[sIndex as number].length - 1] !== ']')))
648
+ || (this.promptMask[sIndex as number] !== this.promptChar && isNullOrUndefined(this.customCharacters))) {
649
+ this.element.selectionStart = this.element.selectionEnd = sIndex;
650
+ event.preventDefault();
651
+ if (event.keyCode === 46 && !multipleDel) {
652
+ ++this.element.selectionStart;
653
+ }
654
+ } else {
655
+ const value: string = this.element.value;
656
+ const prompt: string = this.promptChar;
657
+ const elementValue: string = value.substring(0, sIndex) + prompt + value.substring(startIndex, value.length);
658
+ setElementValue.call(this, elementValue);
659
+ event.preventDefault();
660
+ if (event.keyCode === 46 && !multipleDel) {
661
+ sIndex++;
662
+ }
663
+ this.element.selectionStart = this.element.selectionEnd = sIndex;
664
+ isDeleted = true;
665
+ }
666
+ startIndex = this.element.selectionStart;
667
+ if ((!isDeleted && event.keyCode === 8) || multipleDel || (!isDeleted && !(event.keyCode === 46))) {
668
+ sIndex = startIndex - 1;
669
+ } else {
670
+ sIndex = startIndex;
671
+ isDeleted = false;
672
+ }
673
+ oldValue = this.element.value[sIndex as number];
674
+ if (((initStartIndex !== initEndIndex) && (this.element.selectionStart === initStartIndex))
675
+ || (this.promptMask[sIndex as number] === this.promptChar) || ((oldValue !== this.promptMask[sIndex as number]) &&
676
+ (this.promptMask[sIndex as number] !== this.promptChar) && !isNullOrUndefined(this.customCharacters))) {
677
+ break;
678
+ }
679
+ }
680
+ }
681
+ }
682
+ if (event.keyCode === 46 && multipleDel && isDeleted) {
683
+ this.element.selectionStart = this.element.selectionEnd = deleteEndIndex;
684
+ }
685
+ if (this.element.selectionStart === 0 && (this.element.selectionEnd === this.element.value.length)) {
686
+ setElementValue.call(this, this.promptMask);
687
+ event.preventDefault();
688
+ this.element.selectionStart = this.element.selectionEnd = startIndex;
689
+ }
690
+ this.redoCollec.unshift({
691
+ value: this.element.value, startIndex: this.element.selectionStart,
692
+ endIndex: this.element.selectionEnd
693
+ });
694
+ if (this.element.value !== preValue) {
695
+ triggerMaskChangeEvent.call(this, event, oldEventVal);
696
+ }
697
+ }
698
+ }
699
+
700
+ function maskInputKeyPressHandler(event: KeyboardEvent): void {
701
+ if (this.mask && !this.readonly) {
702
+ const oldValue: string = this.element.value;
703
+ if (!(event.ctrlKey || event.metaKey) || ((event.ctrlKey || event.metaKey) && event.code !== 'KeyA' && event.code !== 'KeyY'
704
+ && event.code !== 'KeyZ' && event.code !== 'KeyX' && event.code !== 'KeyC' && event.code !== 'KeyV')) {
705
+ this.maskKeyPress = true;
706
+ let key: string = event.key;
707
+ if (key === 'Spacebar') {
708
+ key = String.fromCharCode(event.keyCode);
709
+ }
710
+ if (!key) {
711
+ this.isIosInvalid = true;
712
+ validateValue.call(this, String.fromCharCode(event.keyCode), event.ctrlKey, event);
713
+ event.preventDefault();
714
+ this.isIosInvalid = false;
715
+ } else if (key && key.length === 1) {
716
+ validateValue.call(this, key, event.ctrlKey, event);
717
+ event.preventDefault();
718
+ }
719
+ if (event.keyCode === 32 && key === ' ' && this.promptChar === ' ') {
720
+ this.element.selectionStart = this.element.selectionEnd = this.element.selectionStart - key.length;
721
+ }
722
+ }
723
+ if (this.element.value !== oldValue) {
724
+ triggerMaskChangeEvent.call(this, event, oldValue);
725
+ }
726
+ }
727
+ }
728
+
729
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
730
+ function triggerMaskChangeEvent(event: KeyboardEvent, oldValue: string): void {
731
+ const prevOnChange : boolean = this.isProtectedOnChange;
732
+ if (!isNullOrUndefined(this.changeEventArgs) && !this.isInitial) {
733
+ const eventArgs: Object = {};
734
+ this.changeEventArgs = { value: this.element.value, maskedValue: this.element.value, isInteraction: false, isInteracted: false };
735
+ if (this.mask) {
736
+ this.changeEventArgs.value = strippedValue.call(this, this.element);
737
+ }
738
+ if (!isNullOrUndefined(event)) {
739
+ this.changeEventArgs.isInteracted = true;
740
+ this.changeEventArgs.isInteraction = true;
741
+ this.changeEventArgs.event = event;
742
+ }
743
+ this.isProtectedOnChange = true;
744
+ this.value = this.changeEventArgs.value;
745
+ this.isProtectedOnChange = prevOnChange;
746
+ merge(eventArgs, this.changeEventArgs);
747
+ /* istanbul ignore next */
748
+ if (this.isAngular && this.preventChange) {
749
+ this.preventChange = false;
750
+ } else {
751
+ this.trigger('change', eventArgs);
752
+ }
753
+ }
754
+ this.preEleVal = this.element.value;
755
+ this.prevValue = strippedValue.call(this, this.element);
756
+ }
757
+
758
+ function maskInputKeyUpHandler(event: KeyboardEvent): void {
759
+ if (this.mask && !this.readonly) {
760
+ let collec: { value: string; startIndex: number; endIndex: number };
761
+ if (!this.maskKeyPress && event.keyCode === 229) {
762
+ let oldEventVal: string;
763
+ if (this.element.value.length === 1) {
764
+ this.element.value = this.element.value + this.promptMask;
765
+ this.element.setSelectionRange(1, 1);
766
+ }
767
+ if (this.element.value.length > this.promptMask.length) {
768
+ const startIndex: number = this.element.selectionStart;
769
+ const addedValues: number = this.element.value.length - this.promptMask.length;
770
+ let val: string = this.element.value.substring(startIndex - addedValues, startIndex);
771
+ if (this.undoCollec.length > 0) {
772
+ collec = this.undoCollec[this.undoCollec.length - 1];
773
+ const startIndex: number = this.element.selectionStart;
774
+ oldEventVal = collec.value;
775
+ const oldVal: string = collec.value.substring(startIndex - addedValues, startIndex);
776
+ collec = this.redoCollec[0];
777
+ val = val.trim();
778
+ const isSpace: boolean = Browser.isAndroid && val === '';
779
+ if (!isSpace && oldVal !== val && collec.value.substring(startIndex - addedValues, startIndex) !== val) {
780
+ validateValue.call(this, val, event.ctrlKey, event);
781
+ } else if (isSpace) {
782
+ preventUnsupportedValues.call(
783
+ this, event, startIndex - 1, this.element.selectionEnd - 1, val, event.ctrlKey, false);
784
+ }
785
+ } else {
786
+ oldEventVal = this.promptMask;
787
+ validateValue.call(this, val, event.ctrlKey, event);
788
+ }
789
+ this.maskKeyPress = false;
790
+ triggerMaskChangeEvent.call(this, event, oldEventVal);
791
+ }
792
+ } else {
793
+ removeMaskError.call(this);
794
+ }
795
+ const val: string = strippedValue.call(this, this.element);
796
+ if (!((this.element.selectionStart === 0) && (this.promptMask === this.element.value) && val === '')
797
+ || (val === '' && this.value !== val)) {
798
+ this.prevValue = val;
799
+ this.value = val;
800
+ }
801
+ } else {
802
+ triggerMaskChangeEvent.call(this, event);
803
+ }
804
+ if (this.element.selectionStart === 0 && this.element.selectionEnd === 0) {
805
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
806
+ const temp: any = this.element;
807
+ setTimeout(
808
+ () => {
809
+ temp.setSelectionRange(0, 0);
810
+ },
811
+ 0);
812
+ }
813
+ }
814
+
815
+ function mobileSwipeCheck(key: string): void {
816
+ if (key.length > 1 && ((this.promptMask.length + key.length) < this.element.value.length)) {
817
+ const elementValue: string = this.redoCollec[0].value.substring(0, this.redoCollec[0].startIndex) + key +
818
+ this.redoCollec[0].value.substring(this.redoCollec[0].startIndex, this.redoCollec[0].value.length);
819
+ setElementValue.call(this, elementValue);
820
+ this.element.selectionStart = this.element.selectionEnd = this.redoCollec[0].startIndex + key.length;
821
+ }
822
+ this.element.selectionStart = this.element.selectionStart - key.length;
823
+ this.element.selectionEnd = this.element.selectionEnd - key.length;
824
+ }
825
+
826
+ function mobileValidation(key: string): void {
827
+ if (!this.maskKeyPress) {
828
+ mobileSwipeCheck.call(this, key);
829
+ }
830
+ }
831
+
832
+ function validateValue(key: string, isCtrlKey: boolean, event: KeyboardEvent): void {
833
+ mobileValidation.call(this, key);
834
+ if (isNullOrUndefined(this) || isNullOrUndefined(key)) {
835
+ return;
836
+ }
837
+ let startIndex: number = this.element.selectionStart;
838
+ const initStartIndex: number = startIndex;
839
+ let curMask: string;
840
+ let allowText: boolean = false;
841
+ const value: string = this.element.value;
842
+ let eventOldVal: string;
843
+ let prevSupport: boolean = false;
844
+ let isEqualVal: boolean = false;
845
+ for (let k: number = 0; k < key.length; k++) {
846
+ const keyValue: string = key[k as number];
847
+ startIndex = this.element.selectionStart;
848
+ if (!this.maskKeyPress && initStartIndex === startIndex) {
849
+ startIndex = startIndex + k;
850
+ }
851
+ if ((!this.maskKeyPress || startIndex < this.promptMask.length)) {
852
+ for (let i: number = startIndex; i < this.promptMask.length; i++) {
853
+ const maskValue: string = this.escapeMaskValue;
854
+ curMask = maskValue[startIndex as number];
855
+ if (this.hiddenMask[startIndex as number] === '\\' && this.hiddenMask[startIndex + 1] === key) {
856
+ isEqualVal = true;
857
+ }
858
+ if ((isNullOrUndefined(this.regExpCollec[`${curMask}`]) && (isNullOrUndefined(this.customCharacters)
859
+ || (!isNullOrUndefined(this.customCharacters) && isNullOrUndefined(this.customCharacters[`${curMask}`])))
860
+ && ((this.hiddenMask[startIndex as number] !== this.promptChar && this.customRegExpCollec[startIndex as number][0] !== '['
861
+ && this.customRegExpCollec[startIndex as number][this.customRegExpCollec[startIndex as number].length - 1] !== ']')))
862
+ || ((this.promptMask[startIndex as number] !== this.promptChar) && isNullOrUndefined(this.customCharacters))
863
+ || (this.promptChar === curMask && this.escapeMaskValue === this.mask)) {
864
+ this.element.selectionStart = this.element.selectionEnd = startIndex + 1;
865
+ startIndex = this.element.selectionStart;
866
+ curMask = this.hiddenMask[startIndex as number];
867
+ }
868
+ }
869
+ if (!isNullOrUndefined(this.customCharacters) && !isNullOrUndefined(this.customCharacters[`${curMask}`])) {
870
+ const customValStr: string = <string>this.customCharacters[`${curMask}`];
871
+ const customValArr: string[] = customValStr.split(',');
872
+ for (let i: number = 0; i < customValArr.length; i++) {
873
+ /* eslint-disable-next-line security/detect-non-literal-regexp */
874
+ if (keyValue.match(new RegExp('[' + customValArr[i as number] + ']'))) {
875
+ allowText = true;
876
+ break;
877
+ }
878
+ }
879
+ /* eslint-disable-next-line security/detect-non-literal-regexp */
880
+ } else if (!isNullOrUndefined(this.regExpCollec[`${curMask}`]) && keyValue.match(new RegExp(this.regExpCollec[`${curMask}`]))
881
+ && this.promptMask[startIndex as number] === this.promptChar) {
882
+ allowText = true;
883
+ } else if (this.promptMask[startIndex as number] === this.promptChar && this.customRegExpCollec[startIndex as number][0] === '['
884
+ && this.customRegExpCollec[startIndex as number][this.customRegExpCollec[startIndex as number].length - 1] === ']'
885
+ /* eslint-disable-next-line security/detect-non-literal-regexp */
886
+ && keyValue.match(new RegExp(this.customRegExpCollec[startIndex as number]))) {
887
+ allowText = true;
888
+ }
889
+ if ((!this.maskKeyPress || startIndex < this.hiddenMask.length) && allowText) {
890
+ if (k === 0) {
891
+ if (this.maskKeyPress) {
892
+ this.undoCollec.push({ value: value, startIndex: startIndex, endIndex: startIndex });
893
+ } else {
894
+ const sIndex: number = this.element.selectionStart;
895
+ const eIndex: number = this.element.selectionEnd;
896
+ if (this.redoCollec.length > 0) {
897
+ eventOldVal = this.redoCollec[0].value;
898
+ setElementValue.call(this, eventOldVal);
899
+ this.undoCollec.push(this.redoCollec[0]);
900
+ } else {
901
+ this.undoCollec.push({ value: this.promptMask, startIndex: startIndex, endIndex: startIndex });
902
+ eventOldVal = this.promptMask;
903
+ setElementValue.call(this, eventOldVal);
904
+ }
905
+ this.element.selectionStart = sIndex;
906
+ this.element.selectionEnd = eIndex;
907
+ }
908
+ }
909
+ startIndex = this.element.selectionStart;
910
+ applySupportedValues.call(this, event, startIndex, keyValue, eventOldVal, isEqualVal);
911
+ prevSupport = true;
912
+ if (k === key.length - 1) {
913
+ this.redoCollec.unshift({
914
+ value: this.element.value, startIndex: this.element.selectionStart, endIndex: this.element.selectionEnd
915
+ });
916
+ }
917
+ allowText = false;
918
+ } else {
919
+ startIndex = this.element.selectionStart;
920
+ preventUnsupportedValues.call(this, event, startIndex, initStartIndex, key, isCtrlKey, prevSupport);
921
+ }
922
+ if (k === key.length - 1 && !allowText) {
923
+ if (!Browser.isAndroid || (Browser.isAndroid && startIndex < this.promptMask.length)) {
924
+ this.redoCollec.unshift({
925
+ value: this.element.value, startIndex: this.element.selectionStart, endIndex: this.element.selectionEnd
926
+ });
927
+ }
928
+ }
929
+ } else {
930
+ if (key.length === 1 && !isCtrlKey && !isNullOrUndefined(event)) {
931
+ addMaskErrorClass.call(this);
932
+ }
933
+ }
934
+ }
935
+ }
936
+
937
+ function applySupportedValues(event: KeyboardEvent, startIndex: number, keyValue: string, eventOldVal: string, isEqualVal: boolean): void {
938
+ if (this.hiddenMask.length > this.promptMask.length) {
939
+ keyValue = changeToLowerUpperCase.call(this, keyValue, this.element.value);
940
+ }
941
+ if (!isEqualVal) {
942
+ const value: string = this.element.value;
943
+ const elementValue: string = value.substring(0, startIndex) + keyValue + value.substring(startIndex + 1, value.length);
944
+ setElementValue.call(this, elementValue);
945
+ this.element.selectionStart = this.element.selectionEnd = startIndex + 1;
946
+ }
947
+ }
948
+
949
+ function preventUnsupportedValues(event: KeyboardEvent, sIdx: number, idx: number, key: string, ctrl: boolean, chkSupport: boolean): void {
950
+ if (!this.maskKeyPress) {
951
+ const value: string = this.element.value;
952
+ if (sIdx >= this.promptMask.length) {
953
+ setElementValue.call(this, value.substring(0, sIdx));
954
+ } else {
955
+ if (idx === sIdx) {
956
+ setElementValue.call(this, value.substring(0, sIdx) + value.substring(sIdx + 1, value.length));
957
+ } else {
958
+ if (this.promptMask.length === this.element.value.length) {
959
+ setElementValue.call(this, value.substring(0, sIdx) + value.substring(sIdx, value.length));
960
+ } else {
961
+ setElementValue.call(this, value.substring(0, idx) + value.substring(idx + 1, value.length));
962
+ }
963
+ }
964
+ this.element.selectionStart = this.element.selectionEnd = (chkSupport ||
965
+ this.element.value[idx as number] !== this.promptChar) ? sIdx : idx;
966
+ }
967
+ addMaskErrorClass.call(this);
968
+ }
969
+ if (key.length === 1 && !ctrl && !isNullOrUndefined(event)) {
970
+ addMaskErrorClass.call(this);
971
+ }
972
+ }
973
+
974
+ function addMaskErrorClass(): void {
975
+ const parentElement: HTMLElement = <HTMLElement>this.element.parentNode;
976
+ let timer: number = 200;
977
+ if (parentElement.classList.contains(INPUTGROUP) || parentElement.classList.contains(FLOATINPUT)) {
978
+ addClass([parentElement], ERROR);
979
+ } else {
980
+ addClass([this.element], ERROR);
981
+ }
982
+ if (this.isIosInvalid === true) {
983
+ timer = 400;
984
+ }
985
+ attributes(this.element, { 'aria-invalid': 'true' });
986
+ setTimeout(
987
+ () => {
988
+ if (!this.maskKeyPress) {
989
+ removeMaskError.call(this);
990
+ }
991
+ },
992
+ timer);
993
+ }
994
+
995
+ function removeMaskError(): void {
996
+ const parentElement: HTMLElement = <HTMLElement>this.element.parentNode;
997
+ if (!isNullOrUndefined( parentElement)) {
998
+ removeClass([parentElement], ERROR);
999
+ }
1000
+ removeClass([this.element], ERROR);
1001
+ attributes(this.element, { 'aria-invalid': 'false' });
1002
+ }
1003
+
1004
+ /**
1005
+ * Validates user input using masking elements '<' , '>' and '|'.
1006
+ *
1007
+ * @hidden
1008
+ */
1009
+ function changeToLowerUpperCase(key: string, value: string): string {
1010
+ let promptMask: string;
1011
+ let i: number;
1012
+ let curVal: string = value;
1013
+ let caseCount: number = 0;
1014
+ for (i = 0; i < this.hiddenMask.length; i++) {
1015
+ if (this.hiddenMask[i as number] === '\\') {
1016
+ promptMask = curVal.substring(0, i) + '\\' + curVal.substring(i, curVal.length);
1017
+ }
1018
+ if (this.hiddenMask[i as number] === '>' || this.hiddenMask[i as number] === '<' || this.hiddenMask[i as number] === '|') {
1019
+ if (this.hiddenMask[i as number] !== curVal[i as number]) {
1020
+ promptMask = curVal.substring(0, i) + this.hiddenMask[i as number] + curVal.substring(i, curVal.length);
1021
+ }
1022
+ ++caseCount;
1023
+ }
1024
+ if (promptMask) {
1025
+ if (((promptMask[i as number] === this.promptChar) && (i > this.element.selectionStart)) ||
1026
+ (this.element.value.indexOf(this.promptChar) < 0 && (this.element.selectionStart + caseCount) === i)) {
1027
+ caseCount = 0;
1028
+ break;
1029
+ }
1030
+ curVal = promptMask;
1031
+ }
1032
+ }
1033
+ while (i >= 0 && promptMask) {
1034
+ if (i === 0 || promptMask[i - 1] !== '\\') {
1035
+ if (promptMask[i as number] === '>') {
1036
+ key = key.toUpperCase();
1037
+ break;
1038
+ } else if (promptMask[i as number] === '<') {
1039
+ key = key.toLowerCase();
1040
+ break;
1041
+ } else if (promptMask[i as number] === '|') {
1042
+ break;
1043
+ }
1044
+ }
1045
+ --i;
1046
+ }
1047
+ return key;
1048
+ }
1049
+
1050
+ /**
1051
+ * To set updated values in the MaskedTextBox.
1052
+ *
1053
+ * @hidden
1054
+ */
1055
+ export function setMaskValue(val?: string): void {
1056
+ if (this.mask && val !== undefined && (this.prevValue === undefined || this.prevValue !== val)) {
1057
+ this.maskKeyPress = true;
1058
+ setElementValue.call(this, this.promptMask);
1059
+ if (val !== '' && !(val === null && this.floatLabelType === 'Never' && this.placeholder)) {
1060
+ this.element.selectionStart = 0;
1061
+ this.element.selectionEnd = 0;
1062
+ }
1063
+ if (val !== null) {
1064
+ for (let i: number = 0; i < val.length; i++) {
1065
+ validateValue.call(this, val[i as number], false, null);
1066
+ }
1067
+ }
1068
+ const newVal: string = strippedValue.call(this, this.element);
1069
+ this.prevValue = newVal;
1070
+ this.value = newVal;
1071
+ triggerMaskChangeEvent.call(this, null, null);
1072
+ this.maskKeyPress = false;
1073
+ const labelElement: HTMLElement = <HTMLElement>this.element.parentNode.querySelector('.e-float-text');
1074
+ if (this.element.value === this.promptMask && this.floatLabelType === 'Auto' && this.placeholder &&
1075
+ !isNullOrUndefined(labelElement) && labelElement.classList.contains(TOPLABEL) && !this.isFocus) {
1076
+ removeClass([labelElement], TOPLABEL);
1077
+ addClass([labelElement], BOTTOMLABEL);
1078
+ setElementValue.call(this, '');
1079
+ }
1080
+ }
1081
+ if (this.mask === null || this.mask === '' && this.value !== undefined) {
1082
+ setElementValue.call(this, this.value);
1083
+ }
1084
+ }
1085
+
1086
+ /**
1087
+ * To set updated values in the input element.
1088
+ *
1089
+ * @hidden
1090
+ */
1091
+ export function setElementValue(val: string, element?: HTMLInputElement): void {
1092
+ if (!this.isFocus && this.floatLabelType === 'Auto' && this.placeholder && isNullOrUndefined(this.value)) {
1093
+ val = '';
1094
+ }
1095
+ const value: string = strippedValue.call(this, (element ? element : this.element), val);
1096
+ if (value === null || value === '') {
1097
+ Input.setValue(val, (element ? element : this.element), this.floatLabelType, false);
1098
+ if (this.showClearButton) {
1099
+ this.inputObj.clearButton.classList.add('e-clear-icon-hide');
1100
+ }
1101
+ } else {
1102
+ Input.setValue(val, (element ? element : this.element), this.floatLabelType, this.showClearButton);
1103
+ }
1104
+ }
1105
+
1106
+ /**
1107
+ * Provide mask support to input textbox through utility method.
1108
+ *
1109
+ * @hidden
1110
+ */
1111
+ export function maskInput(args: MaskInputArgs): void {
1112
+ const inputEle: Object = getMaskInput(args);
1113
+ applyMask.call(inputEle);
1114
+ const val: string = strippedValue.call(this, this.element);
1115
+ this.prevValue = val;
1116
+ this.value = val;
1117
+ if (args.mask) {
1118
+ unwireEvents.call(inputEle);
1119
+ wireEvents.call(inputEle);
1120
+ }
1121
+ }
1122
+
1123
+ function getMaskInput(args: MaskInputArgs): Object {
1124
+ addClass([args.element], UTILMASK);
1125
+ const inputEle: Object = {
1126
+ element: args.element,
1127
+ mask: args.mask,
1128
+ promptMask: '',
1129
+ hiddenMask: '',
1130
+ escapeMaskValue: '',
1131
+ promptChar: args.promptChar ? (args.promptChar.length > 1) ? args.promptChar = args.promptChar[0]
1132
+ : args.promptChar : '_',
1133
+ value: args.value ? args.value : null,
1134
+ regExpCollec: regularExpressions,
1135
+ customRegExpCollec: [],
1136
+ customCharacters: args.customCharacters,
1137
+ undoCollec: [],
1138
+ redoCollec: [],
1139
+ maskKeyPress: false,
1140
+ prevValue: ''
1141
+ };
1142
+ createMask.call(inputEle);
1143
+ return inputEle;
1144
+ }
1145
+
1146
+ /**
1147
+ * Gets raw value of the textbox which has been masked through utility method.
1148
+ *
1149
+ * @hidden
1150
+ */
1151
+ export function getVal(args: GetValueInputArgs): string {
1152
+ return strippedValue.call(getUtilMaskEle(args), args.element);
1153
+ }
1154
+
1155
+ /**
1156
+ * Gets masked value of the textbox which has been masked through utility method.
1157
+ *
1158
+ * @hidden
1159
+ */
1160
+ export function getMaskedVal(args: GetValueInputArgs): string {
1161
+ return unstrippedValue.call(getUtilMaskEle(args), args.element);
1162
+ }
1163
+
1164
+ function getUtilMaskEle(args: GetValueInputArgs): Object {
1165
+ let inputEle: Object;
1166
+ if (!isNullOrUndefined(args) && args.element.classList.contains(UTILMASK)) {
1167
+ inputEle = getMaskInput(args);
1168
+ }
1169
+ return inputEle;
1170
+ }
1171
+
1172
+ /**
1173
+ * Arguments to get the raw and masked value of MaskedTextBox which has been masked through utility method.
1174
+ *
1175
+ * @hidden
1176
+ */
1177
+ export interface GetValueInputArgs {
1178
+ element: HTMLInputElement
1179
+ mask: string
1180
+ promptChar?: string
1181
+ customCharacters?: { [x: string]: Object }
1182
+ }
1183
+
1184
+ /**
1185
+ * Arguments to mask input textbox through utility method.
1186
+ *
1187
+ * @hidden
1188
+ */
1189
+ export interface MaskInputArgs extends GetValueInputArgs {
1190
+ value?: string
1191
+ }
1192
+
1193
+ /**
1194
+ * Arguments to perform undo and redo functionalities.
1195
+ *
1196
+ * @hidden
1197
+ */
1198
+ export class MaskUndo {
1199
+ public value: string;
1200
+ public startIndex: number;
1201
+ public endIndex: number;
1202
+ }
1203
+
1204
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1205
+ const maskUndo: MaskUndo = new MaskUndo();
1206
+
1207
+ /* eslint-enable valid-jsdoc, jsdoc/require-jsdoc, jsdoc/require-returns, jsdoc/require-param */