import {
- DecoratorNode,
DOMConversion,
DOMConversionMap,
- DOMConversionOutput,
+ DOMConversionOutput, ElementNode,
LexicalEditor, LexicalNode,
- SerializedLexicalNode,
Spread
} from "lexical";
import type {EditorConfig} from "lexical/LexicalEditor";
-import {el} from "../helpers";
-import {EditorDecoratorAdapter} from "../ui/framework/decorator";
+import {CommonBlockAlignment, extractAlignmentFromElement} from "./_common";
+import {$selectSingleNode} from "../utils/selection";
+import {SerializedElementNode} from "lexical/nodes/LexicalElementNode";
export interface ImageNodeOptions {
alt?: string;
alt: string;
width: number;
height: number;
-}, SerializedLexicalNode>
+ alignment: CommonBlockAlignment;
+}, SerializedElementNode>
-export class ImageNode extends DecoratorNode<EditorDecoratorAdapter> {
+export class ImageNode extends ElementNode {
__src: string = '';
__alt: string = '';
__width: number = 0;
__height: number = 0;
- // TODO - Alignment
+ __alignment: CommonBlockAlignment = '';
static getType(): string {
return 'image';
}
static clone(node: ImageNode): ImageNode {
- return new ImageNode(node.__src, {
+ const newNode = new ImageNode(node.__src, {
alt: node.__alt,
width: node.__width,
height: node.__height,
- });
+ }, node.__key);
+ newNode.__alignment = node.__alignment;
+ return newNode;
}
constructor(src: string, options: ImageNodeOptions, key?: string) {
}
}
+ setSrc(src: string): void {
+ const self = this.getWritable();
+ self.__src = src;
+ }
+
+ getSrc(): string {
+ const self = this.getLatest();
+ return self.__src;
+ }
+
setAltText(altText: string): void {
const self = this.getWritable();
self.__alt = altText;
return self.__width;
}
- isInline(): boolean {
- return true;
+ setAlignment(alignment: CommonBlockAlignment) {
+ const self = this.getWritable();
+ self.__alignment = alignment;
}
- decorate(editor: LexicalEditor, config: EditorConfig): EditorDecoratorAdapter {
- return {
- type: 'image',
- getNode: () => this,
- };
+ getAlignment(): CommonBlockAlignment {
+ const self = this.getLatest();
+ return self.__alignment;
+ }
+
+ isInline(): boolean {
+ return true;
}
createDOM(_config: EditorConfig, _editor: LexicalEditor) {
if (this.__alt) {
element.setAttribute('alt', this.__alt);
}
- return el('span', {class: 'editor-image-wrap'}, [
- element,
- ]);
+
+ if (this.__alignment) {
+ element.classList.add('align-' + this.__alignment);
+ }
+
+ element.addEventListener('click', e => {
+ _editor.update(() => {
+ $selectSingleNode(this);
+ });
+ });
+
+ return element;
}
updateDOM(prevNode: ImageNode, dom: HTMLElement) {
- const image = dom.querySelector('img');
- if (!image) return false;
-
if (prevNode.__src !== this.__src) {
- image.setAttribute('src', this.__src);
+ dom.setAttribute('src', this.__src);
}
if (prevNode.__width !== this.__width) {
if (this.__width) {
- image.setAttribute('width', String(this.__width));
+ dom.setAttribute('width', String(this.__width));
} else {
- image.removeAttribute('width');
+ dom.removeAttribute('width');
}
}
if (prevNode.__height !== this.__height) {
if (this.__height) {
- image.setAttribute('height', String(this.__height));
+ dom.setAttribute('height', String(this.__height));
} else {
- image.removeAttribute('height');
+ dom.removeAttribute('height');
}
}
if (prevNode.__alt !== this.__alt) {
if (this.__alt) {
- image.setAttribute('alt', String(this.__alt));
+ dom.setAttribute('alt', String(this.__alt));
} else {
- image.removeAttribute('alt');
+ dom.removeAttribute('alt');
+ }
+ }
+
+ if (prevNode.__alignment !== this.__alignment) {
+ if (prevNode.__alignment) {
+ dom.classList.remove('align-' + prevNode.__alignment);
+ }
+ if (this.__alignment) {
+ dom.classList.add('align-' + this.__alignment);
}
}
width: Number.parseInt(element.getAttribute('width') || '0'),
}
- return {
- node: new ImageNode(src, options),
- };
+ const node = new ImageNode(src, options);
+ node.setAlignment(extractAlignmentFromElement(element));
+
+ return { node };
},
priority: 3,
};
exportJSON(): SerializedImageNode {
return {
+ ...super.exportJSON(),
type: 'image',
version: 1,
src: this.__src,
alt: this.__alt,
height: this.__height,
- width: this.__width
+ width: this.__width,
+ alignment: this.__alignment,
};
}
static importJSON(serializedNode: SerializedImageNode): ImageNode {
- return $createImageNode(serializedNode.src, {
+ const node = $createImageNode(serializedNode.src, {
alt: serializedNode.alt,
width: serializedNode.width,
height: serializedNode.height,
});
+ node.setAlignment(serializedNode.alignment);
+ return node;
}
}