]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/nodes.ts
Opensearch: Fixed XML declaration when php short tags enabled
[bookstack] / resources / js / wysiwyg / nodes.ts
1 import {CalloutNode} from '@lexical/rich-text/LexicalCalloutNode';
2 import {
3     ElementNode,
4     KlassConstructor,
5     LexicalNode,
6     LexicalNodeReplacement, NodeMutation,
7     ParagraphNode
8 } from "lexical";
9 import {LinkNode} from "@lexical/link";
10 import {ImageNode} from "@lexical/rich-text/LexicalImageNode";
11 import {DetailsNode} from "@lexical/rich-text/LexicalDetailsNode";
12 import {ListItemNode, ListNode} from "@lexical/list";
13 import {TableCellNode, TableNode, TableRowNode} from "@lexical/table";
14 import {HorizontalRuleNode} from "@lexical/rich-text/LexicalHorizontalRuleNode";
15 import {CodeBlockNode} from "@lexical/rich-text/LexicalCodeBlockNode";
16 import {DiagramNode} from "@lexical/rich-text/LexicalDiagramNode";
17 import {EditorUiContext} from "./ui/framework/core";
18 import {MediaNode} from "@lexical/rich-text/LexicalMediaNode";
19 import {HeadingNode} from "@lexical/rich-text/LexicalHeadingNode";
20 import {QuoteNode} from "@lexical/rich-text/LexicalQuoteNode";
21 import {CaptionNode} from "@lexical/table/LexicalCaptionNode";
22
23 /**
24  * Load the nodes for lexical.
25  */
26 export function getNodesForPageEditor(): (KlassConstructor<typeof LexicalNode> | LexicalNodeReplacement)[] {
27     return [
28         CalloutNode,
29         HeadingNode,
30         QuoteNode,
31         ListNode,
32         ListItemNode,
33         TableNode,
34         TableRowNode,
35         TableCellNode,
36         CaptionNode,
37         ImageNode, // TODO - Alignment
38         HorizontalRuleNode,
39         DetailsNode,
40         CodeBlockNode,
41         DiagramNode,
42         MediaNode, // TODO - Alignment
43         ParagraphNode,
44         LinkNode,
45     ];
46 }
47
48 export function registerCommonNodeMutationListeners(context: EditorUiContext): void {
49     const decorated = [ImageNode, CodeBlockNode, DiagramNode];
50
51     const decorationDestroyListener = (mutations: Map<string, NodeMutation>): void => {
52         for (let [nodeKey, mutation] of mutations) {
53             if (mutation === "destroyed") {
54                 const decorator = context.manager.getDecoratorByNodeKey(nodeKey);
55                 if (decorator) {
56                     decorator.destroy(context);
57                 }
58             }
59         }
60     };
61
62     for (let decoratedNode of decorated) {
63         // Have to pass a unique function here since they are stored by lexical keyed on listener function.
64         context.editor.registerMutationListener(decoratedNode, (mutations) => decorationDestroyListener(mutations));
65     }
66 }
67
68 export type LexicalNodeMatcher = (node: LexicalNode|null|undefined) => boolean;
69 export type LexicalElementNodeCreator = () => ElementNode;