]> BookStack Code Mirror - bookstack/blobdiff - resources/js/wysiwyg/utils/formats.ts
Lexical: Updated tests after link changes
[bookstack] / resources / js / wysiwyg / utils / formats.ts
index 340be393da0ed7e9d4f140f0005a17bff7b39dff..a5f06f147d27593d9b4635dded3c664bdd5d9305 100644 (file)
@@ -1,40 +1,63 @@
-import {$isQuoteNode, HeadingNode, HeadingTagType} from "@lexical/rich-text";
-import {$getSelection, LexicalEditor, LexicalNode} from "lexical";
+import {
+    $createParagraphNode,
+    $createTextNode,
+    $getSelection,
+    $insertNodes,
+    $isParagraphNode,
+    LexicalEditor,
+    LexicalNode
+} from "lexical";
 import {
     $getBlockElementNodesInSelection,
     $getNodeFromSelection,
-    $insertNewBlockNodeAtSelection,
+    $insertNewBlockNodeAtSelection, $selectionContainsNodeType, $selectSingleNode,
     $toggleSelectionBlockNodeType,
     getLastSelection
 } from "./selection";
-import {$createCustomHeadingNode, $isCustomHeadingNode} from "../nodes/custom-heading";
-import {$createCustomParagraphNode, $isCustomParagraphNode} from "../nodes/custom-paragraph";
-import {$createCustomQuoteNode} from "../nodes/custom-quote";
-import {$createCodeBlockNode, $isCodeBlockNode, $openCodeEditorForNode, CodeBlockNode} from "../nodes/code-block";
-import {$createCalloutNode, $isCalloutNode, CalloutCategory} from "../nodes/callout";
+import {$createCodeBlockNode, $isCodeBlockNode, $openCodeEditorForNode, CodeBlockNode} from "@lexical/rich-text/LexicalCodeBlockNode";
+import {$createCalloutNode, $isCalloutNode, CalloutCategory} from "@lexical/rich-text/LexicalCalloutNode";
+import {$isListNode, insertList, ListNode, ListType, removeList} from "@lexical/list";
+import {$createLinkNode, $isLinkNode} from "@lexical/link";
+import {$createHeadingNode, $isHeadingNode, HeadingTagType} from "@lexical/rich-text/LexicalHeadingNode";
+import {$createQuoteNode, $isQuoteNode} from "@lexical/rich-text/LexicalQuoteNode";
 
 const $isHeaderNodeOfTag = (node: LexicalNode | null | undefined, tag: HeadingTagType) => {
-    return $isCustomHeadingNode(node) && (node as HeadingNode).getTag() === tag;
+    return $isHeadingNode(node) && node.getTag() === tag;
 };
 
 export function toggleSelectionAsHeading(editor: LexicalEditor, tag: HeadingTagType) {
     editor.update(() => {
         $toggleSelectionBlockNodeType(
             (node) => $isHeaderNodeOfTag(node, tag),
-            () => $createCustomHeadingNode(tag),
+            () => $createHeadingNode(tag),
         )
     });
 }
 
 export function toggleSelectionAsParagraph(editor: LexicalEditor) {
     editor.update(() => {
-        $toggleSelectionBlockNodeType($isCustomParagraphNode, $createCustomParagraphNode);
+        $toggleSelectionBlockNodeType($isParagraphNode, $createParagraphNode);
     });
 }
 
 export function toggleSelectionAsBlockquote(editor: LexicalEditor) {
     editor.update(() => {
-        $toggleSelectionBlockNodeType($isQuoteNode, $createCustomQuoteNode);
+        $toggleSelectionBlockNodeType($isQuoteNode, $createQuoteNode);
+    });
+}
+
+export function toggleSelectionAsList(editor: LexicalEditor, type: ListType) {
+    editor.getEditorState().read(() => {
+        const selection = $getSelection();
+        const listSelected = $selectionContainsNodeType(selection, (node: LexicalNode | null | undefined): boolean => {
+            return $isListNode(node) && (node as ListNode).getListType() === type;
+        });
+
+        if (listSelected) {
+            removeList(editor);
+        } else {
+            insertList(editor, type);
+        }
     });
 }
 
@@ -47,9 +70,19 @@ export function formatCodeBlock(editor: LexicalEditor) {
             editor.update(() => {
                 const codeBlock = $createCodeBlockNode();
                 codeBlock.setCode(selection?.getTextContent() || '');
-                $insertNewBlockNodeAtSelection(codeBlock, true);
+
+                const selectionNodes = $getBlockElementNodesInSelection(selection);
+                const firstSelectionNode = selectionNodes[0];
+                const extraNodes = selectionNodes.slice(1);
+                if (firstSelectionNode) {
+                    firstSelectionNode.replace(codeBlock);
+                    extraNodes.forEach(n => n.remove());
+                } else {
+                    $insertNewBlockNodeAtSelection(codeBlock, true);
+                }
+
                 $openCodeEditorForNode(editor, codeBlock);
-                codeBlock.selectStart();
+                $selectSingleNode(codeBlock);
             });
         } else {
             $openCodeEditorForNode(editor, codeBlock);
@@ -85,4 +118,30 @@ export function cycleSelectionCalloutFormats(editor: LexicalEditor) {
             }
         }
     });
+}
+
+export function insertOrUpdateLink(editor: LexicalEditor, linkDetails: {text: string, title: string, target: string, url: string}) {
+    editor.update(() => {
+        const selection = $getSelection();
+        let link = $getNodeFromSelection(selection, $isLinkNode);
+        if ($isLinkNode(link)) {
+            link.setURL(linkDetails.url);
+            link.setTarget(linkDetails.target);
+            link.setTitle(linkDetails.title);
+        } else {
+            link = $createLinkNode(linkDetails.url, {
+                title: linkDetails.title,
+                target: linkDetails.target,
+            });
+
+            $insertNodes([link]);
+        }
+
+        if ($isLinkNode(link)) {
+            for (const child of link.getChildren()) {
+                child.remove(true);
+            }
+            link.append($createTextNode(linkDetails.text));
+        }
+    });
 }
\ No newline at end of file