diff --git a/resources/js/wysiwyg/index.ts b/resources/js/wysiwyg/index.ts index 5f131df57..469738e7f 100644 --- a/resources/js/wysiwyg/index.ts +++ b/resources/js/wysiwyg/index.ts @@ -44,7 +44,7 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st mergeRegister( registerRichText(editor), registerHistory(editor, createEmptyHistoryState(), 300), - registerTableResizer(editor, editArea), + registerTableResizer(editor, editWrap), ); setEditorContentFromHtml(editor, htmlContent); diff --git a/resources/js/wysiwyg/todo.md b/resources/js/wysiwyg/todo.md index 7b9588194..e39a4c655 100644 --- a/resources/js/wysiwyg/todo.md +++ b/resources/js/wysiwyg/todo.md @@ -36,5 +36,5 @@ ## Bugs - Image resizing currently bugged, maybe change to ghost resizer in decorator instead of updating core node. -- Table resize bars often floating around in wrong place, and shows on hover or interrupts mouse actions. -- Removing link around image via button deletes image, not just link \ No newline at end of file +- Removing link around image via button deletes image, not just link +- `SELECTION_CHANGE_COMMAND` not fired when clicking out of a table cell. Prevents toolbar hiding on table unselect. \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts b/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts index 8f1e978e9..2d995883a 100644 --- a/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts +++ b/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts @@ -8,7 +8,7 @@ type MarkerDomRecord = {x: HTMLElement, y: HTMLElement}; class TableResizer { protected editor: LexicalEditor; - protected editArea: HTMLElement; + protected editScrollContainer: HTMLElement; protected markerDom: MarkerDomRecord|null = null; protected mouseTracker: MouseDragTracker|null = null; protected dragging: boolean = false; @@ -16,15 +16,17 @@ class TableResizer { protected xMarkerAtStart : boolean = false; protected yMarkerAtStart : boolean = false; - constructor(editor: LexicalEditor, editArea: HTMLElement) { + constructor(editor: LexicalEditor, editScrollContainer: HTMLElement) { this.editor = editor; - this.editArea = editArea; + this.editScrollContainer = editScrollContainer; this.setupListeners(); } teardown() { - this.editArea.removeEventListener('mousemove', this.onCellMouseMove); + this.editScrollContainer.removeEventListener('mousemove', this.onCellMouseMove); + window.removeEventListener('scroll', this.onScrollOrResize, {capture: true}); + window.removeEventListener('resize', this.onScrollOrResize); if (this.mouseTracker) { this.mouseTracker.teardown(); } @@ -32,7 +34,14 @@ class TableResizer { protected setupListeners() { this.onCellMouseMove = this.onCellMouseMove.bind(this); - this.editArea.addEventListener('mousemove', this.onCellMouseMove); + this.onScrollOrResize = this.onScrollOrResize.bind(this); + this.editScrollContainer.addEventListener('mousemove', this.onCellMouseMove); + window.addEventListener('scroll', this.onScrollOrResize, {capture: true, passive: true}); + window.addEventListener('resize', this.onScrollOrResize, {passive: true}); + } + + protected onScrollOrResize(): void { + this.updateCurrentMarkerTargetPosition(); } protected onCellMouseMove(event: MouseEvent) { @@ -58,14 +67,33 @@ class TableResizer { const markers: MarkerDomRecord = this.getMarkers(); const table = cell.closest('table') as HTMLElement; const tableRect = table.getBoundingClientRect(); + const editBounds = this.editScrollContainer.getBoundingClientRect(); + const maxTop = Math.max(tableRect.top, editBounds.top); + const maxBottom = Math.min(tableRect.bottom, editBounds.bottom); + const maxHeight = maxBottom - maxTop; markers.x.style.left = xPos + 'px'; - markers.x.style.height = tableRect.height + 'px'; - markers.x.style.top = tableRect.top + 'px'; + markers.x.style.top = maxTop + 'px'; + markers.x.style.height = maxHeight + 'px'; markers.y.style.top = yPos + 'px'; markers.y.style.left = tableRect.left + 'px'; markers.y.style.width = tableRect.width + 'px'; + + // Hide markers when out of bounds + markers.y.hidden = yPos < editBounds.top || yPos > editBounds.bottom; + markers.x.hidden = tableRect.top > editBounds.bottom || tableRect.bottom < editBounds.top; + } + + protected updateCurrentMarkerTargetPosition(): void { + if (!this.targetCell) { + return; + } + + const rect = this.targetCell.getBoundingClientRect(); + const xMarkerPos = this.xMarkerAtStart ? rect.left : rect.right; + const yMarkerPos = this.yMarkerAtStart ? rect.top : rect.bottom; + this.updateMarkersTo(this.targetCell, xMarkerPos, yMarkerPos); } protected getMarkers(): MarkerDomRecord { @@ -77,7 +105,7 @@ class TableResizer { const wrapper = el('div', { class: 'editor-table-marker-wrap', }, [this.markerDom.x, this.markerDom.y]); - this.editArea.after(wrapper); + this.editScrollContainer.after(wrapper); this.watchMarkerMouseDrags(wrapper); } @@ -180,8 +208,8 @@ class TableResizer { } -export function registerTableResizer(editor: LexicalEditor, editorArea: HTMLElement): (() => void) { - const resizer = new TableResizer(editor, editorArea); +export function registerTableResizer(editor: LexicalEditor, editScrollContainer: HTMLElement): (() => void) { + const resizer = new TableResizer(editor, editScrollContainer); return () => { resizer.teardown(); diff --git a/resources/js/wysiwyg/ui/framework/manager.ts b/resources/js/wysiwyg/ui/framework/manager.ts index 29d959910..c0357c3ea 100644 --- a/resources/js/wysiwyg/ui/framework/manager.ts +++ b/resources/js/wysiwyg/ui/framework/manager.ts @@ -175,6 +175,7 @@ export class EditorUIManager { protected setupEditor(editor: LexicalEditor) { // Update button states on editor selection change editor.registerCommand(SELECTION_CHANGE_COMMAND, () => { + console.log('select change', arguments); this.triggerStateUpdate({ editor: editor, selection: $getSelection(),