diff --git a/resources/js/wysiwyg/index.ts b/resources/js/wysiwyg/index.ts index 1e5e4b3ce..9015cea0c 100644 --- a/resources/js/wysiwyg/index.ts +++ b/resources/js/wysiwyg/index.ts @@ -13,7 +13,7 @@ import {registerTaskListHandler} from "./ui/framework/helpers/task-list-handler" import {registerTableSelectionHandler} from "./ui/framework/helpers/table-selection-handler"; import {el} from "./utils/dom"; import {registerShortcuts} from "./services/shortcuts"; -import {registerNodeResizer} from "./ui/framework/helpers/image-resizer"; +import {registerNodeResizer} from "./ui/framework/helpers/node-resizer"; export function createPageEditorInstance(container: HTMLElement, htmlContent: string, options: Record = {}): SimpleWysiwygEditorInterface { const config: CreateEditorArgs = { diff --git a/resources/js/wysiwyg/nodes/media.ts b/resources/js/wysiwyg/nodes/media.ts index 5b3c1b9c2..fb940f893 100644 --- a/resources/js/wysiwyg/nodes/media.ts +++ b/resources/js/wysiwyg/nodes/media.ts @@ -4,18 +4,17 @@ import { ElementNode, LexicalEditor, LexicalNode, - SerializedElementNode, Spread + Spread } from 'lexical'; import type {EditorConfig} from "lexical/LexicalEditor"; -import {el, sizeToPixels} from "../utils/dom"; +import {el, setOrRemoveAttribute, sizeToPixels} from "../utils/dom"; import { CommonBlockAlignment, SerializedCommonBlockNode, setCommonBlockPropsFromElement, updateElementWithCommonBlockProps } from "./_common"; -import {elem} from "../../services/dom"; import {$selectSingleNode} from "../utils/selection"; export type MediaNodeTag = 'iframe' | 'embed' | 'object' | 'video' | 'audio'; @@ -218,8 +217,37 @@ export class MediaNode extends ElementNode { return wrap; } - updateDOM(prevNode: unknown, dom: HTMLElement) { - return true; + updateDOM(prevNode: MediaNode, dom: HTMLElement): boolean { + if (prevNode.__tag !== this.__tag) { + return true; + } + + if (JSON.stringify(prevNode.__sources) !== JSON.stringify(this.__sources)) { + return true; + } + + if (JSON.stringify(prevNode.__attributes) !== JSON.stringify(this.__attributes)) { + return true; + } + + const mediaEl = dom.firstElementChild as HTMLElement; + + if (prevNode.__id !== this.__id) { + setOrRemoveAttribute(mediaEl, 'id', this.__id); + } + + if (prevNode.__alignment !== this.__alignment) { + if (prevNode.__alignment) { + dom.classList.remove(`align-${prevNode.__alignment}`); + mediaEl.classList.remove(`align-${prevNode.__alignment}`); + } + if (this.__alignment) { + dom.classList.add(`align-${this.__alignment}`); + mediaEl.classList.add(`align-${this.__alignment}`); + } + } + + return false; } static importDOM(): DOMConversionMap|null { diff --git a/resources/js/wysiwyg/services/drop-paste-handling.ts b/resources/js/wysiwyg/services/drop-paste-handling.ts index 85d0235d8..07e35d443 100644 --- a/resources/js/wysiwyg/services/drop-paste-handling.ts +++ b/resources/js/wysiwyg/services/drop-paste-handling.ts @@ -103,6 +103,7 @@ function createDropListener(context: EditorUiContext): (event: DragEvent) => boo if (templateId) { insertTemplateToEditor(editor, templateId, event); event.preventDefault(); + event.stopPropagation(); return true; } @@ -114,6 +115,7 @@ function createDropListener(context: EditorUiContext): (event: DragEvent) => boo $insertNodesAtEvent(newNodes, event, editor); }); event.preventDefault(); + event.stopPropagation(); return true; } @@ -121,6 +123,7 @@ function createDropListener(context: EditorUiContext): (event: DragEvent) => boo const handled = handleMediaInsert(event.dataTransfer, context); if (handled) { event.preventDefault(); + event.stopPropagation(); return true; } } @@ -150,9 +153,11 @@ export function registerDropPasteHandling(context: EditorUiContext): () => void const unregisterDrop = context.editor.registerCommand(DROP_COMMAND, dropListener, COMMAND_PRIORITY_HIGH); const unregisterPaste = context.editor.registerCommand(PASTE_COMMAND, pasteListener, COMMAND_PRIORITY_HIGH); + context.scrollDOM.addEventListener('drop', dropListener); return () => { unregisterDrop(); unregisterPaste(); + context.scrollDOM.removeEventListener('drop', dropListener); }; } \ No newline at end of file diff --git a/resources/js/wysiwyg/todo.md b/resources/js/wysiwyg/todo.md index 15a59c734..9c196d6d3 100644 --- a/resources/js/wysiwyg/todo.md +++ b/resources/js/wysiwyg/todo.md @@ -16,4 +16,4 @@ ## Bugs -- Template drag/drop not handled when outside core editor area (ignored in margin area). \ No newline at end of file +// \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/framework/helpers/image-resizer.ts b/resources/js/wysiwyg/ui/framework/helpers/node-resizer.ts similarity index 92% rename from resources/js/wysiwyg/ui/framework/helpers/image-resizer.ts rename to resources/js/wysiwyg/ui/framework/helpers/node-resizer.ts index c8105eafc..2e4f2939c 100644 --- a/resources/js/wysiwyg/ui/framework/helpers/image-resizer.ts +++ b/resources/js/wysiwyg/ui/framework/helpers/node-resizer.ts @@ -73,11 +73,15 @@ class NodeResizer { return; } - const nodeDOMBounds = nodeDOM.getBoundingClientRect(); - this.dom.style.left = nodeDOM.offsetLeft + 'px'; - this.dom.style.top = nodeDOM.offsetTop + 'px'; - this.dom.style.width = nodeDOMBounds.width + 'px'; - this.dom.style.height = nodeDOMBounds.height + 'px'; + const scrollAreaRect = this.scrollContainer.getBoundingClientRect(); + const nodeRect = nodeDOM.getBoundingClientRect(); + const top = nodeRect.top - (scrollAreaRect.top - this.scrollContainer.scrollTop); + const left = nodeRect.left - scrollAreaRect.left; + + this.dom.style.top = `${top}px`; + this.dom.style.left = `${left}px`; + this.dom.style.width = nodeRect.width + 'px'; + this.dom.style.height = nodeRect.height + 'px'; } protected updateDOMSize(width: number, height: number): void { diff --git a/resources/js/wysiwyg/utils/dom.ts b/resources/js/wysiwyg/utils/dom.ts index d5c63a816..bbb07cb41 100644 --- a/resources/js/wysiwyg/utils/dom.ts +++ b/resources/js/wysiwyg/utils/dom.ts @@ -70,4 +70,12 @@ export function extractStyleMapFromElement(element: HTMLElement): StyleMap { } return map; +} + +export function setOrRemoveAttribute(element: HTMLElement, name: string, value: string|null|undefined) { + if (value) { + element.setAttribute(name, value); + } else { + element.removeAttribute(name); + } } \ No newline at end of file diff --git a/resources/sass/_editor.scss b/resources/sass/_editor.scss index 31ce564be..04f18702e 100644 --- a/resources/sass/_editor.scss +++ b/resources/sass/_editor.scss @@ -374,10 +374,21 @@ body.editor-is-fullscreen { } .editor-media-wrap { + display: inline-block; cursor: not-allowed; iframe { pointer-events: none; } + &.align-left { + float: left; + } + &.align-right { + float: right; + } + &.align-center { + display: block; + margin-inline: auto; + } } /**