From 284fa37e24ed78d5b3e2b32593587a2ea30475e9 Mon Sep 17 00:00:00 2001 From: Maksym Cierzniak Date: Mon, 25 Jan 2021 23:37:19 +0100 Subject: [PATCH] [#511] * now directive will compare previous mask result with the current one if the binding value is a function when triggering update * `input` event will not fire if calculated masked value is the same as the value of the input --- src/__tests__/index.test.js | 11 +++++++++++ src/directive.js | 24 ++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/__tests__/index.test.js b/src/__tests__/index.test.js index db46180c..091c1a5a 100644 --- a/src/__tests__/index.test.js +++ b/src/__tests__/index.test.js @@ -243,6 +243,17 @@ describe('directive usage', () => { await wrapper.vm.$nextTick(); expect(wrapper.vm.$el.value).toBe('19:32'); }); + + it('should not trigger input events if resolved mask is the same as previous one', async () => { + const wrapper = mountWithMask({ + props: { triggerUpdate: { required: false } }, + data: () => ({ mask: () => [/\d/, /\d/], value: null }), + template: '', + }); + + await wrapper.setProps({ triggerUpdate: true }); + expect(wrapper.emitted().input).toBeFalsy(); + }); }); describe('filter usage', () => { diff --git a/src/directive.js b/src/directive.js index a778c97a..8bdc69a2 100644 --- a/src/directive.js +++ b/src/directive.js @@ -35,6 +35,11 @@ function updateValue(el, force = false) { if ((force || isUpdateNeeded) && mask) { const { conformedValue } = conformToMask(value, mask, { guide: false }); + + if (conformedValue === value) { + return; + } + el.value = conformedValue; triggerInputUpdate(el); } @@ -95,6 +100,22 @@ function maskToString(mask) { return filteredMaskArray.toString(); } +/** + * Check if previous mask has been different than current one + * @param {String|Array.} mask + */ +function hasMaskFromBindingChanged(el, oldValue, currentValue) { + const previousMask = isFunction(oldValue) + ? maskToString(oldValue(options.get(el).previousValue)) + : maskToString(oldValue); + + const currentMask = isFunction(currentValue) + ? maskToString(currentValue(el.value)) + : maskToString(currentValue); + + return previousMask !== currentMask; +} + /** * Create the Vue directive * @param {Object} directiveOptions @@ -139,8 +160,7 @@ export function createDirective(directiveOptions = {}) { componentUpdated(el, { value, oldValue }) { el = queryInputElementInside(el); - const isMaskChanged = isFunction(value) - || maskToString(oldValue) !== maskToString(value); + const isMaskChanged = hasMaskFromBindingChanged(el, oldValue, value); if (isMaskChanged) { updateMask(el, value, instanceMaskReplacers);