]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/helpers.ts
Lexical: Added a range of format buttons
[bookstack] / resources / js / wysiwyg / helpers.ts
1 import {
2     $createParagraphNode,
3     $getSelection,
4     $isTextNode,
5     BaseSelection,
6     ElementFormatType,
7     LexicalEditor, TextFormatType
8 } from "lexical";
9 import {LexicalElementNodeCreator, LexicalNodeMatcher} from "./nodes";
10 import {$getNearestBlockElementAncestorOrThrow} from "@lexical/utils";
11 import {$setBlocksType} from "@lexical/selection";
12 import {TextNodeThemeClasses} from "lexical/LexicalEditor";
13
14 export function selectionContainsNodeType(selection: BaseSelection|null, matcher: LexicalNodeMatcher): boolean {
15     if (!selection) {
16         return false;
17     }
18
19     for (const node of selection.getNodes()) {
20         if (matcher(node)) {
21             return true;
22         }
23
24         for (const parent of node.getParents()) {
25             if (matcher(parent)) {
26                 return true;
27             }
28         }
29     }
30
31     return false;
32 }
33
34 export function selectionContainsTextFormat(selection: BaseSelection|null, format: TextFormatType): boolean {
35     if (!selection) {
36         return false;
37     }
38
39     for (const node of selection.getNodes()) {
40         if ($isTextNode(node) && node.hasFormat(format)) {
41             return true;
42         }
43     }
44
45     return false;
46 }
47
48 export function toggleSelectionBlockNodeType(editor: LexicalEditor, matcher: LexicalNodeMatcher, creator: LexicalElementNodeCreator) {
49     editor.update(() => {
50         const selection = $getSelection();
51         const blockElement = selection ? $getNearestBlockElementAncestorOrThrow(selection.getNodes()[0]) : null;
52         if (selection && matcher(blockElement)) {
53             $setBlocksType(selection, $createParagraphNode);
54         } else {
55             $setBlocksType(selection, creator);
56         }
57     });
58 }