mirror of
https://github.com/facebook/lexical.git
synced 2025-05-17 15:18:47 +08:00
1229 lines
41 KiB
Plaintext
1229 lines
41 KiB
Plaintext
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow strict
|
|
*/
|
|
|
|
/**
|
|
* LexicalCommands
|
|
*/
|
|
|
|
export type LexicalCommand<P> = $ReadOnly<{type?: string}>;
|
|
|
|
declare export var SELECTION_CHANGE_COMMAND: LexicalCommand<void>;
|
|
declare export var CLICK_COMMAND: LexicalCommand<MouseEvent>;
|
|
declare export var DELETE_CHARACTER_COMMAND: LexicalCommand<boolean>;
|
|
declare export var INSERT_LINE_BREAK_COMMAND: LexicalCommand<boolean>;
|
|
declare export var INSERT_PARAGRAPH_COMMAND: LexicalCommand<void>;
|
|
declare export var CONTROLLED_TEXT_INSERTION_COMMAND: LexicalCommand<string>;
|
|
declare export var PASTE_COMMAND: LexicalCommand<ClipboardEvent>;
|
|
declare export var REMOVE_TEXT_COMMAND: LexicalCommand<InputEvent | null>;
|
|
declare export var DELETE_WORD_COMMAND: LexicalCommand<boolean>;
|
|
declare export var DELETE_LINE_COMMAND: LexicalCommand<boolean>;
|
|
declare export var FORMAT_TEXT_COMMAND: LexicalCommand<TextFormatType>;
|
|
declare export var UNDO_COMMAND: LexicalCommand<void>;
|
|
declare export var REDO_COMMAND: LexicalCommand<void>;
|
|
declare export var KEY_DOWN_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var KEY_ARROW_RIGHT_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var KEY_ARROW_LEFT_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var KEY_ARROW_UP_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var KEY_ARROW_DOWN_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var KEY_ENTER_COMMAND: LexicalCommand<KeyboardEvent | null>;
|
|
declare export var KEY_SPACE_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var KEY_BACKSPACE_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var KEY_ESCAPE_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var KEY_DELETE_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var KEY_TAB_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var INSERT_TAB_COMMAND: LexicalCommand<void>;
|
|
declare export var KEY_MODIFIER_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var INDENT_CONTENT_COMMAND: LexicalCommand<void>;
|
|
declare export var OUTDENT_CONTENT_COMMAND: LexicalCommand<void>;
|
|
declare export var DROP_COMMAND: LexicalCommand<DragEvent>;
|
|
declare export var FORMAT_ELEMENT_COMMAND: LexicalCommand<ElementFormatType>;
|
|
declare export var DRAGSTART_COMMAND: LexicalCommand<DragEvent>;
|
|
declare export var DRAGOVER_COMMAND: LexicalCommand<DragEvent>;
|
|
declare export var DRAGEND_COMMAND: LexicalCommand<DragEvent>;
|
|
declare export var COPY_COMMAND: LexicalCommand<
|
|
ClipboardEvent | KeyboardEvent | null,
|
|
>;
|
|
declare export var CUT_COMMAND: LexicalCommand<
|
|
ClipboardEvent | KeyboardEvent | null,
|
|
>;
|
|
declare export var CLEAR_EDITOR_COMMAND: LexicalCommand<void>;
|
|
declare export var CLEAR_HISTORY_COMMAND: LexicalCommand<void>;
|
|
declare export var CAN_REDO_COMMAND: LexicalCommand<boolean>;
|
|
declare export var CAN_UNDO_COMMAND: LexicalCommand<boolean>;
|
|
declare export var FOCUS_COMMAND: LexicalCommand<FocusEvent>;
|
|
declare export var BLUR_COMMAND: LexicalCommand<FocusEvent>;
|
|
declare export var SELECT_ALL_COMMAND: LexicalCommand<KeyboardEvent>;
|
|
declare export var MOVE_TO_END: LexicalCommand<KeyboardEvent>;
|
|
declare export var MOVE_TO_START: LexicalCommand<KeyboardEvent>;
|
|
declare export var SELECTION_INSERT_CLIPBOARD_NODES_COMMAND: LexicalCommand<{
|
|
nodes: Array<LexicalNode>;
|
|
selection: BaseSelection;
|
|
}>;
|
|
|
|
declare export function createCommand<T>(type?: string): LexicalCommand<T>;
|
|
|
|
/**
|
|
* LexicalConstants
|
|
*/
|
|
|
|
declare export var IS_ALL_FORMATTING: number;
|
|
declare export var IS_BOLD: number;
|
|
declare export var IS_CODE: number;
|
|
declare export var IS_HIGHLIGHT: number;
|
|
declare export var IS_ITALIC: number;
|
|
declare export var IS_STRIKETHROUGH: number;
|
|
declare export var IS_SUBSCRIPT: number;
|
|
declare export var IS_SUPERSCRIPT: number;
|
|
declare export var IS_UNDERLINE: number;
|
|
declare export var IS_UPPERCASE: number;
|
|
declare export var IS_LOWERCASE: number;
|
|
declare export var IS_CAPITALIZE: number;
|
|
declare export var TEXT_TYPE_TO_FORMAT: Record<TextFormatType | string, number>;
|
|
|
|
/**
|
|
* LexicalEditor
|
|
*/
|
|
type IntentionallyMarkedAsDirtyElement = boolean;
|
|
|
|
type MutationListeners = Map<MutationListener, Class<LexicalNode>>;
|
|
export type NodeMutation = 'created' | 'updated' | 'destroyed';
|
|
type UpdateListener = ({
|
|
tags: Set<string>,
|
|
prevEditorState: EditorState,
|
|
editorState: EditorState,
|
|
dirtyLeaves: Set<NodeKey>,
|
|
dirtyElements: Map<NodeKey, IntentionallyMarkedAsDirtyElement>,
|
|
normalizedNodes: Set<NodeKey>,
|
|
}) => void;
|
|
type DecoratorListener = (decorator: {
|
|
// $FlowFixMe: defined by user
|
|
[NodeKey]: any,
|
|
}) => void;
|
|
type RootListener = (
|
|
rootElement: null | HTMLElement,
|
|
prevRootElement: null | HTMLElement,
|
|
) => void;
|
|
type TextContentListener = (text: string) => void;
|
|
type ErrorHandler = (error: Error) => void;
|
|
export type MutationListener = (
|
|
nodes: Map<NodeKey, NodeMutation>,
|
|
{
|
|
updateTags: Set<string>,
|
|
dirtyLeaves: Set<string>,
|
|
prevEditorState: EditorState,
|
|
},
|
|
) => void;
|
|
export type MutationListenerOptions = {
|
|
skipInitialization?: boolean;
|
|
};
|
|
export type EditableListener = (editable: boolean) => void;
|
|
type Listeners = {
|
|
decorator: Set<DecoratorListener>,
|
|
mutation: MutationListeners,
|
|
textcontent: Set<TextContentListener>,
|
|
root: Set<RootListener>,
|
|
update: Set<UpdateListener>,
|
|
};
|
|
export type CommandListener<P> = (payload: P, editor: LexicalEditor) => boolean;
|
|
// $FlowFixMe[unclear-type]
|
|
type Commands = Map<LexicalCommand<any>, Array<Set<CommandListener<any>>>>;
|
|
type RegisteredNodes = Map<string, RegisteredNode>;
|
|
type RegisteredNode = {
|
|
klass: Class<LexicalNode>,
|
|
transforms: Set<Transform<LexicalNode>>,
|
|
};
|
|
export type Transform<T> = (node: T) => void;
|
|
|
|
type DOMConversionCache = Map<
|
|
string,
|
|
Array<(node: Node) => DOMConversion | null>,
|
|
>;
|
|
|
|
declare export class LexicalEditor {
|
|
_parentEditor: null | LexicalEditor;
|
|
_rootElement: null | HTMLElement;
|
|
_editorState: EditorState;
|
|
_htmlConversions: DOMConversionCache;
|
|
_pendingEditorState: null | EditorState;
|
|
_compositionKey: null | NodeKey;
|
|
_deferred: Array<() => void>;
|
|
_updates: Array<[() => void, void | EditorUpdateOptions]>;
|
|
_updating: boolean;
|
|
_keyToDOMMap: Map<NodeKey, HTMLElement>;
|
|
_listeners: Listeners;
|
|
_commands: Commands;
|
|
_nodes: RegisteredNodes;
|
|
_onError: ErrorHandler;
|
|
_decorators: {
|
|
[NodeKey]: mixed,
|
|
};
|
|
_pendingDecorators: null | {
|
|
[NodeKey]: mixed,
|
|
};
|
|
_config: EditorConfig;
|
|
_dirtyType: 0 | 1 | 2;
|
|
_cloneNotNeeded: Set<NodeKey>;
|
|
_dirtyLeaves: Set<NodeKey>;
|
|
_dirtyElements: Map<NodeKey, IntentionallyMarkedAsDirtyElement>;
|
|
_normalizedNodes: Set<NodeKey>;
|
|
_updateTags: Set<string>;
|
|
_observer: null | MutationObserver;
|
|
_key: string;
|
|
_editable: boolean;
|
|
_headless: boolean;
|
|
isComposing(): boolean;
|
|
registerUpdateListener(listener: UpdateListener): () => void;
|
|
registerRootListener(listener: RootListener): () => void;
|
|
registerDecoratorListener(listener: DecoratorListener): () => void;
|
|
registerTextContentListener(listener: TextContentListener): () => void;
|
|
registerCommand<P>(
|
|
command: LexicalCommand<P>,
|
|
listener: CommandListener<P>,
|
|
priority: CommandListenerPriority,
|
|
): () => void;
|
|
registerEditableListener(listener: EditableListener): () => void;
|
|
registerMutationListener(
|
|
klass: Class<LexicalNode>,
|
|
listener: MutationListener,
|
|
options?: MutationListenerOptions,
|
|
): () => void;
|
|
registerNodeTransform<T: LexicalNode>(
|
|
klass: Class<T>,
|
|
listener: Transform<T>,
|
|
): () => void;
|
|
dispatchCommand<P>(command: LexicalCommand<P>, payload: P): boolean;
|
|
hasNodes(nodes: Array<Class<LexicalNode>>): boolean;
|
|
getKey(): string;
|
|
getDecorators<X>(): {
|
|
[NodeKey]: X,
|
|
};
|
|
getRootElement(): null | HTMLElement;
|
|
setRootElement(rootElement: null | HTMLElement): void;
|
|
getElementByKey(key: NodeKey): null | HTMLElement;
|
|
getEditorState(): EditorState;
|
|
setEditorState(editorState: EditorState, options?: EditorSetOptions): void;
|
|
parseEditorState(
|
|
maybeStringifiedEditorState: string | SerializedEditorState,
|
|
updateFn?: () => void,
|
|
): EditorState;
|
|
read<V>(callbackFn: () => V, options?: EditorReadOptions): V;
|
|
update(updateFn: () => void, options?: EditorUpdateOptions): boolean;
|
|
focus(callbackFn?: () => void, options?: EditorFocusOptions): void;
|
|
blur(): void;
|
|
isEditable(): boolean;
|
|
setEditable(editable: boolean): void;
|
|
toJSON(): SerializedEditor;
|
|
}
|
|
type EditorReadOptions = {
|
|
pending?: boolean,
|
|
};
|
|
type EditorUpdateOptions = {
|
|
onUpdate?: () => void,
|
|
tag?: string | Array<string>,
|
|
skipTransforms?: true,
|
|
discrete?: true,
|
|
};
|
|
type EditorFocusOptions = {
|
|
defaultSelection?: 'rootStart' | 'rootEnd',
|
|
};
|
|
type EditorSetOptions = {
|
|
tag?: string,
|
|
};
|
|
type EditorThemeClassName = string;
|
|
type TextNodeThemeClasses = {
|
|
base?: EditorThemeClassName,
|
|
bold?: EditorThemeClassName,
|
|
underline?: EditorThemeClassName,
|
|
strikethrough?: EditorThemeClassName,
|
|
underlineStrikethrough?: EditorThemeClassName,
|
|
italic?: EditorThemeClassName,
|
|
code?: EditorThemeClassName,
|
|
subscript?: EditorThemeClassName,
|
|
superscript?: EditorThemeClassName,
|
|
lowercase?: EditorThemeClassName,
|
|
uppercase?: EditorThemeClassName,
|
|
capitalize?: EditorThemeClassName,
|
|
};
|
|
export type EditorThemeClasses = {
|
|
characterLimit?: EditorThemeClassName,
|
|
ltr?: EditorThemeClassName,
|
|
rtl?: EditorThemeClassName,
|
|
text?: TextNodeThemeClasses,
|
|
paragraph?: EditorThemeClassName,
|
|
image?: EditorThemeClassName,
|
|
list?: {
|
|
ul?: EditorThemeClassName,
|
|
ulDepth?: Array<EditorThemeClassName>,
|
|
ol?: EditorThemeClassName,
|
|
olDepth?: Array<EditorThemeClassName>,
|
|
checklist?: EditorThemeClassName,
|
|
listitem?: EditorThemeClassName,
|
|
listitemChecked?: EditorThemeClassName,
|
|
listitemUnchecked?: EditorThemeClassName,
|
|
nested?: {
|
|
list?: EditorThemeClassName,
|
|
listitem?: EditorThemeClassName,
|
|
},
|
|
},
|
|
table?: EditorThemeClassName,
|
|
tableRow?: EditorThemeClassName,
|
|
tableCell?: EditorThemeClassName,
|
|
tableCellHeader?: EditorThemeClassName,
|
|
mark?: EditorThemeClassName,
|
|
markOverlap?: EditorThemeClassName,
|
|
link?: EditorThemeClassName,
|
|
quote?: EditorThemeClassName,
|
|
code?: EditorThemeClassName,
|
|
codeHighlight?: {[string]: EditorThemeClassName},
|
|
hashtag?: EditorThemeClassName,
|
|
heading?: {
|
|
h1?: EditorThemeClassName,
|
|
h2?: EditorThemeClassName,
|
|
h3?: EditorThemeClassName,
|
|
h4?: EditorThemeClassName,
|
|
h5?: EditorThemeClassName,
|
|
h6?: EditorThemeClassName,
|
|
},
|
|
embedBlock?: {
|
|
base?: EditorThemeClassName,
|
|
focus?: EditorThemeClassName,
|
|
},
|
|
// Handle other generic values
|
|
[string]: EditorThemeClassName | {[string]: EditorThemeClassName},
|
|
};
|
|
export type EditorConfig = {
|
|
theme: EditorThemeClasses,
|
|
namespace: string,
|
|
disableEvents?: boolean,
|
|
};
|
|
export type CommandListenerPriority = 0 | 1 | 2 | 3 | 4;
|
|
export const COMMAND_PRIORITY_EDITOR = 0;
|
|
export const COMMAND_PRIORITY_LOW = 1;
|
|
export const COMMAND_PRIORITY_NORMAL = 2;
|
|
export const COMMAND_PRIORITY_HIGH = 3;
|
|
export const COMMAND_PRIORITY_CRITICAL = 4;
|
|
|
|
export type LexicalNodeReplacement = {
|
|
replace: Class<LexicalNode>,
|
|
with: (node: LexicalNode) => LexicalNode,
|
|
withKlass?: Class<LexicalNode>,
|
|
};
|
|
|
|
export type HTMLConfig = {
|
|
export?: Map<
|
|
Class<LexicalNode>,
|
|
(editor: LexicalEditor, target: LexicalNode) => DOMExportOutput,
|
|
>,
|
|
import?: DOMConversionMap,
|
|
};
|
|
|
|
declare export function createEditor(editorConfig?: {
|
|
editorState?: EditorState,
|
|
namespace: string,
|
|
theme?: EditorThemeClasses,
|
|
parentEditor?: LexicalEditor,
|
|
nodes?: $ReadOnlyArray<Class<LexicalNode> | LexicalNodeReplacement>,
|
|
onError: (error: Error) => void,
|
|
disableEvents?: boolean,
|
|
editable?: boolean,
|
|
html?: HTMLConfig,
|
|
}): LexicalEditor;
|
|
|
|
/**
|
|
* LexicalEditorState
|
|
*/
|
|
|
|
export interface EditorState {
|
|
_nodeMap: NodeMap;
|
|
_selection: null | BaseSelection;
|
|
_flushSync: boolean;
|
|
_readOnly: boolean;
|
|
constructor(nodeMap: NodeMap, selection?: BaseSelection | null): void;
|
|
isEmpty(): boolean;
|
|
read<V>(callbackFn: () => V, options?: EditorStateReadOptions): V;
|
|
toJSON(): SerializedEditorState;
|
|
clone(selection?: BaseSelection | null): EditorState;
|
|
}
|
|
type EditorStateReadOptions = {
|
|
editor?: LexicalEditor | null;
|
|
}
|
|
|
|
/**
|
|
* LexicalNode
|
|
*/
|
|
|
|
export type DOMConversion = {
|
|
conversion: DOMConversionFn,
|
|
priority: 0 | 1 | 2 | 3 | 4,
|
|
};
|
|
export type DOMConversionFn = (element: Node) => DOMConversionOutput | null;
|
|
export type DOMChildConversion = (
|
|
lexicalNode: LexicalNode,
|
|
parentLexicalNode: ?LexicalNode | null,
|
|
) => LexicalNode | null | void;
|
|
export type DOMConversionMap = {
|
|
[NodeName]: <T: HTMLElement>(node: T) => DOMConversion | null,
|
|
};
|
|
type NodeName = string;
|
|
export type DOMConversionOutput = {
|
|
after?: (childLexicalNodes: Array<LexicalNode>) => Array<LexicalNode>,
|
|
forChild?: DOMChildConversion,
|
|
node: null | LexicalNode | Array<LexicalNode>,
|
|
};
|
|
export type DOMExportOutput = {
|
|
after?: (generatedElement: ?HTMLElement) => ?HTMLElement,
|
|
element?: HTMLElement | null,
|
|
};
|
|
export type NodeKey = string;
|
|
declare export class LexicalNode {
|
|
__type: string;
|
|
__key: NodeKey;
|
|
__parent: null | NodeKey;
|
|
__next: null | NodeKey;
|
|
__prev: null | NodeKey;
|
|
static getType(): string;
|
|
static clone(data: $FlowFixMe): LexicalNode;
|
|
static importDOM(): DOMConversionMap | null;
|
|
constructor(key?: NodeKey): void;
|
|
exportDOM(editor: LexicalEditor): DOMExportOutput;
|
|
exportJSON(): SerializedLexicalNode;
|
|
updateFromJSON(serializedNode: $FlowFixMe): this;
|
|
getType(): string;
|
|
isAttached(): boolean;
|
|
isSelected(): boolean;
|
|
getKey(): NodeKey;
|
|
getIndexWithinParent(): number;
|
|
getParent<T: ElementNode>(): T | null;
|
|
getParentOrThrow<T: ElementNode>(): T;
|
|
getTopLevelElement(): DecoratorNode<mixed> | ElementNode | null;
|
|
getTopLevelElementOrThrow(): DecoratorNode<mixed> | ElementNode;
|
|
getParents<T: ElementNode>(): Array<T>;
|
|
getParentKeys(): Array<NodeKey>;
|
|
getPreviousSibling<T: LexicalNode>(): T | null;
|
|
getPreviousSiblings<T: LexicalNode>(): Array<T>;
|
|
getNextSibling<T: LexicalNode>(): T | null;
|
|
getNextSiblings<T: LexicalNode>(): Array<T>;
|
|
getCommonAncestor<T: ElementNode>(node: LexicalNode): T | null;
|
|
is(object: ?LexicalNode): boolean;
|
|
isBefore(targetNode: LexicalNode): boolean;
|
|
isParentOf(targetNode: LexicalNode): boolean;
|
|
getNodesBetween(targetNode: LexicalNode): Array<LexicalNode>;
|
|
isDirty(): boolean;
|
|
// $FlowFixMe[incompatible-type]
|
|
getLatest<T: LexicalNode>(this: T): T;
|
|
// $FlowFixMe[incompatible-type]
|
|
getWritable<T: LexicalNode>(this: T): T;
|
|
getTextContent(includeDirectionless?: boolean): string;
|
|
getTextContentSize(includeDirectionless?: boolean): number;
|
|
createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement;
|
|
updateDOM(
|
|
// $FlowFixMe[unclear-type]
|
|
prevNode: any,
|
|
dom: HTMLElement,
|
|
config: EditorConfig,
|
|
): boolean;
|
|
remove(preserveEmptyParent?: boolean): void;
|
|
replace<N: LexicalNode>(replaceWith: N): N;
|
|
insertAfter(
|
|
nodeToInsert: LexicalNode,
|
|
restoreSelection?: boolean,
|
|
): LexicalNode;
|
|
insertBefore(
|
|
nodeToInsert: LexicalNode,
|
|
restoreSelection?: boolean,
|
|
): LexicalNode;
|
|
selectPrevious(anchorOffset?: number, focusOffset?: number): RangeSelection;
|
|
selectNext(anchorOffset?: number, focusOffset?: number): RangeSelection;
|
|
markDirty(): void;
|
|
reconcileObservedMutation(dom: HTMLElement, editor: LexicalEditor): void;
|
|
}
|
|
export type NodeMap = Map<NodeKey, LexicalNode>;
|
|
|
|
/**
|
|
* LexicalSelection
|
|
*/
|
|
|
|
declare export function $isBlockElementNode(
|
|
node: ?LexicalNode,
|
|
): node is ElementNode;
|
|
|
|
export interface BaseSelection {
|
|
dirty: boolean;
|
|
clone(): BaseSelection;
|
|
extract(): Array<LexicalNode>;
|
|
getNodes(): Array<LexicalNode>;
|
|
getStartEndPoints(): null | [PointType, PointType];
|
|
getTextContent(): string;
|
|
insertRawText(text: string): void;
|
|
is(selection: null | BaseSelection): boolean;
|
|
isBackward(): boolean;
|
|
isCollapsed(): boolean;
|
|
insertText(text: string): void;
|
|
insertNodes(nodes: Array<LexicalNode>): void;
|
|
getCachedNodes(): null | Array<LexicalNode>;
|
|
setCachedNodes(nodes: null | Array<LexicalNode>): void;
|
|
}
|
|
|
|
declare export class NodeSelection implements BaseSelection {
|
|
_nodes: Set<NodeKey>;
|
|
dirty: boolean;
|
|
constructor(objects: Set<NodeKey>): void;
|
|
is(selection: null | BaseSelection): boolean;
|
|
isBackward(): boolean;
|
|
isCollapsed(): boolean;
|
|
add(key: NodeKey): void;
|
|
delete(key: NodeKey): void;
|
|
clear(): void;
|
|
has(key: NodeKey): boolean;
|
|
clone(): NodeSelection;
|
|
extract(): Array<LexicalNode>;
|
|
insertRawText(): void;
|
|
insertText(): void;
|
|
getNodes(): Array<LexicalNode>;
|
|
getStartEndPoints(): null;
|
|
getTextContent(): string;
|
|
insertNodes(nodes: Array<LexicalNode>): void;
|
|
getCachedNodes(): null | Array<LexicalNode>;
|
|
setCachedNodes(nodes: null | Array<LexicalNode>): void;
|
|
}
|
|
|
|
declare export function $isNodeSelection(
|
|
x: ?mixed,
|
|
): x is NodeSelection;
|
|
|
|
declare export class RangeSelection implements BaseSelection {
|
|
anchor: PointType;
|
|
focus: PointType;
|
|
dirty: boolean;
|
|
format: number;
|
|
style: string;
|
|
constructor(anchor: PointType, focus: PointType, format: number): void;
|
|
is(selection: null | BaseSelection): boolean;
|
|
isBackward(): boolean;
|
|
isCollapsed(): boolean;
|
|
getNodes(): Array<LexicalNode>;
|
|
setTextNodeRange(
|
|
anchorNode: TextNode,
|
|
anchorOffset: number,
|
|
focusNode: TextNode,
|
|
focusOffset: number,
|
|
): void;
|
|
getTextContent(): string;
|
|
// $FlowFixMe[cannot-resolve-name] DOM API
|
|
applyDOMRange(range: StaticRange): void;
|
|
clone(): RangeSelection;
|
|
toggleFormat(format: TextFormatType): void;
|
|
setStyle(style: string): void;
|
|
hasFormat(type: TextFormatType): boolean;
|
|
insertText(text: string): void;
|
|
insertRawText(text: string): void;
|
|
removeText(): void;
|
|
formatText(formatType: TextFormatType): void;
|
|
insertNodes(nodes: Array<LexicalNode>): void;
|
|
insertParagraph(): void;
|
|
insertLineBreak(selectStart?: boolean): void;
|
|
extract(): Array<LexicalNode>;
|
|
modify(
|
|
alter: 'move' | 'extend',
|
|
isBackward: boolean,
|
|
granularity: 'character' | 'word' | 'lineboundary',
|
|
): void;
|
|
deleteCharacter(isBackward: boolean): void;
|
|
deleteLine(isBackward: boolean): void;
|
|
deleteWord(isBackward: boolean): void;
|
|
insertNodes(nodes: Array<LexicalNode>): void;
|
|
getCachedNodes(): null | Array<LexicalNode>;
|
|
setCachedNodes(nodes: null | Array<LexicalNode>): void;
|
|
forwardDeletion(anchor: PointType, anchorNode: ElementNode | TextNode, isBackward: boolean): boolean;
|
|
getStartEndPoints(): null | [PointType, PointType];
|
|
}
|
|
export type TextPoint = TextPointType;
|
|
type TextPointType = {
|
|
key: NodeKey,
|
|
offset: number,
|
|
type: 'text',
|
|
is: (PointType) => boolean,
|
|
isBefore: (PointType) => boolean,
|
|
getNode: () => TextNode,
|
|
set: (key: NodeKey, offset: number, type: 'text' | 'element') => void,
|
|
getCharacterOffset: () => number,
|
|
};
|
|
export type ElementPoint = ElementPointType;
|
|
type ElementPointType = {
|
|
key: NodeKey,
|
|
offset: number,
|
|
type: 'element',
|
|
is: (PointType) => boolean,
|
|
isBefore: (PointType) => boolean,
|
|
getNode: () => ElementNode,
|
|
set: (key: NodeKey, offset: number, type: 'text' | 'element') => void,
|
|
};
|
|
export type Point = PointType;
|
|
export type PointType = TextPointType | ElementPointType;
|
|
declare class _Point {
|
|
key: NodeKey;
|
|
offset: number;
|
|
type: 'text' | 'element';
|
|
constructor(key: NodeKey, offset: number, type: 'text' | 'element'): void;
|
|
is(point: PointType): boolean;
|
|
isBefore(b: PointType): boolean;
|
|
getNode(): LexicalNode;
|
|
set(key: NodeKey, offset: number, type: 'text' | 'element', onlyIfChanged?: boolean): void;
|
|
}
|
|
|
|
declare export function $createRangeSelection(): RangeSelection;
|
|
declare export function $createNodeSelection(): NodeSelection;
|
|
declare export function $isRangeSelection(
|
|
x: ?mixed,
|
|
): x is RangeSelection;
|
|
declare export function $getSelection(): null | BaseSelection;
|
|
declare export function $getPreviousSelection(): null | BaseSelection;
|
|
declare export function $insertNodes(nodes: Array<LexicalNode>): void;
|
|
declare export function $getCharacterOffsets(
|
|
selection: BaseSelection,
|
|
): [number, number];
|
|
|
|
|
|
/**
|
|
* LexicalTextNode
|
|
*/
|
|
|
|
export type TextFormatType =
|
|
| 'bold'
|
|
| 'underline'
|
|
| 'strikethrough'
|
|
| 'italic'
|
|
| 'highlight'
|
|
| 'code'
|
|
| 'subscript'
|
|
| 'superscript'
|
|
| 'lowercase'
|
|
| 'uppercase'
|
|
| 'capitalize';
|
|
|
|
type TextModeType = 'normal' | 'token' | 'segmented';
|
|
|
|
declare export class TextNode extends LexicalNode {
|
|
__text: string;
|
|
__format: number;
|
|
__style: string;
|
|
__mode: 0 | 1 | 2 | 3;
|
|
__detail: number;
|
|
static getType(): string;
|
|
static clone(node: $FlowFixMe): TextNode;
|
|
constructor(text: string, key?: NodeKey): void;
|
|
getTopLevelElement(): ElementNode | null;
|
|
getTopLevelElementOrThrow(): ElementNode;
|
|
getFormat(): number;
|
|
getStyle(): string;
|
|
isComposing(): boolean;
|
|
isInline(): true;
|
|
isToken(): boolean;
|
|
isSegmented(): boolean;
|
|
isDirectionless(): boolean;
|
|
isUnmergeable(): boolean;
|
|
hasFormat(type: TextFormatType): boolean;
|
|
isSimpleText(): boolean;
|
|
getTextContent(): string;
|
|
getFormatFlags(type: TextFormatType, alignWithFormat: null | number): number;
|
|
createDOM(config: EditorConfig): HTMLElement;
|
|
selectionTransform(
|
|
prevSelection: null | BaseSelection,
|
|
nextSelection: RangeSelection,
|
|
): void;
|
|
setFormat(format: number): this;
|
|
setStyle(style: string): this;
|
|
toggleFormat(type: TextFormatType): TextNode;
|
|
toggleDirectionless(): this;
|
|
toggleUnmergeable(): this;
|
|
setMode(type: TextModeType): this;
|
|
setDetail(detail: number): this;
|
|
getDetail(): number;
|
|
getMode(): TextModeType;
|
|
setTextContent(text: string): TextNode;
|
|
select(_anchorOffset?: number, _focusOffset?: number): RangeSelection;
|
|
spliceText(
|
|
offset: number,
|
|
delCount: number,
|
|
newText: string,
|
|
moveSelection?: boolean,
|
|
): TextNode;
|
|
canInsertTextBefore(): boolean;
|
|
canInsertTextAfter(): boolean;
|
|
splitText(...splitOffsets: Array<number>): Array<TextNode>;
|
|
mergeWithSibling(target: TextNode): TextNode;
|
|
isTextEntity(): boolean;
|
|
static importJSON(serializedTextNode: SerializedTextNode): TextNode;
|
|
exportJSON(): SerializedTextNode;
|
|
}
|
|
declare export function $createTextNode(text?: string): TextNode;
|
|
declare export function $isTextNode(
|
|
node: ?LexicalNode,
|
|
): node is TextNode;
|
|
|
|
/**
|
|
* LexicalTabNode
|
|
*/
|
|
|
|
export type SerializedTabNode = SerializedTextNode;
|
|
|
|
declare export function $createTabNode(): TabNode;
|
|
|
|
declare export function $isTabNode(
|
|
node: LexicalNode | null | void,
|
|
): node is TabNode;
|
|
|
|
declare export class TabNode extends TextNode {
|
|
static getType(): string;
|
|
static clone(node: TabNode): TabNode;
|
|
constructor(key?: NodeKey): void;
|
|
static importDOM(): DOMConversionMap | null;
|
|
static importJSON(serializedTabNode: SerializedTabNode): TabNode;
|
|
exportJSON(): SerializedTabNode;
|
|
}
|
|
|
|
/**
|
|
* LexicalLineBreakNode
|
|
*/
|
|
|
|
declare export class LineBreakNode extends LexicalNode {
|
|
static getType(): string;
|
|
static clone(node: LineBreakNode): LineBreakNode;
|
|
constructor(key?: NodeKey): void;
|
|
getTextContent(): '\n';
|
|
createDOM(): HTMLElement;
|
|
updateDOM(): false;
|
|
isInline(): true;
|
|
static importJSON(
|
|
serializedLineBreakNode: SerializedLineBreakNode,
|
|
): LineBreakNode;
|
|
exportJSON(): SerializedLexicalNode;
|
|
}
|
|
declare export function $createLineBreakNode(): LineBreakNode;
|
|
declare export function $isLineBreakNode(
|
|
node: ?LexicalNode,
|
|
): node is LineBreakNode;
|
|
|
|
/**
|
|
* LexicalRootNode
|
|
*/
|
|
|
|
declare export class RootNode extends ElementNode {
|
|
__cachedText: null | string;
|
|
static getType(): string;
|
|
static clone(): RootNode;
|
|
constructor(): void;
|
|
getTextContent(): string;
|
|
select(_anchorOffset?: number, _focusOffset?: number): RangeSelection;
|
|
remove(): void;
|
|
replace<N: LexicalNode>(node: N): N;
|
|
insertBefore<T: LexicalNode>(nodeToInsert: T): T;
|
|
insertAfter<T: LexicalNode>(nodeToInsert: T): T;
|
|
append(...nodesToAppend: Array<LexicalNode>): this;
|
|
canBeEmpty(): false;
|
|
}
|
|
declare export function $isRootNode(
|
|
node: ?LexicalNode,
|
|
): node is RootNode;
|
|
|
|
/**
|
|
* LexicalElementNode
|
|
*/
|
|
export type ElementFormatType =
|
|
| 'left'
|
|
| 'start'
|
|
| 'center'
|
|
| 'right'
|
|
| 'end'
|
|
| 'justify'
|
|
| '';
|
|
declare export class ElementNode extends LexicalNode {
|
|
__first: null | NodeKey;
|
|
__last: null | NodeKey;
|
|
__size: number;
|
|
__format: number;
|
|
__indent: number;
|
|
__dir: 'ltr' | 'rtl' | null;
|
|
constructor(key?: NodeKey): void;
|
|
getTopLevelElement(): ElementNode | null;
|
|
getTopLevelElementOrThrow(): ElementNode;
|
|
getFormat(): number;
|
|
getFormatType(): ElementFormatType;
|
|
getIndent(): number;
|
|
getChildren<T: LexicalNode>(): Array<T>;
|
|
getChildren<T: Array<LexicalNode>>(): T;
|
|
getChildrenKeys(): Array<NodeKey>;
|
|
getChildrenSize(): number;
|
|
isEmpty(): boolean;
|
|
isDirty(): boolean;
|
|
getAllTextNodes(): Array<TextNode>;
|
|
getFirstDescendant<T: LexicalNode>(): null | T;
|
|
getLastDescendant<T: LexicalNode>(): null | T;
|
|
getDescendantByIndex<T: LexicalNode>(index: number): null | T;
|
|
getFirstChild<T: LexicalNode>(): null | T;
|
|
getFirstChildOrThrow<T: LexicalNode>(): T;
|
|
getLastChild<T: LexicalNode>(): null | T;
|
|
getLastChildOrThrow<T: LexicalNode>(): T;
|
|
getChildAtIndex<T: LexicalNode>(index: number): null | T;
|
|
getTextContent(): string;
|
|
getDirection(): 'ltr' | 'rtl' | null;
|
|
hasFormat(type: ElementFormatType): boolean;
|
|
select(_anchorOffset?: number, _focusOffset?: number): RangeSelection;
|
|
selectStart(): RangeSelection;
|
|
selectEnd(): RangeSelection;
|
|
clear(): this;
|
|
append(...nodesToAppend: Array<LexicalNode>): this;
|
|
setDirection(direction: 'ltr' | 'rtl' | null): this;
|
|
setFormat(type: ElementFormatType): this;
|
|
setIndent(indentLevel: number): this;
|
|
insertNewAfter(
|
|
selection: RangeSelection,
|
|
restoreSelection?: boolean,
|
|
): null | LexicalNode;
|
|
canIndent(): boolean;
|
|
collapseAtStart(selection: RangeSelection): boolean;
|
|
excludeFromCopy(destination: 'clone' | 'html'): boolean;
|
|
canReplaceWith(replacement: LexicalNode): boolean;
|
|
canInsertAfter(node: LexicalNode): boolean;
|
|
extractWithChild(
|
|
child: LexicalNode,
|
|
selection: BaseSelection,
|
|
destination: 'clone' | 'html',
|
|
): boolean;
|
|
canBeEmpty(): boolean;
|
|
canInsertTextBefore(): boolean;
|
|
canInsertTextAfter(): boolean;
|
|
isInline(): boolean;
|
|
isShadowRoot(): boolean;
|
|
canSelectionRemove(): boolean;
|
|
splice(
|
|
start: number,
|
|
deleteCount: number,
|
|
nodesToInsert: Array<LexicalNode>,
|
|
): this;
|
|
exportJSON(): SerializedElementNode;
|
|
getDOMSlot(dom: HTMLElement): ElementDOMSlot;
|
|
}
|
|
declare export function $isElementNode(
|
|
node: ?LexicalNode,
|
|
): node is ElementNode;
|
|
|
|
/**
|
|
* ElementDOMSlot
|
|
*/
|
|
declare export class ElementDOMSlot {
|
|
element: HTMLElement;
|
|
before: Node | null;
|
|
after: Node | null;
|
|
constructor(element: HTMLElement, before?: Node | null | void, after?: Node | null | void): void;
|
|
withBefore(before: Node | null | void): ElementDOMSlot;
|
|
withAfter(after: Node | null | void): ElementDOMSlot;
|
|
withElement(element: HTMLElement): ElementDOMSlot;
|
|
insertChild(dom: Node): this;
|
|
removeChild(dom: Node): this;
|
|
replaceChild(dom: Node, prevDom: Node): this;
|
|
getFirstChild(): Node | null;
|
|
//
|
|
getManagedLineBreak(): HTMLElement | null;
|
|
removeManagedLineBreak(): void;
|
|
insertManagedLineBreak(webkitHack: boolean): void;
|
|
getFirstChildOffset(): number;
|
|
resolveChildIndex(element: ElementNode, elementDOM: HTMLElement, initialDOM: Node, initialOffset: number): [node: ElementNode, idx: number];
|
|
}
|
|
|
|
declare export function setDOMUnmanaged(elementDOM: HTMLElement): void;
|
|
declare export function isDOMUnmanaged(elementDOM: HTMLElement): boolean;
|
|
|
|
/**
|
|
* LexicalDecoratorNode
|
|
*/
|
|
|
|
declare export class DecoratorNode<X> extends LexicalNode {
|
|
constructor(key?: NodeKey): void;
|
|
// Not sure how to get flow to agree that the DecoratorNode<mixed> is compatible with this,
|
|
// so we have a less precise type than in TS
|
|
// getTopLevelElement(): this | ElementNode | null;
|
|
// getTopLevelElementOrThrow(): this | ElementNode;
|
|
decorate(editor: LexicalEditor, config: EditorConfig): X;
|
|
isIsolated(): boolean;
|
|
isInline(): boolean;
|
|
isKeyboardSelectable(): boolean;
|
|
}
|
|
declare export function $isDecoratorNode<T = mixed>(
|
|
node: ?LexicalNode,
|
|
): node is DecoratorNode<T>;
|
|
|
|
/**
|
|
* LexicalParagraphNode
|
|
*/
|
|
declare export class ParagraphNode extends ElementNode {
|
|
static getType(): string;
|
|
static clone(node: ParagraphNode): ParagraphNode;
|
|
constructor(key?: NodeKey): void;
|
|
createDOM(config: EditorConfig): HTMLElement;
|
|
insertNewAfter(
|
|
selection: RangeSelection,
|
|
restoreSelection?: boolean,
|
|
): ParagraphNode;
|
|
collapseAtStart(): boolean;
|
|
static importJSON(
|
|
serializedParagraphNode: SerializedParagraphNode,
|
|
): ParagraphNode;
|
|
exportJSON(): SerializedElementNode;
|
|
}
|
|
declare export function $createParagraphNode(): ParagraphNode;
|
|
declare export function $isParagraphNode(
|
|
node: ?LexicalNode,
|
|
): node is ParagraphNode;
|
|
|
|
/**
|
|
* LexicalUtils
|
|
*/
|
|
export type EventHandler = (event: Event, editor: LexicalEditor) => void;
|
|
declare export function $hasUpdateTag(tag: string): boolean;
|
|
declare export function $addUpdateTag(tag: string): void;
|
|
declare export function $onUpdate(updateFn: () => void): void;
|
|
declare export function getNearestEditorFromDOMNode(
|
|
node: Node | null,
|
|
): LexicalEditor | null;
|
|
declare export function $getNearestNodeFromDOMNode(
|
|
startingDOM: Node,
|
|
): LexicalNode | null;
|
|
declare export function $getNodeByKey<N: LexicalNode>(key: NodeKey): N | null;
|
|
declare export function $getNodeByKeyOrThrow<N: LexicalNode>(key: NodeKey): N;
|
|
declare export function $getRoot(): RootNode;
|
|
declare export function $isLeafNode<T = mixed>(
|
|
node: ?LexicalNode,
|
|
): node is TextNode | LineBreakNode | DecoratorNode<T>;
|
|
declare export function $setCompositionKey(
|
|
compositionKey: null | NodeKey,
|
|
): void;
|
|
declare export function $setSelection(selection: null | BaseSelection): void;
|
|
declare export function $nodesOfType<T: LexicalNode>(klass: Class<T>): Array<T>;
|
|
declare export function $getAdjacentNode(
|
|
focus: Point,
|
|
isBackward: boolean,
|
|
): null | LexicalNode;
|
|
declare export function resetRandomKey(): void;
|
|
declare export function generateRandomKey(): string;
|
|
declare export function $isInlineElementOrDecoratorNode<T = mixed>(
|
|
node: LexicalNode,
|
|
): node is ElementNode| DecoratorNode<T>;
|
|
declare export function $getNearestRootOrShadowRoot(
|
|
node: LexicalNode,
|
|
): RootNode | ElementNode;
|
|
declare export function $isRootOrShadowRoot(
|
|
node: ?LexicalNode,
|
|
): node is RootNode | ElementNode;
|
|
declare export function $hasAncestor(
|
|
child: LexicalNode,
|
|
targetNode: LexicalNode,
|
|
): boolean;
|
|
declare export function $cloneWithProperties<T: LexicalNode>(node: T): T;
|
|
declare export function $copyNode(
|
|
node: ElementNode,
|
|
offset: number,
|
|
): [ElementNode, ElementNode];
|
|
declare export function $getEditor(): LexicalEditor;
|
|
|
|
/**
|
|
* LexicalNormalization
|
|
*/
|
|
|
|
declare export function $normalizeSelection__EXPERIMENTAL(
|
|
selection: RangeSelection,
|
|
): RangeSelection;
|
|
|
|
/**
|
|
* Serialization/Deserialization
|
|
* */
|
|
|
|
type InternalSerializedNode = {
|
|
children?: Array<InternalSerializedNode>,
|
|
type: string,
|
|
version: number,
|
|
};
|
|
|
|
declare export function $parseSerializedNode(
|
|
serializedNode: InternalSerializedNode,
|
|
): LexicalNode;
|
|
|
|
declare export function $applyNodeReplacement<N: LexicalNode>(
|
|
node: LexicalNode,
|
|
): N;
|
|
|
|
export type SerializedLexicalNode = {
|
|
type: string,
|
|
version: number,
|
|
...
|
|
};
|
|
|
|
export type SerializedTextNode = {
|
|
...SerializedLexicalNode,
|
|
detail: number,
|
|
format: number,
|
|
mode: TextModeType,
|
|
style: string,
|
|
text: string,
|
|
...
|
|
};
|
|
|
|
export type SerializedElementNode = {
|
|
...SerializedLexicalNode,
|
|
children: Array<SerializedLexicalNode>,
|
|
direction: 'ltr' | 'rtl' | null,
|
|
format: ElementFormatType,
|
|
indent: number,
|
|
...
|
|
};
|
|
|
|
export type SerializedParagraphNode = {
|
|
...SerializedElementNode,
|
|
...
|
|
};
|
|
|
|
export type SerializedLineBreakNode = {
|
|
...SerializedLexicalNode,
|
|
...
|
|
};
|
|
|
|
export type SerializedDecoratorNode = {
|
|
...SerializedLexicalNode,
|
|
...
|
|
};
|
|
|
|
export type SerializedRootNode = {
|
|
...SerializedElementNode,
|
|
...
|
|
};
|
|
|
|
export type SerializedGridCellNode = {
|
|
...SerializedElementNode,
|
|
colSpan: number,
|
|
...
|
|
};
|
|
|
|
export interface SerializedEditorState {
|
|
root: SerializedRootNode;
|
|
}
|
|
|
|
export type SerializedEditor = {
|
|
editorState: SerializedEditorState,
|
|
};
|
|
|
|
/**
|
|
* LexicalCaret
|
|
*/
|
|
export interface BaseCaret<T: LexicalNode, D: CaretDirection, Type> extends Iterable<SiblingCaret<LexicalNode, D>> {
|
|
+origin: T;
|
|
+type: Type;
|
|
+direction: D;
|
|
getParentAtCaret(): null | ElementNode;
|
|
getNodeAtCaret(): null | LexicalNode;
|
|
getAdjacentCaret(): null | SiblingCaret<LexicalNode, D>;
|
|
getSiblingCaret(): SiblingCaret<T, D>;
|
|
remove(): BaseCaret<T, D, Type>; // this
|
|
insert(node: LexicalNode): BaseCaret<T, D, Type>; // this
|
|
replaceOrInsert(node: LexicalNode, includeChildren?: boolean): BaseCaret<T, D, Type>; // this
|
|
splice(deleteCount: number, nodes: Iterable<LexicalNode>, nodesDirection?: CaretDirection): BaseCaret<T, D, Type>; // this
|
|
}
|
|
export type CaretDirection = 'next' | 'previous';
|
|
type FLIP_DIRECTION = {'next' : 'previous', 'previous': 'next'};
|
|
export interface CaretRange<D: CaretDirection = CaretDirection> extends Iterable<NodeCaret<D>> {
|
|
+type: 'node-caret-range';
|
|
+direction: D;
|
|
anchor: PointCaret<D>;
|
|
focus: PointCaret<D>;
|
|
isCollapsed(): boolean;
|
|
iterNodeCarets(rootMode?: RootMode): Iterable<NodeCaret<D>>;
|
|
getTextSlices(): TextPointCaretSliceTuple<D>;
|
|
}
|
|
export type CaretType = 'sibling' | 'child';
|
|
export interface ChildCaret<T: ElementNode = ElementNode, D: CaretDirection = CaretDirection> extends BaseCaret<T, D, 'child'> {
|
|
getLatest(): ChildCaret<T, D>;
|
|
getParentCaret(mode?: RootMode): null | SiblingCaret<T, D>;
|
|
getParentAtCaret(): T;
|
|
getChildCaret(): ChildCaret<T, D>;
|
|
isSameNodeCaret(other: null | void | PointCaret<CaretDirection>): boolean; // other is ChildCaret<T, D>;
|
|
isSamePointCaret(other: null | void | PointCaret<CaretDirection>): boolean; // other is ChildCaret<T, D>;
|
|
getFlipped(): NodeCaret<FlipDirection<D>>;
|
|
// Refine chained types
|
|
remove(): ChildCaret<T, D>;
|
|
insert(node: LexicalNode): ChildCaret<T, D>;
|
|
replaceOrInsert(node: LexicalNode, includeChildren?: boolean): ChildCaret<T, D>;
|
|
splice(deleteCount: number, nodes: Iterable<LexicalNode>, nodesDirection?: CaretDirection): ChildCaret<T, D>;
|
|
}
|
|
export type FlipDirection<D: CaretDirection> = FLIP_DIRECTION[D];
|
|
export type NodeCaret<D: CaretDirection = CaretDirection> = ChildCaret<ElementNode, D> | SiblingCaret<LexicalNode, D>;
|
|
export type PointCaret<D: CaretDirection = CaretDirection> = ChildCaret<ElementNode, D> | SiblingCaret<LexicalNode, D> | TextPointCaret<TextNode, D>;
|
|
export type RootMode = 'root' | 'shadowRoot';
|
|
export interface SiblingCaret<T: LexicalNode = LexicalNode, D: CaretDirection = CaretDirection> extends BaseCaret<T, D, 'sibling'> {
|
|
getLatest(): SiblingCaret<T, D>;
|
|
getChildCaret(): null | ChildCaret<T & ElementNode, D>;
|
|
getParentCaret(mode?: RootMode): null | SiblingCaret<ElementNode, D>;
|
|
isSameNodeCaret(other: null | void | PointCaret<CaretDirection>): boolean; // </CaretDirection>other is SiblingCaret<T, D> | T extends TextNode ? TextPointCaret<T & TextNode, D> : empty;
|
|
isSamePointCaret(other: null | void | PointCaret<CaretDirection>): boolean; // other is SiblingCaret<T, D>;
|
|
getFlipped(): NodeCaret<FlipDirection<D>>;
|
|
// Refine chained types
|
|
remove(): SiblingCaret<T, D>;
|
|
insert(node: LexicalNode): SiblingCaret<T, D>;
|
|
replaceOrInsert(node: LexicalNode, includeChildren?: boolean): SiblingCaret<T, D>;
|
|
splice(deleteCount: number, nodes: Iterable<LexicalNode>, nodesDirection?: CaretDirection): SiblingCaret<T, D>;
|
|
}
|
|
export interface StepwiseIteratorConfig<State, Stop, Value> {
|
|
+initial: State | Stop;
|
|
+hasNext: (value: State | Stop) => implies value is State;
|
|
+step: (value: State) => State | Stop;
|
|
+map: (value: State) => Value;
|
|
}
|
|
export interface TextPointCaret<T: TextNode = TextNode, D: CaretDirection = CaretDirection> extends BaseCaret<T, D, 'text'> {
|
|
+offset: number;
|
|
getLatest(): TextPointCaret<T, D>;
|
|
getChildCaret(): null;
|
|
getParentCaret(): null | SiblingCaret<ElementNode, D>;
|
|
isSameNodeCaret(other: null | void | PointCaret<CaretDirection>): boolean; // other is TextPointCaret<T, D> | SiblingCaret<T, D>;
|
|
isSamePointCaret(other: null | void | PointCaret<CaretDirection>): boolean; // other is TextPointCaret<T, D>;
|
|
getFlipped(): TextPointCaret<T, FlipDirection<D>>;
|
|
}
|
|
export interface TextPointCaretSlice<T: TextNode = TextNode, D: CaretDirection = CaretDirection> {
|
|
+type: 'slice';
|
|
+caret: TextPointCaret<T, D>;
|
|
+distance: number;
|
|
getSliceIndices(): [startIndex: number, endIndex: number];
|
|
getTextContent(): string;
|
|
getTextContentSize(): number;
|
|
removeTextSlice(): TextPointCaret<T, D>;
|
|
}
|
|
export type TextPointCaretSliceTuple<D: CaretDirection> = [
|
|
+anchorSlice: null | TextPointCaretSlice<TextNode, D>,
|
|
+focusSlice: null | TextPointCaretSlice<TextNode, D>,
|
|
];
|
|
declare export function $getAdjacentChildCaret<D: CaretDirection>(caret: null | NodeCaret<D>): null | NodeCaret<D>;
|
|
declare export function $getCaretRange<D: CaretDirection>(anchor: PointCaret<D>, focus: PointCaret<D>): CaretRange<D>;
|
|
declare export function $getChildCaret<T: null | ElementNode, D: CaretDirection>(origin: T, direction: D): ChildCaret<Exclude<null, T>, D> | Extract<null, T>;
|
|
declare export function $getChildCaretOrSelf<Caret: null | PointCaret<CaretDirection>>(caret: Caret): Caret | ChildCaret<ElementNode, Exclude<null, Caret>['direction']>;
|
|
declare export function $getSiblingCaret<T: null | LexicalNode, D: CaretDirection>(origin: T, direction: D): SiblingCaret<Exclude<null, T>, D> | Extract<null, T>;
|
|
declare export function $getTextNodeOffset(origin: TextNode, offset: number | CaretDirection): number;
|
|
declare export function $getTextPointCaret<T: null | TextNode, D: CaretDirection>(origin: T, direction: D, offset: number | CaretDirection): TextPointCaret<Exclude<null, T>, D> | Extract<null, T>;
|
|
declare export function $getTextPointCaretSlice<T: TextNode, D: CaretDirection>(caret: TextPointCaret<T, D>, distance: number): TextPointCaretSlice<T, D>;
|
|
declare export function $isChildCaret<D: CaretDirection>(caret: null | void | PointCaret<D>): caret is ChildCaret<ElementNode, D>;
|
|
declare export function $isNodeCaret<D: CaretDirection>(caret: null | void | PointCaret<D>): caret is NodeCaret<D>;
|
|
declare export function $isSiblingCaret<D: CaretDirection>(caret: null | void | PointCaret<D>): caret is SiblingCaret<LexicalNode, D>;
|
|
declare export function $isTextPointCaret<D: CaretDirection>(caret: null | void | PointCaret<D>): caret is TextPointCaret<TextNode, D>;
|
|
declare export function $isTextPointCaretSlice<D: CaretDirection>(caret: null | void | PointCaret<D> | TextPointCaretSlice<TextNode, D>): caret is TextPointCaretSlice<TextNode, D>;
|
|
declare export function flipDirection<D: CaretDirection>(direction: D): FlipDirection<D>;
|
|
declare export function makeStepwiseIterator<State, Stop, Value>(
|
|
config: StepwiseIteratorConfig<State, Stop, Value>,
|
|
): Iterator<Value>;
|
|
/**
|
|
* LexicalCaretUtils
|
|
*/
|
|
declare export function $caretFromPoint<D: CaretDirection>(
|
|
point: PointType,
|
|
direction: D,
|
|
): PointCaret<D>;
|
|
declare export function $caretRangeFromSelection(
|
|
selection: RangeSelection,
|
|
): CaretRange<CaretDirection>;
|
|
declare export function $getAdjacentSiblingOrParentSiblingCaret<
|
|
D: CaretDirection,
|
|
>(
|
|
startCaret: NodeCaret<D>,
|
|
rootMode?: RootMode
|
|
): null | [NodeCaret<D>, number]
|
|
declare export function $getCaretInDirection<
|
|
Caret: PointCaret<CaretDirection>,
|
|
D: CaretDirection,
|
|
>(
|
|
caret: Caret,
|
|
direction: D,
|
|
):
|
|
| NodeCaret<D>
|
|
| (Caret extends TextPointCaret<TextNode, CaretDirection>
|
|
? TextPointCaret<TextNode, D>
|
|
: empty);
|
|
declare export function $getCaretRangeInDirection<D: CaretDirection>(
|
|
range: CaretRange<CaretDirection>,
|
|
direction: D,
|
|
): CaretRange<D>;
|
|
declare export function $getChildCaretAtIndex<D: CaretDirection>(
|
|
parent: ElementNode,
|
|
index: number,
|
|
direction: D,
|
|
): NodeCaret<D>;
|
|
declare export function $normalizeCaret<D: CaretDirection>(
|
|
initialCaret: PointCaret<D>,
|
|
): PointCaret<D>;
|
|
declare export function $removeTextFromCaretRange<D: CaretDirection>(
|
|
initialRange: CaretRange<D>,
|
|
sliceMode?:
|
|
| 'removeEmptySlices'
|
|
| 'preserveEmptyTextSliceCaret'
|
|
): CaretRange<D>;
|
|
declare export function $rewindSiblingCaret<
|
|
T: LexicalNode,
|
|
D: CaretDirection,
|
|
>(caret: SiblingCaret<T, D>): NodeCaret<D>;
|
|
declare export function $setPointFromCaret<D: CaretDirection>(
|
|
point: PointType,
|
|
caret: PointCaret<D>,
|
|
): void;
|
|
declare export function $setSelectionFromCaretRange(
|
|
caretRange: CaretRange<CaretDirection>,
|
|
): RangeSelection;
|
|
declare export function $updateRangeSelectionFromCaretRange(
|
|
selection: RangeSelection,
|
|
caretRange: CaretRange<CaretDirection>,
|
|
): void;
|
|
|
|
export type CommonAncestorResult<
|
|
A: LexicalNode,
|
|
B: LexicalNode,
|
|
> =
|
|
| CommonAncestorResultSame<A>
|
|
| CommonAncestorResultAncestor<A & ElementNode>
|
|
| CommonAncestorResultDescendant<B & ElementNode>
|
|
| CommonAncestorResultBranch<A, B>;
|
|
export interface CommonAncestorResultBranch<
|
|
A: LexicalNode,
|
|
B: LexicalNode,
|
|
> {
|
|
+type: 'branch';
|
|
+commonAncestor: ElementNode;
|
|
+a: A | ElementNode;
|
|
+b: B | ElementNode;
|
|
}
|
|
export interface CommonAncestorResultAncestor<A: ElementNode> {
|
|
+type: 'ancestor';
|
|
+commonAncestor: A;
|
|
}
|
|
export interface CommonAncestorResultDescendant<B: ElementNode> {
|
|
+type: 'descendant';
|
|
+commonAncestor: B;
|
|
}
|
|
export interface CommonAncestorResultSame<A: LexicalNode> {
|
|
+type: 'same';
|
|
+commonAncestor: A;
|
|
}
|
|
declare export function $comparePointCaretNext(
|
|
a: PointCaret<'next'>,
|
|
b: PointCaret<'next'>,
|
|
): -1 | 0 | 1;
|
|
declare export function $getCommonAncestorResultBranchOrder<
|
|
A: LexicalNode,
|
|
B: LexicalNode,
|
|
>(compare: CommonAncestorResultBranch<A, B>): -1 | 1 ;
|
|
declare export function $getCommonAncestor<
|
|
A: LexicalNode,
|
|
B: LexicalNode,
|
|
>(a: A, b: B): null | CommonAncestorResult<A, B>;
|
|
declare export function $extendCaretToRange<D: CaretDirection>(
|
|
anchor: PointCaret<D>,
|
|
): CaretRange<D>;
|