import type { App } from 'vue'
import { isExist } from '../utils';
export function digit(app: App) {
let isFirstCompleteDeci = false;
app.directive('digit', {
mounted(el, binding, vnode, prevVnode) {
const input = el.querySelector('input');
let deci = binding.value || 2;
if(typeof binding.value == 'object') {
deci = binding.value.deci;
}
bindEvents(input, input.value, deci);
},
updated(el, binding, vnode) {
const input = el.querySelector('input');
const bindValue = binding.value;
if(bindValue?.isFirstCompleteDeci !== false && !isFirstCompleteDeci) {
isFirstCompleteDeci = true;
input.dispatchEvent(new Event('blur'))
}
}
})
const deciHandler = (input: HTMLElement | EventTarget, deci: number) => {
let value = input.value;
let selectionStart = input.selectionStart;
const reg = new RegExp("(?:[^-.0-9]+)?\\-*(0*)([1-9]\\d*)?(\\.(?:\\d{1,"+deci+"})?)?(?:[^-.0-9]+)?", "g");
const matches = reg.exec(value);
let $1 = ''
if (isExist(matches[1], true)) {
matches[1].length > 1 && selectionStart--;
$1 = matches[1].replace(/0+/, '0');
}
const $2 = matches[2] || '';
const $3 = matches[3] || '';
if ($1 == '0') {
if ($2) {
value = $2 + $3;
} else {
value = $1 + $3;
}
} else {
value = $2 + $3
}
return { value, selectionStart }
}
const bindEvents = (input: HTMLElement, oldValue: string, deci = 2) => {
let lock = false;
input.addEventListener('compositionstart', () => {
lock = true;
})
input.addEventListener('compositionend', () => {
lock = false;
input.dispatchEvent(new Event('input'))
})
input.addEventListener('input', () => {
if (lock) { return }
const curValue = input.value;
const { value, selectionStart } = deciHandler(input, deci);
if(oldValue != curValue) {
oldValue = value;
input.value = value;
input.setSelectionRange(selectionStart, selectionStart);
input.dispatchEvent(new Event('input'))
}
})
input.addEventListener('blur', (e) => {
input.value = Number(input.value).toFixed(deci);
oldValue = input.value;
input.dispatchEvent(new Event('input'))
})
}
}