Skip to content

Commit 717b516

Browse files
committed
Lexical: Made table resize handles more efficent & less buggy
Fine mouse movement and handles will now only be active when actually within a table, otherwise less frequent mouseovers are used to track if in/out a table. Hides handles when out of a table, preventing a range of issues with stray handles floating about.
1 parent fda242d commit 717b516

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class TableResizer {
1515
protected targetCell: HTMLElement|null = null;
1616
protected xMarkerAtStart : boolean = false;
1717
protected yMarkerAtStart : boolean = false;
18+
protected activeInTable: boolean = false;
1819

1920
constructor(editor: LexicalEditor, editScrollContainer: HTMLElement) {
2021
this.editor = editor;
@@ -33,9 +34,10 @@ class TableResizer {
3334
}
3435

3536
protected setupListeners() {
37+
this.onTableMouseOver = this.onTableMouseOver.bind(this);
3638
this.onCellMouseMove = this.onCellMouseMove.bind(this);
3739
this.onScrollOrResize = this.onScrollOrResize.bind(this);
38-
this.editScrollContainer.addEventListener('mousemove', this.onCellMouseMove);
40+
this.editScrollContainer.addEventListener('mouseover', this.onTableMouseOver, { passive: true });
3941
window.addEventListener('scroll', this.onScrollOrResize, {capture: true, passive: true});
4042
window.addEventListener('resize', this.onScrollOrResize, {passive: true});
4143
}
@@ -44,8 +46,26 @@ class TableResizer {
4446
this.updateCurrentMarkerTargetPosition();
4547
}
4648

49+
protected onTableMouseOver(event: MouseEvent): void {
50+
if (this.dragging) {
51+
return;
52+
}
53+
54+
const table = (event.target as HTMLElement).closest('table') as HTMLElement|null;
55+
56+
if (table && !this.activeInTable) {
57+
this.editScrollContainer.addEventListener('mousemove', this.onCellMouseMove, { passive: true });
58+
this.onCellMouseMove(event);
59+
this.activeInTable = true;
60+
} else if (!table && this.activeInTable) {
61+
this.editScrollContainer.removeEventListener('mousemove', this.onCellMouseMove);
62+
this.hideMarkers();
63+
this.activeInTable = false;
64+
}
65+
}
66+
4767
protected onCellMouseMove(event: MouseEvent) {
48-
const cell = (event.target as HTMLElement).closest('td,th') as HTMLElement;
68+
const cell = (event.target as HTMLElement).closest('td,th') as HTMLElement|null;
4969
if (!cell || this.dragging) {
5070
return;
5171
}
@@ -66,10 +86,16 @@ class TableResizer {
6686
protected updateMarkersTo(cell: HTMLElement, xPos: number, yPos: number) {
6787
const markers: MarkerDomRecord = this.getMarkers();
6888
const table = cell.closest('table') as HTMLElement;
89+
const caption: HTMLTableCaptionElement|null = table.querySelector('caption');
6990
const tableRect = table.getBoundingClientRect();
7091
const editBounds = this.editScrollContainer.getBoundingClientRect();
7192

72-
const maxTop = Math.max(tableRect.top, editBounds.top);
93+
let tableTop = tableRect.top;
94+
if (caption) {
95+
tableTop = caption.getBoundingClientRect().bottom;
96+
}
97+
98+
const maxTop = Math.max(tableTop, editBounds.top);
7399
const maxBottom = Math.min(tableRect.bottom, editBounds.bottom);
74100
const maxHeight = maxBottom - maxTop;
75101
markers.x.style.left = xPos + 'px';
@@ -85,6 +111,13 @@ class TableResizer {
85111
markers.x.hidden = tableRect.top > editBounds.bottom || tableRect.bottom < editBounds.top;
86112
}
87113

114+
protected hideMarkers(): void {
115+
if (this.markerDom) {
116+
this.markerDom.x.hidden = true;
117+
this.markerDom.y.hidden = true;
118+
}
119+
}
120+
88121
protected updateCurrentMarkerTargetPosition(): void {
89122
if (!this.targetCell) {
90123
return;

0 commit comments

Comments
 (0)