You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ygdc/assets/js/handlers.js

156 lines
4.1 KiB

2 months ago
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);
}
}