X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/ec965f28c09bf18cab2b615716d902d31ff49cfd..a56a28fbb7eaff40a639c2d06f56de255cd654ea:/resources/js/wysiwyg/nodes/custom-list.ts diff --git a/resources/js/wysiwyg/nodes/custom-list.ts b/resources/js/wysiwyg/nodes/custom-list.ts index 953bcb8cd..4b05fa62e 100644 --- a/resources/js/wysiwyg/nodes/custom-list.ts +++ b/resources/js/wysiwyg/nodes/custom-list.ts @@ -1,11 +1,12 @@ import { DOMConversionFn, - DOMConversionMap, + DOMConversionMap, EditorConfig, LexicalNode, Spread } from "lexical"; -import {EditorConfig} from "lexical/LexicalEditor"; -import {ListNode, ListType, SerializedListNode} from "@lexical/list"; +import {$isListItemNode, ListItemNode, ListNode, ListType, SerializedListNode} from "@lexical/list"; +import {$createCustomListItemNode} from "./custom-list-item"; +import {extractDirectionFromElement} from "./_common"; export type SerializedCustomListNode = Spread<{ @@ -30,8 +31,9 @@ export class CustomListNode extends ListNode { } static clone(node: CustomListNode) { - const newNode = new CustomListNode(node.__listType, 0, node.__key); + const newNode = new CustomListNode(node.__listType, node.__start, node.__key); newNode.__id = node.__id; + newNode.__dir = node.__dir; return newNode; } @@ -41,9 +43,18 @@ export class CustomListNode extends ListNode { dom.setAttribute('id', this.__id); } + if (this.__dir) { + dom.setAttribute('dir', this.__dir); + } + return dom; } + updateDOM(prevNode: ListNode, dom: HTMLElement, config: EditorConfig): boolean { + return super.updateDOM(prevNode, dom, config) || + prevNode.__dir !== this.__dir; + } + exportJSON(): SerializedCustomListNode { return { ...super.exportJSON(), @@ -56,6 +67,7 @@ export class CustomListNode extends ListNode { static importJSON(serializedNode: SerializedCustomListNode): CustomListNode { const node = $createCustomListNode(serializedNode.listType); node.setId(serializedNode.id); + node.setDirection(serializedNode.direction); return node; } @@ -67,6 +79,15 @@ export class CustomListNode extends ListNode { if (element.id && baseResult?.node) { (baseResult.node as CustomListNode).setId(element.id); } + + if (element.dir && baseResult?.node) { + (baseResult.node as CustomListNode).setDirection(extractDirectionFromElement(element)); + } + + if (baseResult) { + baseResult.after = $normalizeChildren; + } + return baseResult; }; @@ -83,8 +104,34 @@ export class CustomListNode extends ListNode { } } +/* + * This function is a custom normalization function to allow nested lists within list item elements. + * Original taken from https://github.com/facebook/lexical/blob/6e10210fd1e113ccfafdc999b1d896733c5c5bea/packages/lexical-list/src/LexicalListNode.ts#L284-L303 + * With modifications made. + * Copyright (c) Meta Platforms, Inc. and affiliates. + * MIT license + */ +function $normalizeChildren(nodes: Array): Array { + const normalizedListItems: Array = []; + + for (const node of nodes) { + if ($isListItemNode(node)) { + normalizedListItems.push(node); + } else { + normalizedListItems.push($wrapInListItem(node)); + } + } + + return normalizedListItems; +} + +function $wrapInListItem(node: LexicalNode): ListItemNode { + const listItemWrapper = $createCustomListItemNode(); + return listItemWrapper.append(node); +} + export function $createCustomListNode(type: ListType): CustomListNode { - return new CustomListNode(type, 0); + return new CustomListNode(type, 1); } export function $isCustomListNode(node: LexicalNode | null | undefined): node is CustomListNode {