Skip to content

Commit 35db077

Browse files
fix: Move mouseover event delegation
- From document to canvas-container - Also, remove unused event handler
1 parent 11a9bb5 commit 35db077

3 files changed

Lines changed: 62 additions & 55 deletions

File tree

frontend/src/utils/helpers.ts

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import AlertDialog from "@/components/AlertDialog.vue";
2+
import useStore from "@/store";
23
import { confirmDialog, FileUploadHandler } from "frappe-ui";
34
import { h, reactive, toRaw } from "vue";
45
import { toast } from "vue-sonner";
@@ -445,28 +446,48 @@ function generateId() {
445446
}
446447

447448
function throttle<T extends (...args: any[]) => void>(func: T, wait: number = 1000) {
448-
let timeout: ReturnType<typeof setTimeout> | null = null
449-
let lastArgs: Parameters<T> | null = null
450-
let pending = false
449+
let timeout: ReturnType<typeof setTimeout> | null = null;
450+
let lastArgs: Parameters<T> | null = null;
451+
let pending = false;
451452

452453
const invoke = (...args: Parameters<T>) => {
453-
lastArgs = args
454+
lastArgs = args;
454455
if (timeout) {
455-
pending = true
456-
return
456+
pending = true;
457+
return;
457458
}
458459

459460
func(...lastArgs);
460461
timeout = setTimeout(() => {
461-
timeout = null
462+
timeout = null;
462463
if (pending && lastArgs) {
463-
pending = false
464-
invoke(...lastArgs)
464+
pending = false;
465+
invoke(...lastArgs);
465466
}
466-
}, wait)
467+
}, wait);
467468
};
468469

469-
return invoke
470+
return invoke;
471+
}
472+
473+
function isBlock(e: MouseEvent) {
474+
return e.target instanceof HTMLElement && e.target.closest(".__builder_component__");
475+
}
476+
477+
type BlockInfo = {
478+
blockId: string;
479+
breakpoint: string;
480+
};
481+
482+
function getBlockInfo(e: MouseEvent) {
483+
const target = (e.target as HTMLElement)?.closest(".__builder_component__") as HTMLElement;
484+
return target.dataset as BlockInfo;
485+
}
486+
487+
function getBlock(e: MouseEvent) {
488+
const store = useStore();
489+
const blockInfo = getBlockInfo(e);
490+
return store.activeCanvas?.findBlock(blockInfo.blockId);
470491
}
471492

472493
export {
@@ -478,7 +499,9 @@ export {
478499
detachBlockFromComponent,
479500
findNearestSiblingIndex,
480501
generateId,
502+
getBlock,
481503
getBlockCopy,
504+
getBlockInfo,
482505
getBlockInstance,
483506
getBlockObjectCopy as getBlockObject,
484507
getBlockString,
@@ -492,6 +515,7 @@ export {
492515
getTextContent,
493516
HexToHSV,
494517
HSVToHex,
518+
isBlock,
495519
isCtrlOrCmd,
496520
isHTMLString,
497521
isJSONString,
@@ -502,6 +526,6 @@ export {
502526
replaceMapKey,
503527
RGBToHex,
504528
stripExtension,
505-
uploadImage,
506529
throttle,
530+
uploadImage,
507531
};

frontend/src/utils/useBlockEventHandlers.ts

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import useStore from "@/store";
22
import getBlockTemplate from "@/utils/blockTemplate";
3+
import { getBlock, getBlockInfo, isBlock } from "@/utils/helpers";
34
import { useEventListener } from "@vueuse/core";
45
import { nextTick } from "vue";
56

@@ -8,8 +9,6 @@ const store = useStore();
89
export function useBlockEventHandlers() {
910
useEventListener(document, "click", handleClick);
1011
useEventListener(document, "dblclick", handleDoubleClick);
11-
useEventListener(document, "mouseover", handleMouseOver);
12-
useEventListener(document, "mouseleave", handleMouseLeave);
1312
useEventListener(document, "contextmenu", triggerContextMenu);
1413

1514
function handleClick(e: MouseEvent) {
@@ -57,26 +56,6 @@ export function useBlockEventHandlers() {
5756
}
5857
}
5958

60-
function handleMouseOver(e: MouseEvent) {
61-
if (!isBlock(e)) return;
62-
if (store.mode === "move" || store.activeCanvas?.resizingBlock) return;
63-
const block = getBlock(e);
64-
const { breakpoint } = getBlockInfo(e);
65-
store.hoveredBlock = block?.blockId || null;
66-
store.hoveredBreakpoint = breakpoint;
67-
e.stopPropagation();
68-
}
69-
70-
function handleMouseLeave(e: MouseEvent) {
71-
if (!isBlock(e)) return;
72-
if (store.mode === "move") return;
73-
const block = getBlock(e);
74-
if (store.hoveredBlock === block?.blockId) {
75-
store.hoveredBlock = null;
76-
e.stopPropagation();
77-
}
78-
}
79-
8059
function triggerContextMenu(e: MouseEvent) {
8160
if (!isBlock(e) || isEditable(e)) return;
8261
const block = getBlock(e);
@@ -93,21 +72,12 @@ export function useBlockEventHandlers() {
9372
}
9473
}
9574

96-
function getBlock(e: MouseEvent) {
97-
const blockInfo = getBlockInfo(e);
98-
return store.activeCanvas?.findBlock(blockInfo.blockId);
99-
}
100-
10175
const isEditable = (e: MouseEvent) => {
10276
const { blockId, breakpoint } = getBlockInfo(e);
10377
// to ensure it is right block and not on different breakpoint
10478
return store.editableBlock?.blockId === blockId && store.activeBreakpoint === breakpoint;
10579
};
10680

107-
function isBlock(e: MouseEvent) {
108-
return e.target instanceof HTMLElement && e.target.closest(".__builder_component__");
109-
}
110-
11181
const selectBlock = (e: MouseEvent) => {
11282
if (isEditable(e) || store.mode !== "select") {
11383
return;
@@ -121,13 +91,3 @@ const selectBlock = (e: MouseEvent) => {
12191
store.leftPanelActiveTab = "Layers";
12292
store.rightPanelActiveTab = "Properties";
12393
};
124-
125-
type BlockInfo = {
126-
blockId: string;
127-
breakpoint: string;
128-
};
129-
130-
const getBlockInfo = (e: MouseEvent) => {
131-
const target = (e.target as HTMLElement)?.closest(".__builder_component__") as HTMLElement;
132-
return target.dataset as BlockInfo;
133-
};

frontend/src/utils/useCanvasEvents.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,19 @@ import useStore from "@/store";
22
import { CanvasHistory } from "@/types/Builder/BuilderCanvas";
33
import Block from "@/utils/block";
44
import getBlockTemplate from "@/utils/blockTemplate";
5-
import { addPxToNumber, getNumberFromPx, isTargetEditable } from "@/utils/helpers";
5+
import {
6+
addPxToNumber,
7+
getBlock,
8+
getBlockInfo,
9+
getNumberFromPx,
10+
isBlock,
11+
isTargetEditable,
12+
} from "@/utils/helpers";
613
import { clamp, useEventListener } from "@vueuse/core";
714
import { Ref } from "vue";
815

16+
const store = useStore();
17+
918
export function useCanvasEvents(
1019
container: Ref<HTMLElement>,
1120
canvasProps: CanvasProps,
@@ -15,7 +24,6 @@ export function useCanvasEvents(
1524
findBlock: (blockId: string) => Block | null,
1625
) {
1726
let counter = 0;
18-
const store = useStore();
1927
useEventListener(container, "mousedown", (ev: MouseEvent) => {
2028
if (store.mode === "move") {
2129
return;
@@ -207,4 +215,19 @@ export function useCanvasEvents(
207215
break;
208216
}
209217
});
218+
219+
useEventListener(container, "mouseover", handleMouseOver);
220+
}
221+
222+
function handleMouseOver(e: MouseEvent) {
223+
if (!isBlock(e)) {
224+
store.hoveredBlock = null;
225+
return;
226+
}
227+
if (store.mode === "move" || store.activeCanvas?.resizingBlock) return;
228+
const block = getBlock(e);
229+
const { breakpoint } = getBlockInfo(e);
230+
store.hoveredBlock = block?.blockId || null;
231+
store.hoveredBreakpoint = breakpoint;
232+
e.stopPropagation();
210233
}

0 commit comments

Comments
 (0)