diff --git a/package.json b/package.json index 4c67093..a76aaad 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "serve": "rimraf dist && NODE_ENV=development rollup -c --watch", "build": "rimraf dist && NODE_ENV=production rollup -c && NODE_ENV=production DISABLE_BABEL=yes rollup -c", "test": "jest", - "lint": "standard 'src/**'" + "lint": "standard 'src/**'", + "lint:fix": "standard 'src/**' --fix" }, "main": "dist/maska.umd.js", "module": "dist/maska.esm.js", diff --git a/src/mask.js b/src/mask.js index 455da03..7c7e38d 100644 --- a/src/mask.js +++ b/src/mask.js @@ -69,7 +69,7 @@ function process (value, mask, tokens, masked = true) { } } - // fix mask that ends with parentesis + // fix mask that ends with parenthesis while (masked && im < mask.length) { // eslint-disable-line no-unmodified-loop-condition const maskCharRest = mask[im] if (tokens[maskCharRest]) { @@ -83,7 +83,16 @@ function process (value, mask, tokens, masked = true) { return ret + rest } +/** + * + * @param {String} value + * @param {'uppercase' | 'lowercase' | 'transform'} token + */ function tokenTransform (value, token) { + if (token.transform) { + value = token.transform(value) + } + if (token.uppercase) { return value.toLocaleUpperCase() } else if (token.lowercase) { diff --git a/src/utils.js b/src/utils.js index 2e58bf3..99aa322 100644 --- a/src/utils.js +++ b/src/utils.js @@ -19,7 +19,7 @@ function fixInputSelection (el, position, digit) { position++ } - const selectionRange = (el.type && el.type.match(/^(text|search|password|tel|url)$/i) || !el.type) + const selectionRange = el.type ? el.type.match(/^(text|search|password|tel|url)$/i) : !el.type if (selectionRange && el === document.activeElement) { el.setSelectionRange(position, position) setTimeout(function () { @@ -32,4 +32,9 @@ function isString (val) { return Object.prototype.toString.call(val) === '[object String]' } -export { event, findInputElement, fixInputSelection, isString } +export { + event, + findInputElement, + fixInputSelection, + isString +} diff --git a/test/mask.test.js b/test/mask.test.js index 95573eb..6d8d63a 100644 --- a/test/mask.test.js +++ b/test/mask.test.js @@ -120,3 +120,75 @@ test('Dynamic CPF/CNPJ', () => { expect(mask('12345678901', '["###.###.###-##", "##.###.###/####-##"]', tokens)).toBe('123.456.789-01') expect(mask('12345678901234', '["###.###.###-##", "##.###.###/####-##"]', tokens)).toBe('12.345.678/9012-34') }) + +test('Custom transform: odd number -> 1, even number -> 0', () => { + // isOdd + const transform = (numberLike) => String(Number(numberLike) % 2) + + expect((mask('1234567890', '#*', { + ...tokens, + ...{ + '#': { + pattern: /[0-9]/, + transform + } + } + }))).toBe('1010101010') +}) + +function transliterate(char) { + const rule = Object.entries({ + a: 'а', + b: 'в', + k: 'к', + m: 'м', + h: 'н', + o: 'о', + p: 'р', + c: 'с', + t: 'т', + y: 'у', + x: 'х', + }).reduce((acc, [from, to]) => { + acc[from] = to + acc[from.toLocaleUpperCase()] = to.toLocaleUpperCase() + return acc + }, {}) + return rule[char] +} + +test('Custom transform: transliterate abkTYX -> авкТУХ', () => { + expect(mask('abkTYX', 'T*', { + ...tokens, + ...{ + 'T': { + pattern: /[a-zA-Z]/, + transform: transliterate + } + } + })).toBe('авкТУХ') +}) + +test('Custom transform with `uppercase` and `lowercase` enabled: abkTYX -> АВКТУХ, abkTYX -> авктух', () => { + expect(mask('abkTYX', 'T*', { + ...tokens, + ...{ + 'T': { + pattern: /[a-zA-Z]/, + transform: transliterate, + uppercase: true, + } + } + })).toBe('АВКТУХ') + + expect(mask('abkTYX', 'T*', { + ...tokens, + ...{ + 'T': { + pattern: /[a-zA-Z]/, + transform: transliterate, + lowercase: true, + } + } + })).toBe('авктух') +}) \ No newline at end of file