Lexical: Split helpers to utils, refactored files
This commit is contained in:
		
							parent
							
								
									e94ad78ea7
								
							
						
					
					
						commit
						efec752985
					
				|  | @ -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<string, any> = {}): SimpleWysiwygEditorInterface { | ||||
|     const config: CreateEditorArgs = { | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 { | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 = { | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import { | |||
|     insertHtmlIntoEditor, | ||||
|     prependHtmlToEditor, | ||||
|     setEditorContentFromHtml | ||||
| } from "./actions"; | ||||
| } from "../utils/actions"; | ||||
| 
 | ||||
| type EditorEventContent = { | ||||
|     html: string; | ||||
|  | @ -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; | ||||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 = { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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', | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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', | ||||
|  |  | |||
|  | @ -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', | ||||
|  |  | |||
|  | @ -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', | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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}; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import {EditorContainerUiElement, EditorUiElement} from "./core"; | ||||
| import {el} from "../../helpers"; | ||||
| 
 | ||||
| import {el} from "../../utils/dom"; | ||||
| 
 | ||||
| export type EditorContextToolbarDefinition = { | ||||
|     selector: string; | ||||
|  |  | |||
|  | @ -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', [ | ||||
|  |  | |||
|  | @ -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(() => { | ||||
|  | @ -0,0 +1,24 @@ | |||
| export function el(tag: string, attrs: Record<string, string | null> = {}, 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'); | ||||
| } | ||||
|  | @ -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; | ||||
| } | ||||
|  | @ -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<string, string|null> = {}, 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; | ||||
| } | ||||
		Loading…
	
		Reference in New Issue