import { ref, watch, nextTick, onBeforeUnmount } from 'vue'; import { state } from "./stateMgr.js"; function getNumberFromKeyEvent(event) { if (event.keyCode >= 96 && event.keyCode <= 105) { return event.keyCode - 96; } else if (event.keyCode >= 48 && event.keyCode <= 57) { return event.keyCode - 48; } return null; } export const ArrowHorizontalKeyHandler = (event) => { if (event.key == "ArrowRight") { const idx = state.sortedElements.indexOf(String(state.activeIndex)); state.activeIndex = state.sortedElements[(idx+1)%state.sortedElements.length]; } else if (event.key == "ArrowLeft") { const idx = state.sortedElements.indexOf(String(state.activeIndex)) state.activeIndex = state.sortedElements[(idx+state.sortedElements.length-1)%state.sortedElements.length]; } } export const ArrowVerticalKeyHandler = (event) => { if (event.key == "ArrowDown") { const idx = state.sortedElements.indexOf(String(state.activeIndex)) state.activeIndex = state.sortedElements[(idx+1)%state.sortedElements.length]; event.preventDefault(); } else if (event.key == "ArrowUp") { const idx = state.sortedElements.indexOf(String(state.activeIndex)) state.activeIndex = state.sortedElements[(idx+state.sortedElements.length-1)%state.sortedElements.length]; event.preventDefault(); } } export const NumberKeyHandler = (event) => { let i; if ((i = getNumberFromKeyEvent(event)) != null) { if (state.elements[i] != undefined) { event.stopPropagation(); event.preventDefault(); state.activeIndex = i; state.elements[i].focus(); state.elements[i].click(); } } } export const EnterHandler = (event) => { if (event.key == "Enter"){ if (state.hasOwnProperty("activeElement") && state.activeElement) { event.stopPropagation(); if (state.activeElement.tagName != "BUTTON"){ event.preventDefault(); } state.activeElement.click(); } } } export const handleActive = (props, keydownHandlers) => { const ownCopy = keydownHandlers.map((f) => (e) => f(e)); const currActive = ref(1); state.activeIndex = 1; const handle = () => { if (props.active){ state.activeIndex = currActive.value; for (var i = 0; i < keydownHandlers.length; i++) { document.addEventListener("keydown", ownCopy[i]); } } else { currActive.value = state.activeIndex; for (var i = 0; i < ownCopy.length; i++) { document.removeEventListener("keydown", ownCopy[i]); } } } onBeforeUnmount(() => { // Cleanup for (var i = 0; i < ownCopy.length; i++) { document.removeEventListener("keydown", ownCopy[i]); } }); watch(() => props.active, handle); handle(); } export const vAutofocus = { mounted(el, binding, vnode, prevVnode) { if (binding.value == undefined || binding.value) { state.activeIndex = getId(el); } } } export function getId(el) { for (var key in state.elements) { if (state.elements[key] == el){ return key; } } } const add = (el) => { const focus = () => { if (state.activeElement !== el) { state.activeIndex = val; state.activeElement = el; } } const blur = (e) => { if (e.relatedTarget === null) { state.activeElement = undefined; state.activeIndex = undefined; } } let val; if (el.dataset["tabindex"]) { val = el.dataset["tabindex"]; } else { val = Object.keys(state.elements).length+1; } el.tabIndex = val; state.elements[val] = el; el.addEventListener("focus", focus); el.addEventListener("blur", blur); el.blurcb = blur; el.focuscb = focus; }; const remove = (el) => { delete el.removeAttribute("tabindex"); delete state.elements[getId(el)] // el.removeEventListener("blur", el.blurfn); // el.removeEventListener("focus", el.focusfn); } export const vIndex = { updated(el, binding, vnode, prevVnode) { if (binding.oldValue != binding.value){ if (binding.oldValue) { remove(el); } else { add(el); } } }, mounted(el, binding, vnode, prevVnode) { add(el); }, beforeUnmount(el, binding, vnode, prevVnode) { remove(el); } }