diff --git a/resources/js/wysiwyg/helpers.ts b/resources/js/wysiwyg/helpers.ts index 600e71dd1..a7c3e4453 100644 --- a/resources/js/wysiwyg/helpers.ts +++ b/resources/js/wysiwyg/helpers.ts @@ -4,7 +4,7 @@ import { $getSelection, $isElementNode, $isTextNode, $setSelection, BaseSelection, ElementFormatType, ElementNode, - LexicalEditor, LexicalNode, TextFormatType + LexicalNode, TextFormatType } from "lexical"; import {LexicalElementNodeCreator, LexicalNodeMatcher} from "./nodes"; import {$findMatchingParent, $getNearestBlockElementAncestorOrThrow} from "@lexical/utils"; @@ -30,11 +30,11 @@ export function el(tag: string, attrs: Record = {}, childre return el; } -export function selectionContainsNodeType(selection: BaseSelection|null, matcher: LexicalNodeMatcher): boolean { - return getNodeFromSelection(selection, matcher) !== null; +export function $selectionContainsNodeType(selection: BaseSelection|null, matcher: LexicalNodeMatcher): boolean { + return $getNodeFromSelection(selection, matcher) !== null; } -export function getNodeFromSelection(selection: BaseSelection|null, matcher: LexicalNodeMatcher): LexicalNode|null { +export function $getNodeFromSelection(selection: BaseSelection|null, matcher: LexicalNodeMatcher): LexicalNode|null { if (!selection) { return null; } @@ -54,7 +54,7 @@ export function getNodeFromSelection(selection: BaseSelection|null, matcher: Lex return null; } -export function selectionContainsTextFormat(selection: BaseSelection|null, format: TextFormatType): boolean { +export function $selectionContainsTextFormat(selection: BaseSelection|null, format: TextFormatType): boolean { if (!selection) { return false; } @@ -68,19 +68,17 @@ export function selectionContainsTextFormat(selection: BaseSelection|null, forma return false; } -export function toggleSelectionBlockNodeType(editor: LexicalEditor, matcher: LexicalNodeMatcher, creator: LexicalElementNodeCreator) { - editor.update(() => { - const selection = $getSelection(); - const blockElement = selection ? $getNearestBlockElementAncestorOrThrow(selection.getNodes()[0]) : null; - if (selection && matcher(blockElement)) { - $setBlocksType(selection, $createParagraphNode); - } else { - $setBlocksType(selection, creator); - } - }); +export function $toggleSelectionBlockNodeType(matcher: LexicalNodeMatcher, creator: LexicalElementNodeCreator) { + const selection = $getSelection(); + const blockElement = selection ? $getNearestBlockElementAncestorOrThrow(selection.getNodes()[0]) : null; + if (selection && matcher(blockElement)) { + $setBlocksType(selection, $createParagraphNode); + } else { + $setBlocksType(selection, creator); + } } -export function insertNewBlockNodeAtSelection(node: LexicalNode, insertAfter: boolean = true) { +export function $insertNewBlockNodeAtSelection(node: LexicalNode, insertAfter: boolean = true) { const selection = $getSelection(); const blockElement = selection ? $getNearestBlockElementAncestorOrThrow(selection.getNodes()[0]) : null; @@ -95,13 +93,13 @@ export function insertNewBlockNodeAtSelection(node: LexicalNode, insertAfter: bo } } -export function selectSingleNode(node: LexicalNode) { +export function $selectSingleNode(node: LexicalNode) { const nodeSelection = $createNodeSelection(); nodeSelection.add(node.getKey()); $setSelection(nodeSelection); } -export function selectionContainsNode(selection: BaseSelection|null, node: LexicalNode): boolean { +export function $selectionContainsNode(selection: BaseSelection|null, node: LexicalNode): boolean { if (!selection) { return false; } @@ -116,8 +114,8 @@ export function selectionContainsNode(selection: BaseSelection|null, node: Lexic return false; } -export function selectionContainsElementFormat(selection: BaseSelection|null, format: ElementFormatType): boolean { - const nodes = getBlockElementNodesInSelection(selection); +export function $selectionContainsElementFormat(selection: BaseSelection|null, format: ElementFormatType): boolean { + const nodes = $getBlockElementNodesInSelection(selection); for (const node of nodes) { if (node.getFormatType() === format) { return true; @@ -127,7 +125,7 @@ export function selectionContainsElementFormat(selection: BaseSelection|null, fo return false; } -export function getBlockElementNodesInSelection(selection: BaseSelection|null): ElementNode[] { +export function $getBlockElementNodesInSelection(selection: BaseSelection|null): ElementNode[] { if (!selection) { return []; } diff --git a/resources/js/wysiwyg/ui/decorators/code-block.ts b/resources/js/wysiwyg/ui/decorators/code-block.ts index 11cc02e8f..cfb2c6aef 100644 --- a/resources/js/wysiwyg/ui/decorators/code-block.ts +++ b/resources/js/wysiwyg/ui/decorators/code-block.ts @@ -1,7 +1,7 @@ import {EditorDecorator} from "../framework/decorator"; import {EditorUiContext} from "../framework/core"; import {$openCodeEditorForNode, CodeBlockNode} from "../../nodes/code-block"; -import {selectionContainsNode, selectSingleNode} from "../../helpers"; +import {$selectionContainsNode, $selectSingleNode} from "../../helpers"; import {context} from "esbuild"; import {BaseSelection} from "lexical"; @@ -36,7 +36,7 @@ export class CodeBlockDecorator extends EditorDecorator { element.addEventListener('click', event => { context.editor.update(() => { - selectSingleNode(this.getNode()); + $selectSingleNode(this.getNode()); }) }); @@ -47,7 +47,7 @@ export class CodeBlockDecorator extends EditorDecorator { }); const selectionChange = (selection: BaseSelection|null): void => { - element.classList.toggle('selected', selectionContainsNode(selection, codeNode)); + element.classList.toggle('selected', $selectionContainsNode(selection, codeNode)); }; context.manager.onSelectionChange(selectionChange); this.onDestroy(() => { diff --git a/resources/js/wysiwyg/ui/decorators/image.ts b/resources/js/wysiwyg/ui/decorators/image.ts index 1bc1ea543..2046260a0 100644 --- a/resources/js/wysiwyg/ui/decorators/image.ts +++ b/resources/js/wysiwyg/ui/decorators/image.ts @@ -1,5 +1,5 @@ import {EditorDecorator} from "../framework/decorator"; -import {el, selectSingleNode} from "../../helpers"; +import {el, $selectSingleNode} from "../../helpers"; import {$createNodeSelection, $setSelection} from "lexical"; import {EditorUiContext} from "../framework/core"; import {ImageNode} from "../../nodes/image"; @@ -41,7 +41,7 @@ export class ImageDecorator extends EditorDecorator { tracker = this.setupTracker(decorateEl, context); context.editor.update(() => { - selectSingleNode(this.getNode()); + $selectSingleNode(this.getNode()); }); }; diff --git a/resources/js/wysiwyg/ui/defaults/button-definitions.ts b/resources/js/wysiwyg/ui/defaults/button-definitions.ts index d1d22dae1..bf725f8c8 100644 --- a/resources/js/wysiwyg/ui/defaults/button-definitions.ts +++ b/resources/js/wysiwyg/ui/defaults/button-definitions.ts @@ -21,11 +21,11 @@ import { UNDO_COMMAND } from "lexical"; import { - getBlockElementNodesInSelection, - getNodeFromSelection, insertNewBlockNodeAtSelection, selectionContainsElementFormat, - selectionContainsNodeType, - selectionContainsTextFormat, - toggleSelectionBlockNodeType + $getBlockElementNodesInSelection, + $getNodeFromSelection, $insertNewBlockNodeAtSelection, $selectionContainsElementFormat, + $selectionContainsNodeType, + $selectionContainsTextFormat, + $toggleSelectionBlockNodeType } from "../../helpers"; import {$createCalloutNode, $isCalloutNodeOfCategory, CalloutCategory} from "../../nodes/callout"; import { @@ -116,14 +116,15 @@ function buildCalloutButton(category: CalloutCategory, name: string): EditorButt return { label: `${name} Callout`, action(context: EditorUiContext) { - toggleSelectionBlockNodeType( - context.editor, - (node) => $isCalloutNodeOfCategory(node, category), - () => $createCalloutNode(category), - ) + context.editor.update(() => { + $toggleSelectionBlockNodeType( + (node) => $isCalloutNodeOfCategory(node, category), + () => $createCalloutNode(category), + ) + }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, (node) => $isCalloutNodeOfCategory(node, category)); + return $selectionContainsNodeType(selection, (node) => $isCalloutNodeOfCategory(node, category)); } }; } @@ -141,14 +142,15 @@ function buildHeaderButton(tag: HeadingTagType, name: string): EditorButtonDefin return { label: name, action(context: EditorUiContext) { - toggleSelectionBlockNodeType( - context.editor, + context.editor.update(() => { + $toggleSelectionBlockNodeType( (node) => isHeaderNodeOfTag(node, tag), () => $createHeadingNode(tag), - ) + ) + }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, (node) => isHeaderNodeOfTag(node, tag)); + return $selectionContainsNodeType(selection, (node) => isHeaderNodeOfTag(node, tag)); } }; } @@ -161,20 +163,24 @@ export const h5: EditorButtonDefinition = buildHeaderButton('h5', 'Tiny Header') export const blockquote: EditorButtonDefinition = { label: 'Blockquote', action(context: EditorUiContext) { - toggleSelectionBlockNodeType(context.editor, $isQuoteNode, $createQuoteNode); + context.editor.update(() => { + $toggleSelectionBlockNodeType($isQuoteNode, $createQuoteNode); + }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, $isQuoteNode); + return $selectionContainsNodeType(selection, $isQuoteNode); } }; export const paragraph: EditorButtonDefinition = { label: 'Paragraph', action(context: EditorUiContext) { - toggleSelectionBlockNodeType(context.editor, $isParagraphNode, $createParagraphNode); + context.editor.update(() => { + $toggleSelectionBlockNodeType($isParagraphNode, $createParagraphNode); + }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, $isParagraphNode); + return $selectionContainsNodeType(selection, $isParagraphNode); } } @@ -186,7 +192,7 @@ function buildFormatButton(label: string, format: TextFormatType, icon: string): context.editor.dispatchCommand(FORMAT_TEXT_COMMAND, format); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsTextFormat(selection, format); + return $selectionContainsTextFormat(selection, format); } }; } @@ -222,7 +228,7 @@ export const clearFormating: EditorButtonDefinition = { function setAlignmentForSection(alignment: ElementFormatType): void { const selection = $getSelection(); - const elements = getBlockElementNodesInSelection(selection); + const elements = $getBlockElementNodesInSelection(selection); for (const node of elements) { node.setFormat(alignment); } @@ -235,7 +241,7 @@ export const alignLeft: EditorButtonDefinition = { context.editor.update(() => setAlignmentForSection('left')); }, isActive(selection: BaseSelection|null) { - return selectionContainsElementFormat(selection, 'left'); + return $selectionContainsElementFormat(selection, 'left'); } }; @@ -246,7 +252,7 @@ export const alignCenter: EditorButtonDefinition = { context.editor.update(() => setAlignmentForSection('center')); }, isActive(selection: BaseSelection|null) { - return selectionContainsElementFormat(selection, 'center'); + return $selectionContainsElementFormat(selection, 'center'); } }; @@ -257,7 +263,7 @@ export const alignRight: EditorButtonDefinition = { context.editor.update(() => setAlignmentForSection('right')); }, isActive(selection: BaseSelection|null) { - return selectionContainsElementFormat(selection, 'right'); + return $selectionContainsElementFormat(selection, 'right'); } }; @@ -268,7 +274,7 @@ export const alignJustify: EditorButtonDefinition = { context.editor.update(() => setAlignmentForSection('justify')); }, isActive(selection: BaseSelection|null) { - return selectionContainsElementFormat(selection, 'justify'); + return $selectionContainsElementFormat(selection, 'justify'); } }; @@ -288,7 +294,7 @@ function buildListButton(label: string, type: ListType, icon: string): EditorBut }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, (node: LexicalNode | null | undefined): boolean => { + return $selectionContainsNodeType(selection, (node: LexicalNode | null | undefined): boolean => { return $isListNode(node) && (node as ListNode).getListType() === type; }); } @@ -307,7 +313,7 @@ export const link: EditorButtonDefinition = { const linkModal = context.manager.createModal('link'); context.editor.getEditorState().read(() => { const selection = $getSelection(); - const selectedLink = getNodeFromSelection(selection, $isLinkNode) as LinkNode|null; + const selectedLink = $getNodeFromSelection(selection, $isLinkNode) as LinkNode|null; let formDefaults = {}; if (selectedLink) { @@ -329,7 +335,7 @@ export const link: EditorButtonDefinition = { }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, $isLinkNode); + return $selectionContainsNodeType(selection, $isLinkNode); } }; @@ -339,7 +345,7 @@ export const unlink: EditorButtonDefinition = { action(context: EditorUiContext) { context.editor.update(() => { const selection = context.lastSelection; - const selectedLink = getNodeFromSelection(selection, $isLinkNode) as LinkNode|null; + const selectedLink = $getNodeFromSelection(selection, $isLinkNode) as LinkNode|null; const selectionPoints = selection?.getStartEndPoints(); if (selectedLink) { @@ -369,7 +375,7 @@ export const image: EditorButtonDefinition = { action(context: EditorUiContext) { const imageModal = context.manager.createModal('image'); const selection = context.lastSelection; - const selectedImage = getNodeFromSelection(selection, $isImageNode) as ImageNode|null; + const selectedImage = $getNodeFromSelection(selection, $isImageNode) as ImageNode|null; context.editor.getEditorState().read(() => { let formDefaults = {}; @@ -392,7 +398,7 @@ export const image: EditorButtonDefinition = { }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, $isImageNode); + return $selectionContainsNodeType(selection, $isImageNode); } }; @@ -401,11 +407,11 @@ export const horizontalRule: EditorButtonDefinition = { icon: horizontalRuleIcon, action(context: EditorUiContext) { context.editor.update(() => { - insertNewBlockNodeAtSelection($createHorizontalRuleNode(), false); + $insertNewBlockNodeAtSelection($createHorizontalRuleNode(), false); }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, $isHorizontalRuleNode); + return $selectionContainsNodeType(selection, $isHorizontalRuleNode); } }; @@ -415,12 +421,12 @@ export const codeBlock: EditorButtonDefinition = { action(context: EditorUiContext) { context.editor.getEditorState().read(() => { const selection = $getSelection(); - const codeBlock = getNodeFromSelection(context.lastSelection, $isCodeBlockNode) as (CodeBlockNode|null); + const codeBlock = $getNodeFromSelection(context.lastSelection, $isCodeBlockNode) as (CodeBlockNode|null); if (codeBlock === null) { context.editor.update(() => { const codeBlock = $createCodeBlockNode(); codeBlock.setCode(selection?.getTextContent() || ''); - insertNewBlockNodeAtSelection(codeBlock, true); + $insertNewBlockNodeAtSelection(codeBlock, true); $openCodeEditorForNode(context.editor, codeBlock); codeBlock.selectStart(); }); @@ -430,7 +436,7 @@ export const codeBlock: EditorButtonDefinition = { }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, $isCodeBlockNode); + return $selectionContainsNodeType(selection, $isCodeBlockNode); } }; @@ -463,7 +469,7 @@ export const details: EditorButtonDefinition = { }); }, isActive(selection: BaseSelection|null): boolean { - return selectionContainsNodeType(selection, $isDetailsNode); + return $selectionContainsNodeType(selection, $isDetailsNode); } } diff --git a/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts b/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts index 8c28953d5..1981fcb86 100644 --- a/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts +++ b/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts @@ -1,4 +1,4 @@ -import {el, insertNewBlockNodeAtSelection} from "../../../helpers"; +import {el, $insertNewBlockNodeAtSelection} from "../../../helpers"; import {EditorUiElement} from "../core"; import {$createTableNodeWithDimensions} from "@lexical/table"; import {CustomTableNode} from "../../../nodes/custom-table"; @@ -75,7 +75,7 @@ export class EditorTableCreator extends EditorUiElement { this.getContext().editor.update(() => { const table = $createTableNodeWithDimensions(rows, columns, false) as CustomTableNode; - insertNewBlockNodeAtSelection(table); + $insertNewBlockNodeAtSelection(table); }); } } \ No newline at end of file