1 import {$isElementNode, LexicalEditor, LexicalNode, SerializedLexicalNode} from "lexical";
3 type SerializedLexicalNodeWithChildren = {
4 node: SerializedLexicalNode,
5 children: SerializedLexicalNodeWithChildren[],
8 function serializeNodeRecursive(node: LexicalNode): SerializedLexicalNodeWithChildren {
9 const childNodes = $isElementNode(node) ? node.getChildren() : [];
11 node: node.exportJSON(),
12 children: childNodes.map(n => serializeNodeRecursive(n)),
16 function unserializeNodeRecursive(editor: LexicalEditor, {node, children}: SerializedLexicalNodeWithChildren): LexicalNode|null {
17 const instance = editor._nodes.get(node.type)?.klass.importJSON(node);
22 const childNodes = children.map(child => unserializeNodeRecursive(editor, child));
23 for (const child of childNodes) {
24 if (child && $isElementNode(instance)) {
25 instance.append(child);
32 export class NodeClipboard<T extends LexicalNode> {
33 nodeClass: {importJSON: (s: SerializedLexicalNode) => T};
34 protected store: SerializedLexicalNodeWithChildren[] = [];
36 constructor(nodeClass: {importJSON: (s: any) => T}) {
37 this.nodeClass = nodeClass;
40 set(...nodes: LexicalNode[]): void {
41 this.store.splice(0, this.store.length);
42 for (const node of nodes) {
43 this.store.push(serializeNodeRecursive(node));
47 get(editor: LexicalEditor): T[] {
48 return this.store.map(json => unserializeNodeRecursive(editor, json)).filter((node) => {
54 return this.store.length;