import { useEffect } from "react";
|
|
export const useRegionsCopyPaste = (entity: any) => {
|
useEffect(() => {
|
const isFocusable = (el: Node | Window | HTMLElement | null) => {
|
if (!el) return false;
|
if ((el as Node).nodeType !== Node.ELEMENT_NODE) return false;
|
|
const element = el as HTMLElement;
|
const tabIndex = Number.parseInt(element.getAttribute("tabindex") ?? "", 10);
|
const isFocusable = element.matches("a, button, input, textarea, select, details, [tabindex], [contenteditable]");
|
|
return isFocusable || tabIndex > -1;
|
};
|
|
const allowCopyPaste = () => {
|
const selection = window.getSelection();
|
const focusNode = selection?.focusNode;
|
const nodeIsFocusable = isFocusable(focusNode as HTMLElement);
|
const activeElementIsFocusable = isFocusable(document.activeElement);
|
const selectionIsCollapsed = selection?.isCollapsed ?? true;
|
|
return selectionIsCollapsed && !nodeIsFocusable && !activeElementIsFocusable;
|
};
|
|
const copyToClipboard = (ev: ClipboardEvent) => {
|
const { clipboardData } = ev;
|
const results = entity.serializedSelection;
|
|
clipboardData?.setData("application/json", JSON.stringify(results));
|
ev.preventDefault();
|
};
|
|
const pasteFromClipboard = (ev: ClipboardEvent) => {
|
const { clipboardData } = ev;
|
const data = clipboardData?.getData("application/json");
|
|
try {
|
const results = (data ? JSON.parse(data) : []).map((res: any) => {
|
return { ...res, readonly: false };
|
});
|
|
entity.appendResults(results);
|
ev.preventDefault();
|
} catch (e) {
|
console.error(e);
|
return;
|
}
|
};
|
|
const copyHandler = (ev: Event) => {
|
if (!allowCopyPaste()) return;
|
|
copyToClipboard(ev as ClipboardEvent);
|
};
|
|
const pasteHandler = (ev: Event) => {
|
if (!allowCopyPaste()) return;
|
|
pasteFromClipboard(ev as ClipboardEvent);
|
};
|
|
const cutHandler = (ev: Event) => {
|
if (!allowCopyPaste()) return;
|
|
copyToClipboard(ev as ClipboardEvent);
|
entity.deleteSelectedRegions();
|
};
|
|
window.addEventListener("copy", copyHandler);
|
window.addEventListener("paste", pasteHandler);
|
window.addEventListener("cut", cutHandler);
|
return () => {
|
window.removeEventListener("copy", copyHandler);
|
window.removeEventListener("paste", pasteHandler);
|
window.removeEventListener("cut", cutHandler);
|
};
|
}, [entity.pk ?? entity.id]);
|
};
|