X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/0f8bd869d8bb0ef3f7318dfe03aa122b87cc9b0d..refs/pull/5313/head:/resources/js/wysiwyg/nodes/callout.ts diff --git a/resources/js/wysiwyg/nodes/callout.ts b/resources/js/wysiwyg/nodes/callout.ts index 89b9b162e..cfe32ec85 100644 --- a/resources/js/wysiwyg/nodes/callout.ts +++ b/resources/js/wysiwyg/nodes/callout.ts @@ -5,27 +5,39 @@ import { ElementNode, LexicalEditor, LexicalNode, - ParagraphNode, SerializedElementNode, Spread + ParagraphNode, Spread } from 'lexical'; import type {EditorConfig} from "lexical/LexicalEditor"; import type {RangeSelection} from "lexical/LexicalSelection"; +import { + CommonBlockAlignment, commonPropertiesDifferent, deserializeCommonBlockNode, + SerializedCommonBlockNode, + setCommonBlockPropsFromElement, + updateElementWithCommonBlockProps +} from "./_common"; export type CalloutCategory = 'info' | 'danger' | 'warning' | 'success'; export type SerializedCalloutNode = Spread<{ category: CalloutCategory; -}, SerializedElementNode> +}, SerializedCommonBlockNode> export class CalloutNode extends ElementNode { - + __id: string = ''; __category: CalloutCategory = 'info'; + __alignment: CommonBlockAlignment = ''; + __inset: number = 0; static getType() { return 'callout'; } static clone(node: CalloutNode) { - return new CalloutNode(node.__category, node.__key); + const newNode = new CalloutNode(node.__category, node.__key); + newNode.__id = node.__id; + newNode.__alignment = node.__alignment; + newNode.__inset = node.__inset; + return newNode; } constructor(category: CalloutCategory, key?: string) { @@ -33,16 +45,56 @@ export class CalloutNode extends ElementNode { this.__category = category; } + setCategory(category: CalloutCategory) { + const self = this.getWritable(); + self.__category = category; + } + + getCategory(): CalloutCategory { + const self = this.getLatest(); + return self.__category; + } + + setId(id: string) { + const self = this.getWritable(); + self.__id = id; + } + + getId(): string { + const self = this.getLatest(); + return self.__id; + } + + setAlignment(alignment: CommonBlockAlignment) { + const self = this.getWritable(); + self.__alignment = alignment; + } + + getAlignment(): CommonBlockAlignment { + const self = this.getLatest(); + return self.__alignment; + } + + setInset(size: number) { + const self = this.getWritable(); + self.__inset = size; + } + + getInset(): number { + const self = this.getLatest(); + return self.__inset; + } + createDOM(_config: EditorConfig, _editor: LexicalEditor) { const element = document.createElement('p'); element.classList.add('callout', this.__category || ''); + updateElementWithCommonBlockProps(element, this); return element; } - updateDOM(prevNode: unknown, dom: HTMLElement) { - // Returning false tells Lexical that this node does not need its - // DOM element replacing with a new copy from createDOM. - return false; + updateDOM(prevNode: CalloutNode): boolean { + return prevNode.__category !== this.__category || + commonPropertiesDifferent(prevNode, this); } insertNewAfter(selection: RangeSelection, restoreSelection?: boolean): CalloutNode|ParagraphNode { @@ -78,8 +130,11 @@ export class CalloutNode extends ElementNode { } } + const node = new CalloutNode(category); + setCommonBlockPropsFromElement(element, node); + return { - node: new CalloutNode(category), + node, }; }, priority: 3, @@ -96,11 +151,16 @@ export class CalloutNode extends ElementNode { type: 'callout', version: 1, category: this.__category, + id: this.__id, + alignment: this.__alignment, + inset: this.__inset, }; } static importJSON(serializedNode: SerializedCalloutNode): CalloutNode { - return $createCalloutNode(serializedNode.category); + const node = $createCalloutNode(serializedNode.category); + deserializeCommonBlockNode(serializedNode, node); + return node; } } @@ -109,6 +169,10 @@ export function $createCalloutNode(category: CalloutCategory = 'info') { return new CalloutNode(category); } -export function $isCalloutNode(node: LexicalNode | null | undefined) { +export function $isCalloutNode(node: LexicalNode | null | undefined): node is CalloutNode { return node instanceof CalloutNode; } + +export function $isCalloutNodeOfCategory(node: LexicalNode | null | undefined, category: CalloutCategory = 'info') { + return node instanceof CalloutNode && (node as CalloutNode).getCategory() === category; +}