import {HeadingNode, QuoteNode} from '@lexical/rich-text';
import {CalloutNode} from './callout';
-import {ElementNode, KlassConstructor, LexicalNode, LexicalNodeReplacement, ParagraphNode} from "lexical";
+import {
+ ElementNode,
+ KlassConstructor,
+ LexicalNode,
+ LexicalNodeReplacement, NodeMutation,
+ ParagraphNode
+} from "lexical";
import {CustomParagraphNode} from "./custom-paragraph";
import {LinkNode} from "@lexical/link";
import {ImageNode} from "./image";
import {ListItemNode, ListNode} from "@lexical/list";
import {TableCellNode, TableNode, TableRowNode} from "@lexical/table";
import {CustomTableNode} from "./custom-table";
+import {HorizontalRuleNode} from "./horizontal-rule";
+import {CodeBlockNode} from "./code-block";
+import {DiagramNode} from "./diagram";
+import {EditorUiContext} from "../ui/framework/core";
+import {MediaNode} from "./media";
+import {CustomListItemNode} from "./custom-list-item";
+import {CustomTableCellNode} from "./custom-table-cell";
+import {CustomTableRowNode} from "./custom-table-row";
+import {CustomHeadingNode} from "./custom-heading";
+import {CustomQuoteNode} from "./custom-quote";
+import {CustomListNode} from "./custom-list";
/**
* Load the nodes for lexical.
*/
export function getNodesForPageEditor(): (KlassConstructor<typeof LexicalNode> | LexicalNodeReplacement)[] {
return [
- CalloutNode, // Todo - Create custom
- HeadingNode, // Todo - Create custom
- QuoteNode, // Todo - Create custom
- ListNode, // Todo - Create custom
- ListItemNode,
+ CalloutNode,
+ CustomHeadingNode,
+ CustomQuoteNode,
+ CustomListNode,
+ CustomListItemNode, // TODO - Alignment?
CustomTableNode,
- TableRowNode,
- TableCellNode,
- ImageNode,
+ CustomTableRowNode,
+ CustomTableCellNode,
+ ImageNode, // TODO - Alignment
+ HorizontalRuleNode,
DetailsNode, SummaryNode,
+ CodeBlockNode,
+ DiagramNode,
+ MediaNode, // TODO - Alignment
CustomParagraphNode,
LinkNode,
{
return new CustomParagraphNode();
}
},
+ {
+ replace: HeadingNode,
+ with: (node: HeadingNode) => {
+ return new CustomHeadingNode(node.__tag);
+ }
+ },
+ {
+ replace: QuoteNode,
+ with: (node: QuoteNode) => {
+ return new CustomQuoteNode();
+ }
+ },
+ {
+ replace: ListNode,
+ with: (node: ListNode) => {
+ return new CustomListNode(node.getListType(), node.getStart());
+ }
+ },
+ {
+ replace: ListItemNode,
+ with: (node: ListItemNode) => {
+ return new CustomListItemNode(node.__value, node.__checked);
+ }
+ },
{
replace: TableNode,
with(node: TableNode) {
return new CustomTableNode();
}
},
+ {
+ replace: TableRowNode,
+ with(node: TableRowNode) {
+ return new CustomTableRowNode();
+ }
+ },
+ {
+ replace: TableCellNode,
+ with: (node: TableCellNode) => {
+ const cell = new CustomTableCellNode(
+ node.__headerState,
+ node.__colSpan,
+ node.__width,
+ );
+ cell.__rowSpan = node.__rowSpan;
+ return cell;
+ }
+ },
];
}
+export function registerCommonNodeMutationListeners(context: EditorUiContext): void {
+ const decorated = [ImageNode, CodeBlockNode, DiagramNode];
+
+ const decorationDestroyListener = (mutations: Map<string, NodeMutation>): void => {
+ for (let [nodeKey, mutation] of mutations) {
+ if (mutation === "destroyed") {
+ const decorator = context.manager.getDecoratorByNodeKey(nodeKey);
+ if (decorator) {
+ decorator.destroy(context);
+ }
+ }
+ }
+ };
+
+ for (let decoratedNode of decorated) {
+ // Have to pass a unique function here since they are stored by lexical keyed on listener function.
+ context.editor.registerMutationListener(decoratedNode, (mutations) => decorationDestroyListener(mutations));
+ }
+}
+
export type LexicalNodeMatcher = (node: LexicalNode|null|undefined) => boolean;
export type LexicalElementNodeCreator = () => ElementNode;
\ No newline at end of file