Lexical: Added block indenting capability

Needed a custom implementation due to hardcoded defaults for Lexical
default indenting.
This commit is contained in:
Dan Brown 2024-09-10 15:55:46 +01:00
parent 2036438203
commit 5083188ed8
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
11 changed files with 193 additions and 25 deletions

View File

@ -1,5 +1,6 @@
import {LexicalNode, Spread} from "lexical"; import {LexicalNode, Spread} from "lexical";
import type {SerializedElementNode} from "lexical/nodes/LexicalElementNode"; import type {SerializedElementNode} from "lexical/nodes/LexicalElementNode";
import {sizeToPixels} from "../utils/dom";
export type CommonBlockAlignment = 'left' | 'right' | 'center' | 'justify' | ''; export type CommonBlockAlignment = 'left' | 'right' | 'center' | 'justify' | '';
const validAlignments: CommonBlockAlignment[] = ['left', 'right', 'center', 'justify']; const validAlignments: CommonBlockAlignment[] = ['left', 'right', 'center', 'justify'];
@ -7,6 +8,7 @@ const validAlignments: CommonBlockAlignment[] = ['left', 'right', 'center', 'jus
export type SerializedCommonBlockNode = Spread<{ export type SerializedCommonBlockNode = Spread<{
id: string; id: string;
alignment: CommonBlockAlignment; alignment: CommonBlockAlignment;
inset: number;
}, SerializedElementNode> }, SerializedElementNode>
export interface NodeHasAlignment { export interface NodeHasAlignment {
@ -21,7 +23,13 @@ export interface NodeHasId {
getId(): string; getId(): string;
} }
interface CommonBlockInterface extends NodeHasId, NodeHasAlignment {} export interface NodeHasInset {
readonly __inset: number;
setInset(inset: number): void;
getInset(): number;
}
interface CommonBlockInterface extends NodeHasId, NodeHasAlignment, NodeHasInset {}
export function extractAlignmentFromElement(element: HTMLElement): CommonBlockAlignment { export function extractAlignmentFromElement(element: HTMLElement): CommonBlockAlignment {
const textAlignStyle: string = element.style.textAlign || ''; const textAlignStyle: string = element.style.textAlign || '';
@ -42,17 +50,24 @@ export function extractAlignmentFromElement(element: HTMLElement): CommonBlockAl
return ''; return '';
} }
export function extractInsetFromElement(element: HTMLElement): number {
const elemPadding: string = element.style.paddingLeft || '0';
return sizeToPixels(elemPadding);
}
export function setCommonBlockPropsFromElement(element: HTMLElement, node: CommonBlockInterface): void { export function setCommonBlockPropsFromElement(element: HTMLElement, node: CommonBlockInterface): void {
if (element.id) { if (element.id) {
node.setId(element.id); node.setId(element.id);
} }
node.setAlignment(extractAlignmentFromElement(element)); node.setAlignment(extractAlignmentFromElement(element));
node.setInset(extractInsetFromElement(element));
} }
export function commonPropertiesDifferent(nodeA: CommonBlockInterface, nodeB: CommonBlockInterface): boolean { export function commonPropertiesDifferent(nodeA: CommonBlockInterface, nodeB: CommonBlockInterface): boolean {
return nodeA.__id !== nodeB.__id || return nodeA.__id !== nodeB.__id ||
nodeA.__alignment !== nodeB.__alignment; nodeA.__alignment !== nodeB.__alignment ||
nodeA.__inset !== nodeB.__inset;
} }
export function updateElementWithCommonBlockProps(element: HTMLElement, node: CommonBlockInterface): void { export function updateElementWithCommonBlockProps(element: HTMLElement, node: CommonBlockInterface): void {
@ -63,6 +78,16 @@ export function updateElementWithCommonBlockProps(element: HTMLElement, node: Co
if (node.__alignment) { if (node.__alignment) {
element.classList.add('align-' + node.__alignment); element.classList.add('align-' + node.__alignment);
} }
if (node.__inset) {
element.style.paddingLeft = `${node.__inset}px`;
}
}
export function deserializeCommonBlockNode(serializedNode: SerializedCommonBlockNode, node: CommonBlockInterface): void {
node.setId(serializedNode.id);
node.setAlignment(serializedNode.alignment);
node.setInset(serializedNode.inset);
} }
export interface NodeHasSize { export interface NodeHasSize {

View File

@ -10,7 +10,7 @@ import {
import type {EditorConfig} from "lexical/LexicalEditor"; import type {EditorConfig} from "lexical/LexicalEditor";
import type {RangeSelection} from "lexical/LexicalSelection"; import type {RangeSelection} from "lexical/LexicalSelection";
import { import {
CommonBlockAlignment, commonPropertiesDifferent, CommonBlockAlignment, commonPropertiesDifferent, deserializeCommonBlockNode,
SerializedCommonBlockNode, SerializedCommonBlockNode,
setCommonBlockPropsFromElement, setCommonBlockPropsFromElement,
updateElementWithCommonBlockProps updateElementWithCommonBlockProps
@ -26,6 +26,7 @@ export class CalloutNode extends ElementNode {
__id: string = ''; __id: string = '';
__category: CalloutCategory = 'info'; __category: CalloutCategory = 'info';
__alignment: CommonBlockAlignment = ''; __alignment: CommonBlockAlignment = '';
__inset: number = 0;
static getType() { static getType() {
return 'callout'; return 'callout';
@ -35,6 +36,7 @@ export class CalloutNode extends ElementNode {
const newNode = new CalloutNode(node.__category, node.__key); const newNode = new CalloutNode(node.__category, node.__key);
newNode.__id = node.__id; newNode.__id = node.__id;
newNode.__alignment = node.__alignment; newNode.__alignment = node.__alignment;
newNode.__inset = node.__inset;
return newNode; return newNode;
} }
@ -73,6 +75,16 @@ export class CalloutNode extends ElementNode {
return self.__alignment; return self.__alignment;
} }
setInset(size: number) {
const self = this.getWritable();
self.__inset = size;
}
getInset(): number {
const self = this.getLatest();
return self.__inset;
}
createDOM(_config: EditorConfig, _editor: LexicalEditor) { createDOM(_config: EditorConfig, _editor: LexicalEditor) {
const element = document.createElement('p'); const element = document.createElement('p');
element.classList.add('callout', this.__category || ''); element.classList.add('callout', this.__category || '');
@ -141,13 +153,13 @@ export class CalloutNode extends ElementNode {
category: this.__category, category: this.__category,
id: this.__id, id: this.__id,
alignment: this.__alignment, alignment: this.__alignment,
inset: this.__inset,
}; };
} }
static importJSON(serializedNode: SerializedCalloutNode): CalloutNode { static importJSON(serializedNode: SerializedCalloutNode): CalloutNode {
const node = $createCalloutNode(serializedNode.category); const node = $createCalloutNode(serializedNode.category);
node.setId(serializedNode.id); deserializeCommonBlockNode(serializedNode, node);
node.setAlignment(serializedNode.alignment);
return node; return node;
} }

View File

@ -7,7 +7,7 @@ import {
import {EditorConfig} from "lexical/LexicalEditor"; import {EditorConfig} from "lexical/LexicalEditor";
import {HeadingNode, HeadingTagType, SerializedHeadingNode} from "@lexical/rich-text"; import {HeadingNode, HeadingTagType, SerializedHeadingNode} from "@lexical/rich-text";
import { import {
CommonBlockAlignment, commonPropertiesDifferent, CommonBlockAlignment, commonPropertiesDifferent, deserializeCommonBlockNode,
SerializedCommonBlockNode, SerializedCommonBlockNode,
setCommonBlockPropsFromElement, setCommonBlockPropsFromElement,
updateElementWithCommonBlockProps updateElementWithCommonBlockProps
@ -19,6 +19,7 @@ export type SerializedCustomHeadingNode = Spread<SerializedCommonBlockNode, Seri
export class CustomHeadingNode extends HeadingNode { export class CustomHeadingNode extends HeadingNode {
__id: string = ''; __id: string = '';
__alignment: CommonBlockAlignment = ''; __alignment: CommonBlockAlignment = '';
__inset: number = 0;
static getType() { static getType() {
return 'custom-heading'; return 'custom-heading';
@ -44,9 +45,20 @@ export class CustomHeadingNode extends HeadingNode {
return self.__alignment; return self.__alignment;
} }
setInset(size: number) {
const self = this.getWritable();
self.__inset = size;
}
getInset(): number {
const self = this.getLatest();
return self.__inset;
}
static clone(node: CustomHeadingNode) { static clone(node: CustomHeadingNode) {
const newNode = new CustomHeadingNode(node.__tag, node.__key); const newNode = new CustomHeadingNode(node.__tag, node.__key);
newNode.__alignment = node.__alignment; newNode.__alignment = node.__alignment;
newNode.__inset = node.__inset;
return newNode; return newNode;
} }
@ -68,13 +80,13 @@ export class CustomHeadingNode extends HeadingNode {
version: 1, version: 1,
id: this.__id, id: this.__id,
alignment: this.__alignment, alignment: this.__alignment,
inset: this.__inset,
}; };
} }
static importJSON(serializedNode: SerializedCustomHeadingNode): CustomHeadingNode { static importJSON(serializedNode: SerializedCustomHeadingNode): CustomHeadingNode {
const node = $createCustomHeadingNode(serializedNode.tag); const node = $createCustomHeadingNode(serializedNode.tag);
node.setId(serializedNode.id); deserializeCommonBlockNode(serializedNode, node);
node.setAlignment(serializedNode.alignment);
return node; return node;
} }

View File

@ -7,7 +7,7 @@ import {
} from "lexical"; } from "lexical";
import {EditorConfig} from "lexical/LexicalEditor"; import {EditorConfig} from "lexical/LexicalEditor";
import { import {
CommonBlockAlignment, commonPropertiesDifferent, CommonBlockAlignment, commonPropertiesDifferent, deserializeCommonBlockNode,
SerializedCommonBlockNode, SerializedCommonBlockNode,
setCommonBlockPropsFromElement, setCommonBlockPropsFromElement,
updateElementWithCommonBlockProps updateElementWithCommonBlockProps
@ -18,6 +18,7 @@ export type SerializedCustomParagraphNode = Spread<SerializedCommonBlockNode, Se
export class CustomParagraphNode extends ParagraphNode { export class CustomParagraphNode extends ParagraphNode {
__id: string = ''; __id: string = '';
__alignment: CommonBlockAlignment = ''; __alignment: CommonBlockAlignment = '';
__inset: number = 0;
static getType() { static getType() {
return 'custom-paragraph'; return 'custom-paragraph';
@ -43,10 +44,21 @@ export class CustomParagraphNode extends ParagraphNode {
return self.__alignment; return self.__alignment;
} }
setInset(size: number) {
const self = this.getWritable();
self.__inset = size;
}
getInset(): number {
const self = this.getLatest();
return self.__inset;
}
static clone(node: CustomParagraphNode): CustomParagraphNode { static clone(node: CustomParagraphNode): CustomParagraphNode {
const newNode = new CustomParagraphNode(node.__key); const newNode = new CustomParagraphNode(node.__key);
newNode.__id = node.__id; newNode.__id = node.__id;
newNode.__alignment = node.__alignment; newNode.__alignment = node.__alignment;
newNode.__inset = node.__inset;
return newNode; return newNode;
} }
@ -68,13 +80,13 @@ export class CustomParagraphNode extends ParagraphNode {
version: 1, version: 1,
id: this.__id, id: this.__id,
alignment: this.__alignment, alignment: this.__alignment,
inset: this.__inset,
}; };
} }
static importJSON(serializedNode: SerializedCustomParagraphNode): CustomParagraphNode { static importJSON(serializedNode: SerializedCustomParagraphNode): CustomParagraphNode {
const node = $createCustomParagraphNode(); const node = $createCustomParagraphNode();
node.setId(serializedNode.id); deserializeCommonBlockNode(serializedNode, node);
node.setAlignment(serializedNode.alignment);
return node; return node;
} }

View File

@ -7,7 +7,7 @@ import {
import {EditorConfig} from "lexical/LexicalEditor"; import {EditorConfig} from "lexical/LexicalEditor";
import {QuoteNode, SerializedQuoteNode} from "@lexical/rich-text"; import {QuoteNode, SerializedQuoteNode} from "@lexical/rich-text";
import { import {
CommonBlockAlignment, commonPropertiesDifferent, CommonBlockAlignment, commonPropertiesDifferent, deserializeCommonBlockNode,
SerializedCommonBlockNode, SerializedCommonBlockNode,
setCommonBlockPropsFromElement, setCommonBlockPropsFromElement,
updateElementWithCommonBlockProps updateElementWithCommonBlockProps
@ -19,6 +19,7 @@ export type SerializedCustomQuoteNode = Spread<SerializedCommonBlockNode, Serial
export class CustomQuoteNode extends QuoteNode { export class CustomQuoteNode extends QuoteNode {
__id: string = ''; __id: string = '';
__alignment: CommonBlockAlignment = ''; __alignment: CommonBlockAlignment = '';
__inset: number = 0;
static getType() { static getType() {
return 'custom-quote'; return 'custom-quote';
@ -44,10 +45,21 @@ export class CustomQuoteNode extends QuoteNode {
return self.__alignment; return self.__alignment;
} }
setInset(size: number) {
const self = this.getWritable();
self.__inset = size;
}
getInset(): number {
const self = this.getLatest();
return self.__inset;
}
static clone(node: CustomQuoteNode) { static clone(node: CustomQuoteNode) {
const newNode = new CustomQuoteNode(node.__key); const newNode = new CustomQuoteNode(node.__key);
newNode.__id = node.__id; newNode.__id = node.__id;
newNode.__alignment = node.__alignment; newNode.__alignment = node.__alignment;
newNode.__inset = node.__inset;
return newNode; return newNode;
} }
@ -68,13 +80,13 @@ export class CustomQuoteNode extends QuoteNode {
version: 1, version: 1,
id: this.__id, id: this.__id,
alignment: this.__alignment, alignment: this.__alignment,
inset: this.__inset,
}; };
} }
static importJSON(serializedNode: SerializedCustomQuoteNode): CustomQuoteNode { static importJSON(serializedNode: SerializedCustomQuoteNode): CustomQuoteNode {
const node = $createCustomQuoteNode(); const node = $createCustomQuoteNode();
node.setId(serializedNode.id); deserializeCommonBlockNode(serializedNode, node);
node.setAlignment(serializedNode.alignment);
return node; return node;
} }

View File

@ -5,7 +5,7 @@ import {EditorConfig} from "lexical/LexicalEditor";
import {el, extractStyleMapFromElement, StyleMap} from "../utils/dom"; import {el, extractStyleMapFromElement, StyleMap} from "../utils/dom";
import {getTableColumnWidths} from "../utils/tables"; import {getTableColumnWidths} from "../utils/tables";
import { import {
CommonBlockAlignment, CommonBlockAlignment, deserializeCommonBlockNode,
SerializedCommonBlockNode, SerializedCommonBlockNode,
setCommonBlockPropsFromElement, setCommonBlockPropsFromElement,
updateElementWithCommonBlockProps updateElementWithCommonBlockProps
@ -21,6 +21,7 @@ export class CustomTableNode extends TableNode {
__colWidths: string[] = []; __colWidths: string[] = [];
__styles: StyleMap = new Map; __styles: StyleMap = new Map;
__alignment: CommonBlockAlignment = ''; __alignment: CommonBlockAlignment = '';
__inset: number = 0;
static getType() { static getType() {
return 'custom-table'; return 'custom-table';
@ -46,6 +47,16 @@ export class CustomTableNode extends TableNode {
return self.__alignment; return self.__alignment;
} }
setInset(size: number) {
const self = this.getWritable();
self.__inset = size;
}
getInset(): number {
const self = this.getLatest();
return self.__inset;
}
setColWidths(widths: string[]) { setColWidths(widths: string[]) {
const self = this.getWritable(); const self = this.getWritable();
self.__colWidths = widths; self.__colWidths = widths;
@ -72,6 +83,7 @@ export class CustomTableNode extends TableNode {
newNode.__colWidths = node.__colWidths; newNode.__colWidths = node.__colWidths;
newNode.__styles = new Map(node.__styles); newNode.__styles = new Map(node.__styles);
newNode.__alignment = node.__alignment; newNode.__alignment = node.__alignment;
newNode.__inset = node.__inset;
return newNode; return newNode;
} }
@ -112,15 +124,15 @@ export class CustomTableNode extends TableNode {
colWidths: this.__colWidths, colWidths: this.__colWidths,
styles: Object.fromEntries(this.__styles), styles: Object.fromEntries(this.__styles),
alignment: this.__alignment, alignment: this.__alignment,
inset: this.__inset,
}; };
} }
static importJSON(serializedNode: SerializedCustomTableNode): CustomTableNode { static importJSON(serializedNode: SerializedCustomTableNode): CustomTableNode {
const node = $createCustomTableNode(); const node = $createCustomTableNode();
node.setId(serializedNode.id); deserializeCommonBlockNode(serializedNode, node);
node.setColWidths(serializedNode.colWidths); node.setColWidths(serializedNode.colWidths);
node.setStyles(new Map(Object.entries(serializedNode.styles))); node.setStyles(new Map(Object.entries(serializedNode.styles)));
node.setAlignment(serializedNode.alignment);
return node; return node;
} }

View File

@ -10,7 +10,7 @@ import type {EditorConfig} from "lexical/LexicalEditor";
import {el, setOrRemoveAttribute, sizeToPixels} from "../utils/dom"; import {el, setOrRemoveAttribute, sizeToPixels} from "../utils/dom";
import { import {
CommonBlockAlignment, CommonBlockAlignment, deserializeCommonBlockNode,
SerializedCommonBlockNode, SerializedCommonBlockNode,
setCommonBlockPropsFromElement, setCommonBlockPropsFromElement,
updateElementWithCommonBlockProps updateElementWithCommonBlockProps
@ -80,6 +80,7 @@ export class MediaNode extends ElementNode {
__tag: MediaNodeTag; __tag: MediaNodeTag;
__attributes: Record<string, string> = {}; __attributes: Record<string, string> = {};
__sources: MediaNodeSource[] = []; __sources: MediaNodeSource[] = [];
__inset: number = 0;
static getType() { static getType() {
return 'media'; return 'media';
@ -91,6 +92,7 @@ export class MediaNode extends ElementNode {
newNode.__sources = node.__sources.map(s => Object.assign({}, s)); newNode.__sources = node.__sources.map(s => Object.assign({}, s));
newNode.__id = node.__id; newNode.__id = node.__id;
newNode.__alignment = node.__alignment; newNode.__alignment = node.__alignment;
newNode.__inset = node.__inset;
return newNode; return newNode;
} }
@ -168,6 +170,16 @@ export class MediaNode extends ElementNode {
return self.__alignment; return self.__alignment;
} }
setInset(size: number) {
const self = this.getWritable();
self.__inset = size;
}
getInset(): number {
const self = this.getLatest();
return self.__inset;
}
setHeight(height: number): void { setHeight(height: number): void {
if (!height) { if (!height) {
return; return;
@ -251,6 +263,10 @@ export class MediaNode extends ElementNode {
} }
} }
if (prevNode.__inset !== this.__inset) {
dom.style.paddingLeft = `${this.__inset}px`;
}
return false; return false;
} }
@ -290,6 +306,7 @@ export class MediaNode extends ElementNode {
version: 1, version: 1,
id: this.__id, id: this.__id,
alignment: this.__alignment, alignment: this.__alignment,
inset: this.__inset,
tag: this.__tag, tag: this.__tag,
attributes: this.__attributes, attributes: this.__attributes,
sources: this.__sources, sources: this.__sources,
@ -298,8 +315,7 @@ export class MediaNode extends ElementNode {
static importJSON(serializedNode: SerializedMediaNode): MediaNode { static importJSON(serializedNode: SerializedMediaNode): MediaNode {
const node = $createMediaNode(serializedNode.tag); const node = $createMediaNode(serializedNode.tag);
node.setId(serializedNode.id); deserializeCommonBlockNode(serializedNode, node);
node.setAlignment(serializedNode.alignment);
return node; return node;
} }

View File

@ -6,6 +6,7 @@
## Main Todo ## Main Todo
- Align list nesting with old editor
- Mac: Shortcut support via command. - Mac: Shortcut support via command.
## Secondary Todo ## Secondary Todo

View File

@ -1,12 +1,24 @@
import {$isListNode, ListNode, ListType} from "@lexical/list"; import {$isListNode, ListNode, ListType} from "@lexical/list";
import {EditorButtonDefinition} from "../../framework/buttons"; import {EditorButtonDefinition} from "../../framework/buttons";
import {EditorUiContext} from "../../framework/core"; import {EditorUiContext} from "../../framework/core";
import {BaseSelection, LexicalNode} from "lexical"; import {
BaseSelection,
LexicalEditor,
LexicalNode,
} from "lexical";
import listBulletIcon from "@icons/editor/list-bullet.svg"; import listBulletIcon from "@icons/editor/list-bullet.svg";
import listNumberedIcon from "@icons/editor/list-numbered.svg"; import listNumberedIcon from "@icons/editor/list-numbered.svg";
import listCheckIcon from "@icons/editor/list-check.svg"; import listCheckIcon from "@icons/editor/list-check.svg";
import {$selectionContainsNodeType} from "../../../utils/selection"; import indentIncreaseIcon from "@icons/editor/indent-increase.svg";
import indentDecreaseIcon from "@icons/editor/indent-decrease.svg";
import {
$getBlockElementNodesInSelection,
$selectionContainsNodeType,
$toggleSelection,
getLastSelection
} from "../../../utils/selection";
import {toggleSelectionAsList} from "../../../utils/formats"; import {toggleSelectionAsList} from "../../../utils/formats";
import {nodeHasInset} from "../../../utils/nodes";
function buildListButton(label: string, type: ListType, icon: string): EditorButtonDefinition { function buildListButton(label: string, type: ListType, icon: string): EditorButtonDefinition {
@ -27,3 +39,45 @@ function buildListButton(label: string, type: ListType, icon: string): EditorBut
export const bulletList: EditorButtonDefinition = buildListButton('Bullet list', 'bullet', listBulletIcon); export const bulletList: EditorButtonDefinition = buildListButton('Bullet list', 'bullet', listBulletIcon);
export const numberList: EditorButtonDefinition = buildListButton('Numbered list', 'number', listNumberedIcon); export const numberList: EditorButtonDefinition = buildListButton('Numbered list', 'number', listNumberedIcon);
export const taskList: EditorButtonDefinition = buildListButton('Task list', 'check', listCheckIcon); export const taskList: EditorButtonDefinition = buildListButton('Task list', 'check', listCheckIcon);
function setInsetForSelection(editor: LexicalEditor, change: number): void {
const selection = getLastSelection(editor);
const elements = $getBlockElementNodesInSelection(selection);
for (const node of elements) {
if (nodeHasInset(node)) {
const currentInset = node.getInset();
const newInset = Math.min(Math.max(currentInset + change, 0), 500);
node.setInset(newInset)
}
}
$toggleSelection(editor);
}
export const indentIncrease: EditorButtonDefinition = {
label: 'Increase indent',
icon: indentIncreaseIcon,
action(context: EditorUiContext) {
context.editor.update(() => {
setInsetForSelection(context.editor, 40);
});
},
isActive() {
return false;
}
};
export const indentDecrease: EditorButtonDefinition = {
label: 'Decrease indent',
icon: indentDecreaseIcon,
action(context: EditorUiContext) {
context.editor.update(() => {
setInsetForSelection(context.editor, -40);
});
},
isActive() {
return false;
}
};

View File

@ -52,7 +52,13 @@ import {
underline underline
} from "./defaults/buttons/inline-formats"; } from "./defaults/buttons/inline-formats";
import {alignCenter, alignJustify, alignLeft, alignRight} from "./defaults/buttons/alignments"; import {alignCenter, alignJustify, alignLeft, alignRight} from "./defaults/buttons/alignments";
import {bulletList, numberList, taskList} from "./defaults/buttons/lists"; import {
bulletList,
indentDecrease,
indentIncrease,
numberList,
taskList
} from "./defaults/buttons/lists";
import { import {
codeBlock, codeBlock,
details, details,
@ -119,10 +125,12 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
]), ]),
// Lists // Lists
new EditorOverflowContainer(3, [ new EditorOverflowContainer(5, [
new EditorButton(bulletList), new EditorButton(bulletList),
new EditorButton(numberList), new EditorButton(numberList),
new EditorButton(taskList), new EditorButton(taskList),
new EditorButton(indentDecrease),
new EditorButton(indentIncrease),
]), ]),
// Insert types // Insert types

View File

@ -11,7 +11,7 @@ import {LexicalNodeMatcher} from "../nodes";
import {$createCustomParagraphNode} from "../nodes/custom-paragraph"; import {$createCustomParagraphNode} from "../nodes/custom-paragraph";
import {$generateNodesFromDOM} from "@lexical/html"; import {$generateNodesFromDOM} from "@lexical/html";
import {htmlToDom} from "./dom"; import {htmlToDom} from "./dom";
import {NodeHasAlignment} from "../nodes/_common"; import {NodeHasAlignment, NodeHasInset} from "../nodes/_common";
import {$findMatchingParent} from "@lexical/utils"; import {$findMatchingParent} from "@lexical/utils";
function wrapTextNodes(nodes: LexicalNode[]): LexicalNode[] { function wrapTextNodes(nodes: LexicalNode[]): LexicalNode[] {
@ -96,4 +96,8 @@ export function $getNearestNodeBlockParent(node: LexicalNode): LexicalNode|null
export function nodeHasAlignment(node: object): node is NodeHasAlignment { export function nodeHasAlignment(node: object): node is NodeHasAlignment {
return '__alignment' in node; return '__alignment' in node;
}
export function nodeHasInset(node: object): node is NodeHasInset {
return '__inset' in node;
} }