diff --git a/resources/js/wysiwyg/index.ts b/resources/js/wysiwyg/index.ts index 71a007f59..9da646a77 100644 --- a/resources/js/wysiwyg/index.ts +++ b/resources/js/wysiwyg/index.ts @@ -4,14 +4,14 @@ import {registerRichText} from '@lexical/rich-text'; import {mergeRegister} from '@lexical/utils'; import {getNodesForPageEditor, registerCommonNodeMutationListeners} from './nodes'; import {buildEditorUI} from "./ui"; -import {getEditorContentAsHtml, setEditorContentFromHtml} from "./actions"; +import {getEditorContentAsHtml, setEditorContentFromHtml} from "./utils/actions"; import {registerTableResizer} from "./ui/framework/helpers/table-resizer"; -import {el} from "./helpers"; import {EditorUiContext} from "./ui/framework/core"; -import {listen as listenToCommonEvents} from "./common-events"; -import {handleDropEvents} from "./drop-handling"; +import {listen as listenToCommonEvents} from "./services/common-events"; +import {handleDropEvents} from "./services/drop-handling"; import {registerTaskListHandler} from "./ui/framework/helpers/task-list-handler"; import {registerTableSelectionHandler} from "./ui/framework/helpers/table-selection-handler"; +import {el} from "./utils/dom"; export function createPageEditorInstance(container: HTMLElement, htmlContent: string, options: Record = {}): SimpleWysiwygEditorInterface { const config: CreateEditorArgs = { diff --git a/resources/js/wysiwyg/nodes/code-block.ts b/resources/js/wysiwyg/nodes/code-block.ts index 2478ba249..e240a3887 100644 --- a/resources/js/wysiwyg/nodes/code-block.ts +++ b/resources/js/wysiwyg/nodes/code-block.ts @@ -8,9 +8,9 @@ import { Spread } from "lexical"; import type {EditorConfig} from "lexical/LexicalEditor"; -import {el} from "../helpers"; import {EditorDecoratorAdapter} from "../ui/framework/decorator"; import {CodeEditor} from "../../components"; +import {el} from "../utils/dom"; export type SerializedCodeBlockNode = Spread<{ language: string; diff --git a/resources/js/wysiwyg/nodes/custom-list-item.ts b/resources/js/wysiwyg/nodes/custom-list-item.ts index 21b9f6d5f..2b4d74146 100644 --- a/resources/js/wysiwyg/nodes/custom-list-item.ts +++ b/resources/js/wysiwyg/nodes/custom-list-item.ts @@ -1,7 +1,8 @@ import {$isListNode, ListItemNode, SerializedListItemNode} from "@lexical/list"; import {EditorConfig} from "lexical/LexicalEditor"; import {DOMExportOutput, LexicalEditor, LexicalNode} from "lexical"; -import {el} from "../helpers"; + +import {el} from "../utils/dom"; function updateListItemChecked( dom: HTMLElement, diff --git a/resources/js/wysiwyg/nodes/custom-table.ts b/resources/js/wysiwyg/nodes/custom-table.ts index 7dda24a7a..32f3ec4fa 100644 --- a/resources/js/wysiwyg/nodes/custom-table.ts +++ b/resources/js/wysiwyg/nodes/custom-table.ts @@ -1,7 +1,8 @@ import {SerializedTableNode, TableNode, TableRowNode} from "@lexical/table"; import {DOMConversion, DOMConversionMap, DOMConversionOutput, LexicalEditor, LexicalNode, Spread} from "lexical"; import {EditorConfig} from "lexical/LexicalEditor"; -import {el} from "../helpers"; + +import {el} from "../utils/dom"; export type SerializedCustomTableNode = Spread<{ id: string; diff --git a/resources/js/wysiwyg/nodes/details.ts b/resources/js/wysiwyg/nodes/details.ts index a18c4d858..8071d5e8f 100644 --- a/resources/js/wysiwyg/nodes/details.ts +++ b/resources/js/wysiwyg/nodes/details.ts @@ -7,7 +7,8 @@ import { SerializedElementNode, } from 'lexical'; import type {EditorConfig} from "lexical/LexicalEditor"; -import {el} from "../helpers"; + +import {el} from "../utils/dom"; export class DetailsNode extends ElementNode { diff --git a/resources/js/wysiwyg/nodes/diagram.ts b/resources/js/wysiwyg/nodes/diagram.ts index 1aff06400..76d939248 100644 --- a/resources/js/wysiwyg/nodes/diagram.ts +++ b/resources/js/wysiwyg/nodes/diagram.ts @@ -8,11 +8,11 @@ import { Spread } from "lexical"; import type {EditorConfig} from "lexical/LexicalEditor"; -import {el} from "../helpers"; import {EditorDecoratorAdapter} from "../ui/framework/decorator"; import * as DrawIO from '../../services/drawio'; import {EditorUiContext} from "../ui/framework/core"; import {HttpError} from "../../services/http"; +import {el} from "../utils/dom"; export type SerializedDiagramNode = Spread<{ id: string; diff --git a/resources/js/wysiwyg/nodes/image.ts b/resources/js/wysiwyg/nodes/image.ts index 92d5518db..ef6bf3572 100644 --- a/resources/js/wysiwyg/nodes/image.ts +++ b/resources/js/wysiwyg/nodes/image.ts @@ -8,8 +8,8 @@ import { Spread } from "lexical"; import type {EditorConfig} from "lexical/LexicalEditor"; -import {el} from "../helpers"; import {EditorDecoratorAdapter} from "../ui/framework/decorator"; +import {el} from "../utils/dom"; export interface ImageNodeOptions { alt?: string; diff --git a/resources/js/wysiwyg/nodes/media.ts b/resources/js/wysiwyg/nodes/media.ts index 751f420fa..aba4f6c37 100644 --- a/resources/js/wysiwyg/nodes/media.ts +++ b/resources/js/wysiwyg/nodes/media.ts @@ -7,7 +7,8 @@ import { SerializedElementNode, Spread } from 'lexical'; import type {EditorConfig} from "lexical/LexicalEditor"; -import {el} from "../helpers"; + +import {el} from "../utils/dom"; export type MediaNodeTag = 'iframe' | 'embed' | 'object' | 'video' | 'audio'; export type MediaNodeSource = { diff --git a/resources/js/wysiwyg/common-events.ts b/resources/js/wysiwyg/services/common-events.ts similarity index 97% rename from resources/js/wysiwyg/common-events.ts rename to resources/js/wysiwyg/services/common-events.ts index 7355d977b..16522d66b 100644 --- a/resources/js/wysiwyg/common-events.ts +++ b/resources/js/wysiwyg/services/common-events.ts @@ -5,7 +5,7 @@ import { insertHtmlIntoEditor, prependHtmlToEditor, setEditorContentFromHtml -} from "./actions"; +} from "../utils/actions"; type EditorEventContent = { html: string; diff --git a/resources/js/wysiwyg/drop-handling.ts b/resources/js/wysiwyg/services/drop-handling.ts similarity index 93% rename from resources/js/wysiwyg/drop-handling.ts rename to resources/js/wysiwyg/services/drop-handling.ts index 5d541365a..7c9bb2713 100644 --- a/resources/js/wysiwyg/drop-handling.ts +++ b/resources/js/wysiwyg/services/drop-handling.ts @@ -3,12 +3,8 @@ import { LexicalEditor, LexicalNode } from "lexical"; -import { - $getNearestBlockNodeForCoords, - $htmlToBlockNodes, - $insertNewBlockNodesAtSelection, - $selectSingleNode -} from "./helpers"; +import {$insertNewBlockNodesAtSelection, $selectSingleNode} from "../utils/selection"; +import {$getNearestBlockNodeForCoords, $htmlToBlockNodes} from "../utils/nodes"; function $getNodeFromMouseEvent(event: MouseEvent, editor: LexicalEditor): LexicalNode|null { const x = event.clientX; diff --git a/resources/js/wysiwyg/ui/decorators/code-block.ts b/resources/js/wysiwyg/ui/decorators/code-block.ts index d6947ea75..650bd64c5 100644 --- a/resources/js/wysiwyg/ui/decorators/code-block.ts +++ b/resources/js/wysiwyg/ui/decorators/code-block.ts @@ -1,8 +1,8 @@ import {EditorDecorator} from "../framework/decorator"; import {EditorUiContext} from "../framework/core"; import {$openCodeEditorForNode, CodeBlockNode} from "../../nodes/code-block"; -import {$selectionContainsNode, $selectSingleNode} from "../../helpers"; import {BaseSelection} from "lexical"; +import {$selectionContainsNode, $selectSingleNode} from "../../utils/selection"; export class CodeBlockDecorator extends EditorDecorator { diff --git a/resources/js/wysiwyg/ui/decorators/diagram.ts b/resources/js/wysiwyg/ui/decorators/diagram.ts index 0f1263f38..7c79f9f41 100644 --- a/resources/js/wysiwyg/ui/decorators/diagram.ts +++ b/resources/js/wysiwyg/ui/decorators/diagram.ts @@ -1,8 +1,8 @@ import {EditorDecorator} from "../framework/decorator"; import {EditorUiContext} from "../framework/core"; -import {$selectionContainsNode, $selectSingleNode} from "../../helpers"; import {BaseSelection} from "lexical"; import {$openDrawingEditorForNode, DiagramNode} from "../../nodes/diagram"; +import {$selectionContainsNode, $selectSingleNode} from "../../utils/selection"; export class DiagramDecorator extends EditorDecorator { diff --git a/resources/js/wysiwyg/ui/decorators/image.ts b/resources/js/wysiwyg/ui/decorators/image.ts index 2046260a0..d110bc499 100644 --- a/resources/js/wysiwyg/ui/decorators/image.ts +++ b/resources/js/wysiwyg/ui/decorators/image.ts @@ -1,9 +1,10 @@ import {EditorDecorator} from "../framework/decorator"; -import {el, $selectSingleNode} from "../../helpers"; import {$createNodeSelection, $setSelection} from "lexical"; import {EditorUiContext} from "../framework/core"; import {ImageNode} from "../../nodes/image"; import {MouseDragTracker, MouseDragTrackerDistance} from "../framework/helpers/mouse-drag-tracker"; +import {$selectSingleNode} from "../../utils/selection"; +import {el} from "../../utils/dom"; export class ImageDecorator extends EditorDecorator { diff --git a/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts b/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts index 2b441e5da..40d9c89dc 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts @@ -1,11 +1,11 @@ import {$getSelection, BaseSelection, ElementFormatType} from "lexical"; -import {$getBlockElementNodesInSelection, $selectionContainsElementFormat} from "../../../helpers"; import {EditorButtonDefinition} from "../../framework/buttons"; import alignLeftIcon from "@icons/editor/align-left.svg"; import {EditorUiContext} from "../../framework/core"; import alignCenterIcon from "@icons/editor/align-center.svg"; import alignRightIcon from "@icons/editor/align-right.svg"; import alignJustifyIcon from "@icons/editor/align-justify.svg"; +import {$getBlockElementNodesInSelection, $selectionContainsElementFormat} from "../../../utils/selection"; function setAlignmentForSection(alignment: ElementFormatType): void { diff --git a/resources/js/wysiwyg/ui/defaults/buttons/block-formats.ts b/resources/js/wysiwyg/ui/defaults/buttons/block-formats.ts index 0eb07ecf1..eba903263 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/block-formats.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/block-formats.ts @@ -1,7 +1,6 @@ import {$createCalloutNode, $isCalloutNodeOfCategory, CalloutCategory} from "../../../nodes/callout"; import {EditorButtonDefinition} from "../../framework/buttons"; import {EditorUiContext} from "../../framework/core"; -import {$selectionContainsNodeType, $toggleSelectionBlockNodeType} from "../../../helpers"; import {$createParagraphNode, $isParagraphNode, BaseSelection, LexicalNode} from "lexical"; import { $createHeadingNode, @@ -11,6 +10,7 @@ import { HeadingNode, HeadingTagType } from "@lexical/rich-text"; +import {$selectionContainsNodeType, $toggleSelectionBlockNodeType} from "../../../utils/selection"; function buildCalloutButton(category: CalloutCategory, name: string): EditorButtonDefinition { return { diff --git a/resources/js/wysiwyg/ui/defaults/buttons/controls.ts b/resources/js/wysiwyg/ui/defaults/buttons/controls.ts index ad69d69d1..2a2fecc40 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/controls.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/controls.ts @@ -11,7 +11,7 @@ import { } from "lexical"; import redoIcon from "@icons/editor/redo.svg"; import sourceIcon from "@icons/editor/source-view.svg"; -import {getEditorContentAsHtml} from "../../../actions"; +import {getEditorContentAsHtml} from "../../../utils/actions"; import fullscreenIcon from "@icons/editor/fullscreen.svg"; export const undo: EditorButtonDefinition = { diff --git a/resources/js/wysiwyg/ui/defaults/buttons/inline-formats.ts b/resources/js/wysiwyg/ui/defaults/buttons/inline-formats.ts index d04f72a2e..a967ecb2f 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/inline-formats.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/inline-formats.ts @@ -1,7 +1,6 @@ import {$getSelection, $isTextNode, BaseSelection, FORMAT_TEXT_COMMAND, TextFormatType} from "lexical"; import {EditorBasicButtonDefinition, EditorButtonDefinition} from "../../framework/buttons"; import {EditorUiContext} from "../../framework/core"; -import {$selectionContainsTextFormat} from "../../../helpers"; import boldIcon from "@icons/editor/bold.svg"; import italicIcon from "@icons/editor/italic.svg"; import underlinedIcon from "@icons/editor/underlined.svg"; @@ -12,6 +11,7 @@ import superscriptIcon from "@icons/editor/superscript.svg"; import subscriptIcon from "@icons/editor/subscript.svg"; import codeIcon from "@icons/editor/code.svg"; import formatClearIcon from "@icons/editor/format-clear.svg"; +import {$selectionContainsTextFormat} from "../../../utils/selection"; function buildFormatButton(label: string, format: TextFormatType, icon: string): EditorButtonDefinition { return { diff --git a/resources/js/wysiwyg/ui/defaults/buttons/lists.ts b/resources/js/wysiwyg/ui/defaults/buttons/lists.ts index ecda290a1..10500eb67 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/lists.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/lists.ts @@ -2,10 +2,10 @@ import {$isListNode, insertList, ListNode, ListType, removeList} from "@lexical/ import {EditorButtonDefinition} from "../../framework/buttons"; import {EditorUiContext} from "../../framework/core"; import {$getSelection, BaseSelection, LexicalNode} from "lexical"; -import {$selectionContainsNodeType} from "../../../helpers"; import listBulletIcon from "@icons/editor/list-bullet.svg"; import listNumberedIcon from "@icons/editor/list-numbered.svg"; import listCheckIcon from "@icons/editor/list-check.svg"; +import {$selectionContainsNodeType} from "../../../utils/selection"; function buildListButton(label: string, type: ListType, icon: string): EditorButtonDefinition { diff --git a/resources/js/wysiwyg/ui/defaults/buttons/objects.ts b/resources/js/wysiwyg/ui/defaults/buttons/objects.ts index 3c14052ba..0eac497fc 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/objects.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/objects.ts @@ -10,7 +10,6 @@ import { BaseSelection, ElementNode } from "lexical"; -import {$getNodeFromSelection, $insertNewBlockNodeAtSelection, $selectionContainsNodeType} from "../../../helpers"; import {$isLinkNode, LinkNode} from "@lexical/link"; import unlinkIcon from "@icons/editor/unlink.svg"; import imageIcon from "@icons/editor/image.svg"; @@ -26,6 +25,11 @@ import detailsIcon from "@icons/editor/details.svg"; import mediaIcon from "@icons/editor/media.svg"; import {$createDetailsNode, $isDetailsNode} from "../../../nodes/details"; import {$isMediaNode, MediaNode} from "../../../nodes/media"; +import { + $getNodeFromSelection, + $insertNewBlockNodeAtSelection, + $selectionContainsNodeType +} from "../../../utils/selection"; export const link: EditorButtonDefinition = { label: 'Insert/edit link', diff --git a/resources/js/wysiwyg/ui/defaults/buttons/tables.ts b/resources/js/wysiwyg/ui/defaults/buttons/tables.ts index b0f0bf346..2cc2e701b 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/tables.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/tables.ts @@ -8,10 +8,6 @@ import insertColumnBeforeIcon from "@icons/editor/table-insert-column-before.svg import insertRowAboveIcon from "@icons/editor/table-insert-row-above.svg"; import insertRowBelowIcon from "@icons/editor/table-insert-row-below.svg"; import {EditorUiContext} from "../../framework/core"; -import { - $getNodeFromSelection, $getParentOfType, - $selectionContainsNodeType -} from "../../../helpers"; import {$getSelection, BaseSelection} from "lexical"; import {$isCustomTableNode} from "../../../nodes/custom-table"; import { @@ -22,6 +18,8 @@ import { $insertTableRow__EXPERIMENTAL, $isTableCellNode, $isTableNode, $isTableRowNode, $isTableSelection, $unmergeCell, TableCellNode, TableNode, } from "@lexical/table"; +import {$getNodeFromSelection, $selectionContainsNodeType} from "../../../utils/selection"; +import {$getParentOfType} from "../../../utils/nodes"; const neverActive = (): boolean => false; const cellNotSelected = (selection: BaseSelection|null) => !$selectionContainsNodeType(selection, $isTableCellNode); diff --git a/resources/js/wysiwyg/ui/defaults/forms/controls.ts b/resources/js/wysiwyg/ui/defaults/forms/controls.ts index bcb2f5bad..fc461f662 100644 --- a/resources/js/wysiwyg/ui/defaults/forms/controls.ts +++ b/resources/js/wysiwyg/ui/defaults/forms/controls.ts @@ -1,6 +1,6 @@ import {EditorFormDefinition} from "../../framework/forms"; import {EditorUiContext} from "../../framework/core"; -import {setEditorContentFromHtml} from "../../../actions"; +import {setEditorContentFromHtml} from "../../../utils/actions"; export const source: EditorFormDefinition = { submitText: 'Save', diff --git a/resources/js/wysiwyg/ui/defaults/forms/objects.ts b/resources/js/wysiwyg/ui/defaults/forms/objects.ts index 7a388751b..dbb89b18f 100644 --- a/resources/js/wysiwyg/ui/defaults/forms/objects.ts +++ b/resources/js/wysiwyg/ui/defaults/forms/objects.ts @@ -4,8 +4,8 @@ import {$createTextNode, $getSelection} from "lexical"; import {$createImageNode} from "../../../nodes/image"; import {$createLinkNode} from "@lexical/link"; import {$createMediaNodeFromHtml, $createMediaNodeFromSrc, $isMediaNode, MediaNode} from "../../../nodes/media"; -import {$getNodeFromSelection} from "../../../helpers"; import {$insertNodeToNearestRoot} from "@lexical/utils"; +import {$getNodeFromSelection} from "../../../utils/selection"; export const image: EditorFormDefinition = { submitText: 'Apply', diff --git a/resources/js/wysiwyg/ui/framework/blocks/color-picker.ts b/resources/js/wysiwyg/ui/framework/blocks/color-picker.ts index 6972d7a8e..48e313f5c 100644 --- a/resources/js/wysiwyg/ui/framework/blocks/color-picker.ts +++ b/resources/js/wysiwyg/ui/framework/blocks/color-picker.ts @@ -1,7 +1,7 @@ -import {el} from "../../../helpers"; import {EditorUiElement} from "../core"; import {$getSelection} from "lexical"; import {$patchStyleText} from "@lexical/selection"; +import {el} from "../../../utils/dom"; const colorChoices = [ '#000000', diff --git a/resources/js/wysiwyg/ui/framework/blocks/dropdown-button.ts b/resources/js/wysiwyg/ui/framework/blocks/dropdown-button.ts index da0d3e5d0..a7905a6dd 100644 --- a/resources/js/wysiwyg/ui/framework/blocks/dropdown-button.ts +++ b/resources/js/wysiwyg/ui/framework/blocks/dropdown-button.ts @@ -1,7 +1,7 @@ -import {el} from "../../../helpers"; import {handleDropdown} from "../helpers/dropdowns"; import {EditorContainerUiElement, EditorUiElement} from "../core"; import {EditorBasicButtonDefinition, EditorButton} from "../buttons"; +import {el} from "../../../utils/dom"; export type EditorDropdownButtonOptions = { showOnHover?: boolean; diff --git a/resources/js/wysiwyg/ui/framework/blocks/format-menu.ts b/resources/js/wysiwyg/ui/framework/blocks/format-menu.ts index b0834fe4d..d666954bf 100644 --- a/resources/js/wysiwyg/ui/framework/blocks/format-menu.ts +++ b/resources/js/wysiwyg/ui/framework/blocks/format-menu.ts @@ -1,7 +1,7 @@ -import {el} from "../../../helpers"; import {EditorUiStateUpdate, EditorContainerUiElement} from "../core"; import {EditorButton} from "../buttons"; import {handleDropdown} from "../helpers/dropdowns"; +import {el} from "../../../utils/dom"; export class EditorFormatMenu extends EditorContainerUiElement { buildDOM(): HTMLElement { diff --git a/resources/js/wysiwyg/ui/framework/blocks/format-preview-button.ts b/resources/js/wysiwyg/ui/framework/blocks/format-preview-button.ts index f83035aa6..2371983dd 100644 --- a/resources/js/wysiwyg/ui/framework/blocks/format-preview-button.ts +++ b/resources/js/wysiwyg/ui/framework/blocks/format-preview-button.ts @@ -1,5 +1,5 @@ -import {el} from "../../../helpers"; import {EditorButton, EditorButtonDefinition} from "../buttons"; +import {el} from "../../../utils/dom"; export class FormatPreviewButton extends EditorButton { protected previewSampleElement: HTMLElement; diff --git a/resources/js/wysiwyg/ui/framework/blocks/overflow-container.ts b/resources/js/wysiwyg/ui/framework/blocks/overflow-container.ts index 108992db8..cd0780534 100644 --- a/resources/js/wysiwyg/ui/framework/blocks/overflow-container.ts +++ b/resources/js/wysiwyg/ui/framework/blocks/overflow-container.ts @@ -1,7 +1,7 @@ import {EditorContainerUiElement, EditorUiElement} from "../core"; -import {el} from "../../../helpers"; import {EditorDropdownButton} from "./dropdown-button"; import moreHorizontal from "@icons/editor/more-horizontal.svg" +import {el} from "../../../utils/dom"; export class EditorOverflowContainer extends EditorContainerUiElement { diff --git a/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts b/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts index 1981fcb86..a8a142df5 100644 --- a/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts +++ b/resources/js/wysiwyg/ui/framework/blocks/table-creator.ts @@ -1,7 +1,8 @@ -import {el, $insertNewBlockNodeAtSelection} from "../../../helpers"; import {EditorUiElement} from "../core"; import {$createTableNodeWithDimensions} from "@lexical/table"; import {CustomTableNode} from "../../../nodes/custom-table"; +import {$insertNewBlockNodeAtSelection} from "../../../utils/selection"; +import {el} from "../../../utils/dom"; export class EditorTableCreator extends EditorUiElement { diff --git a/resources/js/wysiwyg/ui/framework/buttons.ts b/resources/js/wysiwyg/ui/framework/buttons.ts index 9a23edfb7..cf114aa02 100644 --- a/resources/js/wysiwyg/ui/framework/buttons.ts +++ b/resources/js/wysiwyg/ui/framework/buttons.ts @@ -1,6 +1,7 @@ import {BaseSelection} from "lexical"; import {EditorUiContext, EditorUiElement, EditorUiStateUpdate} from "./core"; -import {el} from "../../helpers"; + +import {el} from "../../utils/dom"; export interface EditorBasicButtonDefinition { label: string; diff --git a/resources/js/wysiwyg/ui/framework/core.ts b/resources/js/wysiwyg/ui/framework/core.ts index f644bc37a..3e9f1e3d9 100644 --- a/resources/js/wysiwyg/ui/framework/core.ts +++ b/resources/js/wysiwyg/ui/framework/core.ts @@ -1,6 +1,7 @@ import {BaseSelection, LexicalEditor} from "lexical"; import {EditorUIManager} from "./manager"; -import {el} from "../../helpers"; + +import {el} from "../../utils/dom"; export type EditorUiStateUpdate = { editor: LexicalEditor; diff --git a/resources/js/wysiwyg/ui/framework/forms.ts b/resources/js/wysiwyg/ui/framework/forms.ts index b225a3de2..a2db34dd7 100644 --- a/resources/js/wysiwyg/ui/framework/forms.ts +++ b/resources/js/wysiwyg/ui/framework/forms.ts @@ -5,8 +5,8 @@ import { EditorUiBuilderDefinition, isUiBuilderDefinition } from "./core"; -import {el} from "../../helpers"; import {uniqueId} from "../../../services/util"; +import {el} from "../../utils/dom"; export interface EditorFormFieldDefinition { label: string; diff --git a/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts b/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts index 2d995883a..f312294c5 100644 --- a/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts +++ b/resources/js/wysiwyg/ui/framework/helpers/table-resizer.ts @@ -1,8 +1,8 @@ import {$getNearestNodeFromDOMNode, LexicalEditor} from "lexical"; -import {el} from "../../../helpers"; import {MouseDragTracker, MouseDragTrackerDistance} from "./mouse-drag-tracker"; import {$getTableColumnWidth, $setTableColumnWidth, CustomTableNode} from "../../../nodes/custom-table"; import {TableRowNode} from "@lexical/table"; +import {el} from "../../../utils/dom"; type MarkerDomRecord = {x: HTMLElement, y: HTMLElement}; diff --git a/resources/js/wysiwyg/ui/framework/modals.ts b/resources/js/wysiwyg/ui/framework/modals.ts index 6b09accdc..1768f6f54 100644 --- a/resources/js/wysiwyg/ui/framework/modals.ts +++ b/resources/js/wysiwyg/ui/framework/modals.ts @@ -1,7 +1,7 @@ import {EditorForm, EditorFormDefinition} from "./forms"; -import {el} from "../../helpers"; import {EditorContainerUiElement} from "./core"; import closeIcon from "@icons/close.svg"; +import {el} from "../../utils/dom"; export interface EditorModalDefinition { title: string; diff --git a/resources/js/wysiwyg/ui/framework/toolbars.ts b/resources/js/wysiwyg/ui/framework/toolbars.ts index d7c481934..b4e49af95 100644 --- a/resources/js/wysiwyg/ui/framework/toolbars.ts +++ b/resources/js/wysiwyg/ui/framework/toolbars.ts @@ -1,5 +1,6 @@ import {EditorContainerUiElement, EditorUiElement} from "./core"; -import {el} from "../../helpers"; + +import {el} from "../../utils/dom"; export type EditorContextToolbarDefinition = { selector: string; diff --git a/resources/js/wysiwyg/ui/toolbars.ts b/resources/js/wysiwyg/ui/toolbars.ts index 3346e0a07..48e11837c 100644 --- a/resources/js/wysiwyg/ui/toolbars.ts +++ b/resources/js/wysiwyg/ui/toolbars.ts @@ -1,6 +1,5 @@ import {EditorButton} from "./framework/buttons"; import {EditorContainerUiElement, EditorSimpleClassContainer, EditorUiElement} from "./framework/core"; -import {$selectionContainsNodeType, el} from "../helpers"; import {EditorFormatMenu} from "./framework/blocks/format-menu"; import {FormatPreviewButton} from "./framework/blocks/format-preview-button"; import {EditorDropdownButton} from "./framework/blocks/dropdown-button"; @@ -65,6 +64,8 @@ import { unlink } from "./defaults/buttons/objects"; import {$isTableNode} from "@lexical/table"; +import {$selectionContainsNodeType} from "../utils/selection"; +import {el} from "../utils/dom"; export function getMainEditorFullToolbar(): EditorContainerUiElement { return new EditorSimpleClassContainer('editor-toolbar-main', [ diff --git a/resources/js/wysiwyg/actions.ts b/resources/js/wysiwyg/utils/actions.ts similarity index 97% rename from resources/js/wysiwyg/actions.ts rename to resources/js/wysiwyg/utils/actions.ts index a3d2f0ef6..ae829bae3 100644 --- a/resources/js/wysiwyg/actions.ts +++ b/resources/js/wysiwyg/utils/actions.ts @@ -1,8 +1,6 @@ import {$getRoot, $getSelection, LexicalEditor} from "lexical"; import {$generateHtmlFromNodes} from "@lexical/html"; -import {$htmlToBlockNodes} from "./helpers"; - - +import {$htmlToBlockNodes} from "./nodes"; export function setEditorContentFromHtml(editor: LexicalEditor, html: string) { editor.update(() => { diff --git a/resources/js/wysiwyg/utils/dom.ts b/resources/js/wysiwyg/utils/dom.ts new file mode 100644 index 000000000..dc0872e89 --- /dev/null +++ b/resources/js/wysiwyg/utils/dom.ts @@ -0,0 +1,24 @@ +export function el(tag: string, attrs: Record = {}, children: (string | HTMLElement)[] = []): HTMLElement { + const el = document.createElement(tag); + const attrKeys = Object.keys(attrs); + for (const attr of attrKeys) { + if (attrs[attr] !== null) { + el.setAttribute(attr, attrs[attr] as string); + } + } + + for (const child of children) { + if (typeof child === 'string') { + el.append(document.createTextNode(child)); + } else { + el.append(child); + } + } + + return el; +} + +export function htmlToDom(html: string): Document { + const parser = new DOMParser(); + return parser.parseFromString(html, 'text/html'); +} \ No newline at end of file diff --git a/resources/js/wysiwyg/utils/nodes.ts b/resources/js/wysiwyg/utils/nodes.ts new file mode 100644 index 000000000..8e6c66610 --- /dev/null +++ b/resources/js/wysiwyg/utils/nodes.ts @@ -0,0 +1,53 @@ +import {$getRoot, $isTextNode, LexicalEditor, LexicalNode} from "lexical"; +import {LexicalNodeMatcher} from "../nodes"; +import {$createCustomParagraphNode} from "../nodes/custom-paragraph"; +import {$generateNodesFromDOM} from "@lexical/html"; +import {htmlToDom} from "./dom"; + +function wrapTextNodes(nodes: LexicalNode[]): LexicalNode[] { + return nodes.map(node => { + if ($isTextNode(node)) { + const paragraph = $createCustomParagraphNode(); + paragraph.append(node); + return paragraph; + } + return node; + }); +} + +export function $htmlToBlockNodes(editor: LexicalEditor, html: string): LexicalNode[] { + const dom = htmlToDom(html); + const nodes = $generateNodesFromDOM(editor, dom); + return wrapTextNodes(nodes); +} + +export function $getParentOfType(node: LexicalNode, matcher: LexicalNodeMatcher): LexicalNode | null { + for (const parent of node.getParents()) { + if (matcher(parent)) { + return parent; + } + } + + return null; +} + +/** + * Get the nearest root/block level node for the given position. + */ +export function $getNearestBlockNodeForCoords(editor: LexicalEditor, x: number, y: number): LexicalNode | null { + // TODO - Take into account x for floated blocks? + const rootNodes = $getRoot().getChildren(); + for (const node of rootNodes) { + const nodeDom = editor.getElementByKey(node.__key); + if (!nodeDom) { + continue; + } + + const bounds = nodeDom.getBoundingClientRect(); + if (y <= bounds.bottom) { + return node; + } + } + + return null; +} \ No newline at end of file diff --git a/resources/js/wysiwyg/helpers.ts b/resources/js/wysiwyg/utils/selection.ts similarity index 53% rename from resources/js/wysiwyg/helpers.ts rename to resources/js/wysiwyg/utils/selection.ts index 07755f449..e34afbe36 100644 --- a/resources/js/wysiwyg/helpers.ts +++ b/resources/js/wysiwyg/utils/selection.ts @@ -1,64 +1,28 @@ import { $createNodeSelection, - $createParagraphNode, $getRoot, - $getSelection, $isElementNode, - $isTextNode, $setSelection, - BaseSelection, ElementFormatType, ElementNode, LexicalEditor, - LexicalNode, TextFormatType + $createParagraphNode, + $getRoot, + $getSelection, + $isElementNode, + $isTextNode, + $setSelection, + BaseSelection, + ElementFormatType, + ElementNode, + LexicalNode, + TextFormatType } from "lexical"; -import {LexicalElementNodeCreator, LexicalNodeMatcher} from "./nodes"; import {$findMatchingParent, $getNearestBlockElementAncestorOrThrow} from "@lexical/utils"; +import {LexicalElementNodeCreator, LexicalNodeMatcher} from "../nodes"; import {$setBlocksType} from "@lexical/selection"; -import {$createCustomParagraphNode} from "./nodes/custom-paragraph"; -import {$generateNodesFromDOM} from "@lexical/html"; -export function el(tag: string, attrs: Record = {}, children: (string|HTMLElement)[] = []): HTMLElement { - const el = document.createElement(tag); - const attrKeys = Object.keys(attrs); - for (const attr of attrKeys) { - if (attrs[attr] !== null) { - el.setAttribute(attr, attrs[attr] as string); - } - } +import {$getParentOfType} from "./nodes"; - for (const child of children) { - if (typeof child === 'string') { - el.append(document.createTextNode(child)); - } else { - el.append(child); - } - } - - return el; -} - -function htmlToDom(html: string): Document { - const parser = new DOMParser(); - return parser.parseFromString(html, 'text/html'); -} - -function wrapTextNodes(nodes: LexicalNode[]): LexicalNode[] { - return nodes.map(node => { - if ($isTextNode(node)) { - const paragraph = $createCustomParagraphNode(); - paragraph.append(node); - return paragraph; - } - return node; - }); -} - -export function $htmlToBlockNodes(editor: LexicalEditor, html: string): LexicalNode[] { - const dom = htmlToDom(html); - const nodes = $generateNodesFromDOM(editor, dom); - return wrapTextNodes(nodes); -} - -export function $selectionContainsNodeType(selection: BaseSelection|null, matcher: LexicalNodeMatcher): boolean { +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; } @@ -77,17 +41,7 @@ export function $getNodeFromSelection(selection: BaseSelection|null, matcher: Le return null; } -export function $getParentOfType(node: LexicalNode, matcher: LexicalNodeMatcher): LexicalNode|null { - for (const parent of node.getParents()) { - if (matcher(parent)) { - return parent; - } - } - - return null; -} - -export function $selectionContainsTextFormat(selection: BaseSelection|null, format: TextFormatType): boolean { +export function $selectionContainsTextFormat(selection: BaseSelection | null, format: TextFormatType): boolean { if (!selection) { return false; } @@ -140,7 +94,7 @@ export function $selectSingleNode(node: LexicalNode) { $setSelection(nodeSelection); } -export function $selectionContainsNode(selection: BaseSelection|null, node: LexicalNode): boolean { +export function $selectionContainsNode(selection: BaseSelection | null, node: LexicalNode): boolean { if (!selection) { return false; } @@ -155,7 +109,7 @@ export function $selectionContainsNode(selection: BaseSelection|null, node: Lexi return false; } -export function $selectionContainsElementFormat(selection: BaseSelection|null, format: ElementFormatType): boolean { +export function $selectionContainsElementFormat(selection: BaseSelection | null, format: ElementFormatType): boolean { const nodes = $getBlockElementNodesInSelection(selection); for (const node of nodes) { if (node.getFormatType() === format) { @@ -166,7 +120,7 @@ export function $selectionContainsElementFormat(selection: BaseSelection|null, f return false; } -export function $getBlockElementNodesInSelection(selection: BaseSelection|null): ElementNode[] { +export function $getBlockElementNodesInSelection(selection: BaseSelection | null): ElementNode[] { if (!selection) { return []; } @@ -175,7 +129,7 @@ export function $getBlockElementNodesInSelection(selection: BaseSelection|null): for (const node of selection.getNodes()) { const blockElement = $findMatchingParent(node, (node) => { return $isElementNode(node) && !node.isInline(); - }) as ElementNode|null; + }) as ElementNode | null; if (blockElement) { blockNodes.set(blockElement.getKey(), blockElement); @@ -183,25 +137,4 @@ export function $getBlockElementNodesInSelection(selection: BaseSelection|null): } return Array.from(blockNodes.values()); -} - -/** - * Get the nearest root/block level node for the given position. - */ -export function $getNearestBlockNodeForCoords(editor: LexicalEditor, x: number, y: number): LexicalNode|null { - // TODO - Take into account x for floated blocks? - const rootNodes = $getRoot().getChildren(); - for (const node of rootNodes) { - const nodeDom = editor.getElementByKey(node.__key); - if (!nodeDom) { - continue; - } - - const bounds = nodeDom.getBoundingClientRect(); - if (y <= bounds.bottom) { - return node; - } - } - - return null; } \ No newline at end of file