57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
export const CANVAS_AGENT_VIEW_INTERACTION_DEFER_MS = 700;
|
|
|
|
const CANVAS_AGENT_VIEW_OPERATION_TARGET_SELECTOR = [
|
|
'[data-canvas-workspace-root="true"]',
|
|
"[data-canvas-node-id]",
|
|
"[data-canvas-overlay]",
|
|
].join(", ");
|
|
|
|
const EDITABLE_SELECTOR = [
|
|
"input",
|
|
"textarea",
|
|
"select",
|
|
'[contenteditable="true"]',
|
|
'[role="textbox"]',
|
|
].join(", ");
|
|
|
|
export function isCanvasAgentViewOperationTarget(target: EventTarget | null) {
|
|
return target instanceof Element
|
|
? Boolean(target.closest(CANVAS_AGENT_VIEW_OPERATION_TARGET_SELECTOR))
|
|
: false;
|
|
}
|
|
|
|
export function isCanvasAgentViewEditableElement(params: {
|
|
activeElement?: Element | null;
|
|
rootElement?: Element | null;
|
|
}) {
|
|
const activeElement = params.activeElement;
|
|
if (!(activeElement instanceof HTMLElement)) return false;
|
|
if (params.rootElement && !params.rootElement.contains(activeElement)) {
|
|
return false;
|
|
}
|
|
return activeElement.isContentEditable || Boolean(activeElement.closest(EDITABLE_SELECTOR));
|
|
}
|
|
|
|
export function shouldDeferCanvasAgentViewOperation(params: {
|
|
activeEditable?: boolean;
|
|
deferMs?: number;
|
|
lastPointerInteractionAt?: number | null;
|
|
now?: number;
|
|
pointerDown?: boolean;
|
|
}) {
|
|
if (params.pointerDown) return true;
|
|
if (params.activeEditable) return true;
|
|
|
|
const lastPointerInteractionAt = Number(params.lastPointerInteractionAt || 0);
|
|
if (lastPointerInteractionAt <= 0) return false;
|
|
|
|
const now = Number.isFinite(Number(params.now)) ? Number(params.now) : Date.now();
|
|
const deferMs = Math.max(
|
|
0,
|
|
Number.isFinite(Number(params.deferMs))
|
|
? Number(params.deferMs)
|
|
: CANVAS_AGENT_VIEW_INTERACTION_DEFER_MS
|
|
);
|
|
return now - lastPointerInteractionAt < deferMs;
|
|
}
|