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