mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Lexical: Further fixes
- Improved node resizer positioning to be more accurate - Fixed drop handling not running within editor margin space - Made media dom update smarter to reduce reloads - Fixed media alignment, broken due to added wrapper
This commit is contained in:
parent
16518a4f89
commit
fd07aa0f05
@ -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<string, any> = {}): SimpleWysiwygEditorInterface {
|
||||
const config: CreateEditorArgs = {
|
||||
|
@ -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,10 +217,39 @@ export class MediaNode extends ElementNode {
|
||||
return wrap;
|
||||
}
|
||||
|
||||
updateDOM(prevNode: unknown, dom: HTMLElement) {
|
||||
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 {
|
||||
|
||||
const buildConverter = (tag: MediaNodeTag) => {
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
@ -16,4 +16,4 @@
|
||||
|
||||
## Bugs
|
||||
|
||||
- Template drag/drop not handled when outside core editor area (ignored in margin area).
|
||||
//
|
@ -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 {
|
@ -71,3 +71,11 @@ 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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user