diff --git a/dist/v-mask.esm.js b/dist/v-mask.esm.js index 6ab5cb70..dfafb7be 100644 --- a/dist/v-mask.esm.js +++ b/dist/v-mask.esm.js @@ -1,35 +1,18 @@ function format (text, wholeMask) { if (!wholeMask) return text; - var maskStartRegExp = /^([^#ANX]+)/; + return mask(clean(prepare(text, wholeMask), wholeMask), wholeMask); +} - if (+text.length === 1 && maskStartRegExp.test(wholeMask)) { - text = maskStartRegExp.exec(wholeMask)[0] + text; - } +var mask = function mask(text, wholeMask) { + if (!wholeMask) return text; var newText = ''; var charOffset = 0; - for (var maskIndex = 0; maskIndex < wholeMask.length; maskIndex += 1) { - var mask = wholeMask.charAt(maskIndex); - switch (mask) { - case '#': - break; - case 'A': - break; - case '?': - break; - case 'N': - break; - case 'X': - break; - default: - text = text.replace(mask, ''); - } - } - for (var _maskIndex = 0, x = 1; x && _maskIndex < wholeMask.length; _maskIndex += 1) { - var char = text.charAt(_maskIndex - charOffset); - var _mask = wholeMask.charAt(_maskIndex); + for (var maskIndex = 0, x = 1; x && maskIndex < wholeMask.length; maskIndex += 1) { + var char = text.charAt(maskIndex - charOffset); + var _mask = wholeMask.charAt(maskIndex); switch (_mask) { case '#': @@ -59,7 +42,43 @@ function format (text, wholeMask) { } } return newText; -} +}; + +var clean = function clean(text, wholeMask) { + if (!wholeMask) return text; + + for (var maskIndex = 0; maskIndex < wholeMask.length; maskIndex += 1) { + var _mask2 = wholeMask.charAt(maskIndex); + switch (_mask2) { + case '#': + break; + case 'A': + break; + case '?': + break; + case 'N': + break; + case 'X': + break; + default: + text = text.replace(_mask2, ''); + } + } + + return text; +}; + +var prepare = function prepare(text, wholeMask) { + if (!wholeMask) return text; + + var maskStartRegExp = /^([^#ANX]+)/; + + if (+text.length === 1 && maskStartRegExp.test(wholeMask)) { + text = maskStartRegExp.exec(wholeMask)[0] + text; + } + + return text; +}; var trigger = function trigger(el, type) { var e = document.createEvent('HTMLEvents'); @@ -79,11 +98,11 @@ function updateValue(el) { _el$dataset = el.dataset, _el$dataset$previousV = _el$dataset.previousValue, previousValue = _el$dataset$previousV === undefined ? '' : _el$dataset$previousV, - mask = _el$dataset.mask; + mask$$1 = _el$dataset.mask; if (force || value && value !== previousValue && value.length > previousValue.length) { - el.value = format(value, mask); + el.value = format(value, mask$$1); if (isAndroid && isChrome) { setTimeout(function () { return trigger(el, 'input'); @@ -94,10 +113,11 @@ function updateValue(el) { } el.dataset.previousValue = value; + el.dataset.rawValue = clean(value, mask$$1); } -function updateMask(el, mask) { - el.dataset.mask = mask; +function updateMask(el, mask$$1) { + el.dataset.mask = mask$$1; } var directive = { diff --git a/dist/v-mask.js b/dist/v-mask.js index fa2c534f..0efcfe8b 100644 --- a/dist/v-mask.js +++ b/dist/v-mask.js @@ -7,35 +7,18 @@ function format (text, wholeMask) { if (!wholeMask) return text; - var maskStartRegExp = /^([^#ANX]+)/; + return mask(clean(prepare(text, wholeMask), wholeMask), wholeMask); + } - if (+text.length === 1 && maskStartRegExp.test(wholeMask)) { - text = maskStartRegExp.exec(wholeMask)[0] + text; - } + var mask = function mask(text, wholeMask) { + if (!wholeMask) return text; var newText = ''; var charOffset = 0; - for (var maskIndex = 0; maskIndex < wholeMask.length; maskIndex += 1) { - var mask = wholeMask.charAt(maskIndex); - switch (mask) { - case '#': - break; - case 'A': - break; - case '?': - break; - case 'N': - break; - case 'X': - break; - default: - text = text.replace(mask, ''); - } - } - for (var _maskIndex = 0, x = 1; x && _maskIndex < wholeMask.length; _maskIndex += 1) { - var char = text.charAt(_maskIndex - charOffset); - var _mask = wholeMask.charAt(_maskIndex); + for (var maskIndex = 0, x = 1; x && maskIndex < wholeMask.length; maskIndex += 1) { + var char = text.charAt(maskIndex - charOffset); + var _mask = wholeMask.charAt(maskIndex); switch (_mask) { case '#': @@ -65,7 +48,43 @@ } } return newText; - } + }; + + var clean = function clean(text, wholeMask) { + if (!wholeMask) return text; + + for (var maskIndex = 0; maskIndex < wholeMask.length; maskIndex += 1) { + var _mask2 = wholeMask.charAt(maskIndex); + switch (_mask2) { + case '#': + break; + case 'A': + break; + case '?': + break; + case 'N': + break; + case 'X': + break; + default: + text = text.replace(_mask2, ''); + } + } + + return text; + }; + + var prepare = function prepare(text, wholeMask) { + if (!wholeMask) return text; + + var maskStartRegExp = /^([^#ANX]+)/; + + if (+text.length === 1 && maskStartRegExp.test(wholeMask)) { + text = maskStartRegExp.exec(wholeMask)[0] + text; + } + + return text; + }; var trigger = function trigger(el, type) { var e = document.createEvent('HTMLEvents'); @@ -85,11 +104,11 @@ _el$dataset = el.dataset, _el$dataset$previousV = _el$dataset.previousValue, previousValue = _el$dataset$previousV === undefined ? '' : _el$dataset$previousV, - mask = _el$dataset.mask; + mask$$1 = _el$dataset.mask; if (force || value && value !== previousValue && value.length > previousValue.length) { - el.value = format(value, mask); + el.value = format(value, mask$$1); if (isAndroid && isChrome) { setTimeout(function () { return trigger(el, 'input'); @@ -100,10 +119,11 @@ } el.dataset.previousValue = value; + el.dataset.rawValue = clean(value, mask$$1); } - function updateMask(el, mask) { - el.dataset.mask = mask; + function updateMask(el, mask$$1) { + el.dataset.mask = mask$$1; } var directive = { diff --git a/dist/v-mask.min.js b/dist/v-mask.min.js index 45657d9e..701a94e1 100644 --- a/dist/v-mask.min.js +++ b/dist/v-mask.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.VueMask={})}(this,function(e){"use strict";var t=function(e,t){var a=document.createEvent("HTMLEvents");a.initEvent(t,!0,!0),e.dispatchEvent(a)},a="undefined"!=typeof window&&window.navigator.userAgent.toLowerCase(),n=a&&a.indexOf("edge/")>0,i=a&&a.indexOf("android")>0,r=a&&/chrome\/\d+/.test(a)&&!n;function u(e){var a=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=e.value,u=e.dataset,o=u.previousValue,s=void 0===o?"":o,c=u.mask;(a||n&&n!==s&&n.length>s.length)&&(e.value=function(e,t){if(!t)return e;var a=/^([^#ANX]+)/;1==+e.length&&a.test(t)&&(e=a.exec(t)[0]+e);for(var n="",i=0,r=0;r0,o=i&&i.indexOf("android")>0,s=i&&/chrome\/\d+/.test(i)&&!u;function c(e){var i,u,c=arguments.length>1&&void 0!==arguments[1]&&arguments[1],d=e.value,f=e.dataset,v=f.previousValue,l=void 0===v?"":v,p=f.mask;(c||d&&d!==l&&d.length>l.length)&&(e.value=(i=d,(u=p)?t(a(n(i,u),u),u):i),o&&s?setTimeout(function(){return r(e,"input")},0):r(e,"input")),e.dataset.previousValue=d,e.dataset.rawValue=a(d,p)}function d(e,t){e.dataset.mask=t}var f={bind:function(e,t){d(e,t.value),c(e)},componentUpdated:function(e,t){var a=t.value,n=a!==t.oldValue;n&&d(e,a),c(e,n)}},v=function(e){e.directive("mask",f)};e.default=v,e.VueMaskPlugin=v,e.VueMaskDirective=f,Object.defineProperty(e,"__esModule",{value:!0})}); diff --git a/src/__tests__/clean.test.js b/src/__tests__/clean.test.js new file mode 100644 index 00000000..bb24d7f3 --- /dev/null +++ b/src/__tests__/clean.test.js @@ -0,0 +1,25 @@ +import { clean } from '../format'; + +describe('format.js - clean function', () => { + + it('should return the entry value without the mask', () => { + // time with seconds + expect(clean('11:15:15', '##:##:##')).toBe('111515'); + // hours and minutes + expect(clean('20h15m', '##h##m')).toBe('2015'); + // date-time + expect(clean('27/10/2016 23:15', '##/##/#### ##:##')).toBe('271020162315'); + // credit card + expect(clean('4532 4782 5524 7634', '#### #### #### ####')).toBe('4532478255247634'); + // phone number + expect(clean('(999) 999-9999', '(###) ###-####')).toBe('9999999999'); + // phone number (US) + expect(clean('+1 (999) 999-9999', '+1 (###) ###-####')).toBe('9999999999'); + // CPF + expect(clean('390.533.447-05', '###.###.###-##')).toBe('39053344705'); + // CPNJ + expect(clean('53.288.196/0001-28', '##.###.###/####-##')).toBe('53288196000128'); + // Social Security number + expect(clean('365-03-8704', '###-##-####')).toBe('365038704'); + }); +}); diff --git a/src/directive.js b/src/directive.js index 295adc03..4926b755 100644 --- a/src/directive.js +++ b/src/directive.js @@ -1,5 +1,5 @@ /* eslint-disable no-param-reassign */ -import format from './format'; +import format, { clean } from './format'; import { trigger, queryInputElementInside } from './utils'; import { isAndroid, isChrome } from './utils/env'; @@ -21,6 +21,7 @@ function updateValue(el, force = false) { } el.dataset.previousValue = value; + el.dataset.rawValue = clean(value, mask) } /** diff --git a/src/format.js b/src/format.js index 31090d12..8927c833 100644 --- a/src/format.js +++ b/src/format.js @@ -11,33 +11,22 @@ export default function (text, wholeMask) { if (!wholeMask) return text; - const maskStartRegExp = /^([^#ANX]+)/; + return mask(clean(prepare(text, wholeMask), wholeMask), wholeMask); +} - if (+text.length === 1 && maskStartRegExp.test(wholeMask)) { - text = maskStartRegExp.exec(wholeMask)[0] + text; - } +/** + * Applies mask to data. + * + * @param {String} text String to mask (input value) + * @param {String} [wholeMask] Mask format, like `####-##` + * @returns {string} Formatted text + */ +export const mask = (text, wholeMask) => { + if (!wholeMask) return text; let newText = ''; let charOffset = 0; - // Cleans data to avoid value loss on dynamic mask changing - for (let maskIndex = 0; maskIndex < wholeMask.length; maskIndex += 1) { - const mask = wholeMask.charAt(maskIndex); - switch (mask) { - case '#': - break; - case 'A': - break; - case '?': - break; - case 'N': - break; - case 'X': - break; - default: - text = text.replace(mask, ''); - } - } for (let maskIndex = 0, x = 1; x && maskIndex < wholeMask.length; maskIndex += 1) { const char = text.charAt(maskIndex - charOffset); const mask = wholeMask.charAt(maskIndex); @@ -73,3 +62,53 @@ export default function (text, wholeMask) { } return newText; } + +/** + * Cleans data. + * + * @param {String} text String to clean (input value) + * @param {String} [wholeMask] Mask format, like `####-##` + * @returns {string} Cleaned text + */ +export const clean = (text, wholeMask) => { + if (!wholeMask) return text; + + for (let maskIndex = 0; maskIndex < wholeMask.length; maskIndex += 1) { + const mask = wholeMask.charAt(maskIndex); + switch (mask) { + case '#': + break; + case 'A': + break; + case '?': + break; + case 'N': + break; + case 'X': + break; + default: + text = text.replace(mask, ''); + } + } + + return text; +} + +/** + * Prepares data. + * + * @param {String} text String to prepare (input value) + * @param {String} [wholeMask] Mask format, like `####-##` + * @returns {string} Prepared text + */ +export const prepare = (text, wholeMask) => { + if (!wholeMask) return text; + + const maskStartRegExp = /^([^#ANX]+)/; + + if (+text.length === 1 && maskStartRegExp.test(wholeMask)) { + text = maskStartRegExp.exec(wholeMask)[0] + text; + } + + return text; +}