mirror of
https://github.com/facebook/lexical.git
synced 2025-05-21 00:57:23 +08:00
Create Flow definition file for Lexical core (#1350)
This commit is contained in:

committed by
acywatson

parent
198611d5bd
commit
993a2ea4ed
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
packages/**/dist/*.js
|
packages/**/dist/*.js
|
||||||
packages/**/config/*.js
|
packages/**/config/*.js
|
||||||
|
packages/**/*.js.flow
|
||||||
packages/playwright
|
packages/playwright
|
||||||
packages/playwright-core
|
packages/playwright-core
|
||||||
packages/babel-plugin-transform-stylex
|
packages/babel-plugin-transform-stylex
|
||||||
|
@ -16,8 +16,6 @@ untyped-type-import=error
|
|||||||
server.max_workers=4
|
server.max_workers=4
|
||||||
exact_by_default=true
|
exact_by_default=true
|
||||||
|
|
||||||
module.name_mapper='^lexical$' -> '<PROJECT_ROOT>/packages/lexical/src/index.js'
|
|
||||||
|
|
||||||
module.name_mapper='^lexical/HeadingNode' -> '<PROJECT_ROOT>/packages/lexical/src/nodes/extended/LexicalHeadingNode.js'
|
module.name_mapper='^lexical/HeadingNode' -> '<PROJECT_ROOT>/packages/lexical/src/nodes/extended/LexicalHeadingNode.js'
|
||||||
module.name_mapper='^lexical/QuoteNode' -> '<PROJECT_ROOT>/packages/lexical/src/nodes/extended/LexicalQuoteNode.js'
|
module.name_mapper='^lexical/QuoteNode' -> '<PROJECT_ROOT>/packages/lexical/src/nodes/extended/LexicalQuoteNode.js'
|
||||||
module.name_mapper='^lexical/CodeNode' -> '<PROJECT_ROOT>/packages/lexical/src/nodes/extended/LexicalCodeNode.js'
|
module.name_mapper='^lexical/CodeNode' -> '<PROJECT_ROOT>/packages/lexical/src/nodes/extended/LexicalCodeNode.js'
|
||||||
@ -82,7 +80,6 @@ module.name_mapper='^@lexical/yjs$' -> '<PROJECT_ROOT>/packages/lexical-yjs/src/
|
|||||||
|
|
||||||
module.name_mapper='^shared/invariant' -> '<PROJECT_ROOT>/packages/shared/src/invariant.js'
|
module.name_mapper='^shared/invariant' -> '<PROJECT_ROOT>/packages/shared/src/invariant.js'
|
||||||
module.name_mapper='^shared/environment' -> '<PROJECT_ROOT>/packages/shared/src/environment.js'
|
module.name_mapper='^shared/environment' -> '<PROJECT_ROOT>/packages/shared/src/environment.js'
|
||||||
module.name_mapper='^shared/getPossibleDecoratorNode' -> '<PROJECT_ROOT>/packages/shared/src/getPossibleDecoratorNode.js'
|
|
||||||
module.name_mapper='^shared/useLayoutEffect' -> '<PROJECT_ROOT>/packages/shared/src/useLayoutEffect.js'
|
module.name_mapper='^shared/useLayoutEffect' -> '<PROJECT_ROOT>/packages/shared/src/useLayoutEffect.js'
|
||||||
module.name_mapper='^shared/canUseDOM' -> '<PROJECT_ROOT>/packages/shared/src/canUseDOM.js'
|
module.name_mapper='^shared/canUseDOM' -> '<PROJECT_ROOT>/packages/shared/src/canUseDOM.js'
|
||||||
|
|
||||||
|
@ -86,8 +86,6 @@ module.exports = {
|
|||||||
'<rootDir>/packages/lexical/src/nodes/extended/LexicalQuoteNode.js',
|
'<rootDir>/packages/lexical/src/nodes/extended/LexicalQuoteNode.js',
|
||||||
'^shared/canUseDOM$': '<rootDir>/packages/shared/src/canUseDOM.js',
|
'^shared/canUseDOM$': '<rootDir>/packages/shared/src/canUseDOM.js',
|
||||||
'^shared/environment$': '<rootDir>/packages/shared/src/environment.js',
|
'^shared/environment$': '<rootDir>/packages/shared/src/environment.js',
|
||||||
'^shared/getPossibleDecoratorNode$':
|
|
||||||
'<rootDir>/packages/shared/src/getPossibleDecoratorNode.js',
|
|
||||||
'^shared/invariant$': '<rootDir>/packages/shared/src/invariant.js',
|
'^shared/invariant$': '<rootDir>/packages/shared/src/invariant.js',
|
||||||
'^shared/useLayoutEffect$':
|
'^shared/useLayoutEffect$':
|
||||||
'<rootDir>/packages/shared/src/useLayoutEffect.js',
|
'<rootDir>/packages/shared/src/useLayoutEffect.js',
|
||||||
|
@ -22,14 +22,13 @@ import {$cloneContents} from '@lexical/helpers/selection';
|
|||||||
import {
|
import {
|
||||||
$createNodeFromParse,
|
$createNodeFromParse,
|
||||||
$createParagraphNode,
|
$createParagraphNode,
|
||||||
|
$getDecoratorNode,
|
||||||
$getSelection,
|
$getSelection,
|
||||||
$isDecoratorNode,
|
$isDecoratorNode,
|
||||||
$isElementNode,
|
$isElementNode,
|
||||||
$isRangeSelection,
|
$isRangeSelection,
|
||||||
} from 'lexical';
|
} from 'lexical';
|
||||||
|
|
||||||
import getPossibleDecoratorNode from '../../shared/src/getPossibleDecoratorNode';
|
|
||||||
|
|
||||||
// TODO the Flow types here needs fixing
|
// TODO the Flow types here needs fixing
|
||||||
export type EventHandler = (
|
export type EventHandler = (
|
||||||
// $FlowFixMe: not sure how to handle this generic properly
|
// $FlowFixMe: not sure how to handle this generic properly
|
||||||
@ -216,7 +215,7 @@ export function $shouldOverrideDefaultCharacterSelection(
|
|||||||
selection: RangeSelection,
|
selection: RangeSelection,
|
||||||
isBackward: boolean,
|
isBackward: boolean,
|
||||||
): boolean {
|
): boolean {
|
||||||
const possibleNode = getPossibleDecoratorNode(selection.focus, isBackward);
|
const possibleNode = $getDecoratorNode(selection.focus, isBackward);
|
||||||
return $isDecoratorNode(possibleNode) && !possibleNode.isIsolated();
|
return $isDecoratorNode(possibleNode) && !possibleNode.isIsolated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
931
packages/lexical/Lexical.js.flow
Normal file
931
packages/lexical/Lexical.js.flow
Normal file
@ -0,0 +1,931 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type {Node as ReactNode} from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalEditor
|
||||||
|
*/
|
||||||
|
|
||||||
|
type MutationListeners = Map<MutationListener, Class<LexicalNode>>;
|
||||||
|
export type NodeMutation = 'created' | 'destroyed';
|
||||||
|
export type ErrorListener = (error: Error) => void;
|
||||||
|
type UpdateListener = ({
|
||||||
|
tags: Set<string>,
|
||||||
|
prevEditorState: EditorState,
|
||||||
|
editorState: EditorState,
|
||||||
|
dirtyLeaves: Set<NodeKey>,
|
||||||
|
dirtyElements: Map<NodeKey, IntentionallyMarkedAsDirtyElement>,
|
||||||
|
normalizedNodes: Set<NodeKey>,
|
||||||
|
}) => void;
|
||||||
|
type DecoratorListener = (decorator: {
|
||||||
|
[NodeKey]: ReactNode,
|
||||||
|
}) => void;
|
||||||
|
type RootListener = (
|
||||||
|
element: null | HTMLElement,
|
||||||
|
element: null | HTMLElement,
|
||||||
|
) => void;
|
||||||
|
type TextContentListener = (text: string) => void;
|
||||||
|
type MutationListener = (nodes: Map<NodeKey, NodeMutation>) => void;
|
||||||
|
type CommandListener = (
|
||||||
|
type: string,
|
||||||
|
payload: CommandPayload,
|
||||||
|
editor: LexicalEditor,
|
||||||
|
) => boolean;
|
||||||
|
|
||||||
|
//$FlowFixMe
|
||||||
|
type CommandPayload = any;
|
||||||
|
type Listeners = {
|
||||||
|
decorator: Set<DecoratorListener>,
|
||||||
|
error: Set<ErrorListener>,
|
||||||
|
mutation: MutationListeners,
|
||||||
|
textcontent: Set<TextContentListener>,
|
||||||
|
root: Set<RootListener>,
|
||||||
|
update: Set<UpdateListener>,
|
||||||
|
command: Array<Set<CommandListener>>,
|
||||||
|
};
|
||||||
|
type RegisteredNodes = Map<string, RegisteredNode>;
|
||||||
|
type RegisteredNode = {
|
||||||
|
klass: Class<LexicalNode>,
|
||||||
|
transforms: Set<Transform<LexicalNode>>,
|
||||||
|
};
|
||||||
|
type Transform<T> = (node: T) => void;
|
||||||
|
|
||||||
|
type DOMConversionCache = Map<
|
||||||
|
string,
|
||||||
|
Array<(node: Node) => DOMConversion | null>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
declare export class LexicalEditor {
|
||||||
|
_htmlConversions: DOMConversionCache;
|
||||||
|
_parentEditor: null | LexicalEditor;
|
||||||
|
_rootElement: null | HTMLElement;
|
||||||
|
_editorState: EditorState;
|
||||||
|
_pendingEditorState: null | EditorState;
|
||||||
|
_compositionKey: null | NodeKey;
|
||||||
|
_deferred: Array<() => void>;
|
||||||
|
_updates: Array<[() => void, void | EditorUpdateOptions]>;
|
||||||
|
_updating: boolean;
|
||||||
|
_keyToDOMMap: Map<NodeKey, HTMLElement>;
|
||||||
|
_listeners: Listeners;
|
||||||
|
_nodes: RegisteredNodes;
|
||||||
|
_decorators: {
|
||||||
|
[NodeKey]: ReactNode,
|
||||||
|
};
|
||||||
|
_pendingDecorators: null | {
|
||||||
|
[NodeKey]: ReactNode,
|
||||||
|
};
|
||||||
|
_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;
|
||||||
|
isComposing(): boolean;
|
||||||
|
addListener(type: 'error', listener: ErrorListener): () => void;
|
||||||
|
addListener(type: 'update', listener: UpdateListener): () => void;
|
||||||
|
addListener(type: 'root', listener: RootListener): () => void;
|
||||||
|
addListener(type: 'decorator', listener: DecoratorListener): () => void;
|
||||||
|
addListener(type: 'textcontent', listener: TextContentListener): () => void;
|
||||||
|
addListener(
|
||||||
|
type: 'command',
|
||||||
|
listener: CommandListener,
|
||||||
|
priority: CommandListenerPriority,
|
||||||
|
): () => void;
|
||||||
|
addListener(
|
||||||
|
type: 'mutation',
|
||||||
|
klass: Class<LexicalNode>,
|
||||||
|
listener: MutationListener,
|
||||||
|
): () => void;
|
||||||
|
addTransform<T: LexicalNode>(
|
||||||
|
klass: Class<T>,
|
||||||
|
listener: Transform<T>,
|
||||||
|
): () => void;
|
||||||
|
execCommand(type: string, payload: CommandPayload): boolean;
|
||||||
|
hasNodes(nodes: Array<Class<LexicalNode>>): boolean;
|
||||||
|
getDecorators(): {
|
||||||
|
[NodeKey]: ReactNode,
|
||||||
|
};
|
||||||
|
getRootElement(): null | HTMLElement;
|
||||||
|
setRootElement(rootElement: null | HTMLElement): void;
|
||||||
|
getElementByKey(key: NodeKey): null | HTMLElement;
|
||||||
|
getEditorState(): EditorState;
|
||||||
|
setEditorState(editorState: EditorState, options?: EditorSetOptions): void;
|
||||||
|
parseEditorState(stringifiedEditorState: string): EditorState;
|
||||||
|
update(updateFn: () => void, options?: EditorUpdateOptions): boolean;
|
||||||
|
focus(callbackFn?: () => void): void;
|
||||||
|
blur(): void;
|
||||||
|
}
|
||||||
|
type EditorUpdateOptions = {
|
||||||
|
onUpdate?: () => void,
|
||||||
|
tag?: string,
|
||||||
|
skipTransforms?: true,
|
||||||
|
};
|
||||||
|
type EditorSetOptions = {
|
||||||
|
tag?: string,
|
||||||
|
};
|
||||||
|
type EditorThemeClassName = string;
|
||||||
|
type TextNodeThemeClasses = {
|
||||||
|
base?: EditorThemeClassName,
|
||||||
|
bold?: EditorThemeClassName,
|
||||||
|
underline?: EditorThemeClassName,
|
||||||
|
strikethrough?: EditorThemeClassName,
|
||||||
|
underlineStrikethrough?: EditorThemeClassName,
|
||||||
|
italic?: EditorThemeClassName,
|
||||||
|
code?: EditorThemeClassName,
|
||||||
|
};
|
||||||
|
export type EditorThemeClasses = {
|
||||||
|
ltr?: EditorThemeClassName,
|
||||||
|
rtl?: EditorThemeClassName,
|
||||||
|
root?: EditorThemeClassName,
|
||||||
|
text?: TextNodeThemeClasses,
|
||||||
|
paragraph?: EditorThemeClassName,
|
||||||
|
image?: EditorThemeClassName,
|
||||||
|
list?: {
|
||||||
|
ul?: EditorThemeClassName,
|
||||||
|
ul1?: EditorThemeClassName,
|
||||||
|
ul2?: EditorThemeClassName,
|
||||||
|
ul3?: EditorThemeClassName,
|
||||||
|
ul4?: EditorThemeClassName,
|
||||||
|
ul5?: EditorThemeClassName,
|
||||||
|
ol?: EditorThemeClassName,
|
||||||
|
ol1?: EditorThemeClassName,
|
||||||
|
ol2?: EditorThemeClassName,
|
||||||
|
ol3?: EditorThemeClassName,
|
||||||
|
ol4?: EditorThemeClassName,
|
||||||
|
ol5?: EditorThemeClassName,
|
||||||
|
listitem?: EditorThemeClassName,
|
||||||
|
nested?: {
|
||||||
|
list?: EditorThemeClassName,
|
||||||
|
listitem?: EditorThemeClassName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
table?: EditorThemeClassName,
|
||||||
|
tableRow?: EditorThemeClassName,
|
||||||
|
tableCell?: EditorThemeClassName,
|
||||||
|
tableCellHeader?: EditorThemeClassName,
|
||||||
|
link?: EditorThemeClassName,
|
||||||
|
quote?: EditorThemeClassName,
|
||||||
|
code?: EditorThemeClassName,
|
||||||
|
codeHighlight?: {[string]: EditorThemeClassName},
|
||||||
|
hashtag?: EditorThemeClassName,
|
||||||
|
heading?: {
|
||||||
|
h1?: EditorThemeClassName,
|
||||||
|
h2?: EditorThemeClassName,
|
||||||
|
h3?: EditorThemeClassName,
|
||||||
|
h4?: EditorThemeClassName,
|
||||||
|
h5?: EditorThemeClassName,
|
||||||
|
},
|
||||||
|
// Handle other generic values
|
||||||
|
[string]: EditorThemeClassName | {[string]: EditorThemeClassName},
|
||||||
|
};
|
||||||
|
export type EditorConfig<EditorContext> = {
|
||||||
|
namespace: string,
|
||||||
|
theme: EditorThemeClasses,
|
||||||
|
context: EditorContext,
|
||||||
|
disableEvents?: boolean,
|
||||||
|
};
|
||||||
|
export type CommandListenerEditorPriority = 0;
|
||||||
|
export type CommandListenerLowPriority = 1;
|
||||||
|
export type CommandListenerNormalPriority = 2;
|
||||||
|
export type CommandListenerHighPriority = 3;
|
||||||
|
export type CommandListenerCriticalPriority = 4;
|
||||||
|
type CommandListenerPriority =
|
||||||
|
| CommandListenerEditorPriority
|
||||||
|
| CommandListenerLowPriority
|
||||||
|
| CommandListenerNormalPriority
|
||||||
|
| CommandListenerHighPriority
|
||||||
|
| CommandListenerCriticalPriority;
|
||||||
|
|
||||||
|
export type IntentionallyMarkedAsDirtyElement = boolean;
|
||||||
|
declare export function createEditor<EditorContext>(editorConfig?: {
|
||||||
|
namespace?: string,
|
||||||
|
editorState?: EditorState,
|
||||||
|
theme?: EditorThemeClasses,
|
||||||
|
context?: EditorContext,
|
||||||
|
parentEditor?: LexicalEditor,
|
||||||
|
nodes?: Array<Class<LexicalNode>>,
|
||||||
|
onError?: (error: Error) => void,
|
||||||
|
disableEvents?: boolean,
|
||||||
|
}): LexicalEditor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalEditorState
|
||||||
|
*/
|
||||||
|
export type ParsedEditorState = {
|
||||||
|
_selection: null | {
|
||||||
|
anchor: {
|
||||||
|
key: string,
|
||||||
|
offset: number,
|
||||||
|
type: 'text' | 'element',
|
||||||
|
},
|
||||||
|
focus: {
|
||||||
|
key: string,
|
||||||
|
offset: number,
|
||||||
|
type: 'text' | 'element',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
_nodeMap: Array<[NodeKey, ParsedNode]>,
|
||||||
|
};
|
||||||
|
type JSONEditorState = {
|
||||||
|
_nodeMap: Array<[NodeKey, LexicalNode]>,
|
||||||
|
_selection: null | ParsedSelection,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export class EditorState {
|
||||||
|
_nodeMap: NodeMap;
|
||||||
|
_selection: null | RangeSelection | NodeSelection | GridSelection;
|
||||||
|
_flushSync: boolean;
|
||||||
|
_readOnly: boolean;
|
||||||
|
constructor(
|
||||||
|
nodeMap: NodeMap,
|
||||||
|
selection?: RangeSelection | NodeSelection | GridSelection | null,
|
||||||
|
): void;
|
||||||
|
isEmpty(): boolean;
|
||||||
|
read<V>(callbackFn: () => V): V;
|
||||||
|
toJSON(space?: string | number): JSONEditorState;
|
||||||
|
clone(
|
||||||
|
selection?: RangeSelection | NodeSelection | GridSelection | null,
|
||||||
|
): EditorState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalNode
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type NodeKey = string;
|
||||||
|
declare export class LexicalNode {
|
||||||
|
__type: string;
|
||||||
|
__key: NodeKey;
|
||||||
|
__parent: null | NodeKey;
|
||||||
|
static getType(): string;
|
||||||
|
static clone(data: $FlowFixMe): LexicalNode;
|
||||||
|
constructor(key?: NodeKey): void;
|
||||||
|
getType(): string;
|
||||||
|
isAttached(): boolean;
|
||||||
|
isSelected(): boolean;
|
||||||
|
getKey(): NodeKey;
|
||||||
|
getIndexWithinParent(): number;
|
||||||
|
getParent(): ElementNode | null;
|
||||||
|
getParentOrThrow(): ElementNode;
|
||||||
|
getTopLevelElement(): null | ElementNode;
|
||||||
|
getTopLevelElementOrThrow(): ElementNode;
|
||||||
|
getParents(): Array<ElementNode>;
|
||||||
|
getParentKeys(): Array<NodeKey>;
|
||||||
|
getPreviousSibling(): LexicalNode | null;
|
||||||
|
getPreviousSiblings(): Array<LexicalNode>;
|
||||||
|
getNextSibling(): LexicalNode | null;
|
||||||
|
getNextSiblings(): Array<LexicalNode>;
|
||||||
|
getCommonAncestor(node: LexicalNode): ElementNode | null;
|
||||||
|
is(object: ?LexicalNode): boolean;
|
||||||
|
isBefore(targetNode: LexicalNode): boolean;
|
||||||
|
isParentOf(targetNode: LexicalNode): boolean;
|
||||||
|
getNodesBetween(targetNode: LexicalNode): Array<LexicalNode>;
|
||||||
|
isDirty(): boolean;
|
||||||
|
isComposing(): boolean;
|
||||||
|
// $FlowFixMe
|
||||||
|
getLatest<T: LexicalNode>(this: T): T;
|
||||||
|
// $FlowFixMe
|
||||||
|
getWritable<T: LexicalNode>(this: T): T;
|
||||||
|
getTextContent(includeInert?: boolean, includeDirectionless?: false): string;
|
||||||
|
getTextContentSize(
|
||||||
|
includeInert?: boolean,
|
||||||
|
includeDirectionless?: false,
|
||||||
|
): number;
|
||||||
|
// $FlowFixMe
|
||||||
|
createDOM<EditorContext: Object>(
|
||||||
|
config: EditorConfig<EditorContext>,
|
||||||
|
editor: LexicalEditor,
|
||||||
|
): HTMLElement;
|
||||||
|
// $FlowFixMe
|
||||||
|
updateDOM<EditorContext: Object>(
|
||||||
|
// $FlowFixMe
|
||||||
|
prevNode: any,
|
||||||
|
dom: HTMLElement,
|
||||||
|
config: EditorConfig<EditorContext>,
|
||||||
|
): boolean;
|
||||||
|
remove(): void;
|
||||||
|
replace<N: LexicalNode>(replaceWith: N): N;
|
||||||
|
insertAfter(nodeToInsert: LexicalNode): LexicalNode;
|
||||||
|
insertBefore(nodeToInsert: LexicalNode): LexicalNode;
|
||||||
|
selectPrevious(anchorOffset?: number, focusOffset?: number): Selection;
|
||||||
|
selectNext(anchorOffset?: number, focusOffset?: number): Selection;
|
||||||
|
markDirty(): void;
|
||||||
|
}
|
||||||
|
export type NodeMap = Map<NodeKey, LexicalNode>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalParsing
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type ParsedNode = {
|
||||||
|
__key: NodeKey,
|
||||||
|
__type: string,
|
||||||
|
__parent: null | NodeKey,
|
||||||
|
...
|
||||||
|
};
|
||||||
|
export type ParsedNodeMap = Map<NodeKey, ParsedNode>;
|
||||||
|
declare export function $createNodeFromParse(
|
||||||
|
parsedNode: ParsedNode,
|
||||||
|
parsedNodeMap: ParsedNodeMap,
|
||||||
|
): LexicalNode;
|
||||||
|
type ParsedSelection = {
|
||||||
|
anchor: {
|
||||||
|
key: NodeKey,
|
||||||
|
offset: number,
|
||||||
|
type: 'text' | 'element',
|
||||||
|
},
|
||||||
|
focus: {
|
||||||
|
key: NodeKey,
|
||||||
|
offset: number,
|
||||||
|
type: 'text' | 'element',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalSelection
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface BaseSelection {
|
||||||
|
clone(): BaseSelection;
|
||||||
|
dirty: boolean;
|
||||||
|
extract(): Array<LexicalNode>;
|
||||||
|
getNodes(): Array<LexicalNode>;
|
||||||
|
getTextContent(): string;
|
||||||
|
insertRawText(text: string): void;
|
||||||
|
is(selection: null | RangeSelection | NodeSelection | GridSelection): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare export class GridSelection implements BaseSelection {
|
||||||
|
gridKey: NodeKey;
|
||||||
|
anchorCellKey: NodeKey;
|
||||||
|
focusCellKey: NodeKey;
|
||||||
|
dirty: boolean;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
gridKey: NodeKey,
|
||||||
|
anchorCellKey: NodeKey,
|
||||||
|
focusCellKey: NodeKey,
|
||||||
|
): void;
|
||||||
|
|
||||||
|
is(selection: null | RangeSelection | NodeSelection | GridSelection): boolean;
|
||||||
|
|
||||||
|
set(gridKey: NodeKey, anchorCellKey: NodeKey, focusCellKey: NodeKey): void;
|
||||||
|
|
||||||
|
clone(): GridSelection;
|
||||||
|
|
||||||
|
extract(): Array<LexicalNode>;
|
||||||
|
|
||||||
|
insertRawText(): void;
|
||||||
|
|
||||||
|
insertText(): void;
|
||||||
|
|
||||||
|
getNodes(): Array<LexicalNode>;
|
||||||
|
|
||||||
|
getTextContent(): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare export function $isGridSelection(
|
||||||
|
x: ?mixed,
|
||||||
|
): boolean %checks(x instanceof GridSelection);
|
||||||
|
|
||||||
|
declare export class NodeSelection implements BaseSelection {
|
||||||
|
_nodes: Set<NodeKey>;
|
||||||
|
dirty: boolean;
|
||||||
|
|
||||||
|
constructor(objects: Set<NodeKey>): void;
|
||||||
|
|
||||||
|
is(selection: null | RangeSelection | NodeSelection | GridSelection): 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>;
|
||||||
|
|
||||||
|
getTextContent(): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare export function $isNodeSelection(
|
||||||
|
x: ?mixed,
|
||||||
|
): boolean %checks(x instanceof NodeSelection);
|
||||||
|
|
||||||
|
declare export class RangeSelection implements BaseSelection {
|
||||||
|
anchor: PointType;
|
||||||
|
focus: PointType;
|
||||||
|
dirty: boolean;
|
||||||
|
format: number;
|
||||||
|
constructor(anchor: PointType, focus: PointType, format: number): void;
|
||||||
|
is(selection: null | RangeSelection | GridSelection | NodeSelection): boolean;
|
||||||
|
isBackward(): boolean;
|
||||||
|
isCollapsed(): boolean;
|
||||||
|
getNodes(): Array<LexicalNode>;
|
||||||
|
setTextNodeRange(
|
||||||
|
anchorNode: TextNode,
|
||||||
|
anchorOffset: number,
|
||||||
|
focusNode: TextNode,
|
||||||
|
focusOffset: number,
|
||||||
|
): void;
|
||||||
|
getTextContent(): string;
|
||||||
|
// $FlowFixMe DOM API
|
||||||
|
applyDOMRange(range: StaticRange): void;
|
||||||
|
clone(): RangeSelection;
|
||||||
|
toggleFormat(format: TextFormatType): void;
|
||||||
|
hasFormat(type: TextFormatType): boolean;
|
||||||
|
insertText(text: string): void;
|
||||||
|
insertRawText(text: string): void;
|
||||||
|
removeText(): void;
|
||||||
|
formatText(formatType: TextFormatType): void;
|
||||||
|
insertNodes(nodes: Array<LexicalNode>, selectStart?: boolean): boolean;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
isAtNodeEnd: () => boolean,
|
||||||
|
};
|
||||||
|
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,
|
||||||
|
getCharacterOffset: () => number,
|
||||||
|
isAtNodeEnd: () => boolean,
|
||||||
|
};
|
||||||
|
export type Point = PointType;
|
||||||
|
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;
|
||||||
|
getCharacterOffset(): number;
|
||||||
|
getNode(): LexicalNode;
|
||||||
|
set(key: NodeKey, offset: number, type: 'text' | 'element'): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare export function $createRangeSelection(): RangeSelection;
|
||||||
|
declare export function $createNodeSelection(): NodeSelection;
|
||||||
|
declare export function $createGridSelection(): GridSelection;
|
||||||
|
declare export function $isRangeSelection(
|
||||||
|
x: ?mixed,
|
||||||
|
): boolean %checks(x instanceof RangeSelection);
|
||||||
|
declare export function $getSelection(): null | RangeSelection;
|
||||||
|
declare export function $getPreviousSelection(): null | RangeSelection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorator State
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type DecoratorStateValue =
|
||||||
|
| DecoratorMap
|
||||||
|
| DecoratorEditor
|
||||||
|
| DecoratorArray
|
||||||
|
| null
|
||||||
|
| boolean
|
||||||
|
| number
|
||||||
|
| string;
|
||||||
|
|
||||||
|
declare export class DecoratorEditor {
|
||||||
|
id: string;
|
||||||
|
editorState: null | EditorState | string;
|
||||||
|
editor: null | LexicalEditor;
|
||||||
|
|
||||||
|
constructor(id?: string, editorState?: string | EditorState): void;
|
||||||
|
|
||||||
|
init(editor: LexicalEditor): void;
|
||||||
|
|
||||||
|
set(editor: LexicalEditor): void;
|
||||||
|
|
||||||
|
toJSON(): $ReadOnly<{
|
||||||
|
id: string,
|
||||||
|
type: 'editor',
|
||||||
|
editorState: null | string,
|
||||||
|
}>;
|
||||||
|
|
||||||
|
isEmpty(): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DecoratorMapObserver = (
|
||||||
|
key: string,
|
||||||
|
value: DecoratorStateValue,
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
export type DecoratorArrayObserver = (
|
||||||
|
index: number,
|
||||||
|
delCont: number,
|
||||||
|
value: void | DecoratorStateValue,
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
declare export class DecoratorMap {
|
||||||
|
_editor: LexicalEditor;
|
||||||
|
_map: Map<string, DecoratorStateValue>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
editor: LexicalEditor,
|
||||||
|
map?: Map<string, DecoratorStateValue>,
|
||||||
|
): void;
|
||||||
|
|
||||||
|
get(key: string): void | DecoratorStateValue;
|
||||||
|
|
||||||
|
has(key: string): boolean;
|
||||||
|
|
||||||
|
set(key: string, value: DecoratorStateValue): void;
|
||||||
|
|
||||||
|
observe(observer: DecoratorMapObserver): () => void;
|
||||||
|
|
||||||
|
destroy(): void;
|
||||||
|
|
||||||
|
toJSON(): $ReadOnly<{
|
||||||
|
type: 'map',
|
||||||
|
map: Array<[string, DecoratorStateValue]>,
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare export function createDecoratorEditor(
|
||||||
|
id?: string,
|
||||||
|
editorState?: string | EditorState,
|
||||||
|
): DecoratorEditor;
|
||||||
|
|
||||||
|
declare export function isDecoratorEditor(
|
||||||
|
obj: ?mixed,
|
||||||
|
): boolean %checks(obj instanceof DecoratorEditor);
|
||||||
|
|
||||||
|
declare export function createDecoratorMap(
|
||||||
|
editor: LexicalEditor,
|
||||||
|
map?: Map<string, DecoratorStateValue>,
|
||||||
|
): DecoratorMap;
|
||||||
|
|
||||||
|
declare export function isDecoratorMap(
|
||||||
|
obj: ?mixed,
|
||||||
|
): boolean %checks(obj instanceof DecoratorMap);
|
||||||
|
|
||||||
|
declare export class DecoratorArray {
|
||||||
|
_editor: LexicalEditor;
|
||||||
|
_observers: Set<DecoratorArrayObserver>;
|
||||||
|
_array: Array<DecoratorStateValue>;
|
||||||
|
|
||||||
|
constructor(editor: LexicalEditor, array?: Array<DecoratorStateValue>): void;
|
||||||
|
|
||||||
|
observe(observer: DecoratorArrayObserver): () => void;
|
||||||
|
|
||||||
|
map<V>(
|
||||||
|
fn: (DecoratorStateValue, number, Array<DecoratorStateValue>) => V,
|
||||||
|
): Array<V>;
|
||||||
|
|
||||||
|
reduce(
|
||||||
|
fn: (DecoratorStateValue, DecoratorStateValue) => DecoratorStateValue,
|
||||||
|
initial?: DecoratorStateValue,
|
||||||
|
): DecoratorStateValue | void;
|
||||||
|
|
||||||
|
push(value: DecoratorStateValue): void;
|
||||||
|
|
||||||
|
getLength(): number;
|
||||||
|
|
||||||
|
splice(
|
||||||
|
insertIndex: number,
|
||||||
|
delCount: number,
|
||||||
|
value?: DecoratorStateValue,
|
||||||
|
): void;
|
||||||
|
|
||||||
|
indexOf(value: DecoratorStateValue): number;
|
||||||
|
|
||||||
|
destroy(): void;
|
||||||
|
|
||||||
|
toJSON(): $ReadOnly<{
|
||||||
|
type: 'array',
|
||||||
|
array: Array<DecoratorStateValue>,
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare export function createDecoratorArray(
|
||||||
|
editor: LexicalEditor,
|
||||||
|
list?: Array<DecoratorStateValue>,
|
||||||
|
): DecoratorArray;
|
||||||
|
|
||||||
|
declare export function isDecoratorArray(
|
||||||
|
x?: mixed,
|
||||||
|
): boolean %checks(x instanceof DecoratorArray);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalTextNode
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type TextFormatType =
|
||||||
|
| 'bold'
|
||||||
|
| 'underline'
|
||||||
|
| 'strikethrough'
|
||||||
|
| 'italic'
|
||||||
|
| 'code'
|
||||||
|
| 'subscript'
|
||||||
|
| 'superscript';
|
||||||
|
type TextModeType = 'normal' | 'token' | 'segmented' | 'inert';
|
||||||
|
|
||||||
|
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;
|
||||||
|
getFormat(): number;
|
||||||
|
getStyle(): string;
|
||||||
|
isToken(): boolean;
|
||||||
|
isSegmented(): boolean;
|
||||||
|
isInert(): boolean;
|
||||||
|
isDirectionless(): boolean;
|
||||||
|
isUnmergeable(): boolean;
|
||||||
|
hasFormat(type: TextFormatType): boolean;
|
||||||
|
isSimpleText(): boolean;
|
||||||
|
getTextContent(includeInert?: boolean, includeDirectionless?: false): string;
|
||||||
|
getFormatFlags(type: TextFormatType, alignWithFormat: null | number): number;
|
||||||
|
// $FlowFixMe
|
||||||
|
createDOM<EditorContext: Object>(
|
||||||
|
config: EditorConfig<EditorContext>,
|
||||||
|
): HTMLElement;
|
||||||
|
// $FlowFixMe
|
||||||
|
updateDOM<EditorContext: Object>(
|
||||||
|
prevNode: TextNode,
|
||||||
|
dom: HTMLElement,
|
||||||
|
config: EditorConfig<EditorContext>,
|
||||||
|
): boolean;
|
||||||
|
selectionTransform(
|
||||||
|
prevSelection: null | RangeSelection,
|
||||||
|
nextSelection: RangeSelection,
|
||||||
|
): void;
|
||||||
|
setFormat(format: number): this;
|
||||||
|
setStyle(style: string): this;
|
||||||
|
toggleFormat(type: TextFormatType): TextNode;
|
||||||
|
toggleDirectionless(): this;
|
||||||
|
toggleUnmergeable(): this;
|
||||||
|
setMode(type: TextModeType): this;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
declare export function $createTextNode(text?: string): TextNode;
|
||||||
|
declare export function $isTextNode(
|
||||||
|
node: ?LexicalNode,
|
||||||
|
): boolean %checks(node instanceof TextNode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
declare export function $createLineBreakNode(): LineBreakNode;
|
||||||
|
declare export function $isLineBreakNode(
|
||||||
|
node: ?LexicalNode,
|
||||||
|
): boolean %checks(node instanceof LineBreakNode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalRootNode
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare export class RootNode extends ElementNode {
|
||||||
|
__cachedText: null | string;
|
||||||
|
static getType(): string;
|
||||||
|
static clone(): RootNode;
|
||||||
|
constructor(): void;
|
||||||
|
getTextContent(includeInert?: boolean, includeDirectionless?: false): string;
|
||||||
|
select(): RangeSelection;
|
||||||
|
remove(): void;
|
||||||
|
replace<N: LexicalNode>(node: N): N;
|
||||||
|
insertBefore(): LexicalNode;
|
||||||
|
insertAfter(node: LexicalNode): LexicalNode;
|
||||||
|
updateDOM(prevNode: RootNode, dom: HTMLElement): false;
|
||||||
|
append(...nodesToAppend: Array<LexicalNode>): ElementNode;
|
||||||
|
canBeEmpty(): false;
|
||||||
|
}
|
||||||
|
declare export function $isRootNode(
|
||||||
|
node: ?LexicalNode,
|
||||||
|
): boolean %checks(node instanceof RootNode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalElementNode
|
||||||
|
*/
|
||||||
|
export type ElementFormatType = 'left' | 'center' | 'right' | 'justify';
|
||||||
|
declare export class ElementNode extends LexicalNode {
|
||||||
|
__children: Array<NodeKey>;
|
||||||
|
__format: number;
|
||||||
|
__indent: number;
|
||||||
|
__dir: 'ltr' | 'rtl' | null;
|
||||||
|
constructor(key?: NodeKey): void;
|
||||||
|
getFormat(): number;
|
||||||
|
getIndent(): number;
|
||||||
|
getChildren(): Array<LexicalNode>;
|
||||||
|
getChildrenKeys(): Array<NodeKey>;
|
||||||
|
getChildrenSize(): number;
|
||||||
|
isEmpty(): boolean;
|
||||||
|
isDirty(): boolean;
|
||||||
|
getAllTextNodes(includeInert?: boolean): Array<TextNode>;
|
||||||
|
getFirstDescendant(): null | LexicalNode;
|
||||||
|
getLastDescendant(): null | LexicalNode;
|
||||||
|
getDescendantByIndex(index: number): LexicalNode;
|
||||||
|
getFirstChild<T: LexicalNode>(): null | T;
|
||||||
|
getFirstChildOrThrow<T: LexicalNode>(): T;
|
||||||
|
getLastChild(): null | LexicalNode;
|
||||||
|
getChildAtIndex(index: number): null | LexicalNode;
|
||||||
|
getTextContent(includeInert?: boolean, includeDirectionless?: false): string;
|
||||||
|
getDirection(): 'ltr' | 'rtl' | null;
|
||||||
|
hasFormat(type: ElementFormatType): boolean;
|
||||||
|
select(_anchorOffset?: number, _focusOffset?: number): RangeSelection;
|
||||||
|
selectStart(): RangeSelection;
|
||||||
|
selectEnd(): RangeSelection;
|
||||||
|
clear(): ElementNode;
|
||||||
|
append(...nodesToAppend: Array<LexicalNode>): ElementNode;
|
||||||
|
setDirection(direction: 'ltr' | 'rtl' | null): this;
|
||||||
|
setFormat(type: ElementFormatType): this;
|
||||||
|
setIndent(indentLevel: number): this;
|
||||||
|
insertNewAfter(selection: RangeSelection): null | LexicalNode;
|
||||||
|
canInsertTab(): boolean;
|
||||||
|
collapseAtStart(selection: RangeSelection): boolean;
|
||||||
|
excludeFromCopy(): boolean;
|
||||||
|
canExtractContents(): boolean;
|
||||||
|
canReplaceWith(replacement: LexicalNode): boolean;
|
||||||
|
canInsertAfter(node: LexicalNode): boolean;
|
||||||
|
canBeEmpty(): boolean;
|
||||||
|
canInsertTextBefore(): boolean;
|
||||||
|
canInsertTextAfter(): boolean;
|
||||||
|
isInline(): boolean;
|
||||||
|
canSelectionRemove(): boolean;
|
||||||
|
splice(
|
||||||
|
start: number,
|
||||||
|
deleteCount: number,
|
||||||
|
nodesToInsert: Array<LexicalNode>,
|
||||||
|
): ElementNode;
|
||||||
|
}
|
||||||
|
declare export function $isElementNode(
|
||||||
|
node: ?LexicalNode,
|
||||||
|
): boolean %checks(node instanceof ElementNode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalDecoratorNode
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare export class DecoratorNode extends LexicalNode {
|
||||||
|
__state: DecoratorMap;
|
||||||
|
constructor(state?: DecoratorMap, key?: NodeKey): void;
|
||||||
|
decorate(editor: LexicalEditor): ReactNode;
|
||||||
|
isIsolated(): boolean;
|
||||||
|
}
|
||||||
|
declare export function $isDecoratorNode(
|
||||||
|
node: ?LexicalNode,
|
||||||
|
): boolean %checks(node instanceof DecoratorNode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalHorizontalRuleNode
|
||||||
|
*/
|
||||||
|
declare export class HorizontalRuleNode extends LexicalNode {
|
||||||
|
static getType(): string;
|
||||||
|
static clone(node: HorizontalRuleNode): HorizontalRuleNode;
|
||||||
|
constructor(key?: NodeKey): void;
|
||||||
|
createDOM(): HTMLElement;
|
||||||
|
updateDOM(): false;
|
||||||
|
}
|
||||||
|
declare export function $createHorizontalRuleNode(): HorizontalRuleNode;
|
||||||
|
declare export function $isHorizontalRuleNode(node: ?LexicalNode): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalParagraphNode
|
||||||
|
*/
|
||||||
|
declare export class ParagraphNode extends ElementNode {
|
||||||
|
static getType(): string;
|
||||||
|
static clone(node: ParagraphNode): ParagraphNode;
|
||||||
|
constructor(key?: NodeKey): void;
|
||||||
|
createDOM<EditorContext>(config: EditorConfig<EditorContext>): HTMLElement;
|
||||||
|
updateDOM(prevNode: ParagraphNode, dom: HTMLElement): boolean;
|
||||||
|
insertNewAfter(): ParagraphNode;
|
||||||
|
collapseAtStart(): boolean;
|
||||||
|
}
|
||||||
|
declare export function $createParagraphNode(): ParagraphNode;
|
||||||
|
declare export function $isParagraphNode(
|
||||||
|
node: ?LexicalNode,
|
||||||
|
): boolean %checks(node instanceof ParagraphNode);
|
||||||
|
|
||||||
|
declare export class GridNode extends ElementNode {}
|
||||||
|
|
||||||
|
declare export function $isGridNode(
|
||||||
|
node: ?LexicalNode,
|
||||||
|
): boolean %checks(node instanceof GridNode);
|
||||||
|
|
||||||
|
declare export class GridRowNode extends ElementNode {}
|
||||||
|
|
||||||
|
declare export function $isGridRowNode(
|
||||||
|
node: ?LexicalNode,
|
||||||
|
): boolean %checks(node instanceof GridRowNode);
|
||||||
|
|
||||||
|
declare export class GridCellNode extends ElementNode {
|
||||||
|
__colSpan: number;
|
||||||
|
|
||||||
|
constructor(colSpan: number, key?: NodeKey): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare export function $isGridCellNode(
|
||||||
|
node: ?LexicalNode,
|
||||||
|
): boolean %checks(node instanceof GridCellNode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LexicalUtils
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare export function $getNearestNodeFromDOMNode(
|
||||||
|
startingDOM: Node,
|
||||||
|
): LexicalNode | null;
|
||||||
|
declare export function $getNodeByKey<N: LexicalNode>(key: NodeKey): N | null;
|
||||||
|
declare export function $getRoot(): RootNode;
|
||||||
|
declare export function $isLeafNode(node: ?LexicalNode): boolean;
|
||||||
|
declare export function $setCompositionKey(
|
||||||
|
compositionKey: null | NodeKey,
|
||||||
|
): void;
|
||||||
|
declare export function $setSelection(
|
||||||
|
selection: null | RangeSelection | NodeSelection | GridSelection,
|
||||||
|
): void;
|
||||||
|
|
||||||
|
declare export var VERSION: string;
|
||||||
|
|
||||||
|
export type DOMConversion = {
|
||||||
|
conversion: DOMConversionFn,
|
||||||
|
priority: 0 | 1 | 2 | 3 | 4,
|
||||||
|
};
|
||||||
|
export type DOMConversionFn = (
|
||||||
|
element: Node,
|
||||||
|
parent?: Node,
|
||||||
|
) => DOMConversionOutput;
|
||||||
|
export type DOMChildConversion = (lexicalNode: LexicalNode) => void;
|
||||||
|
export type DOMConversionMap = {
|
||||||
|
[NodeName]: (node: Node) => DOMConversion | null,
|
||||||
|
};
|
||||||
|
type NodeName = string;
|
||||||
|
export type DOMConversionOutput = {
|
||||||
|
after?: (childLexicalNodes: Array<LexicalNode>) => Array<LexicalNode>,
|
||||||
|
forChild?: DOMChildConversion,
|
||||||
|
node: LexicalNode | null,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare export function $getDecoratorNode(
|
||||||
|
focus: Point,
|
||||||
|
isBackward: boolean,
|
||||||
|
): null | LexicalNode;
|
@ -14,7 +14,6 @@ import type {ParsedSelection} from './LexicalParsing';
|
|||||||
import type {ElementNode} from './nodes/base/LexicalElementNode';
|
import type {ElementNode} from './nodes/base/LexicalElementNode';
|
||||||
import type {TextFormatType} from './nodes/base/LexicalTextNode';
|
import type {TextFormatType} from './nodes/base/LexicalTextNode';
|
||||||
|
|
||||||
import getPossibleDecoratorNode from 'shared/getPossibleDecoratorNode';
|
|
||||||
import invariant from 'shared/invariant';
|
import invariant from 'shared/invariant';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -38,6 +37,7 @@ import {
|
|||||||
} from './LexicalUpdates';
|
} from './LexicalUpdates';
|
||||||
import {
|
import {
|
||||||
$getCompositionKey,
|
$getCompositionKey,
|
||||||
|
$getDecoratorNode,
|
||||||
$getNodeByKey,
|
$getNodeByKey,
|
||||||
$isTokenOrInert,
|
$isTokenOrInert,
|
||||||
$setCompositionKey,
|
$setCompositionKey,
|
||||||
@ -378,6 +378,7 @@ export class GridSelection implements BaseSelection {
|
|||||||
return textContent;
|
return textContent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function $isGridSelection(x: ?mixed): boolean %checks {
|
export function $isGridSelection(x: ?mixed): boolean %checks {
|
||||||
return x instanceof GridSelection;
|
return x instanceof GridSelection;
|
||||||
}
|
}
|
||||||
@ -1355,7 +1356,7 @@ export class RangeSelection implements BaseSelection {
|
|||||||
const collapse = alter === 'move';
|
const collapse = alter === 'move';
|
||||||
|
|
||||||
// Handle the selection movement around decorators.
|
// Handle the selection movement around decorators.
|
||||||
const possibleNode = getPossibleDecoratorNode(focus, isBackward);
|
const possibleNode = $getDecoratorNode(focus, isBackward);
|
||||||
if ($isDecoratorNode(possibleNode) && !possibleNode.isIsolated()) {
|
if ($isDecoratorNode(possibleNode) && !possibleNode.isIsolated()) {
|
||||||
const sibling = isBackward
|
const sibling = isBackward
|
||||||
? possibleNode.getPreviousSibling()
|
? possibleNode.getPreviousSibling()
|
||||||
|
@ -20,6 +20,7 @@ import type {LexicalNode, NodeKey, NodeMap} from './LexicalNode';
|
|||||||
import type {
|
import type {
|
||||||
GridSelection,
|
GridSelection,
|
||||||
NodeSelection,
|
NodeSelection,
|
||||||
|
PointType,
|
||||||
RangeSelection,
|
RangeSelection,
|
||||||
} from './LexicalSelection';
|
} from './LexicalSelection';
|
||||||
import type {RootNode} from './nodes/base/LexicalRootNode';
|
import type {RootNode} from './nodes/base/LexicalRootNode';
|
||||||
@ -38,6 +39,7 @@ import {
|
|||||||
$isLineBreakNode,
|
$isLineBreakNode,
|
||||||
$isRangeSelection,
|
$isRangeSelection,
|
||||||
$isTextNode,
|
$isTextNode,
|
||||||
|
ElementNode,
|
||||||
} from '.';
|
} from '.';
|
||||||
import {
|
import {
|
||||||
DOM_TEXT_TYPE,
|
DOM_TEXT_TYPE,
|
||||||
@ -840,3 +842,53 @@ export function $nodesOfType<T: LexicalNode>(klass: Class<T>): Array<T> {
|
|||||||
}
|
}
|
||||||
return nodesOfType;
|
return nodesOfType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveElement(
|
||||||
|
element: ElementNode,
|
||||||
|
isBackward: boolean,
|
||||||
|
focusOffset: number,
|
||||||
|
): LexicalNode | null {
|
||||||
|
const parent = element.getParent();
|
||||||
|
let offset = focusOffset;
|
||||||
|
let block = element;
|
||||||
|
if (parent !== null) {
|
||||||
|
if (isBackward && focusOffset === 0) {
|
||||||
|
offset = block.getIndexWithinParent();
|
||||||
|
block = parent;
|
||||||
|
} else if (!isBackward && focusOffset === block.getChildrenSize()) {
|
||||||
|
offset = block.getIndexWithinParent() + 1;
|
||||||
|
block = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return block.getChildAtIndex(isBackward ? offset - 1 : offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function $getDecoratorNode(
|
||||||
|
focus: PointType,
|
||||||
|
isBackward: boolean,
|
||||||
|
): null | LexicalNode {
|
||||||
|
const focusOffset = focus.offset;
|
||||||
|
if (focus.type === 'element') {
|
||||||
|
const block = focus.getNode();
|
||||||
|
return resolveElement(block, isBackward, focusOffset);
|
||||||
|
} else {
|
||||||
|
const focusNode = focus.getNode();
|
||||||
|
if (
|
||||||
|
(isBackward && focusOffset === 0) ||
|
||||||
|
(!isBackward && focusOffset === focusNode.getTextContentSize())
|
||||||
|
) {
|
||||||
|
const possibleNode = isBackward
|
||||||
|
? focusNode.getPreviousSibling()
|
||||||
|
: focusNode.getNextSibling();
|
||||||
|
if (possibleNode === null) {
|
||||||
|
return resolveElement(
|
||||||
|
focusNode.getParentOrThrow(),
|
||||||
|
isBackward,
|
||||||
|
focusNode.getIndexWithinParent() + (isBackward ? 0 : 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return possibleNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
$isRangeSelection,
|
$isRangeSelection,
|
||||||
} from './LexicalSelection';
|
} from './LexicalSelection';
|
||||||
import {
|
import {
|
||||||
|
$getDecoratorNode,
|
||||||
$getNearestNodeFromDOMNode,
|
$getNearestNodeFromDOMNode,
|
||||||
$getNodeByKey,
|
$getNodeByKey,
|
||||||
$getRoot,
|
$getRoot,
|
||||||
@ -59,50 +60,6 @@ import {
|
|||||||
TextNode,
|
TextNode,
|
||||||
} from './nodes/base/LexicalTextNode';
|
} from './nodes/base/LexicalTextNode';
|
||||||
|
|
||||||
export type {
|
|
||||||
CommandListenerCriticalPriority,
|
|
||||||
CommandListenerEditorPriority,
|
|
||||||
CommandListenerHighPriority,
|
|
||||||
CommandListenerLowPriority,
|
|
||||||
CommandListenerNormalPriority,
|
|
||||||
EditorConfig,
|
|
||||||
EditorThemeClasses,
|
|
||||||
IntentionallyMarkedAsDirtyElement,
|
|
||||||
LexicalEditor,
|
|
||||||
NodeMutation,
|
|
||||||
RegisteredNodes,
|
|
||||||
} from './LexicalEditor';
|
|
||||||
export type {EditorState, ParsedEditorState} from './LexicalEditorState';
|
|
||||||
export type {
|
|
||||||
DOMChildConversion,
|
|
||||||
DOMConversion,
|
|
||||||
DOMConversionFn,
|
|
||||||
DOMConversionMap,
|
|
||||||
DOMConversionOutput,
|
|
||||||
LexicalNode,
|
|
||||||
NodeKey,
|
|
||||||
NodeMap,
|
|
||||||
} from './LexicalNode';
|
|
||||||
export type {ParsedNode, ParsedNodeMap} from './LexicalParsing';
|
|
||||||
export type {
|
|
||||||
ElementPointType as ElementPoint,
|
|
||||||
GridSelection,
|
|
||||||
NodeSelection,
|
|
||||||
PointType as Point,
|
|
||||||
RangeSelection,
|
|
||||||
TextPointType as TextPoint,
|
|
||||||
} from './LexicalSelection';
|
|
||||||
export type {
|
|
||||||
DecoratorArray,
|
|
||||||
DecoratorEditor,
|
|
||||||
DecoratorMap,
|
|
||||||
DecoratorStateValue,
|
|
||||||
} from './nodes/base/LexicalDecoratorNode';
|
|
||||||
export type {ElementFormatType} from './nodes/base/LexicalElementNode';
|
|
||||||
export type {LineBreakNode} from './nodes/base/LexicalLineBreakNode';
|
|
||||||
export type {RootNode} from './nodes/base/LexicalRootNode';
|
|
||||||
export type {TextFormatType} from './nodes/base/LexicalTextNode';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
$createGridSelection,
|
$createGridSelection,
|
||||||
$createLineBreakNode,
|
$createLineBreakNode,
|
||||||
@ -111,6 +68,7 @@ export {
|
|||||||
$createParagraphNode,
|
$createParagraphNode,
|
||||||
$createRangeSelection,
|
$createRangeSelection,
|
||||||
$createTextNode,
|
$createTextNode,
|
||||||
|
$getDecoratorNode,
|
||||||
$getNearestNodeFromDOMNode,
|
$getNearestNodeFromDOMNode,
|
||||||
$getNodeByKey,
|
$getNodeByKey,
|
||||||
$getPreviousSelection,
|
$getPreviousSelection,
|
||||||
|
@ -7,9 +7,13 @@
|
|||||||
* @flow strict
|
* @flow strict
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {EditorThemeClasses} from '../../LexicalEditor';
|
import type {EditorConfig, EditorThemeClasses} from '../../LexicalEditor';
|
||||||
import type {DOMConversionMap, DOMConversionOutput} from '../../LexicalNode';
|
import type {
|
||||||
import type {EditorConfig, LexicalNode, NodeKey} from 'lexical';
|
DOMConversionMap,
|
||||||
|
DOMConversionOutput,
|
||||||
|
LexicalNode,
|
||||||
|
NodeKey,
|
||||||
|
} from '../../LexicalNode';
|
||||||
|
|
||||||
import {getCachedClassNameArray} from '../../LexicalUtils';
|
import {getCachedClassNameArray} from '../../LexicalUtils';
|
||||||
import {ElementNode} from './LexicalElementNode';
|
import {ElementNode} from './LexicalElementNode';
|
||||||
|
@ -7,8 +7,9 @@
|
|||||||
* @flow strict
|
* @flow strict
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {DOMConversionMap, DOMConversionOutput} from '../../LexicalNode';
|
|
||||||
import type {
|
import type {
|
||||||
|
DOMConversionMap,
|
||||||
|
DOMConversionOutput,
|
||||||
EditorConfig,
|
EditorConfig,
|
||||||
LexicalNode,
|
LexicalNode,
|
||||||
NodeKey,
|
NodeKey,
|
||||||
|
@ -7,8 +7,14 @@
|
|||||||
* @flow strict
|
* @flow strict
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {DOMConversionMap, DOMConversionOutput} from '../../LexicalNode';
|
import type {
|
||||||
import type {EditorConfig, LexicalNode, NodeKey, ParagraphNode} from 'lexical';
|
DOMConversionMap,
|
||||||
|
DOMConversionOutput,
|
||||||
|
EditorConfig,
|
||||||
|
LexicalNode,
|
||||||
|
NodeKey,
|
||||||
|
ParagraphNode,
|
||||||
|
} from 'lexical';
|
||||||
|
|
||||||
import {addClassNamesToElement} from '@lexical/helpers/elements';
|
import {addClassNamesToElement} from '@lexical/helpers/elements';
|
||||||
import {$createParagraphNode, ElementNode} from 'lexical';
|
import {$createParagraphNode, ElementNode} from 'lexical';
|
||||||
|
@ -7,8 +7,14 @@
|
|||||||
* @flow strict
|
* @flow strict
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {DOMConversionMap, DOMConversionOutput} from '../../LexicalNode';
|
import type {
|
||||||
import type {EditorConfig, LexicalNode, NodeKey, RangeSelection} from 'lexical';
|
DOMConversionMap,
|
||||||
|
DOMConversionOutput,
|
||||||
|
EditorConfig,
|
||||||
|
LexicalNode,
|
||||||
|
NodeKey,
|
||||||
|
RangeSelection,
|
||||||
|
} from 'lexical';
|
||||||
|
|
||||||
import {addClassNamesToElement} from '@lexical/helpers/elements';
|
import {addClassNamesToElement} from '@lexical/helpers/elements';
|
||||||
import {$isElementNode, ElementNode} from 'lexical';
|
import {$isElementNode, ElementNode} from 'lexical';
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type {ElementNode, LexicalNode, Point} from 'lexical';
|
|
||||||
|
|
||||||
function resolveElement(
|
|
||||||
element: ElementNode,
|
|
||||||
isBackward: boolean,
|
|
||||||
focusOffset: number,
|
|
||||||
): LexicalNode | null {
|
|
||||||
const parent = element.getParent();
|
|
||||||
let offset = focusOffset;
|
|
||||||
let block = element;
|
|
||||||
if (parent !== null) {
|
|
||||||
if (isBackward && focusOffset === 0) {
|
|
||||||
offset = block.getIndexWithinParent();
|
|
||||||
block = parent;
|
|
||||||
} else if (!isBackward && focusOffset === block.getChildrenSize()) {
|
|
||||||
offset = block.getIndexWithinParent() + 1;
|
|
||||||
block = parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return block.getChildAtIndex(isBackward ? offset - 1 : offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function getPossibleDecoratorNode(
|
|
||||||
focus: Point,
|
|
||||||
isBackward: boolean,
|
|
||||||
): null | LexicalNode {
|
|
||||||
const focusOffset = focus.offset;
|
|
||||||
if (focus.type === 'element') {
|
|
||||||
const block = focus.getNode();
|
|
||||||
return resolveElement(block, isBackward, focusOffset);
|
|
||||||
} else {
|
|
||||||
const focusNode = focus.getNode();
|
|
||||||
if (
|
|
||||||
(isBackward && focusOffset === 0) ||
|
|
||||||
(!isBackward && focusOffset === focusNode.getTextContentSize())
|
|
||||||
) {
|
|
||||||
const possibleNode = isBackward
|
|
||||||
? focusNode.getPreviousSibling()
|
|
||||||
: focusNode.getNextSibling();
|
|
||||||
if (possibleNode === null) {
|
|
||||||
return resolveElement(
|
|
||||||
focusNode.getParentOrThrow(),
|
|
||||||
isBackward,
|
|
||||||
focusNode.getIndexWithinParent() + (isBackward ? 0 : 1),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return possibleNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
Reference in New Issue
Block a user