ngx-mask 14.2.3 → 14.3.0

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/README.md +124 -23
  2. package/esm2020/index.mjs +6 -8
  3. package/esm2020/lib/custom-keyboard-event.mjs +2 -1
  4. package/esm2020/lib/ngx-mask-applier.service.mjs +643 -0
  5. package/esm2020/lib/ngx-mask-expression.enum.mjs +2 -0
  6. package/esm2020/lib/ngx-mask.config.mjs +90 -0
  7. package/esm2020/lib/ngx-mask.directive.mjs +909 -0
  8. package/esm2020/lib/ngx-mask.pipe.mjs +104 -0
  9. package/esm2020/lib/ngx-mask.providers.mjs +34 -0
  10. package/esm2020/lib/ngx-mask.service.mjs +570 -0
  11. package/fesm2015/ngx-mask.mjs +1205 -559
  12. package/fesm2015/ngx-mask.mjs.map +1 -1
  13. package/fesm2020/ngx-mask.mjs +1204 -547
  14. package/fesm2020/ngx-mask.mjs.map +1 -1
  15. package/index.d.ts +5 -7
  16. package/lib/custom-keyboard-event.d.ts +1 -1
  17. package/lib/{mask-applier.service.d.ts → ngx-mask-applier.service.d.ts} +21 -14
  18. package/lib/ngx-mask-expression.enum.d.ts +42 -0
  19. package/lib/{config.d.ts → ngx-mask.config.d.ts} +16 -5
  20. package/lib/ngx-mask.directive.d.ts +71 -0
  21. package/lib/ngx-mask.pipe.d.ts +13 -0
  22. package/lib/ngx-mask.providers.d.ts +4 -0
  23. package/lib/{mask.service.d.ts → ngx-mask.service.d.ts} +21 -17
  24. package/package.json +4 -4
  25. package/esm2020/lib/config.mjs +0 -81
  26. package/esm2020/lib/mask-applier.service.mjs +0 -519
  27. package/esm2020/lib/mask.directive.mjs +0 -599
  28. package/esm2020/lib/mask.pipe.mjs +0 -30
  29. package/esm2020/lib/mask.service.mjs +0 -400
  30. package/esm2020/lib/ngx-mask.module.mjs +0 -53
  31. package/lib/mask.directive.d.ts +0 -69
  32. package/lib/mask.pipe.d.ts +0 -11
  33. package/lib/ngx-mask.module.d.ts +0 -16
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, EventEmitter, Injectable, Inject, forwardRef, Directive, Input, Output, HostListener, Pipe, NgModule } from '@angular/core';
3
- import { __awaiter } from 'tslib';
4
- import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
2
+ import { InjectionToken, EventEmitter, inject, Injectable, ElementRef, Renderer2, makeEnvironmentProviders, Directive, Input, Output, HostListener, Pipe } from '@angular/core';
5
3
  import { DOCUMENT } from '@angular/common';
4
+ import { __awaiter, __rest } from 'tslib';
5
+ import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
6
6
 
7
- const config = new InjectionToken('ngx-mask config');
7
+ const NGX_MASK_CONFIG = new InjectionToken('ngx-mask config');
8
8
  const NEW_CONFIG = new InjectionToken('new ngx-mask config');
9
9
  const INITIAL_CONFIG = new InjectionToken('initial ngx-mask config');
10
10
  const initialConfig = {
@@ -25,7 +25,12 @@ const initialConfig = {
25
25
  // eslint-disable-next-line @typescript-eslint/quotes
26
26
  specialCharacters: ['-', '/', '(', ')', '.', ':', ' ', '+', ',', '@', '[', ']', '"', "'"],
27
27
  leadZeroDateTime: false,
28
+ apm: false,
29
+ leadZero: false,
30
+ keepCharacterPositions: false,
28
31
  triggerOnMaskChange: false,
32
+ inputTransformFn: (value) => value,
33
+ outputTransformFn: (value) => value,
29
34
  maskFilled: new EventEmitter(),
30
35
  patterns: {
31
36
  '0': {
@@ -71,43 +76,70 @@ const initialConfig = {
71
76
  },
72
77
  },
73
78
  };
74
- const timeMasks = ['Hh:m0:s0', 'Hh:m0', 'm0:s0'];
79
+ const timeMasks = [
80
+ "Hh:m0:s0" /* MaskExpression.HOURS_MINUTES_SECONDS */,
81
+ "Hh:m0" /* MaskExpression.HOURS_MINUTES */,
82
+ "m0:s0" /* MaskExpression.MINUTES_SECONDS */,
83
+ ];
75
84
  const withoutValidation = [
76
- 'percent',
77
- 'Hh',
78
- 's0',
79
- 'm0',
80
- 'separator',
81
- 'd0/M0/0000',
82
- 'd0/M0',
83
- 'd0',
84
- 'M0',
85
+ "percent" /* MaskExpression.PERCENT */,
86
+ "Hh" /* MaskExpression.HOURS_HOUR */,
87
+ "s0" /* MaskExpression.SECONDS */,
88
+ "m0" /* MaskExpression.MINUTES */,
89
+ "separator" /* MaskExpression.SEPARATOR */,
90
+ "d0/M0/0000" /* MaskExpression.DAYS_MONTHS_YEARS */,
91
+ "d0/M0" /* MaskExpression.DAYS_MONTHS */,
92
+ "d0" /* MaskExpression.DAYS */,
93
+ "M0" /* MaskExpression.MONTHS */,
85
94
  ];
86
95
 
87
- class MaskApplierService {
88
- constructor(_config) {
89
- this._config = _config;
96
+ class NgxMaskApplierService {
97
+ constructor() {
98
+ this._config = inject(NGX_MASK_CONFIG);
99
+ this.dropSpecialCharacters = this._config.dropSpecialCharacters;
100
+ this.hiddenInput = this._config.hiddenInput;
101
+ this.clearIfNotMatch = this._config.clearIfNotMatch;
102
+ this.specialCharacters = this._config.specialCharacters;
103
+ this.patterns = this._config.patterns;
104
+ this.prefix = this._config.prefix;
105
+ this.suffix = this._config.suffix;
106
+ this.thousandSeparator = this._config.thousandSeparator;
107
+ this.decimalMarker = this._config.decimalMarker;
108
+ this.showMaskTyped = this._config.showMaskTyped;
109
+ this.placeHolderCharacter = this._config.placeHolderCharacter;
110
+ this.validation = this._config.validation;
111
+ this.separatorLimit = this._config.separatorLimit;
112
+ this.allowNegativeNumbers = this._config.allowNegativeNumbers;
113
+ this.leadZeroDateTime = this._config.leadZeroDateTime;
114
+ this.leadZero = this._config.leadZero;
115
+ this.apm = this._config.apm;
116
+ this.inputTransformFn = this._config.inputTransformFn;
117
+ this.outputTransformFn = this._config.outputTransformFn;
118
+ this.keepCharacterPositions = this._config.keepCharacterPositions;
119
+ this._shift = new Set();
90
120
  this.maskExpression = '';
91
121
  this.actualValue = '';
122
+ this.showKeepCharacterExp = '';
92
123
  this.shownMaskExpression = '';
124
+ this.deletedSpecialCharacter = false;
93
125
  this._formatWithSeparators = (str, thousandSeparatorChar, decimalChars, precision) => {
94
- var _a, _b;
126
+ var _a, _b, _c;
95
127
  let x = [];
96
128
  let decimalChar = '';
97
129
  if (Array.isArray(decimalChars)) {
98
130
  const regExp = new RegExp(decimalChars.map((v) => ('[\\^$.|?*+()'.indexOf(v) >= 0 ? `\\${v}` : v)).join('|'));
99
131
  x = str.split(regExp);
100
- decimalChar = (_b = (_a = str.match(regExp)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : '';
132
+ decimalChar = (_b = (_a = str.match(regExp)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : "" /* MaskExpression.EMPTY_STRING */;
101
133
  }
102
134
  else {
103
135
  x = str.split(decimalChars);
104
136
  decimalChar = decimalChars;
105
137
  }
106
- const decimals = x.length > 1 ? `${decimalChar}${x[1]}` : '';
107
- let res = x[0];
108
- const separatorLimit = this.separatorLimit.replace(/\s/g, '');
138
+ const decimals = x.length > 1 ? `${decimalChar}${x[1]}` : "" /* MaskExpression.EMPTY_STRING */;
139
+ let res = (_c = x[0]) !== null && _c !== void 0 ? _c : "" /* MaskExpression.EMPTY_STRING */;
140
+ const separatorLimit = this.separatorLimit.replace(/\s/g, "" /* MaskExpression.EMPTY_STRING */);
109
141
  if (separatorLimit && +separatorLimit) {
110
- if (res[0] === '-') {
142
+ if (res[0] === "-" /* MaskExpression.MINUS */) {
111
143
  res = `-${res.slice(1, res.length).slice(0, separatorLimit.length)}`;
112
144
  }
113
145
  else {
@@ -124,30 +156,35 @@ class MaskApplierService {
124
156
  else if (precision === 0) {
125
157
  return res;
126
158
  }
127
- return res + decimals.substr(0, precision + 1);
159
+ return res + decimals.substring(0, precision + 1);
128
160
  };
129
161
  this.percentage = (str) => {
130
- return Number(str) >= 0 && Number(str) <= 100;
162
+ const sanitizedStr = str.replace(',', '.');
163
+ const value = Number(sanitizedStr);
164
+ return !isNaN(value) && value >= 0 && value <= 100;
131
165
  };
132
166
  this.getPrecision = (maskExpression) => {
133
- const x = maskExpression.split('.');
167
+ const x = maskExpression.split("." /* MaskExpression.DOT */);
134
168
  if (x.length > 1) {
135
169
  return Number(x[x.length - 1]);
136
170
  }
137
171
  return Infinity;
138
172
  };
139
173
  this.checkAndRemoveSuffix = (inputValue) => {
140
- var _a, _b, _c;
174
+ var _a, _b, _c, _d;
141
175
  for (let i = ((_a = this.suffix) === null || _a === void 0 ? void 0 : _a.length) - 1; i >= 0; i--) {
142
- const substr = this.suffix.substr(i, (_b = this.suffix) === null || _b === void 0 ? void 0 : _b.length);
176
+ const substr = this.suffix.substring(i, (_b = this.suffix) === null || _b === void 0 ? void 0 : _b.length);
143
177
  if (inputValue.includes(substr) &&
144
- (i - 1 < 0 || !inputValue.includes(this.suffix.substr(i - 1, (_c = this.suffix) === null || _c === void 0 ? void 0 : _c.length)))) {
145
- return inputValue.replace(substr, '');
178
+ i !== ((_c = this.suffix) === null || _c === void 0 ? void 0 : _c.length) - 1 &&
179
+ (i - 1 < 0 ||
180
+ !inputValue.includes(this.suffix.substring(i - 1, (_d = this.suffix) === null || _d === void 0 ? void 0 : _d.length)))) {
181
+ return inputValue.replace(substr, "" /* MaskExpression.EMPTY_STRING */);
146
182
  }
147
183
  }
148
184
  return inputValue;
149
185
  };
150
186
  this.checkInputPrecision = (inputValue, precision, decimalMarker) => {
187
+ var _a, _b;
151
188
  if (precision < Infinity) {
152
189
  // TODO need think about decimalMarker
153
190
  if (Array.isArray(decimalMarker)) {
@@ -157,8 +194,9 @@ class MaskApplierService {
157
194
  }
158
195
  const precisionRegEx = new RegExp(this._charToRegExpExpression(decimalMarker) + `\\d{${precision}}.*$`);
159
196
  const precisionMatch = inputValue.match(precisionRegEx);
160
- if (precisionMatch && precisionMatch[0].length - 1 > precision) {
161
- const diff = precisionMatch[0].length - 1 - precision;
197
+ const precisionMatchLength = (_b = (precisionMatch && ((_a = precisionMatch[0]) === null || _a === void 0 ? void 0 : _a.length))) !== null && _b !== void 0 ? _b : 0;
198
+ if (precisionMatchLength - 1 > precision) {
199
+ const diff = precisionMatchLength - 1 - precision;
162
200
  // eslint-disable-next-line no-param-reassign
163
201
  inputValue = inputValue.substring(0, inputValue.length - diff);
164
202
  }
@@ -170,32 +208,18 @@ class MaskApplierService {
170
208
  }
171
209
  return inputValue;
172
210
  };
173
- this._shift = new Set();
174
- this.clearIfNotMatch = this._config.clearIfNotMatch;
175
- this.dropSpecialCharacters = this._config.dropSpecialCharacters;
176
- this.maskSpecialCharacters = this._config.specialCharacters;
177
- this.maskAvailablePatterns = this._config.patterns;
178
- this.prefix = this._config.prefix;
179
- this.suffix = this._config.suffix;
180
- this.thousandSeparator = this._config.thousandSeparator;
181
- this.decimalMarker = this._config.decimalMarker;
182
- this.hiddenInput = this._config.hiddenInput;
183
- this.showMaskTyped = this._config.showMaskTyped;
184
- this.placeHolderCharacter = this._config.placeHolderCharacter;
185
- this.validation = this._config.validation;
186
- this.separatorLimit = this._config.separatorLimit;
187
- this.allowNegativeNumbers = this._config.allowNegativeNumbers;
188
- this.leadZeroDateTime = this._config.leadZeroDateTime;
189
211
  }
190
212
  applyMaskWithPattern(inputValue, maskAndPattern) {
191
213
  const [mask, customPattern] = maskAndPattern;
192
214
  this.customPattern = customPattern;
193
215
  return this.applyMask(inputValue, mask);
194
216
  }
195
- applyMask(inputValue, maskExpression, position = 0, justPasted = false, backspaced = false, cb = () => { }) {
196
- var _a, _b;
217
+ applyMask(inputValue, maskExpression, position = 0, justPasted = false, backspaced = false,
218
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-explicit-any
219
+ cb = () => { }) {
220
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
197
221
  if (!maskExpression || typeof inputValue !== 'string') {
198
- return '';
222
+ return "" /* MaskExpression.EMPTY_STRING */;
199
223
  }
200
224
  let cursor = 0;
201
225
  let result = '';
@@ -203,7 +227,7 @@ class MaskApplierService {
203
227
  let backspaceShift = false;
204
228
  let shift = 1;
205
229
  let stepBack = false;
206
- if (inputValue.slice(0, this.prefix.length) === this.prefix) {
230
+ if (inputValue.slice(0, this.prefix.length) === this.prefix && !this.showMaskTyped) {
207
231
  // eslint-disable-next-line no-param-reassign
208
232
  inputValue = inputValue.slice(this.prefix.length, inputValue.length);
209
233
  }
@@ -211,9 +235,18 @@ class MaskApplierService {
211
235
  // eslint-disable-next-line no-param-reassign
212
236
  inputValue = this.checkAndRemoveSuffix(inputValue);
213
237
  }
214
- const inputArray = inputValue.toString().split('');
215
- if (maskExpression === 'IP') {
216
- const valuesIP = inputValue.split('.');
238
+ if (inputValue === '(' && this.prefix) {
239
+ // eslint-disable-next-line no-param-reassign
240
+ inputValue = '';
241
+ }
242
+ const inputArray = inputValue.toString().split("" /* MaskExpression.EMPTY_STRING */);
243
+ if (this.allowNegativeNumbers &&
244
+ inputValue.slice(cursor, cursor + 1) === "-" /* MaskExpression.MINUS */) {
245
+ // eslint-disable-next-line no-param-reassign
246
+ result += inputValue.slice(cursor, cursor + 1);
247
+ }
248
+ if (maskExpression === "IP" /* MaskExpression.IP */) {
249
+ const valuesIP = inputValue.split("." /* MaskExpression.DOT */);
217
250
  this.ipError = this._validIP(valuesIP);
218
251
  // eslint-disable-next-line no-param-reassign
219
252
  maskExpression = '099.099.099.099';
@@ -221,10 +254,10 @@ class MaskApplierService {
221
254
  const arr = [];
222
255
  for (let i = 0; i < inputValue.length; i++) {
223
256
  if ((_a = inputValue[i]) === null || _a === void 0 ? void 0 : _a.match('\\d')) {
224
- arr.push(inputValue[i]);
257
+ arr.push((_b = inputValue[i]) !== null && _b !== void 0 ? _b : "" /* MaskExpression.EMPTY_STRING */);
225
258
  }
226
259
  }
227
- if (maskExpression === 'CPF_CNPJ') {
260
+ if (maskExpression === "CPF_CNPJ" /* MaskExpression.CPF_CNPJ */) {
228
261
  this.cpfCnpjError = arr.length !== 11 && arr.length !== 14;
229
262
  if (arr.length > 11) {
230
263
  // eslint-disable-next-line no-param-reassign
@@ -235,33 +268,45 @@ class MaskApplierService {
235
268
  maskExpression = '000.000.000-00';
236
269
  }
237
270
  }
238
- if (maskExpression.startsWith('percent')) {
271
+ if (maskExpression.startsWith("percent" /* MaskExpression.PERCENT */)) {
239
272
  if (inputValue.match('[a-z]|[A-Z]') ||
240
- inputValue.match(/[-!$%^&*()_+|~=`{}\[\]:";'<>?,\/.]/)) {
273
+ // eslint-disable-next-line no-useless-escape
274
+ (inputValue.match(/[-!$%^&*()_+|~=`{}\[\]:";'<>?,\/.]/) && !backspaced)) {
241
275
  // eslint-disable-next-line no-param-reassign
242
276
  inputValue = this._stripToDecimal(inputValue);
243
277
  const precision = this.getPrecision(maskExpression);
244
278
  // eslint-disable-next-line no-param-reassign
245
279
  inputValue = this.checkInputPrecision(inputValue, precision, this.decimalMarker);
246
280
  }
247
- if (inputValue.indexOf('.') > 0 &&
248
- !this.percentage(inputValue.substring(0, inputValue.indexOf('.')))) {
249
- const base = inputValue.substring(0, inputValue.indexOf('.') - 1);
281
+ const decimalMarker = typeof this.decimalMarker === 'string' ? this.decimalMarker : "." /* MaskExpression.DOT */;
282
+ if (inputValue.indexOf(decimalMarker) > 0 &&
283
+ !this.percentage(inputValue.substring(0, inputValue.indexOf(decimalMarker)))) {
284
+ let base = inputValue.substring(0, inputValue.indexOf(decimalMarker) - 1);
285
+ if (this.allowNegativeNumbers &&
286
+ inputValue.slice(cursor, cursor + 1) === "-" /* MaskExpression.MINUS */ &&
287
+ !backspaced) {
288
+ base = inputValue.substring(0, inputValue.indexOf(decimalMarker));
289
+ }
250
290
  // eslint-disable-next-line no-param-reassign
251
- inputValue = `${base}${inputValue.substring(inputValue.indexOf('.'), inputValue.length)}`;
291
+ inputValue = `${base}${inputValue.substring(inputValue.indexOf(decimalMarker), inputValue.length)}`;
252
292
  }
253
- if (this.percentage(inputValue)) {
254
- result = inputValue;
293
+ let value = '';
294
+ this.allowNegativeNumbers &&
295
+ inputValue.slice(cursor, cursor + 1) === "-" /* MaskExpression.MINUS */
296
+ ? (value = inputValue.slice(cursor + 1, cursor + inputValue.length))
297
+ : (value = inputValue);
298
+ if (this.percentage(value)) {
299
+ result = this._splitPercentZero(inputValue);
255
300
  }
256
301
  else {
257
- result = inputValue.substring(0, inputValue.length - 1);
302
+ result = this._splitPercentZero(inputValue.substring(0, inputValue.length - 1));
258
303
  }
259
304
  }
260
- else if (maskExpression.startsWith('separator')) {
305
+ else if (maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
261
306
  if (inputValue.match('[wа-яА-Я]') ||
262
307
  inputValue.match('[ЁёА-я]') ||
263
308
  inputValue.match('[a-z]|[A-Z]') ||
264
- inputValue.match(/[-@#!$%\\^&*()_£¬'+|~=`{}\[\]:";<>.?\/]/) ||
309
+ inputValue.match(/[-@#!$%\\^&*()_£¬'+|~=`{}\]:";<>.?/]/) ||
265
310
  inputValue.match('[^A-Za-z0-9,]')) {
266
311
  // eslint-disable-next-line no-param-reassign
267
312
  inputValue = this._stripToDecimal(inputValue);
@@ -288,7 +333,7 @@ class MaskApplierService {
288
333
  //.replace(decimalMarkerEscaped, '');
289
334
  if (Array.isArray(this.decimalMarker)) {
290
335
  for (const marker of this.decimalMarker) {
291
- invalidChars = invalidChars.replace(this._charToRegExpExpression(marker), '');
336
+ invalidChars = invalidChars.replace(this._charToRegExpExpression(marker), "" /* MaskExpression.EMPTY_STRING */);
292
337
  }
293
338
  }
294
339
  else {
@@ -306,9 +351,9 @@ class MaskApplierService {
306
351
  inputValue = this.checkInputPrecision(inputValue, precision, this.decimalMarker);
307
352
  const strForSep = inputValue.replace(new RegExp(thousandSeparatorCharEscaped, 'g'), '');
308
353
  result = this._formatWithSeparators(strForSep, this.thousandSeparator, this.decimalMarker, precision);
309
- const commaShift = result.indexOf(',') - inputValue.indexOf(',');
354
+ const commaShift = result.indexOf("," /* MaskExpression.COMMA */) - inputValue.indexOf("," /* MaskExpression.COMMA */);
310
355
  const shiftStep = result.length - inputValue.length;
311
- if (shiftStep > 0 && result[position] !== ',') {
356
+ if (shiftStep > 0 && result[position] !== this.thousandSeparator) {
312
357
  backspaceShift = true;
313
358
  let _shift = 0;
314
359
  do {
@@ -316,8 +361,18 @@ class MaskApplierService {
316
361
  _shift++;
317
362
  } while (_shift < shiftStep);
318
363
  }
319
- else if ((commaShift !== 0 && position > 0 && !(result.indexOf(',') >= position && position > 3)) ||
320
- (!(result.indexOf('.') >= position && position > 3) && shiftStep <= 0)) {
364
+ else if (result[position - 1] === this.decimalMarker ||
365
+ shiftStep === -4 ||
366
+ shiftStep === -3 ||
367
+ result[position] === "," /* MaskExpression.COMMA */) {
368
+ this._shift.clear();
369
+ this._shift.add(position - 1);
370
+ }
371
+ else if ((commaShift !== 0 &&
372
+ position > 0 &&
373
+ !(result.indexOf("," /* MaskExpression.COMMA */) >= position && position > 3)) ||
374
+ (!(result.indexOf("." /* MaskExpression.DOT */) >= position && position > 3) &&
375
+ shiftStep <= 0)) {
321
376
  this._shift.clear();
322
377
  backspaceShift = true;
323
378
  shift = shiftStep;
@@ -332,35 +387,39 @@ class MaskApplierService {
332
387
  else {
333
388
  for (
334
389
  // eslint-disable-next-line
335
- let i = 0, inputSymbol = inputArray[0]; i < inputArray.length; i++, inputSymbol = inputArray[i]) {
390
+ let i = 0, inputSymbol = inputArray[0]; i < inputArray.length; i++, inputSymbol = (_c = inputArray[i]) !== null && _c !== void 0 ? _c : "" /* MaskExpression.EMPTY_STRING */) {
336
391
  if (cursor === maskExpression.length) {
337
392
  break;
338
393
  }
339
- if (this._checkSymbolMask(inputSymbol, maskExpression[cursor]) &&
340
- maskExpression[cursor + 1] === '?') {
394
+ const symbolStarInPattern = "*" /* MaskExpression.SYMBOL_STAR */ in this.patterns;
395
+ if (this._checkSymbolMask(inputSymbol, (_d = maskExpression[cursor]) !== null && _d !== void 0 ? _d : "" /* MaskExpression.EMPTY_STRING */) &&
396
+ maskExpression[cursor + 1] === "?" /* MaskExpression.SYMBOL_QUESTION */) {
341
397
  result += inputSymbol;
342
398
  cursor += 2;
343
399
  }
344
- else if (maskExpression[cursor + 1] === '*' &&
400
+ else if (maskExpression[cursor + 1] === "*" /* MaskExpression.SYMBOL_STAR */ &&
345
401
  multi &&
346
- this._checkSymbolMask(inputSymbol, maskExpression[cursor + 2])) {
402
+ this._checkSymbolMask(inputSymbol, (_e = maskExpression[cursor + 2]) !== null && _e !== void 0 ? _e : "" /* MaskExpression.EMPTY_STRING */)) {
347
403
  result += inputSymbol;
348
404
  cursor += 3;
349
405
  multi = false;
350
406
  }
351
- else if (this._checkSymbolMask(inputSymbol, maskExpression[cursor]) &&
352
- maskExpression[cursor + 1] === '*') {
407
+ else if (this._checkSymbolMask(inputSymbol, (_f = maskExpression[cursor]) !== null && _f !== void 0 ? _f : "" /* MaskExpression.EMPTY_STRING */) &&
408
+ maskExpression[cursor + 1] === "*" /* MaskExpression.SYMBOL_STAR */ &&
409
+ !symbolStarInPattern) {
353
410
  result += inputSymbol;
354
411
  multi = true;
355
412
  }
356
- else if (maskExpression[cursor + 1] === '?' &&
357
- this._checkSymbolMask(inputSymbol, maskExpression[cursor + 2])) {
413
+ else if (maskExpression[cursor + 1] === "?" /* MaskExpression.SYMBOL_QUESTION */ &&
414
+ this._checkSymbolMask(inputSymbol, (_g = maskExpression[cursor + 2]) !== null && _g !== void 0 ? _g : "" /* MaskExpression.EMPTY_STRING */)) {
358
415
  result += inputSymbol;
359
416
  cursor += 3;
360
417
  }
361
- else if (this._checkSymbolMask(inputSymbol, maskExpression[cursor])) {
362
- if (maskExpression[cursor] === 'H') {
363
- if (Number(inputSymbol) > 2) {
418
+ else if (this._checkSymbolMask(inputSymbol, (_h = maskExpression[cursor]) !== null && _h !== void 0 ? _h : "" /* MaskExpression.EMPTY_STRING */)) {
419
+ if (maskExpression[cursor] === "H" /* MaskExpression.HOURS */) {
420
+ if (this.apm ? Number(inputSymbol) > 9 : Number(inputSymbol) > 2) {
421
+ // eslint-disable-next-line no-param-reassign
422
+ position = position + 1;
364
423
  cursor += 1;
365
424
  this._shiftStep(maskExpression, cursor, inputArray.length);
366
425
  i--;
@@ -370,26 +429,33 @@ class MaskApplierService {
370
429
  continue;
371
430
  }
372
431
  }
373
- if (maskExpression[cursor] === 'h') {
374
- if (result === '2' && Number(inputSymbol) > 3) {
375
- cursor += 1;
376
- i--;
377
- continue;
378
- }
379
- }
380
- if (maskExpression[cursor] === 'm') {
381
- if (Number(inputSymbol) > 5) {
432
+ if (maskExpression[cursor] === "h" /* MaskExpression.HOUR */) {
433
+ if (this.apm
434
+ ? (result.length === 1 && Number(result) > 1) ||
435
+ (result === '1' && Number(inputSymbol) > 2) ||
436
+ (inputValue.slice(cursor - 1, cursor).length === 1 &&
437
+ Number(inputValue.slice(cursor - 1, cursor)) > 2) ||
438
+ (inputValue.slice(cursor - 1, cursor) === '1' &&
439
+ Number(inputSymbol) > 2)
440
+ : (result === '2' && Number(inputSymbol) > 3) ||
441
+ ((result.slice(cursor - 2, cursor) === '2' ||
442
+ result.slice(cursor - 3, cursor) === '2' ||
443
+ result.slice(cursor - 4, cursor) === '2' ||
444
+ result.slice(cursor - 1, cursor) === '2') &&
445
+ Number(inputSymbol) > 3 &&
446
+ cursor > 10)) {
447
+ // eslint-disable-next-line no-param-reassign
448
+ position = position + 1;
382
449
  cursor += 1;
383
- this._shiftStep(maskExpression, cursor, inputArray.length);
384
450
  i--;
385
- if (this.leadZeroDateTime) {
386
- result += '0';
387
- }
388
451
  continue;
389
452
  }
390
453
  }
391
- if (maskExpression[cursor] === 's') {
454
+ if (maskExpression[cursor] === "m" /* MaskExpression.MINUTE */ ||
455
+ maskExpression[cursor] === "s" /* MaskExpression.SECOND */) {
392
456
  if (Number(inputSymbol) > 5) {
457
+ // eslint-disable-next-line no-param-reassign
458
+ position = position + 1;
393
459
  cursor += 1;
394
460
  this._shiftStep(maskExpression, cursor, inputArray.length);
395
461
  i--;
@@ -400,10 +466,34 @@ class MaskApplierService {
400
466
  }
401
467
  }
402
468
  const daysCount = 31;
403
- if (maskExpression[cursor] === 'd') {
469
+ const inputValueCursor = inputValue[cursor];
470
+ const inputValueCursorPlusOne = inputValue[cursor + 1];
471
+ const inputValueCursorPlusTwo = inputValue[cursor + 2];
472
+ const inputValueCursorMinusOne = inputValue[cursor - 1];
473
+ const inputValueCursorMinusTwo = inputValue[cursor - 2];
474
+ const inputValueCursorMinusThree = inputValue[cursor - 3];
475
+ const inputValueSliceMinusThreeMinusOne = inputValue.slice(cursor - 3, cursor - 1);
476
+ const inputValueSliceMinusOnePlusOne = inputValue.slice(cursor - 1, cursor + 1);
477
+ const inputValueSliceCursorPlusTwo = inputValue.slice(cursor, cursor + 2);
478
+ const inputValueSliceMinusTwoCursor = inputValue.slice(cursor - 2, cursor);
479
+ if (maskExpression[cursor] === "d" /* MaskExpression.DAY */) {
480
+ const maskStartWithMonth = maskExpression.slice(0, 2) === "M0" /* MaskExpression.MONTHS */;
481
+ const startWithMonthInput = maskExpression.slice(0, 2) === "M0" /* MaskExpression.MONTHS */ &&
482
+ this.specialCharacters.includes(inputValueCursorMinusTwo);
404
483
  if ((Number(inputSymbol) > 3 && this.leadZeroDateTime) ||
405
- Number(inputValue.slice(cursor, cursor + 2)) > daysCount ||
406
- inputValue[cursor + 1] === '/') {
484
+ (!maskStartWithMonth &&
485
+ (Number(inputValueSliceCursorPlusTwo) > daysCount ||
486
+ Number(inputValueSliceMinusOnePlusOne) > daysCount ||
487
+ this.specialCharacters.includes(inputValueCursorPlusOne))) ||
488
+ (startWithMonthInput
489
+ ? Number(inputValueSliceMinusOnePlusOne) > daysCount ||
490
+ (!this.specialCharacters.includes(inputValueCursor) &&
491
+ this.specialCharacters.includes(inputValueCursorPlusTwo)) ||
492
+ this.specialCharacters.includes(inputValueCursor)
493
+ : Number(inputValueSliceCursorPlusTwo) > daysCount ||
494
+ this.specialCharacters.includes(inputValueCursorPlusOne))) {
495
+ // eslint-disable-next-line no-param-reassign
496
+ position = position + 1;
407
497
  cursor += 1;
408
498
  this._shiftStep(maskExpression, cursor, inputArray.length);
409
499
  i--;
@@ -413,45 +503,53 @@ class MaskApplierService {
413
503
  continue;
414
504
  }
415
505
  }
416
- if (maskExpression[cursor] === 'M') {
506
+ if (maskExpression[cursor] === "M" /* MaskExpression.MONTH */) {
417
507
  const monthsCount = 12;
418
508
  // mask without day
419
509
  const withoutDays = cursor === 0 &&
420
510
  (Number(inputSymbol) > 2 ||
421
- Number(inputValue.slice(cursor, cursor + 2)) > monthsCount ||
422
- inputValue[cursor + 1] === '/');
511
+ Number(inputValueSliceCursorPlusTwo) > monthsCount ||
512
+ this.specialCharacters.includes(inputValueCursorPlusOne));
423
513
  // day<10 && month<12 for input
424
- const day1monthInput = inputValue.slice(cursor - 3, cursor - 1).includes('/') &&
425
- ((inputValue[cursor - 2] === '/' &&
426
- Number(inputValue.slice(cursor - 1, cursor + 1)) > monthsCount &&
427
- inputValue[cursor] !== '/') ||
428
- inputValue[cursor] === '/' ||
429
- (inputValue[cursor - 3] === '/' &&
430
- Number(inputValue.slice(cursor - 2, cursor)) > monthsCount &&
431
- inputValue[cursor - 1] !== '/') ||
432
- inputValue[cursor - 1] === '/');
433
- // 10<day<31 && month<12 for input
434
- const day2monthInput = Number(inputValue.slice(cursor - 3, cursor - 1)) <= daysCount &&
435
- !inputValue.slice(cursor - 3, cursor - 1).includes('/') &&
436
- inputValue[cursor - 1] === '/' &&
437
- (Number(inputValue.slice(cursor, cursor + 2)) > monthsCount ||
438
- inputValue[cursor + 1] === '/');
439
- // day<10 && month<12 for paste whole data
440
- const day1monthPaste = Number(inputValue.slice(cursor - 3, cursor - 1)) > daysCount &&
441
- !inputValue.slice(cursor - 3, cursor - 1).includes('/') &&
442
- !inputValue.slice(cursor - 2, cursor).includes('/') &&
443
- Number(inputValue.slice(cursor - 2, cursor)) > monthsCount;
514
+ const specialChart = maskExpression.slice(cursor + 2, cursor + 3);
515
+ const day1monthInput = inputValueSliceMinusThreeMinusOne.includes(specialChart) &&
516
+ ((this.specialCharacters.includes(inputValueCursorMinusTwo) &&
517
+ Number(inputValueSliceMinusOnePlusOne) > monthsCount &&
518
+ !this.specialCharacters.includes(inputValueCursor)) ||
519
+ this.specialCharacters.includes(inputValueCursor) ||
520
+ (this.specialCharacters.includes(inputValueCursorMinusThree) &&
521
+ Number(inputValueSliceMinusTwoCursor) > monthsCount &&
522
+ !this.specialCharacters.includes(inputValueCursorMinusOne)) ||
523
+ this.specialCharacters.includes(inputValueCursorMinusOne));
524
+ // month<12 && day<10 for input
525
+ const day2monthInput = Number(inputValueSliceMinusThreeMinusOne) <= daysCount &&
526
+ !this.specialCharacters.includes(inputValueSliceMinusThreeMinusOne) &&
527
+ this.specialCharacters.includes(inputValueCursorMinusOne) &&
528
+ (Number(inputValueSliceCursorPlusTwo) > monthsCount ||
529
+ this.specialCharacters.includes(inputValueCursorPlusOne));
530
+ // cursor === 5 && without days
531
+ const day2monthInputDot = (Number(inputValueSliceCursorPlusTwo) > monthsCount && cursor === 5) ||
532
+ (this.specialCharacters.includes(inputValueCursorPlusOne) &&
533
+ cursor === 5);
534
+ // // day<10 && month<12 for paste whole data
535
+ const day1monthPaste = Number(inputValueSliceMinusThreeMinusOne) > daysCount &&
536
+ !this.specialCharacters.includes(inputValueSliceMinusThreeMinusOne) &&
537
+ !this.specialCharacters.includes(inputValueSliceMinusTwoCursor) &&
538
+ Number(inputValueSliceMinusTwoCursor) > monthsCount;
444
539
  // 10<day<31 && month<12 for paste whole data
445
- const day2monthPaste = Number(inputValue.slice(cursor - 3, cursor - 1)) <= daysCount &&
446
- !inputValue.slice(cursor - 3, cursor - 1).includes('/') &&
447
- inputValue[cursor - 1] !== '/' &&
448
- Number(inputValue.slice(cursor - 1, cursor + 1)) > monthsCount;
540
+ const day2monthPaste = Number(inputValueSliceMinusThreeMinusOne) <= daysCount &&
541
+ !this.specialCharacters.includes(inputValueSliceMinusThreeMinusOne) &&
542
+ !this.specialCharacters.includes(inputValueCursorMinusOne) &&
543
+ Number(inputValueSliceMinusOnePlusOne) > monthsCount;
449
544
  if ((Number(inputSymbol) > 1 && this.leadZeroDateTime) ||
450
545
  withoutDays ||
451
546
  day1monthInput ||
452
- day2monthInput ||
547
+ day2monthPaste ||
453
548
  day1monthPaste ||
454
- day2monthPaste) {
549
+ day2monthInput ||
550
+ (day2monthInputDot && !this.leadZeroDateTime)) {
551
+ // eslint-disable-next-line no-param-reassign
552
+ position = position + 1;
455
553
  cursor += 1;
456
554
  this._shiftStep(maskExpression, cursor, inputArray.length);
457
555
  i--;
@@ -464,52 +562,64 @@ class MaskApplierService {
464
562
  result += inputSymbol;
465
563
  cursor++;
466
564
  }
467
- else if (inputSymbol === ' ' && maskExpression[cursor] === ' ') {
565
+ else if ((inputSymbol === " " /* MaskExpression.WHITE_SPACE */ &&
566
+ maskExpression[cursor] === " " /* MaskExpression.WHITE_SPACE */) ||
567
+ (inputSymbol === "/" /* MaskExpression.SLASH */ &&
568
+ maskExpression[cursor] === "/" /* MaskExpression.SLASH */)) {
468
569
  result += inputSymbol;
469
570
  cursor++;
470
571
  }
471
- else if (this.maskSpecialCharacters.indexOf(maskExpression[cursor]) !== -1) {
572
+ else if (this.specialCharacters.indexOf((_j = maskExpression[cursor]) !== null && _j !== void 0 ? _j : "" /* MaskExpression.EMPTY_STRING */) !== -1) {
472
573
  result += maskExpression[cursor];
473
574
  cursor++;
474
575
  this._shiftStep(maskExpression, cursor, inputArray.length);
475
576
  i--;
476
577
  }
477
- else if (this.maskSpecialCharacters.indexOf(inputSymbol) > -1 &&
478
- this.maskAvailablePatterns[maskExpression[cursor]] &&
479
- ((_b = this.maskAvailablePatterns[maskExpression[cursor]]) === null || _b === void 0 ? void 0 : _b.optional)) {
578
+ else if (maskExpression[cursor] === "9" /* MaskExpression.NUMBER_NINE */ &&
579
+ this.showMaskTyped) {
580
+ this._shiftStep(maskExpression, cursor, inputArray.length);
581
+ }
582
+ else if (this.patterns[(_k = maskExpression[cursor]) !== null && _k !== void 0 ? _k : "" /* MaskExpression.EMPTY_STRING */] &&
583
+ ((_m = this.patterns[(_l = maskExpression[cursor]) !== null && _l !== void 0 ? _l : "" /* MaskExpression.EMPTY_STRING */]) === null || _m === void 0 ? void 0 : _m.optional)) {
480
584
  if (!!inputArray[cursor] &&
481
585
  maskExpression !== '099.099.099.099' &&
482
586
  maskExpression !== '000.000.000-00' &&
483
587
  maskExpression !== '00.000.000/0000-00' &&
484
- !maskExpression.match(/^9+\.0+$/)) {
588
+ !maskExpression.match(/^9+\.0+$/) &&
589
+ !((_p = this.patterns[(_o = maskExpression[cursor]) !== null && _o !== void 0 ? _o : "" /* MaskExpression.EMPTY_STRING */]) === null || _p === void 0 ? void 0 : _p.optional)) {
485
590
  result += inputArray[cursor];
486
591
  }
592
+ if (maskExpression.includes("9" /* MaskExpression.NUMBER_NINE */ + "*" /* MaskExpression.SYMBOL_STAR */) &&
593
+ maskExpression.includes("0" /* MaskExpression.NUMBER_ZERO */ + "*" /* MaskExpression.SYMBOL_STAR */)) {
594
+ cursor++;
595
+ }
487
596
  cursor++;
488
597
  i--;
489
598
  }
490
- else if (this.maskExpression[cursor + 1] === '*' &&
491
- this._findSpecialChar(this.maskExpression[cursor + 2]) &&
599
+ else if (this.maskExpression[cursor + 1] === "*" /* MaskExpression.SYMBOL_STAR */ &&
600
+ this._findSpecialChar((_q = this.maskExpression[cursor + 2]) !== null && _q !== void 0 ? _q : "" /* MaskExpression.EMPTY_STRING */) &&
492
601
  this._findSpecialChar(inputSymbol) === this.maskExpression[cursor + 2] &&
493
602
  multi) {
494
603
  cursor += 3;
495
604
  result += inputSymbol;
496
605
  }
497
- else if (this.maskExpression[cursor + 1] === '?' &&
498
- this._findSpecialChar(this.maskExpression[cursor + 2]) &&
606
+ else if (this.maskExpression[cursor + 1] === "?" /* MaskExpression.SYMBOL_QUESTION */ &&
607
+ this._findSpecialChar((_r = this.maskExpression[cursor + 2]) !== null && _r !== void 0 ? _r : "" /* MaskExpression.EMPTY_STRING */) &&
499
608
  this._findSpecialChar(inputSymbol) === this.maskExpression[cursor + 2] &&
500
609
  multi) {
501
610
  cursor += 3;
502
611
  result += inputSymbol;
503
612
  }
504
613
  else if (this.showMaskTyped &&
505
- this.maskSpecialCharacters.indexOf(inputSymbol) < 0 &&
506
- inputSymbol !== this.placeHolderCharacter) {
614
+ this.specialCharacters.indexOf(inputSymbol) < 0 &&
615
+ inputSymbol !== this.placeHolderCharacter &&
616
+ this.placeHolderCharacter.length === 1) {
507
617
  stepBack = true;
508
618
  }
509
619
  }
510
620
  }
511
621
  if (result.length + 1 === maskExpression.length &&
512
- this.maskSpecialCharacters.indexOf(maskExpression[maskExpression.length - 1]) !== -1) {
622
+ this.specialCharacters.indexOf((_s = maskExpression[maskExpression.length - 1]) !== null && _s !== void 0 ? _s : "" /* MaskExpression.EMPTY_STRING */) !== -1) {
513
623
  result += maskExpression[maskExpression.length - 1];
514
624
  }
515
625
  let newPosition = position + 1;
@@ -517,7 +627,7 @@ class MaskApplierService {
517
627
  shift++;
518
628
  newPosition++;
519
629
  }
520
- let actualShift = justPasted && !maskExpression.startsWith('separator')
630
+ let actualShift = justPasted && !maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */)
521
631
  ? cursor
522
632
  : this._shift.has(position)
523
633
  ? shift
@@ -531,28 +641,34 @@ class MaskApplierService {
531
641
  }
532
642
  let onlySpecial = false;
533
643
  if (backspaced) {
534
- onlySpecial = inputArray.every((char) => this.maskSpecialCharacters.includes(char));
644
+ onlySpecial = inputArray.every((char) => this.specialCharacters.includes(char));
535
645
  }
536
- let res = `${this.prefix}${onlySpecial ? '' : result}${this.suffix}`;
646
+ let res = `${this.prefix}${onlySpecial ? "" /* MaskExpression.EMPTY_STRING */ : result}${this.suffix}`;
537
647
  if (result.length === 0) {
538
- res = `${this.prefix}${result}`;
648
+ res = !this.dropSpecialCharacters ? `${this.prefix}${result}` : `${result}`;
649
+ }
650
+ if (result.includes("-" /* MaskExpression.MINUS */) && this.prefix && this.allowNegativeNumbers) {
651
+ if (backspaced && result === "-" /* MaskExpression.MINUS */) {
652
+ return '';
653
+ }
654
+ res = `${"-" /* MaskExpression.MINUS */}${this.prefix}${result
655
+ .split("-" /* MaskExpression.MINUS */)
656
+ .join("" /* MaskExpression.EMPTY_STRING */)}${this.suffix}`;
539
657
  }
540
658
  return res;
541
659
  }
542
660
  _findSpecialChar(inputSymbol) {
543
- return this.maskSpecialCharacters.find((val) => val === inputSymbol);
661
+ return this.specialCharacters.find((val) => val === inputSymbol);
544
662
  }
545
663
  _checkSymbolMask(inputSymbol, maskSymbol) {
546
- this.maskAvailablePatterns = this.customPattern
547
- ? this.customPattern
548
- : this.maskAvailablePatterns;
549
- return (this.maskAvailablePatterns[maskSymbol] &&
550
- this.maskAvailablePatterns[maskSymbol].pattern &&
551
- this.maskAvailablePatterns[maskSymbol].pattern.test(inputSymbol));
664
+ var _a, _b, _c;
665
+ this.patterns = this.customPattern ? this.customPattern : this.patterns;
666
+ return ((_c = (((_a = this.patterns[maskSymbol]) === null || _a === void 0 ? void 0 : _a.pattern) &&
667
+ ((_b = this.patterns[maskSymbol]) === null || _b === void 0 ? void 0 : _b.pattern.test(inputSymbol)))) !== null && _c !== void 0 ? _c : false);
552
668
  }
553
669
  _stripToDecimal(str) {
554
670
  return str
555
- .split('')
671
+ .split("" /* MaskExpression.EMPTY_STRING */)
556
672
  .filter((i, idx) => {
557
673
  const isDecimalMarker = typeof this.decimalMarker === 'string'
558
674
  ? i === this.decimalMarker
@@ -561,9 +677,9 @@ class MaskApplierService {
561
677
  return (i.match('^-?\\d') ||
562
678
  i === this.thousandSeparator ||
563
679
  isDecimalMarker ||
564
- (i === '-' && idx === 0 && this.allowNegativeNumbers));
680
+ (i === "-" /* MaskExpression.MINUS */ && idx === 0 && this.allowNegativeNumbers));
565
681
  })
566
- .join('');
682
+ .join("" /* MaskExpression.EMPTY_STRING */);
567
683
  }
568
684
  _charToRegExpExpression(char) {
569
685
  // if (Array.isArray(char)) {
@@ -576,7 +692,9 @@ class MaskApplierService {
576
692
  return char;
577
693
  }
578
694
  _shiftStep(maskExpression, cursor, inputLength) {
579
- const shiftStep = /[*?]/g.test(maskExpression.slice(0, cursor)) ? inputLength : cursor;
695
+ const shiftStep = /[*?]/g.test(maskExpression.slice(0, cursor))
696
+ ? inputLength
697
+ : cursor;
580
698
  this._shift.add(shiftStep + this.prefix.length || 0);
581
699
  }
582
700
  _compareOrIncludes(value, comparedValue, excludedValue) {
@@ -588,33 +706,40 @@ class MaskApplierService {
588
706
  return !(valuesIP.length === 4 &&
589
707
  !valuesIP.some((value, index) => {
590
708
  if (valuesIP.length !== index + 1) {
591
- return value === '' || Number(value) > 255;
709
+ return value === "" /* MaskExpression.EMPTY_STRING */ || Number(value) > 255;
592
710
  }
593
- return value === '' || Number(value.substring(0, 3)) > 255;
711
+ return value === "" /* MaskExpression.EMPTY_STRING */ || Number(value.substring(0, 3)) > 255;
594
712
  }));
595
713
  }
714
+ _splitPercentZero(value) {
715
+ const decimalIndex = typeof this.decimalMarker === 'string'
716
+ ? value.indexOf(this.decimalMarker)
717
+ : value.indexOf("." /* MaskExpression.DOT */);
718
+ if (decimalIndex === -1) {
719
+ const parsedValue = parseInt(value, 10);
720
+ return isNaN(parsedValue) ? "" /* MaskExpression.EMPTY_STRING */ : parsedValue.toString();
721
+ }
722
+ else {
723
+ const integerPart = parseInt(value.substring(0, decimalIndex), 10);
724
+ const decimalPart = value.substring(decimalIndex + 1);
725
+ const integerString = isNaN(integerPart) ? '' : integerPart.toString();
726
+ const decimal = typeof this.decimalMarker === 'string' ? this.decimalMarker : "." /* MaskExpression.DOT */;
727
+ return integerString === "" /* MaskExpression.EMPTY_STRING */
728
+ ? "" /* MaskExpression.EMPTY_STRING */
729
+ : integerString + decimal + decimalPart;
730
+ }
731
+ }
596
732
  }
597
- MaskApplierService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskApplierService, deps: [{ token: config }], target: i0.ɵɵFactoryTarget.Injectable });
598
- MaskApplierService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskApplierService });
599
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskApplierService, decorators: [{
733
+ NgxMaskApplierService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskApplierService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
734
+ NgxMaskApplierService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskApplierService });
735
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskApplierService, decorators: [{
600
736
  type: Injectable
601
- }], ctorParameters: function () {
602
- return [{ type: undefined, decorators: [{
603
- type: Inject,
604
- args: [config]
605
- }] }];
606
- } });
737
+ }] });
607
738
 
608
- class MaskService extends MaskApplierService {
609
- constructor(document, _config, _elementRef, _renderer) {
610
- super(_config);
611
- this.document = document;
612
- this._config = _config;
613
- this._elementRef = _elementRef;
614
- this._renderer = _renderer;
615
- this.maskExpression = '';
739
+ class NgxMaskService extends NgxMaskApplierService {
740
+ constructor() {
741
+ super(...arguments);
616
742
  this.isNumberValue = false;
617
- this.placeHolderCharacter = '_';
618
743
  this.maskIsShown = '';
619
744
  this.selStart = null;
620
745
  this.selEnd = null;
@@ -624,82 +749,155 @@ class MaskService extends MaskApplierService {
624
749
  */
625
750
  this.writingValue = false;
626
751
  this.maskChanged = false;
752
+ this._maskExpressionArray = [];
627
753
  this.triggerOnMaskChange = false;
754
+ this._emitValue = false;
755
+ this._previousValue = '';
756
+ this._currentValue = '';
757
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-explicit-any
628
758
  this.onChange = (_) => { };
759
+ this.document = inject(DOCUMENT);
760
+ this._config = inject(NGX_MASK_CONFIG);
761
+ this._elementRef = inject(ElementRef, { optional: true });
762
+ this._renderer = inject(Renderer2, { optional: true });
629
763
  }
630
764
  // eslint-disable-next-line complexity
631
- applyMask(inputValue, maskExpression, position = 0, justPasted = false, backspaced = false, cb = () => { }) {
765
+ applyMask(inputValue, maskExpression, position = 0, justPasted = false, backspaced = false,
766
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-explicit-any
767
+ cb = () => { }) {
768
+ var _a;
632
769
  if (!maskExpression) {
633
770
  return inputValue !== this.actualValue ? this.actualValue : inputValue;
634
771
  }
635
- this.maskIsShown = this.showMaskTyped ? this.showMaskInInput() : '';
636
- if (this.maskExpression === 'IP' && this.showMaskTyped) {
637
- this.maskIsShown = this.showMaskInInput(inputValue || '#');
772
+ this.maskIsShown = this.showMaskTyped
773
+ ? this.showMaskInInput()
774
+ : "" /* MaskExpression.EMPTY_STRING */;
775
+ if (this.maskExpression === "IP" /* MaskExpression.IP */ && this.showMaskTyped) {
776
+ this.maskIsShown = this.showMaskInInput(inputValue || "#" /* MaskExpression.HASH */);
638
777
  }
639
- if (this.maskExpression === 'CPF_CNPJ' && this.showMaskTyped) {
640
- this.maskIsShown = this.showMaskInInput(inputValue || '#');
778
+ if (this.maskExpression === "CPF_CNPJ" /* MaskExpression.CPF_CNPJ */ && this.showMaskTyped) {
779
+ this.maskIsShown = this.showMaskInInput(inputValue || "#" /* MaskExpression.HASH */);
641
780
  }
642
781
  if (!inputValue && this.showMaskTyped) {
643
782
  this.formControlResult(this.prefix);
644
783
  return this.prefix + this.maskIsShown;
645
784
  }
646
- const getSymbol = !!inputValue && typeof this.selStart === 'number' ? inputValue[this.selStart] : '';
785
+ const getSymbol = !!inputValue && typeof this.selStart === 'number'
786
+ ? (_a = inputValue[this.selStart]) !== null && _a !== void 0 ? _a : "" /* MaskExpression.EMPTY_STRING */
787
+ : "" /* MaskExpression.EMPTY_STRING */;
647
788
  let newInputValue = '';
648
789
  if (this.hiddenInput !== undefined && !this.writingValue) {
649
- let actualResult = this.actualValue.split('');
790
+ let actualResult = inputValue && inputValue.length === 1
791
+ ? inputValue.split("" /* MaskExpression.EMPTY_STRING */)
792
+ : this.actualValue.split("" /* MaskExpression.EMPTY_STRING */);
650
793
  // eslint-disable @typescript-eslint/no-unused-expressions
651
794
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
652
- inputValue !== '' && actualResult.length
653
- ? typeof this.selStart === 'number' && typeof this.selEnd === 'number'
654
- ? inputValue.length > actualResult.length
655
- ? actualResult.splice(this.selStart, 0, getSymbol)
656
- : inputValue.length < actualResult.length
657
- ? actualResult.length - inputValue.length === 1
658
- ? actualResult.splice(this.selStart - 1, 1)
659
- : actualResult.splice(this.selStart, this.selEnd - this.selStart)
660
- : null
661
- : null
662
- : (actualResult = []);
795
+ if (typeof this.selStart === 'object' && typeof this.selEnd === 'object') {
796
+ this.selStart = Number(this.selStart);
797
+ this.selEnd = Number(this.selEnd);
798
+ }
799
+ else {
800
+ inputValue !== "" /* MaskExpression.EMPTY_STRING */ && actualResult.length
801
+ ? typeof this.selStart === 'number' && typeof this.selEnd === 'number'
802
+ ? inputValue.length > actualResult.length
803
+ ? actualResult.splice(this.selStart, 0, getSymbol)
804
+ : inputValue.length < actualResult.length
805
+ ? actualResult.length - inputValue.length === 1
806
+ ? backspaced
807
+ ? actualResult.splice(this.selStart - 1, 1)
808
+ : actualResult.splice(inputValue.length - 1, 1)
809
+ : actualResult.splice(this.selStart, this.selEnd - this.selStart)
810
+ : null
811
+ : null
812
+ : (actualResult = []);
813
+ }
663
814
  if (this.showMaskTyped) {
664
- // eslint-disable-next-line no-param-reassign
665
- inputValue = this.removeMask(inputValue);
815
+ if (!this.hiddenInput) {
816
+ // eslint-disable-next-line no-param-reassign
817
+ inputValue = this.removeMask(inputValue);
818
+ }
666
819
  }
667
820
  // eslint-enable @typescript-eslint/no-unused-expressions
668
821
  newInputValue =
669
822
  this.actualValue.length && actualResult.length <= inputValue.length
670
- ? this.shiftTypedSymbols(actualResult.join(''))
823
+ ? this.shiftTypedSymbols(actualResult.join("" /* MaskExpression.EMPTY_STRING */))
671
824
  : inputValue;
672
825
  }
673
- if (this.showMaskTyped) {
826
+ if (justPasted && (this.hiddenInput || !this.hiddenInput)) {
827
+ newInputValue = inputValue;
828
+ }
829
+ if (this.deletedSpecialCharacter && position) {
830
+ if (this.specialCharacters.includes(this.actualValue.slice(position, position + 1))) {
831
+ // eslint-disable-next-line no-param-reassign
832
+ position = position + 1;
833
+ }
834
+ else if (maskExpression.slice(position - 1, position + 1) !== "M0" /* MaskExpression.MONTHS */) {
835
+ // eslint-disable-next-line no-param-reassign
836
+ position = position - 2;
837
+ }
838
+ // eslint-disable-next-line no-param-reassign
839
+ this.deletedSpecialCharacter = false;
840
+ }
841
+ if (this.showMaskTyped &&
842
+ this.placeHolderCharacter.length === 1 &&
843
+ !this.leadZeroDateTime) {
674
844
  // eslint-disable-next-line no-param-reassign
675
845
  inputValue = this.removeMask(inputValue);
676
846
  }
677
- newInputValue = Boolean(newInputValue) && newInputValue.length ? newInputValue : inputValue;
847
+ if (this.maskChanged) {
848
+ newInputValue = inputValue;
849
+ }
850
+ else {
851
+ newInputValue =
852
+ Boolean(newInputValue) && newInputValue.length ? newInputValue : inputValue;
853
+ }
854
+ if (this.showMaskTyped && this.keepCharacterPositions && this.actualValue && !justPasted) {
855
+ const value = this.dropSpecialCharacters
856
+ ? this.removeMask(this.actualValue)
857
+ : this.actualValue;
858
+ this.formControlResult(value);
859
+ return this.actualValue
860
+ ? this.actualValue
861
+ : this.prefix + this.maskIsShown + this.suffix;
862
+ }
678
863
  const result = super.applyMask(newInputValue, maskExpression, position, justPasted, backspaced, cb);
679
864
  this.actualValue = this.getActualValue(result);
680
865
  // handle some separator implications:
681
866
  // a.) adjust decimalMarker default (. -> ,) if thousandSeparator is a dot
682
- if (this.thousandSeparator === '.' && this.decimalMarker === '.') {
683
- this.decimalMarker = ',';
867
+ if (this.thousandSeparator === "." /* MaskExpression.DOT */ &&
868
+ this.decimalMarker === "." /* MaskExpression.DOT */) {
869
+ this.decimalMarker = "," /* MaskExpression.COMMA */;
684
870
  }
685
871
  // b) remove decimal marker from list of special characters to mask
686
- if (this.maskExpression.startsWith('separator') && this.dropSpecialCharacters === true) {
687
- this.maskSpecialCharacters = this.maskSpecialCharacters.filter((item) => !this._compareOrIncludes(item, this.decimalMarker, this.thousandSeparator));
688
- }
689
- this.formControlResult(result);
690
- if (!this.showMaskTyped) {
872
+ if (this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) &&
873
+ this.dropSpecialCharacters === true) {
874
+ this.specialCharacters = this.specialCharacters.filter((item) => !this._compareOrIncludes(item, this.decimalMarker, this.thousandSeparator) //item !== this.decimalMarker, // !
875
+ );
876
+ }
877
+ if (result || result === '') {
878
+ this._previousValue = this._currentValue;
879
+ this._currentValue = result;
880
+ this._emitValue = this._previousValue !== this._currentValue || this.maskChanged;
881
+ }
882
+ this._emitValue ? this.formControlResult(result) : '';
883
+ if (!this.showMaskTyped || (this.showMaskTyped && this.hiddenInput)) {
691
884
  if (this.hiddenInput) {
692
- return result && result.length ? this.hideInput(result, this.maskExpression) : result;
885
+ if (backspaced) {
886
+ return this.hideInput(result, this.maskExpression);
887
+ }
888
+ return (this.hideInput(result, this.maskExpression) +
889
+ this.maskIsShown.slice(result.length));
693
890
  }
694
891
  return result;
695
892
  }
696
893
  const resLen = result.length;
697
894
  const prefNmask = this.prefix + this.maskIsShown;
698
- if (this.maskExpression.includes('H')) {
895
+ if (this.maskExpression.includes("H" /* MaskExpression.HOURS */)) {
699
896
  const countSkipedSymbol = this._numberSkipedSymbols(result);
700
897
  return result + prefNmask.slice(resLen + countSkipedSymbol);
701
898
  }
702
- else if (this.maskExpression === 'IP' || this.maskExpression === 'CPF_CNPJ') {
899
+ else if (this.maskExpression === "IP" /* MaskExpression.IP */ ||
900
+ this.maskExpression === "CPF_CNPJ" /* MaskExpression.CPF_CNPJ */) {
703
901
  return result + prefNmask;
704
902
  }
705
903
  return result + prefNmask.slice(resLen);
@@ -715,8 +913,14 @@ class MaskService extends MaskApplierService {
715
913
  }
716
914
  return countSkipedSymbol;
717
915
  }
718
- applyValueChanges(position, justPasted, backspaced, cb = () => { }) {
719
- const formElement = this._elementRef.nativeElement;
916
+ applyValueChanges(position, justPasted, backspaced,
917
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-explicit-any
918
+ cb = () => { }) {
919
+ var _a;
920
+ const formElement = (_a = this._elementRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
921
+ if (!formElement) {
922
+ return;
923
+ }
720
924
  formElement.value = this.applyMask(formElement.value, this.maskExpression, position, justPasted, backspaced, cb);
721
925
  if (formElement === this._getActiveElement()) {
722
926
  return;
@@ -725,48 +929,54 @@ class MaskService extends MaskApplierService {
725
929
  }
726
930
  hideInput(inputValue, maskExpression) {
727
931
  return inputValue
728
- .split('')
932
+ .split("" /* MaskExpression.EMPTY_STRING */)
729
933
  .map((curr, index) => {
730
- var _a, _b;
731
- if (this.maskAvailablePatterns &&
732
- this.maskAvailablePatterns[maskExpression[index]] &&
733
- ((_a = this.maskAvailablePatterns[maskExpression[index]]) === null || _a === void 0 ? void 0 : _a.symbol)) {
734
- return (_b = this.maskAvailablePatterns[maskExpression[index]]) === null || _b === void 0 ? void 0 : _b.symbol;
934
+ var _a, _b, _c, _d, _e;
935
+ if (this.patterns &&
936
+ this.patterns[(_a = maskExpression[index]) !== null && _a !== void 0 ? _a : "" /* MaskExpression.EMPTY_STRING */] &&
937
+ ((_c = this.patterns[(_b = maskExpression[index]) !== null && _b !== void 0 ? _b : "" /* MaskExpression.EMPTY_STRING */]) === null || _c === void 0 ? void 0 : _c.symbol)) {
938
+ return (_e = this.patterns[(_d = maskExpression[index]) !== null && _d !== void 0 ? _d : "" /* MaskExpression.EMPTY_STRING */]) === null || _e === void 0 ? void 0 : _e.symbol;
735
939
  }
736
940
  return curr;
737
941
  })
738
- .join('');
942
+ .join("" /* MaskExpression.EMPTY_STRING */);
739
943
  }
740
944
  // this function is not necessary, it checks result against maskExpression
741
945
  getActualValue(res) {
742
946
  const compare = res
743
- .split('')
744
- .filter((symbol, i) => this._checkSymbolMask(symbol, this.maskExpression[i]) ||
745
- (this.maskSpecialCharacters.includes(this.maskExpression[i]) &&
746
- symbol === this.maskExpression[i]));
747
- if (compare.join('') === res) {
748
- return compare.join('');
947
+ .split("" /* MaskExpression.EMPTY_STRING */)
948
+ .filter((symbol, i) => {
949
+ var _a;
950
+ const maskChar = (_a = this.maskExpression[i]) !== null && _a !== void 0 ? _a : "" /* MaskExpression.EMPTY_STRING */;
951
+ return (this._checkSymbolMask(symbol, maskChar) ||
952
+ (this.specialCharacters.includes(maskChar) && symbol === maskChar));
953
+ });
954
+ if (compare.join("" /* MaskExpression.EMPTY_STRING */) === res) {
955
+ return compare.join("" /* MaskExpression.EMPTY_STRING */);
749
956
  }
750
957
  return res;
751
958
  }
752
959
  shiftTypedSymbols(inputValue) {
753
960
  let symbolToReplace = '';
754
961
  const newInputValue = (inputValue &&
755
- inputValue.split('').map((currSymbol, index) => {
756
- if (this.maskSpecialCharacters.includes(inputValue[index + 1]) &&
962
+ inputValue
963
+ .split("" /* MaskExpression.EMPTY_STRING */)
964
+ .map((currSymbol, index) => {
965
+ var _a;
966
+ if (this.specialCharacters.includes((_a = inputValue[index + 1]) !== null && _a !== void 0 ? _a : "" /* MaskExpression.EMPTY_STRING */) &&
757
967
  inputValue[index + 1] !== this.maskExpression[index + 1]) {
758
968
  symbolToReplace = currSymbol;
759
969
  return inputValue[index + 1];
760
970
  }
761
971
  if (symbolToReplace.length) {
762
972
  const replaceSymbol = symbolToReplace;
763
- symbolToReplace = '';
973
+ symbolToReplace = "" /* MaskExpression.EMPTY_STRING */;
764
974
  return replaceSymbol;
765
975
  }
766
976
  return currSymbol;
767
977
  })) ||
768
978
  [];
769
- return newInputValue.join('');
979
+ return newInputValue.join("" /* MaskExpression.EMPTY_STRING */);
770
980
  }
771
981
  /**
772
982
  * Convert number value to string
@@ -774,13 +984,20 @@ class MaskService extends MaskApplierService {
774
984
  * 1e-7 -> '0.0000001'
775
985
  */
776
986
  numberToString(value) {
777
- if (!value && value !== 0) {
987
+ if ((!value && value !== 0) ||
988
+ (this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) &&
989
+ (this.leadZero || !this.dropSpecialCharacters)) ||
990
+ (this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) &&
991
+ this.separatorLimit.length > 14 &&
992
+ String(value).length > 14)) {
778
993
  return String(value);
779
994
  }
780
- return Number(value).toLocaleString('fullwide', {
995
+ return Number(value)
996
+ .toLocaleString('fullwide', {
781
997
  useGrouping: false,
782
998
  maximumFractionDigits: 20,
783
- });
999
+ })
1000
+ .replace(`/${"-" /* MaskExpression.MINUS */}/`, "-" /* MaskExpression.MINUS */);
784
1001
  }
785
1002
  showMaskInInput(inputVal) {
786
1003
  if (this.showMaskTyped && !!this.shownMaskExpression) {
@@ -793,45 +1010,62 @@ class MaskService extends MaskApplierService {
793
1010
  }
794
1011
  else if (this.showMaskTyped) {
795
1012
  if (inputVal) {
796
- if (this.maskExpression === 'IP') {
1013
+ if (this.maskExpression === "IP" /* MaskExpression.IP */) {
797
1014
  return this._checkForIp(inputVal);
798
1015
  }
799
- if (this.maskExpression === 'CPF_CNPJ') {
1016
+ if (this.maskExpression === "CPF_CNPJ" /* MaskExpression.CPF_CNPJ */) {
800
1017
  return this._checkForCpfCnpj(inputVal);
801
1018
  }
802
1019
  }
1020
+ if (this.placeHolderCharacter.length === this.maskExpression.length) {
1021
+ return this.placeHolderCharacter;
1022
+ }
803
1023
  return this.maskExpression.replace(/\w/g, this.placeHolderCharacter);
804
1024
  }
805
1025
  return '';
806
1026
  }
807
1027
  clearIfNotMatchFn() {
808
- const formElement = this._elementRef.nativeElement;
1028
+ var _a;
1029
+ const formElement = (_a = this._elementRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
1030
+ if (!formElement) {
1031
+ return;
1032
+ }
809
1033
  if (this.clearIfNotMatch &&
810
1034
  this.prefix.length + this.maskExpression.length + this.suffix.length !==
811
- formElement.value.replace(/_/g, '').length) {
812
- this.formElementProperty = ['value', ''];
813
- this.applyMask(formElement.value, this.maskExpression);
1035
+ formElement.value.replace(this.placeHolderCharacter, "" /* MaskExpression.EMPTY_STRING */)
1036
+ .length) {
1037
+ this.formElementProperty = ['value', "" /* MaskExpression.EMPTY_STRING */];
1038
+ this.applyMask('', this.maskExpression);
814
1039
  }
815
1040
  }
816
1041
  set formElementProperty([name, value]) {
817
- Promise.resolve().then(() => this._renderer.setProperty(this._elementRef.nativeElement, name, value));
1042
+ if (!this._renderer || !this._elementRef) {
1043
+ return;
1044
+ }
1045
+ Promise.resolve().then(() => { var _a, _b; return (_a = this._renderer) === null || _a === void 0 ? void 0 : _a.setProperty((_b = this._elementRef) === null || _b === void 0 ? void 0 : _b.nativeElement, name, value); });
818
1046
  }
819
1047
  checkSpecialCharAmount(mask) {
820
- const chars = mask.split('').filter((item) => this._findSpecialChar(item));
1048
+ const chars = mask
1049
+ .split("" /* MaskExpression.EMPTY_STRING */)
1050
+ .filter((item) => this._findSpecialChar(item));
821
1051
  return chars.length;
822
1052
  }
823
1053
  removeMask(inputValue) {
824
- return this._removeMask(this._removeSuffix(this._removePrefix(inputValue)), this.maskSpecialCharacters.concat('_').concat(this.placeHolderCharacter));
1054
+ return this._removeMask(this._removeSuffix(this._removePrefix(inputValue)), this.specialCharacters.concat('_').concat(this.placeHolderCharacter));
825
1055
  }
826
1056
  _checkForIp(inputVal) {
827
1057
  var _a;
828
- if (inputVal === '#') {
1058
+ if (inputVal === "#" /* MaskExpression.HASH */) {
829
1059
  return `${this.placeHolderCharacter}.${this.placeHolderCharacter}.${this.placeHolderCharacter}.${this.placeHolderCharacter}`;
830
1060
  }
831
1061
  const arr = [];
832
1062
  for (let i = 0; i < inputVal.length; i++) {
833
- if ((_a = inputVal[i]) === null || _a === void 0 ? void 0 : _a.match('\\d')) {
834
- arr.push(inputVal[i]);
1063
+ const value = (_a = inputVal[i]) !== null && _a !== void 0 ? _a : "" /* MaskExpression.EMPTY_STRING */;
1064
+ if (!value) {
1065
+ continue;
1066
+ }
1067
+ if (value.match('\\d')) {
1068
+ arr.push(value);
835
1069
  }
836
1070
  }
837
1071
  if (arr.length <= 3) {
@@ -859,13 +1093,17 @@ class MaskService extends MaskApplierService {
859
1093
  `.${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}` +
860
1094
  `/${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}` +
861
1095
  `-${this.placeHolderCharacter}${this.placeHolderCharacter}`;
862
- if (inputVal === '#') {
1096
+ if (inputVal === "#" /* MaskExpression.HASH */) {
863
1097
  return cpf;
864
1098
  }
865
1099
  const arr = [];
866
1100
  for (let i = 0; i < inputVal.length; i++) {
867
- if ((_a = inputVal[i]) === null || _a === void 0 ? void 0 : _a.match('\\d')) {
868
- arr.push(inputVal[i]);
1101
+ const value = (_a = inputVal[i]) !== null && _a !== void 0 ? _a : "" /* MaskExpression.EMPTY_STRING */;
1102
+ if (!value) {
1103
+ continue;
1104
+ }
1105
+ if (value.match('\\d')) {
1106
+ arr.push(value);
869
1107
  }
870
1108
  }
871
1109
  if (arr.length <= 3) {
@@ -916,55 +1154,88 @@ class MaskService extends MaskApplierService {
916
1154
  */
917
1155
  formControlResult(inputValue) {
918
1156
  if (this.writingValue || (!this.triggerOnMaskChange && this.maskChanged)) {
1157
+ this.maskChanged
1158
+ ? this.onChange(this.outputTransformFn(this._toNumber(this._checkSymbols(this._removeSuffix(this._removePrefix(inputValue))))))
1159
+ : '';
919
1160
  this.maskChanged = false;
920
1161
  return;
921
1162
  }
922
1163
  if (Array.isArray(this.dropSpecialCharacters)) {
923
- this.onChange(this._toNumber(this._removeMask(this._removeSuffix(this._removePrefix(inputValue)), this.dropSpecialCharacters)));
1164
+ this.onChange(this.outputTransformFn(this._toNumber(this._checkSymbols(this._removeMask(this._removeSuffix(this._removePrefix(inputValue)), this.dropSpecialCharacters)))));
924
1165
  }
925
- else if (this.dropSpecialCharacters) {
926
- this.onChange(this._toNumber(this._checkSymbols(inputValue)));
1166
+ else if (this.dropSpecialCharacters ||
1167
+ (!this.dropSpecialCharacters && this.prefix === inputValue)) {
1168
+ this.onChange(this.outputTransformFn(this._toNumber(this._checkSymbols(this._removeSuffix(this._removePrefix(inputValue))))));
927
1169
  }
928
1170
  else {
929
- this.onChange(this._removeSuffix(inputValue));
1171
+ this.onChange(this.outputTransformFn(this._toNumber(inputValue)));
930
1172
  }
931
1173
  }
932
1174
  _toNumber(value) {
933
- if (!this.isNumberValue || value === '') {
1175
+ if (!this.isNumberValue || value === "" /* MaskExpression.EMPTY_STRING */) {
1176
+ return value;
1177
+ }
1178
+ if (this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) &&
1179
+ (this.leadZero || !this.dropSpecialCharacters)) {
934
1180
  return value;
935
1181
  }
1182
+ if (String(value).length > 16 && this.separatorLimit.length > 14) {
1183
+ return String(value);
1184
+ }
936
1185
  const num = Number(value);
1186
+ if (this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) && Number.isNaN(num)) {
1187
+ const val = String(value).replace(',', '.');
1188
+ return Number(val);
1189
+ }
937
1190
  return Number.isNaN(num) ? value : num;
938
1191
  }
939
1192
  _removeMask(value, specialCharactersForRemove) {
940
- return value ? value.replace(this._regExpForRemove(specialCharactersForRemove), '') : value;
1193
+ if (this.maskExpression.startsWith("percent" /* MaskExpression.PERCENT */) &&
1194
+ value.includes("." /* MaskExpression.DOT */)) {
1195
+ return value;
1196
+ }
1197
+ return value
1198
+ ? value.replace(this._regExpForRemove(specialCharactersForRemove), "" /* MaskExpression.EMPTY_STRING */)
1199
+ : value;
941
1200
  }
942
1201
  _removePrefix(value) {
943
1202
  if (!this.prefix) {
944
1203
  return value;
945
1204
  }
946
- return value ? value.replace(this.prefix, '') : value;
1205
+ return value ? value.replace(this.prefix, "" /* MaskExpression.EMPTY_STRING */) : value;
947
1206
  }
948
1207
  _removeSuffix(value) {
949
1208
  if (!this.suffix) {
950
1209
  return value;
951
1210
  }
952
- return value ? value.replace(this.suffix, '') : value;
1211
+ return value ? value.replace(this.suffix, "" /* MaskExpression.EMPTY_STRING */) : value;
953
1212
  }
954
1213
  _retrieveSeparatorValue(result) {
955
- return this._removeMask(this._removeSuffix(this._removePrefix(result)), this.maskSpecialCharacters);
1214
+ const specialCharacters = Array.isArray(this.dropSpecialCharacters)
1215
+ ? this.specialCharacters.filter((v) => {
1216
+ return this.dropSpecialCharacters.includes(v);
1217
+ })
1218
+ : this.specialCharacters;
1219
+ return this._removeMask(result, specialCharacters);
956
1220
  }
957
1221
  _regExpForRemove(specialCharactersForRemove) {
958
1222
  return new RegExp(specialCharactersForRemove.map((item) => `\\${item}`).join('|'), 'gi');
959
1223
  }
960
1224
  _replaceDecimalMarkerToDot(value) {
961
- const markers = Array.isArray(this.decimalMarker) ? this.decimalMarker : [this.decimalMarker];
962
- return value.replace(this._regExpForRemove(markers), '.');
1225
+ const markers = Array.isArray(this.decimalMarker)
1226
+ ? this.decimalMarker
1227
+ : [this.decimalMarker];
1228
+ return value.replace(this._regExpForRemove(markers), "." /* MaskExpression.DOT */);
963
1229
  }
964
1230
  _checkSymbols(result) {
965
- if (result === '') {
1231
+ if (result === "" /* MaskExpression.EMPTY_STRING */) {
966
1232
  return result;
967
1233
  }
1234
+ if (this.maskExpression.startsWith("percent" /* MaskExpression.PERCENT */) &&
1235
+ this.decimalMarker === "," /* MaskExpression.COMMA */) {
1236
+ // eslint-disable-next-line no-param-reassign
1237
+ result = result.replace("," /* MaskExpression.COMMA */, "." /* MaskExpression.DOT */);
1238
+ }
968
1239
  const separatorPrecision = this._retrieveSeparatorPrecision(this.maskExpression);
969
1240
  const separatorValue = this._replaceDecimalMarkerToDot(this._retrieveSeparatorValue(result));
970
1241
  if (!this.isNumberValue) {
@@ -974,10 +1245,13 @@ class MaskService extends MaskApplierService {
974
1245
  if (result === this.decimalMarker) {
975
1246
  return null;
976
1247
  }
1248
+ if (this.separatorLimit.length > 14) {
1249
+ return String(separatorValue);
1250
+ }
977
1251
  return this._checkPrecision(this.maskExpression, separatorValue);
978
1252
  }
979
1253
  else {
980
- return Number(separatorValue);
1254
+ return separatorValue;
981
1255
  }
982
1256
  }
983
1257
  // TODO should think about helpers or separting decimal precision to own property
@@ -986,31 +1260,87 @@ class MaskService extends MaskApplierService {
986
1260
  return matcher ? Number(matcher[1]) : null;
987
1261
  }
988
1262
  _checkPrecision(separatorExpression, separatorValue) {
989
- if (separatorExpression.indexOf('2') > 0) {
990
- return Number(separatorValue).toFixed(2);
1263
+ const separatorPrecision = separatorExpression.slice(10, 11);
1264
+ if (separatorExpression.indexOf('2') > 0 ||
1265
+ (this.leadZero && Number(separatorPrecision) > 1)) {
1266
+ if (this.decimalMarker === "," /* MaskExpression.COMMA */ && this.leadZero) {
1267
+ // eslint-disable-next-line no-param-reassign
1268
+ separatorValue = separatorValue.replace(',', '.');
1269
+ }
1270
+ return this.leadZero
1271
+ ? Number(separatorValue).toFixed(Number(separatorPrecision))
1272
+ : Number(separatorValue).toFixed(2);
991
1273
  }
992
- return Number(separatorValue);
1274
+ return this.numberToString(separatorValue);
1275
+ }
1276
+ _repeatPatternSymbols(maskExp) {
1277
+ return ((maskExp.match(/{[0-9]+}/) &&
1278
+ maskExp
1279
+ .split("" /* MaskExpression.EMPTY_STRING */)
1280
+ .reduce((accum, currVal, index) => {
1281
+ this._start =
1282
+ currVal === "{" /* MaskExpression.CURLY_BRACKETS_LEFT */ ? index : this._start;
1283
+ if (currVal !== "}" /* MaskExpression.CURLY_BRACKETS_RIGHT */) {
1284
+ return this._findSpecialChar(currVal) ? accum + currVal : accum;
1285
+ }
1286
+ this._end = index;
1287
+ const repeatNumber = Number(maskExp.slice(this._start + 1, this._end));
1288
+ const replaceWith = new Array(repeatNumber + 1).join(maskExp[this._start - 1]);
1289
+ if (maskExp.slice(0, this._start).length > 1 &&
1290
+ maskExp.includes("S" /* MaskExpression.LETTER_S */)) {
1291
+ const symbols = maskExp.slice(0, this._start - 1);
1292
+ return symbols.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)
1293
+ ? accum + replaceWith
1294
+ : symbols + accum + replaceWith;
1295
+ }
1296
+ else {
1297
+ return accum + replaceWith;
1298
+ }
1299
+ }, '')) ||
1300
+ maskExp);
1301
+ }
1302
+ currentLocaleDecimalMarker() {
1303
+ return (1.1).toLocaleString().substring(1, 2);
993
1304
  }
994
1305
  }
995
- MaskService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskService, deps: [{ token: DOCUMENT }, { token: config }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Injectable });
996
- MaskService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskService });
997
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskService, decorators: [{
1306
+ NgxMaskService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1307
+ NgxMaskService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskService });
1308
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskService, decorators: [{
998
1309
  type: Injectable
999
- }], ctorParameters: function () {
1000
- return [{ type: undefined, decorators: [{
1001
- type: Inject,
1002
- args: [DOCUMENT]
1003
- }] }, { type: undefined, decorators: [{
1004
- type: Inject,
1005
- args: [config]
1006
- }] }, { type: i0.ElementRef }, { type: i0.Renderer2 }];
1007
- } });
1310
+ }] });
1008
1311
 
1009
- class MaskDirective {
1010
- constructor(document, _maskService, _config) {
1011
- this.document = document;
1012
- this._maskService = _maskService;
1013
- this._config = _config;
1312
+ /**
1313
+ * @internal
1314
+ */
1315
+ function _configFactory() {
1316
+ const initConfig = inject(INITIAL_CONFIG);
1317
+ const configValue = inject(NEW_CONFIG);
1318
+ return configValue instanceof Function
1319
+ ? Object.assign(Object.assign({}, initConfig), configValue()) : Object.assign(Object.assign({}, initConfig), configValue);
1320
+ }
1321
+ function provideNgxMask(configValue) {
1322
+ return [
1323
+ {
1324
+ provide: NEW_CONFIG,
1325
+ useValue: configValue,
1326
+ },
1327
+ {
1328
+ provide: INITIAL_CONFIG,
1329
+ useValue: initialConfig,
1330
+ },
1331
+ {
1332
+ provide: NGX_MASK_CONFIG,
1333
+ useFactory: _configFactory,
1334
+ },
1335
+ NgxMaskService,
1336
+ ];
1337
+ }
1338
+ function provideEnvironmentNgxMask(configValue) {
1339
+ return makeEnvironmentProviders(provideNgxMask(configValue));
1340
+ }
1341
+
1342
+ class NgxMaskDirective {
1343
+ constructor() {
1014
1344
  // eslint-disable-next-line @angular-eslint/no-input-rename
1015
1345
  this.maskExpression = '';
1016
1346
  this.specialCharacters = [];
@@ -1030,25 +1360,45 @@ class MaskDirective {
1030
1360
  this.separatorLimit = null;
1031
1361
  this.allowNegativeNumbers = null;
1032
1362
  this.leadZeroDateTime = null;
1363
+ this.leadZero = null;
1033
1364
  this.triggerOnMaskChange = null;
1365
+ this.apm = null;
1366
+ this.inputTransformFn = null;
1367
+ this.outputTransformFn = null;
1368
+ this.keepCharacterPositions = null;
1034
1369
  this.maskFilled = new EventEmitter();
1035
1370
  this._maskValue = '';
1036
1371
  this._position = null;
1037
1372
  this._maskExpressionArray = [];
1038
1373
  this._justPasted = false;
1374
+ /**For IME composition event */
1375
+ this._isComposing = false;
1376
+ this.document = inject(DOCUMENT);
1377
+ this._maskService = inject(NgxMaskService, { self: true });
1378
+ this._config = inject(NGX_MASK_CONFIG);
1379
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-explicit-any
1039
1380
  this.onChange = (_) => { };
1381
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1040
1382
  this.onTouch = () => { };
1041
1383
  }
1042
1384
  ngOnChanges(changes) {
1043
- const { maskExpression, specialCharacters, patterns, prefix, suffix, thousandSeparator, decimalMarker, dropSpecialCharacters, hiddenInput, showMaskTyped, placeHolderCharacter, shownMaskExpression, showTemplate, clearIfNotMatch, validation, separatorLimit, allowNegativeNumbers, leadZeroDateTime, triggerOnMaskChange, } = changes;
1385
+ const { maskExpression, specialCharacters, patterns, prefix, suffix, thousandSeparator, decimalMarker, dropSpecialCharacters, hiddenInput, showMaskTyped, placeHolderCharacter, shownMaskExpression, showTemplate, clearIfNotMatch, validation, separatorLimit, allowNegativeNumbers, leadZeroDateTime, leadZero, triggerOnMaskChange, apm, inputTransformFn, outputTransformFn, keepCharacterPositions, } = changes;
1044
1386
  if (maskExpression) {
1045
1387
  if (maskExpression.currentValue !== maskExpression.previousValue &&
1046
1388
  !maskExpression.firstChange) {
1047
1389
  this._maskService.maskChanged = true;
1048
1390
  }
1049
- if (maskExpression.currentValue && maskExpression.currentValue.split('||').length > 1) {
1391
+ if (allowNegativeNumbers) {
1392
+ this._maskService.allowNegativeNumbers = allowNegativeNumbers.currentValue;
1393
+ if (this._maskService.allowNegativeNumbers) {
1394
+ this._maskService.specialCharacters =
1395
+ this._maskService.specialCharacters.filter((c) => c !== "-" /* MaskExpression.MINUS */);
1396
+ }
1397
+ }
1398
+ if (maskExpression.currentValue &&
1399
+ maskExpression.currentValue.split("||" /* MaskExpression.OR */).length > 1) {
1050
1400
  this._maskExpressionArray = maskExpression.currentValue
1051
- .split('||')
1401
+ .split("||" /* MaskExpression.OR */)
1052
1402
  .sort((a, b) => {
1053
1403
  return a.length - b.length;
1054
1404
  });
@@ -1056,7 +1406,7 @@ class MaskDirective {
1056
1406
  }
1057
1407
  else {
1058
1408
  this._maskExpressionArray = [];
1059
- this._maskValue = maskExpression.currentValue || '';
1409
+ this._maskValue = maskExpression.currentValue || "" /* MaskExpression.EMPTY_STRING */;
1060
1410
  this._maskService.maskExpression = this._maskValue;
1061
1411
  }
1062
1412
  }
@@ -1065,12 +1415,15 @@ class MaskDirective {
1065
1415
  return;
1066
1416
  }
1067
1417
  else {
1068
- this._maskService.maskSpecialCharacters = specialCharacters.currentValue || [];
1418
+ this._maskService.specialCharacters = specialCharacters.currentValue || [];
1069
1419
  }
1070
1420
  }
1071
1421
  // Only overwrite the mask available patterns if a pattern has actually been passed in
1072
1422
  if (patterns && patterns.currentValue) {
1073
- this._maskService.maskAvailablePatterns = patterns.currentValue;
1423
+ this._maskService.patterns = patterns.currentValue;
1424
+ }
1425
+ if (apm && apm.currentValue) {
1426
+ this._maskService.apm = apm.currentValue;
1074
1427
  }
1075
1428
  if (prefix) {
1076
1429
  this._maskService.prefix = prefix.currentValue;
@@ -1111,22 +1464,29 @@ class MaskDirective {
1111
1464
  if (separatorLimit) {
1112
1465
  this._maskService.separatorLimit = separatorLimit.currentValue;
1113
1466
  }
1114
- if (allowNegativeNumbers) {
1115
- this._maskService.allowNegativeNumbers = allowNegativeNumbers.currentValue;
1116
- if (this._maskService.allowNegativeNumbers) {
1117
- this._maskService.maskSpecialCharacters = this._maskService.maskSpecialCharacters.filter((c) => c !== '-');
1118
- }
1119
- }
1120
1467
  if (leadZeroDateTime) {
1121
1468
  this._maskService.leadZeroDateTime = leadZeroDateTime.currentValue;
1122
1469
  }
1470
+ if (leadZero) {
1471
+ this._maskService.leadZero = leadZero.currentValue;
1472
+ }
1123
1473
  if (triggerOnMaskChange) {
1124
1474
  this._maskService.triggerOnMaskChange = triggerOnMaskChange.currentValue;
1125
1475
  }
1476
+ if (inputTransformFn) {
1477
+ this._maskService.inputTransformFn = inputTransformFn.currentValue;
1478
+ }
1479
+ if (outputTransformFn) {
1480
+ this._maskService.outputTransformFn = outputTransformFn.currentValue;
1481
+ }
1482
+ if (keepCharacterPositions) {
1483
+ this._maskService.keepCharacterPositions = keepCharacterPositions.currentValue;
1484
+ }
1126
1485
  this._applyMask();
1127
1486
  }
1128
1487
  // eslint-disable-next-line complexity
1129
1488
  validate({ value }) {
1489
+ var _a, _b, _c;
1130
1490
  if (!this._maskService.validation || !this._maskValue) {
1131
1491
  return null;
1132
1492
  }
@@ -1136,7 +1496,7 @@ class MaskDirective {
1136
1496
  if (this._maskService.cpfCnpjError) {
1137
1497
  return this._createValidationError(value);
1138
1498
  }
1139
- if (this._maskValue.startsWith('separator')) {
1499
+ if (this._maskValue.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
1140
1500
  return null;
1141
1501
  }
1142
1502
  if (withoutValidation.includes(this._maskValue)) {
@@ -1150,13 +1510,16 @@ class MaskDirective {
1150
1510
  }
1151
1511
  if (value && value.toString().length >= 1) {
1152
1512
  let counterOfOpt = 0;
1153
- for (const key in this._maskService.maskAvailablePatterns) {
1154
- if (this._maskService.maskAvailablePatterns[key].optional) {
1513
+ if (this._maskValue.startsWith("percent" /* MaskExpression.PERCENT */)) {
1514
+ return null;
1515
+ }
1516
+ for (const key in this._maskService.patterns) {
1517
+ if ((_a = this._maskService.patterns[key]) === null || _a === void 0 ? void 0 : _a.optional) {
1155
1518
  if (this._maskValue.indexOf(key) !== this._maskValue.lastIndexOf(key)) {
1156
1519
  const opt = this._maskValue
1157
- .split('')
1520
+ .split("" /* MaskExpression.EMPTY_STRING */)
1158
1521
  .filter((i) => i === key)
1159
- .join('');
1522
+ .join("" /* MaskExpression.EMPTY_STRING */);
1160
1523
  counterOfOpt += opt.length;
1161
1524
  }
1162
1525
  else if (this._maskValue.indexOf(key) !== -1) {
@@ -1171,31 +1534,64 @@ class MaskDirective {
1171
1534
  }
1172
1535
  }
1173
1536
  }
1174
- if (this._maskValue.indexOf('{') === 1 &&
1537
+ if (this._maskValue.indexOf("{" /* MaskExpression.CURLY_BRACKETS_LEFT */) === 1 &&
1175
1538
  value.toString().length ===
1176
- this._maskValue.length + Number(this._maskValue.split('{')[1].split('}')[0]) - 4) {
1177
- return null;
1178
- }
1179
- if (this._maskValue.indexOf('*') === 1 || this._maskValue.indexOf('?') === 1) {
1539
+ this._maskValue.length +
1540
+ Number(((_b = this._maskValue.split("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)[1]) !== null && _b !== void 0 ? _b : "" /* MaskExpression.EMPTY_STRING */).split("}" /* MaskExpression.CURLY_BRACKETS_RIGHT */)[0]) -
1541
+ 4) {
1180
1542
  return null;
1181
1543
  }
1182
- else if ((this._maskValue.indexOf('*') > 1 &&
1183
- value.toString().length < this._maskValue.indexOf('*')) ||
1184
- (this._maskValue.indexOf('?') > 1 &&
1185
- value.toString().length < this._maskValue.indexOf('?')) ||
1186
- this._maskValue.indexOf('{') === 1) {
1544
+ else if ((this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) > 1 &&
1545
+ value.toString().length <
1546
+ this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */)) ||
1547
+ (this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */) > 1 &&
1548
+ value.toString().length <
1549
+ this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */)) ||
1550
+ this._maskValue.indexOf("{" /* MaskExpression.CURLY_BRACKETS_LEFT */) === 1) {
1187
1551
  return this._createValidationError(value);
1188
1552
  }
1189
- if (this._maskValue.indexOf('*') === -1 || this._maskValue.indexOf('?') === -1) {
1553
+ if (this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) === -1 ||
1554
+ this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */) === -1) {
1555
+ const array = this._maskValue.split('*');
1190
1556
  const length = this._maskService.dropSpecialCharacters
1191
1557
  ? this._maskValue.length -
1192
1558
  this._maskService.checkSpecialCharAmount(this._maskValue) -
1193
1559
  counterOfOpt
1194
- : this._maskValue.length - counterOfOpt;
1195
- if (value.toString().length < length) {
1196
- return this._createValidationError(value);
1560
+ : this.prefix
1561
+ ? this._maskValue.length + this.prefix.length - counterOfOpt
1562
+ : this._maskValue.length - counterOfOpt;
1563
+ if (array.length === 1) {
1564
+ if (value.toString().length < length) {
1565
+ return this._createValidationError(value);
1566
+ }
1567
+ }
1568
+ if (array.length > 1) {
1569
+ const lastIndexArray = array[array.length - 1];
1570
+ if (lastIndexArray &&
1571
+ this._maskService.specialCharacters.includes(lastIndexArray[0]) &&
1572
+ String(value).includes((_c = lastIndexArray[0]) !== null && _c !== void 0 ? _c : '') &&
1573
+ !this.dropSpecialCharacters) {
1574
+ const special = value.split(lastIndexArray[0]);
1575
+ return special[special.length - 1].length === lastIndexArray.length - 1
1576
+ ? null
1577
+ : this._createValidationError(value);
1578
+ }
1579
+ else if (((lastIndexArray &&
1580
+ !this._maskService.specialCharacters.includes(lastIndexArray[0])) ||
1581
+ !lastIndexArray ||
1582
+ this._maskService.dropSpecialCharacters) &&
1583
+ value.length >= length - 1) {
1584
+ return null;
1585
+ }
1586
+ else {
1587
+ return this._createValidationError(value);
1588
+ }
1197
1589
  }
1198
1590
  }
1591
+ if (this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) === 1 ||
1592
+ this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */) === 1) {
1593
+ return null;
1594
+ }
1199
1595
  }
1200
1596
  if (value) {
1201
1597
  this.maskFilled.emit();
@@ -1208,47 +1604,215 @@ class MaskDirective {
1208
1604
  }
1209
1605
  onModelChange(value) {
1210
1606
  // on form reset we need to update the actualValue
1211
- if ((value === '' || value === null || value === undefined) && this._maskService.actualValue) {
1212
- this._maskService.actualValue = this._maskService.getActualValue('');
1607
+ if ((value === "" /* MaskExpression.EMPTY_STRING */ || value === null || value === undefined) &&
1608
+ this._maskService.actualValue) {
1609
+ this._maskService.actualValue = this._maskService.getActualValue("" /* MaskExpression.EMPTY_STRING */);
1213
1610
  }
1214
1611
  }
1215
1612
  onInput(e) {
1216
- const el = e.target;
1217
- this._inputValue = el.value;
1218
- this._setMask();
1219
- if (!this._maskValue) {
1220
- this.onChange(el.value);
1221
- return;
1222
- }
1223
- const position = el.selectionStart === 1
1224
- ? el.selectionStart + this._maskService.prefix.length
1225
- : el.selectionStart;
1226
- let caretShift = 0;
1227
- let backspaceShift = false;
1228
- this._maskService.applyValueChanges(position, this._justPasted, this._code === 'Backspace' || this._code === 'Delete', (shift, _backspaceShift) => {
1229
- this._justPasted = false;
1230
- caretShift = shift;
1231
- backspaceShift = _backspaceShift;
1232
- });
1233
- // only set the selection if the element is active
1234
- if (this._getActiveElement() !== el) {
1613
+ var _a, _b, _c, _d;
1614
+ // If IME is composing text, we wait for the composed text.
1615
+ if (this._isComposing)
1235
1616
  return;
1617
+ const el = e.target;
1618
+ const transformedValue = this._maskService.inputTransformFn(el.value);
1619
+ if (el.type !== 'number') {
1620
+ if (typeof transformedValue === 'string' || typeof transformedValue === 'number') {
1621
+ el.value = transformedValue.toString();
1622
+ this._inputValue = el.value;
1623
+ this._setMask();
1624
+ if (!this._maskValue) {
1625
+ this.onChange(el.value);
1626
+ return;
1627
+ }
1628
+ let position = el.selectionStart === 1
1629
+ ? el.selectionStart + this._maskService.prefix.length
1630
+ : el.selectionStart;
1631
+ if (this.showMaskTyped &&
1632
+ this.keepCharacterPositions &&
1633
+ this._maskService.placeHolderCharacter.length === 1) {
1634
+ const inputSymbol = el.value.slice(position - 1, position);
1635
+ const prefixLength = this.prefix.length;
1636
+ const checkSymbols = this._maskService._checkSymbolMask(inputSymbol, (_a = this._maskService.maskExpression[position - 1 - prefixLength]) !== null && _a !== void 0 ? _a : "" /* MaskExpression.EMPTY_STRING */);
1637
+ const checkSpecialCharacter = this._maskService._checkSymbolMask(inputSymbol, (_b = this._maskService.maskExpression[position + 1 - prefixLength]) !== null && _b !== void 0 ? _b : "" /* MaskExpression.EMPTY_STRING */);
1638
+ const selectRangeBackspace = this._maskService.selStart === this._maskService.selEnd;
1639
+ const selStart = (_c = Number(this._maskService.selStart) - prefixLength) !== null && _c !== void 0 ? _c : '';
1640
+ const selEnd = (_d = Number(this._maskService.selEnd) - prefixLength) !== null && _d !== void 0 ? _d : '';
1641
+ if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
1642
+ if (!selectRangeBackspace) {
1643
+ if (this._maskService.selStart === prefixLength) {
1644
+ this._maskService.actualValue =
1645
+ this.prefix +
1646
+ this._maskService.maskIsShown.slice(0, selEnd) +
1647
+ this._inputValue.split(this.prefix).join('');
1648
+ }
1649
+ else if (this._maskService.selStart ===
1650
+ this._maskService.maskIsShown.length + prefixLength) {
1651
+ this._maskService.actualValue =
1652
+ this._inputValue +
1653
+ this._maskService.maskIsShown.slice(selStart, selEnd);
1654
+ }
1655
+ else {
1656
+ this._maskService.actualValue =
1657
+ this.prefix +
1658
+ this._inputValue
1659
+ .split(this.prefix)
1660
+ .join('')
1661
+ .slice(0, selStart) +
1662
+ this._maskService.maskIsShown.slice(selStart, selEnd) +
1663
+ this._maskService.actualValue.slice(selEnd + prefixLength, this._maskService.maskIsShown.length + prefixLength) +
1664
+ this.suffix;
1665
+ }
1666
+ }
1667
+ else if (!this._maskService.specialCharacters.includes(this._maskService.maskExpression.slice(position - this.prefix.length, position + 1 - this.prefix.length)) &&
1668
+ selectRangeBackspace) {
1669
+ if (selStart === 1 && this.prefix) {
1670
+ this._maskService.actualValue =
1671
+ this.prefix +
1672
+ this._maskService.placeHolderCharacter +
1673
+ el.value
1674
+ .split(this.prefix)
1675
+ .join('')
1676
+ .split(this.suffix)
1677
+ .join('') +
1678
+ this.suffix;
1679
+ position = position - 1;
1680
+ }
1681
+ else {
1682
+ const part1 = el.value.substring(0, position);
1683
+ const part2 = el.value.substring(position);
1684
+ this._maskService.actualValue =
1685
+ part1 + this._maskService.placeHolderCharacter + part2;
1686
+ }
1687
+ }
1688
+ }
1689
+ if (this._code !== "Backspace" /* MaskExpression.BACKSPACE */) {
1690
+ if (!checkSymbols && !checkSpecialCharacter && selectRangeBackspace) {
1691
+ position = Number(el.selectionStart) - 1;
1692
+ }
1693
+ else if (this._maskService.specialCharacters.includes(el.value.slice(position, position + 1)) &&
1694
+ checkSpecialCharacter &&
1695
+ !this._maskService.specialCharacters.includes(el.value.slice(position + 1, position + 2))) {
1696
+ this._maskService.actualValue =
1697
+ el.value.slice(0, position - 1) +
1698
+ el.value.slice(position, position + 1) +
1699
+ inputSymbol +
1700
+ el.value.slice(position + 2);
1701
+ position = position + 1;
1702
+ }
1703
+ else if (checkSymbols) {
1704
+ this._maskService.actualValue =
1705
+ el.value.slice(0, position - 1) +
1706
+ inputSymbol +
1707
+ el.value
1708
+ .slice(position + 1)
1709
+ .split(this.suffix)
1710
+ .join('') +
1711
+ this.suffix;
1712
+ }
1713
+ }
1714
+ }
1715
+ let caretShift = 0;
1716
+ let backspaceShift = false;
1717
+ if (this._code === "Delete" /* MaskExpression.DELETE */ && "separator" /* MaskExpression.SEPARATOR */) {
1718
+ this._maskService.deletedSpecialCharacter = true;
1719
+ }
1720
+ if (this._inputValue.length >= this._maskService.maskExpression.length - 1 &&
1721
+ this._code !== "Backspace" /* MaskExpression.BACKSPACE */ &&
1722
+ this._maskService.maskExpression === "d0/M0/0000" /* MaskExpression.DAYS_MONTHS_YEARS */ &&
1723
+ position < 10) {
1724
+ const inputSymbol = this._inputValue.slice(position - 1, position);
1725
+ el.value =
1726
+ this._inputValue.slice(0, position - 1) +
1727
+ inputSymbol +
1728
+ this._inputValue.slice(position + 1);
1729
+ }
1730
+ if (this._maskService.maskExpression === "Hh:m0:s0" /* MaskExpression.HOURS_MINUTES_SECONDS */ &&
1731
+ this.apm) {
1732
+ if (this._justPasted && el.value.slice(0, 2) === "00" /* MaskExpression.DOUBLE_ZERO */) {
1733
+ el.value = el.value.slice(1, 2) + el.value.slice(2, el.value.length);
1734
+ }
1735
+ el.value =
1736
+ el.value === "00" /* MaskExpression.DOUBLE_ZERO */
1737
+ ? "0" /* MaskExpression.NUMBER_ZERO */
1738
+ : el.value;
1739
+ }
1740
+ this._maskService.applyValueChanges(position, this._justPasted, this._code === "Backspace" /* MaskExpression.BACKSPACE */ || this._code === "Delete" /* MaskExpression.DELETE */, (shift, _backspaceShift) => {
1741
+ this._justPasted = false;
1742
+ caretShift = shift;
1743
+ backspaceShift = _backspaceShift;
1744
+ });
1745
+ // only set the selection if the element is active
1746
+ if (this._getActiveElement() !== el) {
1747
+ return;
1748
+ }
1749
+ // update position after applyValueChanges to prevent cursor on wrong position when it has an array of maskExpression
1750
+ if (this._maskExpressionArray.length) {
1751
+ if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
1752
+ position = this.specialCharacters.includes(this._inputValue.slice(position - 1, position))
1753
+ ? position - 1
1754
+ : position;
1755
+ }
1756
+ else {
1757
+ position =
1758
+ el.selectionStart === 1
1759
+ ? el.selectionStart + this._maskService.prefix.length
1760
+ : el.selectionStart;
1761
+ }
1762
+ }
1763
+ this._position =
1764
+ this._position === 1 && this._inputValue.length === 1 ? null : this._position;
1765
+ let positionToApply = this._position
1766
+ ? this._inputValue.length + position + caretShift
1767
+ : position +
1768
+ (this._code === "Backspace" /* MaskExpression.BACKSPACE */ && !backspaceShift ? 0 : caretShift);
1769
+ if (positionToApply > this._getActualInputLength()) {
1770
+ positionToApply = this._getActualInputLength();
1771
+ }
1772
+ if (positionToApply < 0) {
1773
+ positionToApply = 0;
1774
+ }
1775
+ el.setSelectionRange(positionToApply, positionToApply);
1776
+ this._position = null;
1777
+ }
1778
+ else {
1779
+ console.warn('Ngx-mask writeValue work with string | number, your current value:', typeof transformedValue);
1780
+ }
1236
1781
  }
1237
- this._position = this._position === 1 && this._inputValue.length === 1 ? null : this._position;
1238
- let positionToApply = this._position
1239
- ? this._inputValue.length + position + caretShift
1240
- : position + (this._code === 'Backspace' && !backspaceShift ? 0 : caretShift);
1241
- if (positionToApply > this._getActualInputLength()) {
1242
- positionToApply = this._getActualInputLength();
1243
- }
1244
- if (positionToApply < 0) {
1245
- positionToApply = 0;
1782
+ else {
1783
+ this._maskService.applyValueChanges(el.value.length, this._justPasted, this._code === "Backspace" /* MaskExpression.BACKSPACE */ || this._code === "Delete" /* MaskExpression.DELETE */);
1246
1784
  }
1247
- el.setSelectionRange(positionToApply, positionToApply);
1248
- this._position = null;
1249
1785
  }
1250
- onBlur() {
1786
+ // IME starts
1787
+ onCompositionStart() {
1788
+ this._isComposing = true;
1789
+ }
1790
+ // IME completes
1791
+ onCompositionEnd(e) {
1792
+ this._isComposing = false;
1793
+ this._justPasted = true;
1794
+ this.onInput(e);
1795
+ }
1796
+ onBlur(e) {
1251
1797
  if (this._maskValue) {
1798
+ const el = e.target;
1799
+ if (this.leadZero && el.value.length > 0 && typeof this.decimalMarker === 'string') {
1800
+ const maskExpression = this._maskService.maskExpression;
1801
+ const precision = Number(this._maskService.maskExpression.slice(maskExpression.length - 1, maskExpression.length));
1802
+ if (precision > 1) {
1803
+ el.value = this.suffix ? el.value.split(this.suffix).join('') : el.value;
1804
+ const decimalPart = el.value.split(this.decimalMarker)[1];
1805
+ el.value = el.value.includes(this.decimalMarker)
1806
+ ? el.value +
1807
+ "0" /* MaskExpression.NUMBER_ZERO */.repeat(precision - decimalPart.length) +
1808
+ this.suffix
1809
+ : el.value +
1810
+ this.decimalMarker +
1811
+ "0" /* MaskExpression.NUMBER_ZERO */.repeat(precision) +
1812
+ this.suffix;
1813
+ this._maskService.actualValue = el.value;
1814
+ }
1815
+ }
1252
1816
  this._maskService.clearIfNotMatchFn();
1253
1817
  }
1254
1818
  this.onTouch();
@@ -1266,7 +1830,7 @@ class MaskDirective {
1266
1830
  el.selectionStart > this._maskService.prefix.length &&
1267
1831
  // eslint-disable-next-line
1268
1832
  e.keyCode !== 38) {
1269
- if (this._maskService.showMaskTyped) {
1833
+ if (this._maskService.showMaskTyped && !this.keepCharacterPositions) {
1270
1834
  // We are showing the mask in the input
1271
1835
  this._maskService.maskIsShown = this._maskService.showMaskInInput();
1272
1836
  if (el.setSelectionRange &&
@@ -1284,132 +1848,190 @@ class MaskDirective {
1284
1848
  }
1285
1849
  }
1286
1850
  }
1287
- const nextValue = !el.value || el.value === this._maskService.prefix
1288
- ? this._maskService.prefix + this._maskService.maskIsShown
1289
- : el.value;
1851
+ const nextValue = el &&
1852
+ (el.value === this._maskService.prefix
1853
+ ? this._maskService.prefix + this._maskService.maskIsShown
1854
+ : el.value);
1290
1855
  /** Fix of cursor position jumping to end in most browsers no matter where cursor is inserted onFocus */
1291
- if (el.value !== nextValue) {
1856
+ if (el && el.value !== nextValue) {
1292
1857
  el.value = nextValue;
1293
1858
  }
1294
1859
  /** fix of cursor position with prefix when mouse click occur */
1295
- if ((el.selectionStart || el.selectionEnd) <=
1296
- this._maskService.prefix.length) {
1860
+ if (el &&
1861
+ el.type !== 'number' &&
1862
+ (el.selectionStart || el.selectionEnd) <=
1863
+ this._maskService.prefix.length) {
1297
1864
  el.selectionStart = this._maskService.prefix.length;
1298
1865
  return;
1299
1866
  }
1300
1867
  /** select only inserted text */
1301
- if (el.selectionEnd > this._getActualInputLength()) {
1868
+ if (el && el.selectionEnd > this._getActualInputLength()) {
1302
1869
  el.selectionEnd = this._getActualInputLength();
1303
1870
  }
1304
1871
  }
1305
1872
  // eslint-disable-next-line complexity
1306
1873
  onKeyDown(e) {
1307
- var _a;
1874
+ var _a, _b;
1308
1875
  if (!this._maskValue) {
1309
1876
  return;
1310
1877
  }
1878
+ if (this._isComposing) {
1879
+ // User finalize their choice from IME composition, so trigger onInput() for the composed text.
1880
+ if (e.key === 'Enter')
1881
+ this.onCompositionEnd(e);
1882
+ return;
1883
+ }
1311
1884
  this._code = e.code ? e.code : e.key;
1312
1885
  const el = e.target;
1313
1886
  this._inputValue = el.value;
1314
1887
  this._setMask();
1315
- if (e.keyCode === 38) {
1316
- e.preventDefault();
1317
- }
1318
- if (e.keyCode === 37 || e.keyCode === 8 || e.keyCode === 46) {
1319
- if (e.keyCode === 8 && el.value.length === 0) {
1320
- el.selectionStart = el.selectionEnd;
1321
- }
1322
- if (e.keyCode === 8 && el.selectionStart !== 0) {
1323
- // If specialChars is false, (shouldn't ever happen) then set to the defaults
1324
- this.specialCharacters = ((_a = this.specialCharacters) === null || _a === void 0 ? void 0 : _a.length)
1325
- ? this.specialCharacters
1326
- : this._config.specialCharacters;
1327
- if (this.prefix.length > 1 && el.selectionStart <= this.prefix.length) {
1328
- el.setSelectionRange(this.prefix.length, el.selectionEnd);
1888
+ if (el.type !== 'number') {
1889
+ if (e.key === "ArrowUp" /* MaskExpression.ARROW_UP */) {
1890
+ e.preventDefault();
1891
+ }
1892
+ if (e.key === "ArrowLeft" /* MaskExpression.ARROW_LEFT */ ||
1893
+ e.key === "Backspace" /* MaskExpression.BACKSPACE */ ||
1894
+ e.key === "Delete" /* MaskExpression.DELETE */) {
1895
+ if (e.key === "Backspace" /* MaskExpression.BACKSPACE */ && el.value.length === 0) {
1896
+ el.selectionStart = el.selectionEnd;
1329
1897
  }
1330
- else {
1331
- if (this._inputValue.length !== el.selectionStart &&
1332
- el.selectionStart !== 1) {
1333
- while (this.specialCharacters.includes(this._inputValue[el.selectionStart - 1].toString()) &&
1334
- ((this.prefix.length >= 1 && el.selectionStart > this.prefix.length) ||
1335
- this.prefix.length === 0)) {
1336
- el.setSelectionRange(el.selectionStart - 1, el.selectionEnd);
1898
+ if (e.key === "Backspace" /* MaskExpression.BACKSPACE */ && el.selectionStart !== 0) {
1899
+ // If specialChars is false, (shouldn't ever happen) then set to the defaults
1900
+ this.specialCharacters = ((_a = this.specialCharacters) === null || _a === void 0 ? void 0 : _a.length)
1901
+ ? this.specialCharacters
1902
+ : this._config.specialCharacters;
1903
+ if (this.prefix.length > 1 &&
1904
+ el.selectionStart <= this.prefix.length) {
1905
+ el.setSelectionRange(this.prefix.length, el.selectionEnd);
1906
+ }
1907
+ else {
1908
+ if (this._inputValue.length !== el.selectionStart &&
1909
+ el.selectionStart !== 1) {
1910
+ while (this.specialCharacters.includes(((_b = this._inputValue[el.selectionStart - 1]) !== null && _b !== void 0 ? _b : "" /* MaskExpression.EMPTY_STRING */).toString()) &&
1911
+ ((this.prefix.length >= 1 &&
1912
+ el.selectionStart > this.prefix.length) ||
1913
+ this.prefix.length === 0)) {
1914
+ el.setSelectionRange(el.selectionStart - 1, el.selectionEnd);
1915
+ }
1337
1916
  }
1338
1917
  }
1339
1918
  }
1919
+ this.checkSelectionOnDeletion(el);
1920
+ if (this._maskService.prefix.length &&
1921
+ el.selectionStart <= this._maskService.prefix.length &&
1922
+ el.selectionEnd <= this._maskService.prefix.length) {
1923
+ e.preventDefault();
1924
+ }
1925
+ const cursorStart = el.selectionStart;
1926
+ if (e.key === "Backspace" /* MaskExpression.BACKSPACE */ &&
1927
+ !el.readOnly &&
1928
+ cursorStart === 0 &&
1929
+ el.selectionEnd === el.value.length &&
1930
+ el.value.length !== 0) {
1931
+ this._position = this._maskService.prefix ? this._maskService.prefix.length : 0;
1932
+ this._maskService.applyMask(this._maskService.prefix, this._maskService.maskExpression, this._position);
1933
+ }
1340
1934
  }
1341
- this.checkSelectionOnDeletion(el);
1342
- if (this._maskService.prefix.length &&
1343
- el.selectionStart <= this._maskService.prefix.length &&
1344
- el.selectionEnd <= this._maskService.prefix.length) {
1345
- e.preventDefault();
1935
+ if (!!this.suffix &&
1936
+ this.suffix.length > 1 &&
1937
+ this._inputValue.length - this.suffix.length < el.selectionStart) {
1938
+ el.setSelectionRange(this._inputValue.length - this.suffix.length, this._inputValue.length);
1346
1939
  }
1347
- const cursorStart = el.selectionStart;
1348
- if (e.keyCode === 8 &&
1349
- !el.readOnly &&
1350
- cursorStart === 0 &&
1351
- el.selectionEnd === el.value.length &&
1352
- el.value.length !== 0) {
1353
- this._position = this._maskService.prefix ? this._maskService.prefix.length : 0;
1354
- this._maskService.applyMask(this._maskService.prefix, this._maskService.maskExpression, this._position);
1940
+ else if ((e.code === 'KeyA' && e.ctrlKey) ||
1941
+ (e.code === 'KeyA' && e.metaKey) // Cmd + A (Mac)
1942
+ ) {
1943
+ el.setSelectionRange(0, this._getActualInputLength());
1944
+ e.preventDefault();
1355
1945
  }
1946
+ this._maskService.selStart = el.selectionStart;
1947
+ this._maskService.selEnd = el.selectionEnd;
1356
1948
  }
1357
- if (!!this.suffix &&
1358
- this.suffix.length > 1 &&
1359
- this._inputValue.length - this.suffix.length < el.selectionStart) {
1360
- el.setSelectionRange(this._inputValue.length - this.suffix.length, this._inputValue.length);
1361
- }
1362
- else if ((e.keyCode === 65 && e.ctrlKey) ||
1363
- (e.keyCode === 65 && e.metaKey) // Cmd + A (Mac)
1364
- ) {
1365
- el.setSelectionRange(0, this._getActualInputLength());
1366
- e.preventDefault();
1367
- }
1368
- this._maskService.selStart = el.selectionStart;
1369
- this._maskService.selEnd = el.selectionEnd;
1370
1949
  }
1371
1950
  /** It writes the value in the input */
1372
- writeValue(inputValue) {
1951
+ writeValue(controlValue) {
1952
+ var _a;
1373
1953
  return __awaiter(this, void 0, void 0, function* () {
1374
- if (typeof inputValue === 'object' && inputValue !== null && 'value' in inputValue) {
1375
- if ('disable' in inputValue) {
1376
- this.setDisabledState(Boolean(inputValue.disable));
1954
+ if (typeof controlValue === 'object' && controlValue !== null && 'value' in controlValue) {
1955
+ if ('disable' in controlValue) {
1956
+ this.setDisabledState(Boolean(controlValue.disable));
1377
1957
  }
1378
1958
  // eslint-disable-next-line no-param-reassign
1379
- inputValue = inputValue.value;
1959
+ controlValue = controlValue.value;
1380
1960
  }
1381
- if (typeof inputValue === 'number' || this._maskValue.startsWith('separator')) {
1961
+ if (controlValue !== null) {
1382
1962
  // eslint-disable-next-line no-param-reassign
1383
- inputValue = this._maskService.numberToString(inputValue);
1384
- if (!Array.isArray(this.decimalMarker)) {
1385
- // eslint-disable-next-line no-param-reassign
1386
- inputValue =
1387
- this.decimalMarker !== '.' ? inputValue.replace('.', this.decimalMarker) : inputValue;
1388
- }
1389
- this._maskService.isNumberValue = true;
1963
+ controlValue = this.inputTransformFn
1964
+ ? this.inputTransformFn(controlValue)
1965
+ : controlValue;
1390
1966
  }
1391
- if (typeof inputValue !== 'string') {
1967
+ if (typeof controlValue === 'string' ||
1968
+ typeof controlValue === 'number' ||
1969
+ controlValue === null) {
1392
1970
  // eslint-disable-next-line no-param-reassign
1393
- inputValue = '';
1394
- }
1395
- this._inputValue = inputValue;
1396
- this._setMask();
1397
- if ((inputValue && this._maskService.maskExpression) ||
1398
- (this._maskService.maskExpression &&
1399
- (this._maskService.prefix || this._maskService.showMaskTyped))) {
1400
- // Let the service we know we are writing value so that triggering onChange function wont happen during applyMask
1401
- this._maskService.writingValue = true;
1402
- this._maskService.formElementProperty = [
1403
- 'value',
1404
- this._maskService.applyMask(inputValue, this._maskService.maskExpression),
1405
- ];
1406
- // Let the service know we've finished writing value
1407
- this._maskService.writingValue = false;
1971
+ let inputValue = controlValue;
1972
+ if (typeof inputValue === 'number' ||
1973
+ this._maskValue.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
1974
+ // eslint-disable-next-line no-param-reassign
1975
+ inputValue = String(inputValue);
1976
+ const localeDecimalMarker = this._maskService.currentLocaleDecimalMarker();
1977
+ if (!Array.isArray(this._maskService.decimalMarker)) {
1978
+ // eslint-disable-next-line no-param-reassign
1979
+ inputValue =
1980
+ this._maskService.decimalMarker !== localeDecimalMarker
1981
+ ? inputValue.replace(localeDecimalMarker, this._maskService.decimalMarker)
1982
+ : inputValue;
1983
+ }
1984
+ if (this._maskService.leadZero &&
1985
+ inputValue &&
1986
+ this.maskExpression &&
1987
+ this.dropSpecialCharacters !== false) {
1988
+ // eslint-disable-next-line no-param-reassign
1989
+ inputValue = this._maskService._checkPrecision(this._maskService.maskExpression, inputValue);
1990
+ }
1991
+ if (this._maskService.decimalMarker === "," /* MaskExpression.COMMA */) {
1992
+ // eslint-disable-next-line no-param-reassign
1993
+ inputValue = inputValue
1994
+ .toString()
1995
+ .replace("." /* MaskExpression.DOT */, "," /* MaskExpression.COMMA */);
1996
+ }
1997
+ if (((_a = this.maskExpression) === null || _a === void 0 ? void 0 : _a.startsWith("separator" /* MaskExpression.SEPARATOR */)) && this.leadZero) {
1998
+ requestAnimationFrame(() => {
1999
+ var _a;
2000
+ this._maskService.applyMask((_a = inputValue === null || inputValue === void 0 ? void 0 : inputValue.toString()) !== null && _a !== void 0 ? _a : '', this._maskService.maskExpression);
2001
+ });
2002
+ }
2003
+ this._maskService.isNumberValue = true;
2004
+ }
2005
+ if (typeof inputValue !== 'string') {
2006
+ // eslint-disable-next-line no-param-reassign
2007
+ inputValue = '';
2008
+ }
2009
+ this._inputValue = inputValue;
2010
+ this._setMask();
2011
+ if ((inputValue && this._maskService.maskExpression) ||
2012
+ (this._maskService.maskExpression &&
2013
+ (this._maskService.prefix || this._maskService.showMaskTyped))) {
2014
+ // Let the service we know we are writing value so that triggering onChange function won't happen during applyMask
2015
+ typeof this.inputTransformFn !== 'function'
2016
+ ? (this._maskService.writingValue = true)
2017
+ : '';
2018
+ this._maskService.formElementProperty = [
2019
+ 'value',
2020
+ this._maskService.applyMask(inputValue, this._maskService.maskExpression),
2021
+ ];
2022
+ // Let the service know we've finished writing value
2023
+ typeof this.inputTransformFn !== 'function'
2024
+ ? (this._maskService.writingValue = false)
2025
+ : '';
2026
+ }
2027
+ else {
2028
+ this._maskService.formElementProperty = ['value', inputValue];
2029
+ }
2030
+ this._inputValue = inputValue;
1408
2031
  }
1409
2032
  else {
1410
- this._maskService.formElementProperty = ['value', inputValue];
2033
+ console.warn('Ngx-mask writeValue work with string | number, your current value:', typeof controlValue);
1411
2034
  }
1412
- this._inputValue = inputValue;
1413
2035
  });
1414
2036
  }
1415
2037
  registerOnChange(fn) {
@@ -1436,34 +2058,23 @@ class MaskDirective {
1436
2058
  setDisabledState(isDisabled) {
1437
2059
  this._maskService.formElementProperty = ['disabled', isDisabled];
1438
2060
  }
1439
- _repeatPatternSymbols(maskExp) {
1440
- return ((maskExp.match(/{[0-9]+}/) &&
1441
- maskExp.split('').reduce((accum, currval, index) => {
1442
- this._start = currval === '{' ? index : this._start;
1443
- if (currval !== '}') {
1444
- return this._maskService._findSpecialChar(currval) ? accum + currval : accum;
1445
- }
1446
- this._end = index;
1447
- const repeatNumber = Number(maskExp.slice(this._start + 1, this._end));
1448
- const replaceWith = new Array(repeatNumber + 1).join(maskExp[this._start - 1]);
1449
- return accum + replaceWith;
1450
- }, '')) ||
1451
- maskExp);
1452
- }
1453
2061
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1454
2062
  _applyMask() {
1455
- this._maskService.maskExpression = this._repeatPatternSymbols(this._maskValue || '');
2063
+ this._maskService.maskExpression = this._maskService._repeatPatternSymbols(this._maskValue || '');
1456
2064
  this._maskService.formElementProperty = [
1457
2065
  'value',
1458
2066
  this._maskService.applyMask(this._inputValue, this._maskService.maskExpression),
1459
2067
  ];
1460
2068
  }
1461
2069
  _validateTime(value) {
1462
- const rowMaskLen = this._maskValue.split('').filter((s) => s !== ':').length;
2070
+ var _a;
2071
+ const rowMaskLen = this._maskValue
2072
+ .split("" /* MaskExpression.EMPTY_STRING */)
2073
+ .filter((s) => s !== ':').length;
1463
2074
  if (!value) {
1464
2075
  return null; // Don't validate empty values to allow for optional form control
1465
2076
  }
1466
- if ((+value[value.length - 1] === 0 && value.length < rowMaskLen) ||
2077
+ if ((+((_a = value[value.length - 1]) !== null && _a !== void 0 ? _a : -1) === 0 && value.length < rowMaskLen) ||
1467
2078
  value.length <= rowMaskLen - 2) {
1468
2079
  return this._createValidationError(value);
1469
2080
  }
@@ -1482,69 +2093,82 @@ class MaskDirective {
1482
2093
  };
1483
2094
  }
1484
2095
  _setMask() {
1485
- if (this._maskExpressionArray.length > 0) {
1486
- this._maskExpressionArray.some((mask) => {
1487
- var _a, _b;
2096
+ this._maskExpressionArray.some((mask) => {
2097
+ var _a, _b, _c, _d;
2098
+ const specialChart = mask
2099
+ .split("" /* MaskExpression.EMPTY_STRING */)
2100
+ .some((char) => this._maskService.specialCharacters.includes(char));
2101
+ if ((specialChart && this._inputValue && !mask.includes("S" /* MaskExpression.LETTER_S */)) ||
2102
+ mask.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)) {
1488
2103
  const test = ((_a = this._maskService.removeMask(this._inputValue)) === null || _a === void 0 ? void 0 : _a.length) <=
1489
2104
  ((_b = this._maskService.removeMask(mask)) === null || _b === void 0 ? void 0 : _b.length);
1490
- if (this._inputValue && test) {
1491
- this._maskValue = mask;
1492
- this.maskExpression = mask;
1493
- this._maskService.maskExpression = mask;
2105
+ if (test) {
2106
+ this._maskValue =
2107
+ this.maskExpression =
2108
+ this._maskService.maskExpression =
2109
+ mask.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)
2110
+ ? this._maskService._repeatPatternSymbols(mask)
2111
+ : mask;
1494
2112
  return test;
1495
2113
  }
1496
2114
  else {
1497
- this._maskValue = this._maskExpressionArray[this._maskExpressionArray.length - 1];
1498
- this.maskExpression = this._maskExpressionArray[this._maskExpressionArray.length - 1];
1499
- this._maskService.maskExpression =
1500
- this._maskExpressionArray[this._maskExpressionArray.length - 1];
2115
+ const expression = (_c = this._maskExpressionArray[this._maskExpressionArray.length - 1]) !== null && _c !== void 0 ? _c : "" /* MaskExpression.EMPTY_STRING */;
2116
+ this._maskValue =
2117
+ this.maskExpression =
2118
+ this._maskService.maskExpression =
2119
+ expression.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)
2120
+ ? this._maskService._repeatPatternSymbols(expression)
2121
+ : expression;
1501
2122
  }
1502
- });
1503
- }
2123
+ }
2124
+ else {
2125
+ const check = (_d = this._inputValue) === null || _d === void 0 ? void 0 : _d.split("" /* MaskExpression.EMPTY_STRING */).every((character, index) => {
2126
+ const indexMask = mask.charAt(index);
2127
+ return this._maskService._checkSymbolMask(character, indexMask);
2128
+ });
2129
+ if (check) {
2130
+ this._maskValue = this.maskExpression = this._maskService.maskExpression = mask;
2131
+ return check;
2132
+ }
2133
+ }
2134
+ });
1504
2135
  }
1505
2136
  }
1506
- MaskDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskDirective, deps: [{ token: DOCUMENT }, { token: MaskService }, { token: config }], target: i0.ɵɵFactoryTarget.Directive });
1507
- MaskDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.1", type: MaskDirective, selector: "input[mask], textarea[mask]", inputs: { maskExpression: ["mask", "maskExpression"], specialCharacters: "specialCharacters", patterns: "patterns", prefix: "prefix", suffix: "suffix", thousandSeparator: "thousandSeparator", decimalMarker: "decimalMarker", dropSpecialCharacters: "dropSpecialCharacters", hiddenInput: "hiddenInput", showMaskTyped: "showMaskTyped", placeHolderCharacter: "placeHolderCharacter", shownMaskExpression: "shownMaskExpression", showTemplate: "showTemplate", clearIfNotMatch: "clearIfNotMatch", validation: "validation", separatorLimit: "separatorLimit", allowNegativeNumbers: "allowNegativeNumbers", leadZeroDateTime: "leadZeroDateTime", triggerOnMaskChange: "triggerOnMaskChange" }, outputs: { maskFilled: "maskFilled" }, host: { listeners: { "paste": "onPaste()", "ngModelChange": "onModelChange($event)", "input": "onInput($event)", "blur": "onBlur()", "click": "onClick($event)", "keydown": "onKeyDown($event)" } }, providers: [
2137
+ NgxMaskDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2138
+ NgxMaskDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.8", type: NgxMaskDirective, isStandalone: true, selector: "input[mask], textarea[mask]", inputs: { maskExpression: ["mask", "maskExpression"], specialCharacters: "specialCharacters", patterns: "patterns", prefix: "prefix", suffix: "suffix", thousandSeparator: "thousandSeparator", decimalMarker: "decimalMarker", dropSpecialCharacters: "dropSpecialCharacters", hiddenInput: "hiddenInput", showMaskTyped: "showMaskTyped", placeHolderCharacter: "placeHolderCharacter", shownMaskExpression: "shownMaskExpression", showTemplate: "showTemplate", clearIfNotMatch: "clearIfNotMatch", validation: "validation", separatorLimit: "separatorLimit", allowNegativeNumbers: "allowNegativeNumbers", leadZeroDateTime: "leadZeroDateTime", leadZero: "leadZero", triggerOnMaskChange: "triggerOnMaskChange", apm: "apm", inputTransformFn: "inputTransformFn", outputTransformFn: "outputTransformFn", keepCharacterPositions: "keepCharacterPositions" }, outputs: { maskFilled: "maskFilled" }, host: { listeners: { "paste": "onPaste()", "ngModelChange": "onModelChange($event)", "input": "onInput($event)", "compositionstart": "onCompositionStart($event)", "compositionend": "onCompositionEnd($event)", "blur": "onBlur($event)", "click": "onClick($event)", "keydown": "onKeyDown($event)" } }, providers: [
1508
2139
  {
1509
2140
  provide: NG_VALUE_ACCESSOR,
1510
- useExisting: forwardRef(() => MaskDirective),
2141
+ useExisting: NgxMaskDirective,
1511
2142
  multi: true,
1512
2143
  },
1513
2144
  {
1514
2145
  provide: NG_VALIDATORS,
1515
- useExisting: forwardRef(() => MaskDirective),
2146
+ useExisting: NgxMaskDirective,
1516
2147
  multi: true,
1517
2148
  },
1518
- MaskService,
2149
+ NgxMaskService,
1519
2150
  ], exportAs: ["mask", "ngxMask"], usesOnChanges: true, ngImport: i0 });
1520
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskDirective, decorators: [{
2151
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskDirective, decorators: [{
1521
2152
  type: Directive,
1522
2153
  args: [{
1523
2154
  selector: 'input[mask], textarea[mask]',
2155
+ standalone: true,
1524
2156
  providers: [
1525
2157
  {
1526
2158
  provide: NG_VALUE_ACCESSOR,
1527
- useExisting: forwardRef(() => MaskDirective),
2159
+ useExisting: NgxMaskDirective,
1528
2160
  multi: true,
1529
2161
  },
1530
2162
  {
1531
2163
  provide: NG_VALIDATORS,
1532
- useExisting: forwardRef(() => MaskDirective),
2164
+ useExisting: NgxMaskDirective,
1533
2165
  multi: true,
1534
2166
  },
1535
- MaskService,
2167
+ NgxMaskService,
1536
2168
  ],
1537
2169
  exportAs: 'mask,ngxMask',
1538
2170
  }]
1539
- }], ctorParameters: function () {
1540
- return [{ type: undefined, decorators: [{
1541
- type: Inject,
1542
- args: [DOCUMENT]
1543
- }] }, { type: MaskService }, { type: undefined, decorators: [{
1544
- type: Inject,
1545
- args: [config]
1546
- }] }];
1547
- }, propDecorators: { maskExpression: [{
2171
+ }], propDecorators: { maskExpression: [{
1548
2172
  type: Input,
1549
2173
  args: ['mask']
1550
2174
  }], specialCharacters: [{
@@ -1581,8 +2205,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImpor
1581
2205
  type: Input
1582
2206
  }], leadZeroDateTime: [{
1583
2207
  type: Input
2208
+ }], leadZero: [{
2209
+ type: Input
1584
2210
  }], triggerOnMaskChange: [{
1585
2211
  type: Input
2212
+ }], apm: [{
2213
+ type: Input
2214
+ }], inputTransformFn: [{
2215
+ type: Input
2216
+ }], outputTransformFn: [{
2217
+ type: Input
2218
+ }], keepCharacterPositions: [{
2219
+ type: Input
1586
2220
  }], maskFilled: [{
1587
2221
  type: Output
1588
2222
  }], onPaste: [{
@@ -1594,9 +2228,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImpor
1594
2228
  }], onInput: [{
1595
2229
  type: HostListener,
1596
2230
  args: ['input', ['$event']]
2231
+ }], onCompositionStart: [{
2232
+ type: HostListener,
2233
+ args: ['compositionstart', ['$event']]
2234
+ }], onCompositionEnd: [{
2235
+ type: HostListener,
2236
+ args: ['compositionend', ['$event']]
1597
2237
  }], onBlur: [{
1598
2238
  type: HostListener,
1599
- args: ['blur']
2239
+ args: ['blur', ['$event']]
1600
2240
  }], onClick: [{
1601
2241
  type: HostListener,
1602
2242
  args: ['click', ['$event']]
@@ -1605,97 +2245,103 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImpor
1605
2245
  args: ['keydown', ['$event']]
1606
2246
  }] } });
1607
2247
 
1608
- class MaskPipe {
1609
- constructor(_maskService) {
1610
- this._maskService = _maskService;
2248
+ class NgxMaskPipe {
2249
+ constructor() {
2250
+ this.defaultOptions = {};
2251
+ this._maskService = inject(NgxMaskService);
2252
+ this._maskExpressionArray = [];
2253
+ this.mask = '';
1611
2254
  }
1612
- transform(value, mask, thousandSeparator = null) {
1613
- if (!value && typeof value !== 'number') {
1614
- return '';
2255
+ transform(value, mask, _a = {}) {
2256
+ var { patterns } = _a, config = __rest(_a, ["patterns"]);
2257
+ const currentConfig = Object.assign(Object.assign(Object.assign({ maskExpression: mask }, this.defaultOptions), config), { patterns: Object.assign(Object.assign({}, this._maskService.patterns), patterns) });
2258
+ Object.entries(currentConfig).forEach(([key, value]) => {
2259
+ //eslint-disable-next-line @typescript-eslint/no-explicit-any
2260
+ this._maskService[key] = value;
2261
+ });
2262
+ if (mask.includes('||')) {
2263
+ if (mask.split('||').length > 1) {
2264
+ this._maskExpressionArray = mask.split('||').sort((a, b) => {
2265
+ return a.length - b.length;
2266
+ });
2267
+ this._setMask(value);
2268
+ return this._maskService.applyMask(`${value}`, this.mask);
2269
+ }
2270
+ else {
2271
+ this._maskExpressionArray = [];
2272
+ return this._maskService.applyMask(`${value}`, this.mask);
2273
+ }
1615
2274
  }
1616
- if (thousandSeparator) {
1617
- this._maskService.thousandSeparator = thousandSeparator;
2275
+ if (mask.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)) {
2276
+ return this._maskService.applyMask(`${value}`, this._maskService._repeatPatternSymbols(mask));
1618
2277
  }
1619
- if (typeof mask === 'string') {
1620
- return this._maskService.applyMask(`${value}`, mask);
2278
+ if (mask.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
2279
+ if (config.decimalMarker) {
2280
+ this._maskService.decimalMarker = config.decimalMarker;
2281
+ }
2282
+ if (config.thousandSeparator) {
2283
+ this._maskService.thousandSeparator = config.thousandSeparator;
2284
+ }
2285
+ if (config.leadZero) {
2286
+ // eslint-disable-next-line no-param-reassign
2287
+ this._maskService.leadZero = config.leadZero;
2288
+ }
2289
+ // eslint-disable-next-line no-param-reassign
2290
+ value = String(value);
2291
+ const localeDecimalMarker = this._maskService.currentLocaleDecimalMarker();
2292
+ if (!Array.isArray(this._maskService.decimalMarker)) {
2293
+ // eslint-disable-next-line no-param-reassign
2294
+ value =
2295
+ this._maskService.decimalMarker !== localeDecimalMarker
2296
+ ? value.replace(localeDecimalMarker, this._maskService.decimalMarker)
2297
+ : value;
2298
+ }
2299
+ if (this._maskService.leadZero &&
2300
+ value &&
2301
+ this._maskService.dropSpecialCharacters !== false) {
2302
+ // eslint-disable-next-line no-param-reassign
2303
+ value = this._maskService._checkPrecision(mask, value);
2304
+ }
2305
+ if (this._maskService.decimalMarker === "," /* MaskExpression.COMMA */) {
2306
+ // eslint-disable-next-line no-param-reassign
2307
+ value = value.toString().replace("." /* MaskExpression.DOT */, "," /* MaskExpression.COMMA */);
2308
+ }
2309
+ this._maskService.isNumberValue = true;
2310
+ }
2311
+ return this._maskService.applyMask(`${value}`, mask);
2312
+ }
2313
+ _setMask(value) {
2314
+ if (this._maskExpressionArray.length > 0) {
2315
+ this._maskExpressionArray.some((mask) => {
2316
+ var _a, _b, _c;
2317
+ const test = ((_a = this._maskService.removeMask(value)) === null || _a === void 0 ? void 0 : _a.length) <=
2318
+ ((_b = this._maskService.removeMask(mask)) === null || _b === void 0 ? void 0 : _b.length);
2319
+ if (value && test) {
2320
+ this.mask = mask;
2321
+ return test;
2322
+ }
2323
+ else {
2324
+ const expression = (_c = this._maskExpressionArray[this._maskExpressionArray.length - 1]) !== null && _c !== void 0 ? _c : "" /* MaskExpression.EMPTY_STRING */;
2325
+ this.mask = expression;
2326
+ }
2327
+ });
1621
2328
  }
1622
- return this._maskService.applyMaskWithPattern(`${value}`, mask);
1623
2329
  }
1624
2330
  }
1625
- MaskPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskPipe, deps: [{ token: MaskApplierService }], target: i0.ɵɵFactoryTarget.Pipe });
1626
- MaskPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.1", ngImport: i0, type: MaskPipe, name: "mask" });
1627
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: MaskPipe, decorators: [{
2331
+ NgxMaskPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2332
+ NgxMaskPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskPipe, isStandalone: true, name: "mask" });
2333
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgxMaskPipe, decorators: [{
1628
2334
  type: Pipe,
1629
2335
  args: [{
1630
2336
  name: 'mask',
1631
2337
  pure: true,
1632
- }]
1633
- }], ctorParameters: function () { return [{ type: MaskApplierService }]; } });
1634
-
1635
- /**
1636
- * @internal
1637
- */
1638
- function _configFactory(initConfig, configValue) {
1639
- return configValue instanceof Function
1640
- ? Object.assign(Object.assign({}, initConfig), configValue()) : Object.assign(Object.assign({}, initConfig), configValue);
1641
- }
1642
- class NgxMaskModule {
1643
- static forRoot(configValue) {
1644
- return {
1645
- ngModule: NgxMaskModule,
1646
- providers: [
1647
- {
1648
- provide: NEW_CONFIG,
1649
- useValue: configValue,
1650
- },
1651
- {
1652
- provide: INITIAL_CONFIG,
1653
- useValue: initialConfig,
1654
- },
1655
- {
1656
- provide: config,
1657
- useFactory: _configFactory,
1658
- deps: [INITIAL_CONFIG, NEW_CONFIG],
1659
- },
1660
- MaskApplierService,
1661
- ],
1662
- };
1663
- }
1664
- static forChild() {
1665
- return {
1666
- ngModule: NgxMaskModule,
1667
- };
1668
- }
1669
- }
1670
- NgxMaskModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: NgxMaskModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1671
- NgxMaskModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.1", ngImport: i0, type: NgxMaskModule, declarations: [MaskDirective, MaskPipe], exports: [MaskDirective, MaskPipe] });
1672
- NgxMaskModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: NgxMaskModule });
1673
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.1", ngImport: i0, type: NgxMaskModule, decorators: [{
1674
- type: NgModule,
1675
- args: [{
1676
- exports: [MaskDirective, MaskPipe],
1677
- declarations: [MaskDirective, MaskPipe],
2338
+ standalone: true,
1678
2339
  }]
1679
2340
  }] });
1680
2341
 
1681
- const commonjsGlobal = typeof globalThis !== 'undefined'
1682
- ? globalThis
1683
- : typeof window !== 'undefined'
1684
- ? window
1685
- : typeof global !== 'undefined'
1686
- ? global
1687
- : typeof self !== 'undefined'
1688
- ? self
1689
- : {};
1690
- (function () {
1691
- if (!commonjsGlobal.KeyboardEvent) {
1692
- commonjsGlobal.KeyboardEvent = function (_eventType, _init) { };
1693
- }
1694
- })();
1695
-
1696
2342
  /**
1697
2343
  * Generated bundle index. Do not edit.
1698
2344
  */
1699
2345
 
1700
- export { INITIAL_CONFIG, MaskApplierService, MaskDirective, MaskPipe, MaskService, NEW_CONFIG, NgxMaskModule, _configFactory, config, initialConfig, timeMasks, withoutValidation };
2346
+ export { INITIAL_CONFIG, NEW_CONFIG, NGX_MASK_CONFIG, NgxMaskDirective, NgxMaskPipe, NgxMaskService, initialConfig, provideEnvironmentNgxMask, provideNgxMask, timeMasks, withoutValidation };
1701
2347
  //# sourceMappingURL=ngx-mask.mjs.map