15 import {$findMatchingParent, $getNearestBlockElementAncestorOrThrow} from "@lexical/utils";
16 import {LexicalElementNodeCreator, LexicalNodeMatcher} from "../nodes";
17 import {$setBlocksType} from "@lexical/selection";
19 import {$getParentOfType} from "./nodes";
21 export function $selectionContainsNodeType(selection: BaseSelection | null, matcher: LexicalNodeMatcher): boolean {
22 return $getNodeFromSelection(selection, matcher) !== null;
25 export function $getNodeFromSelection(selection: BaseSelection | null, matcher: LexicalNodeMatcher): LexicalNode | null {
30 for (const node of selection.getNodes()) {
35 const matchedParent = $getParentOfType(node, matcher);
44 export function $selectionContainsTextFormat(selection: BaseSelection | null, format: TextFormatType): boolean {
49 for (const node of selection.getNodes()) {
50 if ($isTextNode(node) && node.hasFormat(format)) {
58 export function $toggleSelectionBlockNodeType(matcher: LexicalNodeMatcher, creator: LexicalElementNodeCreator) {
59 const selection = $getSelection();
60 const blockElement = selection ? $getNearestBlockElementAncestorOrThrow(selection.getNodes()[0]) : null;
61 if (selection && matcher(blockElement)) {
62 $setBlocksType(selection, $createParagraphNode);
64 $setBlocksType(selection, creator);
68 export function $insertNewBlockNodeAtSelection(node: LexicalNode, insertAfter: boolean = true) {
69 $insertNewBlockNodesAtSelection([node], insertAfter);
72 export function $insertNewBlockNodesAtSelection(nodes: LexicalNode[], insertAfter: boolean = true) {
73 const selection = $getSelection();
74 const blockElement = selection ? $getNearestBlockElementAncestorOrThrow(selection.getNodes()[0]) : null;
78 for (let i = nodes.length - 1; i >= 0; i--) {
79 blockElement.insertAfter(nodes[i]);
82 for (const node of nodes) {
83 blockElement.insertBefore(node);
87 $getRoot().append(...nodes);
91 export function $selectSingleNode(node: LexicalNode) {
92 const nodeSelection = $createNodeSelection();
93 nodeSelection.add(node.getKey());
94 $setSelection(nodeSelection);
97 export function $selectionContainsNode(selection: BaseSelection | null, node: LexicalNode): boolean {
102 const key = node.getKey();
103 for (const node of selection.getNodes()) {
104 if (node.getKey() === key) {
112 export function $selectionContainsElementFormat(selection: BaseSelection | null, format: ElementFormatType): boolean {
113 const nodes = $getBlockElementNodesInSelection(selection);
114 for (const node of nodes) {
115 if (node.getFormatType() === format) {
123 export function $getBlockElementNodesInSelection(selection: BaseSelection | null): ElementNode[] {
128 const blockNodes: Map<string, ElementNode> = new Map();
129 for (const node of selection.getNodes()) {
130 const blockElement = $findMatchingParent(node, (node) => {
131 return $isElementNode(node) && !node.isInline();
132 }) as ElementNode | null;
135 blockNodes.set(blockElement.getKey(), blockElement);
139 return Array.from(blockNodes.values());