UNPKG

primevue

Version:

PrimeVue is a premium UI library for Vue featuring a rich set of 90+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock, wh

543 lines (537 loc) 20.8 kB
import { getUserAgent } from '@primeuix/utils/dom'; import BaseDirective from '@primevue/core/basedirective'; import MaskStyle from 'primevue/mask/style'; var BaseMask = BaseDirective.extend({ style: MaskStyle }); function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var CARET_TIMEOUT = 10; var STATE_KEYS = ['$_pmaskMask', '$_pmaskSlotChar', '$_pmaskAutoClear', '$_pmaskUnmask', '$_pmaskTests', '$_pmaskBuffer', '$_pmaskDefaultBuffer', '$_pmaskDefs', '$_pmaskLen', '$_pmaskPartialPosition', '$_pmaskFirstNonMaskPos', '$_pmaskLastReqPos', '$_pmaskAndroidChrome', '$_pmaskAndroid', '$_pmaskIPhone', '$_pmaskCurrentVal', '$_pmaskFocusText', '$_pmaskOldVal', '$_pmaskFocus', '$_pmaskCursor', '$_pmaskInternal', '$_pmaskExpectedWriteback', '$_pmaskOnChange']; var Mask = BaseMask.extend('mask', { mounted: function mounted(el, options) { var target = this.getTarget(el); if (!target) return; el.$_pmaskTarget = target; this.initTarget(target, options); }, updated: function updated(el, options) { var target = this.getTarget(el); var previousTarget = el.$_pmaskTarget; if (previousTarget && previousTarget !== target) { this.cleanupTarget(previousTarget); } el.$_pmaskTarget = target; if (!target) return; if (previousTarget !== target) { this.initTarget(target, options); return; } var previousMask = target.$_pmaskMask; var previousSlotChar = target.$_pmaskSlotChar; this.applyOptions(target, options); if (previousMask !== target.$_pmaskMask || previousSlotChar !== target.$_pmaskSlotChar) { this.clearCaretTimer(target); this.init(target); return; } // After updateModel emitted a value that differs from the masked display, Vue may have // written that emitted value back into the DOM via v-model. Restore the masked string here. if (target.$_pmaskExpectedWriteback) { target.$_pmaskExpectedWriteback = false; var expectedMasked = target.$_pmaskBuffer.join(''); if (target.value !== expectedMasked) { target.value = expectedMasked; } this.restoreCursor(target); target.$_pmaskCursor = null; return; } this.syncExternalValue(target); }, unmounted: function unmounted(el) { var target = el.$_pmaskTarget || this.getTarget(el); if (!target) return; this.cleanupTarget(target); el.$_pmaskTarget = null; }, methods: { getTarget: function getTarget(el) { if (!el) return null; if (el.tagName === 'INPUT') return el; return el.querySelector('input') || null; }, applyOptions: function applyOptions(target, options) { var _value$mask; var value = options.value; var isObject = value !== null && _typeof(value) === 'object' && !Array.isArray(value); target.$_pmaskMask = isObject ? (_value$mask = value.mask) !== null && _value$mask !== void 0 ? _value$mask : null : value !== null && value !== void 0 ? value : null; target.$_pmaskSlotChar = isObject && value.slotChar !== undefined ? value.slotChar : '_'; target.$_pmaskAutoClear = isObject && value.autoClear === false ? false : true; target.$_pmaskUnmask = isObject ? !!value.unmask : false; target.$_pmaskOnChange = isObject && typeof value.onChange === 'function' ? value.onChange : null; }, initTarget: function initTarget(target, options) { this.applyOptions(target, options); this.bindEvents(target); target.setAttribute('data-pd-mask', true); this.init(target); }, clearCaretTimer: function clearCaretTimer(target) { if (target.$_pmaskCaretTimeout) { clearTimeout(target.$_pmaskCaretTimeout); target.$_pmaskCaretTimeout = null; } }, clearState: function clearState(target) { for (var _i = 0, _STATE_KEYS = STATE_KEYS; _i < _STATE_KEYS.length; _i++) { var key = _STATE_KEYS[_i]; target[key] = null; } }, cleanupTarget: function cleanupTarget(target) { this.clearCaretTimer(target); this.unbindEvents(target); this.clearState(target); target.removeAttribute('data-pd-mask'); }, bindEvents: function bindEvents(target) { var _this = this; target.$_pmaskInputEvent = function (event) { return _this.onInput(event, target); }; target.$_pmaskFocusEvent = function (event) { return _this.onFocus(event, target); }; target.$_pmaskBlurEvent = function (event) { return _this.onBlur(event, target); }; target.$_pmaskKeyDownEvent = function (event) { return _this.onKeyDown(event, target); }; target.$_pmaskKeyPressEvent = function (event) { return _this.onKeyPress(event, target); }; target.addEventListener('input', target.$_pmaskInputEvent); target.addEventListener('focus', target.$_pmaskFocusEvent); target.addEventListener('blur', target.$_pmaskBlurEvent); target.addEventListener('keydown', target.$_pmaskKeyDownEvent); target.addEventListener('keypress', target.$_pmaskKeyPressEvent); }, unbindEvents: function unbindEvents(target) { target.removeEventListener('input', target.$_pmaskInputEvent); target.removeEventListener('focus', target.$_pmaskFocusEvent); target.removeEventListener('blur', target.$_pmaskBlurEvent); target.removeEventListener('keydown', target.$_pmaskKeyDownEvent); target.removeEventListener('keypress', target.$_pmaskKeyPressEvent); target.$_pmaskInputEvent = null; target.$_pmaskFocusEvent = null; target.$_pmaskBlurEvent = null; target.$_pmaskKeyDownEvent = null; target.$_pmaskKeyPressEvent = null; }, init: function init(target) { var mask = target.$_pmaskMask; target.$_pmaskTests = []; target.$_pmaskPartialPosition = mask ? mask.length : 0; target.$_pmaskLen = mask ? mask.length : 0; target.$_pmaskFirstNonMaskPos = null; target.$_pmaskLastReqPos = 0; target.$_pmaskDefs = { 9: '[0-9]', a: '[A-Za-z]', '*': '[A-Za-z0-9]' }; var ua = getUserAgent(); target.$_pmaskAndroidChrome = /chrome/i.test(ua) && /android/i.test(ua); target.$_pmaskAndroid = /android/i.test(ua); target.$_pmaskIPhone = /iphone/i.test(ua); var maskTokens = mask ? mask.split('') : ''; for (var i = 0; i < maskTokens.length; i++) { var c = maskTokens[i]; if (c === '?') { target.$_pmaskLen--; target.$_pmaskPartialPosition = i; } else if (target.$_pmaskDefs[c]) { target.$_pmaskTests.push(new RegExp(target.$_pmaskDefs[c])); if (target.$_pmaskFirstNonMaskPos === null) { target.$_pmaskFirstNonMaskPos = target.$_pmaskTests.length - 1; } if (i < target.$_pmaskPartialPosition) { target.$_pmaskLastReqPos = target.$_pmaskTests.length - 1; } } else { target.$_pmaskTests.push(null); } } target.$_pmaskBuffer = []; for (var _i2 = 0; _i2 < maskTokens.length; _i2++) { var _c = maskTokens[_i2]; if (_c !== '?') { if (target.$_pmaskDefs[_c]) target.$_pmaskBuffer.push(this.getPlaceholder(target, _i2));else target.$_pmaskBuffer.push(_c); } } target.$_pmaskDefaultBuffer = target.$_pmaskBuffer.join(''); if (target.value) { this.checkVal(target); this.updateModel(target); } target.$_pmaskFocusText = target.value; }, syncExternalValue: function syncExternalValue(target) { if (!target.$_pmaskTests || !target.$_pmaskTests.length) return; if (target.$_pmaskInternal) return; var expectedMasked = target.$_pmaskBuffer.join(''); if (!target.value) { if (expectedMasked !== target.$_pmaskDefaultBuffer) { this.checkVal(target, true); this.writeBuffer(target); } return; } if (target.value !== expectedMasked) { this.checkVal(target, true); this.writeBuffer(target); } }, saveCursor: function saveCursor(target) { if (target === document.activeElement) { target.$_pmaskCursor = { start: target.selectionStart, end: target.selectionEnd }; } else { target.$_pmaskCursor = null; } }, restoreCursor: function restoreCursor(target) { var cursor = target.$_pmaskCursor; if (!cursor || target !== document.activeElement) return; try { target.setSelectionRange(cursor.start, cursor.end); } catch (_unused) { // ignore — input may not be in selectable state } }, caret: function caret(target, first, last) { var _target$selectionStar, _target$selectionEnd; if (typeof first === 'number') { if (!target.offsetParent || target !== document.activeElement) return; var begin = first; var end = typeof last === 'number' ? last : begin; if (target.setSelectionRange) { target.setSelectionRange(begin, end); } return; } return { begin: (_target$selectionStar = target.selectionStart) !== null && _target$selectionStar !== void 0 ? _target$selectionStar : 0, end: (_target$selectionEnd = target.selectionEnd) !== null && _target$selectionEnd !== void 0 ? _target$selectionEnd : 0 }; }, getPlaceholder: function getPlaceholder(target, i) { var slotChar = target.$_pmaskSlotChar; if (i < slotChar.length) { return slotChar.charAt(i); } return slotChar.charAt(0); }, seekNext: function seekNext(target, pos) { while (++pos < target.$_pmaskLen && !target.$_pmaskTests[pos]) {} return pos; }, seekPrev: function seekPrev(target, pos) { while (--pos >= 0 && !target.$_pmaskTests[pos]) {} return pos; }, shiftL: function shiftL(target, begin, end) { var i, j; if (begin < 0) { return; } for (i = begin, j = this.seekNext(target, end); i < target.$_pmaskLen; i++) { if (target.$_pmaskTests[i]) { if (j < target.$_pmaskLen && target.$_pmaskTests[i].test(target.$_pmaskBuffer[j])) { target.$_pmaskBuffer[i] = target.$_pmaskBuffer[j]; target.$_pmaskBuffer[j] = this.getPlaceholder(target, j); } else { break; } j = this.seekNext(target, j); } } this.writeBuffer(target); this.caret(target, Math.max(target.$_pmaskFirstNonMaskPos, begin)); }, shiftR: function shiftR(target, pos) { var i, c, j, t; for (i = pos, c = this.getPlaceholder(target, pos); i < target.$_pmaskLen; i++) { if (target.$_pmaskTests[i]) { j = this.seekNext(target, i); t = target.$_pmaskBuffer[i]; target.$_pmaskBuffer[i] = c; if (j < target.$_pmaskLen && target.$_pmaskTests[j].test(t)) { c = t; } else { break; } } } }, clearBuffer: function clearBuffer(target, start, end) { for (var i = start; i < end && i < target.$_pmaskLen; i++) { if (target.$_pmaskTests[i]) { target.$_pmaskBuffer[i] = this.getPlaceholder(target, i); } } }, writeBuffer: function writeBuffer(target) { target.value = target.$_pmaskBuffer.join(''); }, checkVal: function checkVal(target, allow) { var test = target.value; var lastMatch = -1; var i, c, pos; for (i = 0, pos = 0; i < target.$_pmaskLen; i++) { if (target.$_pmaskTests[i]) { target.$_pmaskBuffer[i] = this.getPlaceholder(target, i); while (pos++ < test.length) { c = test.charAt(pos - 1); if (target.$_pmaskTests[i].test(c)) { target.$_pmaskBuffer[i] = c; lastMatch = i; break; } } if (pos > test.length) { this.clearBuffer(target, i + 1, target.$_pmaskLen); break; } } else { if (target.$_pmaskBuffer[i] === test.charAt(pos)) { pos++; } if (i < target.$_pmaskPartialPosition) { lastMatch = i; } } } if (allow) { this.writeBuffer(target); } else if (lastMatch + 1 < target.$_pmaskPartialPosition) { if (target.$_pmaskAutoClear || target.$_pmaskBuffer.join('') === target.$_pmaskDefaultBuffer) { if (target.value) target.value = ''; this.clearBuffer(target, 0, target.$_pmaskLen); } else { this.writeBuffer(target); } } else { this.writeBuffer(target); target.value = target.value.substring(0, lastMatch + 1); } return target.$_pmaskPartialPosition ? i : target.$_pmaskFirstNonMaskPos; }, getUnmaskedValue: function getUnmaskedValue(target) { var unmaskedBuffer = []; for (var i = 0; i < target.$_pmaskBuffer.length; i++) { var c = target.$_pmaskBuffer[i]; if (target.$_pmaskTests[i] && c !== this.getPlaceholder(target, i)) { unmaskedBuffer.push(c); } } return unmaskedBuffer.join(''); }, unmaskValue: function unmaskValue(target, value) { var unmaskedBuffer = []; var chars = value.split(''); for (var i = 0; i < chars.length; i++) { var c = chars[i]; if (target.$_pmaskTests[i] && c !== this.getPlaceholder(target, i)) { unmaskedBuffer.push(c); } } return unmaskedBuffer.join(''); }, updateModel: function updateModel(target) { var masked = target.value; if (target.$_pmaskCurrentVal === masked) return; target.$_pmaskCurrentVal = masked; var unmaskedValue = this.getUnmaskedValue(target); var valueToEmit = target.$_pmaskUnmask ? unmaskedValue : masked; var finalValue = target.$_pmaskDefaultBuffer !== valueToEmit ? valueToEmit : ''; if (target.$_pmaskOnChange) { var maskedValue = target.$_pmaskDefaultBuffer !== masked ? masked : ''; target.$_pmaskOnChange({ value: maskedValue, rawValue: unmaskedValue }); } this.saveCursor(target); target.$_pmaskInternal = true; // Vue's v-model reads target.value at the moment 'input' fires, so when the value we emit // (finalValue) differs from the masked display, we briefly swap target.value, dispatch, then // restore the masked string. The next directive `updated` consumes $_pmaskExpectedWriteback // to undo Vue's writeback if it tries to push finalValue back into the DOM. if (target.$_pmaskUnmask) { target.$_pmaskExpectedWriteback = true; target.value = finalValue; target.dispatchEvent(new Event('input', { bubbles: true })); target.value = masked; } else if (finalValue === '' && masked !== '') { target.$_pmaskExpectedWriteback = true; target.value = ''; target.dispatchEvent(new Event('input', { bubbles: true })); target.value = masked; } else { target.dispatchEvent(new Event('input', { bubbles: true })); } target.$_pmaskInternal = false; this.restoreCursor(target); }, handleAndroidInput: function handleAndroidInput(event, target) { var curVal = target.value; var pos = this.caret(target); if (target.$_pmaskOldVal && target.$_pmaskOldVal.length && target.$_pmaskOldVal.length > curVal.length) { this.checkVal(target, true); while (pos.begin > 0 && !target.$_pmaskTests[pos.begin - 1]) pos.begin--; if (pos.begin === 0) { while (pos.begin < target.$_pmaskFirstNonMaskPos && !target.$_pmaskTests[pos.begin]) pos.begin++; } this.caret(target, pos.begin, pos.begin); } else { this.checkVal(target, true); while (pos.begin < target.$_pmaskLen && !target.$_pmaskTests[pos.begin]) pos.begin++; this.caret(target, pos.begin, pos.begin); } }, handleInputChange: function handleInputChange(event, target) { if (target.readOnly) return; var pos = this.checkVal(target, true); this.caret(target, pos); }, onInput: function onInput(event, target) { if (target.$_pmaskInternal) return; if (event.isComposing) return; if (target.$_pmaskAndroidChrome) this.handleAndroidInput(event, target);else this.handleInputChange(event, target); this.updateModel(target); }, onFocus: function onFocus(event, target) { var _this2 = this; if (target.readOnly) { return; } target.$_pmaskFocus = true; target.$_pmaskFocusText = target.value; this.clearCaretTimer(target); if (!target.value || target.value === target.$_pmaskDefaultBuffer) { target.$_pmaskCaretTimeout = setTimeout(function () { target.$_pmaskCaretTimeout = null; if (typeof document === 'undefined') return; if (target !== document.activeElement) return; _this2.caret(target, 0, 0); }, CARET_TIMEOUT); } else { var pos = this.checkVal(target); target.$_pmaskCaretTimeout = setTimeout(function () { target.$_pmaskCaretTimeout = null; if (typeof document === 'undefined') return; if (target !== document.activeElement) return; _this2.writeBuffer(target); if (pos === target.$_pmaskMask.replace('?', '').length) { _this2.caret(target, 0, pos); } else { _this2.caret(target, pos); } }, CARET_TIMEOUT); } }, onBlur: function onBlur(event, target) { if (target.readOnly) { return; } target.$_pmaskFocus = false; this.checkVal(target); this.updateModel(target); if (target.value !== target.$_pmaskFocusText) { target.dispatchEvent(new Event('change', { bubbles: true })); } }, onKeyDown: function onKeyDown(event, target) { if (target.readOnly) { return; } var k = event.code; var pos, begin, end; target.$_pmaskOldVal = target.value; if (k === 'Backspace' || k === 'Delete' || target.$_pmaskIPhone && k === 'Escape') { pos = this.caret(target); begin = pos.begin; end = pos.end; if (end - begin === 0) { if (k === 'Delete') { begin = this.seekNext(target, begin - 1); end = this.seekNext(target, begin); } else { begin = this.seekPrev(target, begin); } } this.clearBuffer(target, begin, end); this.shiftL(target, begin, end - 1); this.updateModel(target); event.preventDefault(); } else if (k === 'Enter') { target.blur(); this.updateModel(target); } else if (k === 'Escape') { target.value = target.$_pmaskFocusText; this.caret(target, 0, this.checkVal(target)); this.updateModel(target); event.preventDefault(); } }, onKeyPress: function onKeyPress(event, target) { var _this3 = this; if (target.readOnly) { return; } var k = event.code; var pos = this.caret(target); var p, c, next; if (event.ctrlKey || event.altKey || event.metaKey || event.shiftKey || event.key === 'CapsLock' || event.key === 'Escape' || event.key === 'Tab') { return; } else if (k && k !== 'Enter') { if (pos.end - pos.begin !== 0) { this.clearBuffer(target, pos.begin, pos.end); this.shiftL(target, pos.begin, pos.end - 1); } p = this.seekNext(target, pos.begin - 1); if (p < target.$_pmaskLen) { c = event.key; if (target.$_pmaskTests[p].test(c)) { this.shiftR(target, p); target.$_pmaskBuffer[p] = c; this.writeBuffer(target); next = this.seekNext(target, p); if (target.$_pmaskAndroid) { setTimeout(function () { _this3.caret(target, next); }, 0); } else { this.caret(target, next); } } } event.preventDefault(); } this.updateModel(target); } } }); export { Mask as default };