Move Grid to @lexical/table (#5528)

This commit is contained in:
Gerard Rovira
2024-01-24 14:14:58 +00:00
committed by GitHub
parent e4fe60267c
commit 1154413a2c
19 changed files with 363 additions and 398 deletions

View File

@ -6,28 +6,27 @@
* *
*/ */
import type { import type {ElementNode, LexicalEditor} from 'lexical';
DEPRECATED_GridCellNode,
ElementNode,
LexicalEditor,
} from 'lexical';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext'; import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import useLexicalEditable from '@lexical/react/useLexicalEditable'; import useLexicalEditable from '@lexical/react/useLexicalEditable';
import { import {
$deleteTableColumn__EXPERIMENTAL, $deleteTableColumn__EXPERIMENTAL,
$deleteTableRow__EXPERIMENTAL, $deleteTableRow__EXPERIMENTAL,
$getNodeTriplet,
$getTableCellNodeFromLexicalNode, $getTableCellNodeFromLexicalNode,
$getTableColumnIndexFromTableCellNode, $getTableColumnIndexFromTableCellNode,
$getTableNodeFromLexicalNodeOrThrow, $getTableNodeFromLexicalNodeOrThrow,
$getTableRowIndexFromTableCellNode, $getTableRowIndexFromTableCellNode,
$insertTableColumn__EXPERIMENTAL, $insertTableColumn__EXPERIMENTAL,
$insertTableRow__EXPERIMENTAL, $insertTableRow__EXPERIMENTAL,
$isGridCellNode,
$isGridSelection, $isGridSelection,
$isTableCellNode, $isTableCellNode,
$isTableRowNode, $isTableRowNode,
$unmergeCell, $unmergeCell,
getTableSelectionFromTableElement, getTableSelectionFromTableElement,
GridCellNode,
GridSelection, GridSelection,
HTMLTableElementWithWithTableSelectionState, HTMLTableElementWithWithTableSelectionState,
TableCellHeaderStates, TableCellHeaderStates,
@ -42,8 +41,6 @@ import {
$isParagraphNode, $isParagraphNode,
$isRangeSelection, $isRangeSelection,
$isTextNode, $isTextNode,
DEPRECATED_$getNodeTriplet,
DEPRECATED_$isGridCellNode,
} from 'lexical'; } from 'lexical';
import * as React from 'react'; import * as React from 'react';
import {ReactPortal, useCallback, useEffect, useRef, useState} from 'react'; import {ReactPortal, useCallback, useEffect, useRef, useState} from 'react';
@ -115,11 +112,11 @@ function $canUnmerge(): boolean {
) { ) {
return false; return false;
} }
const [cell] = DEPRECATED_$getNodeTriplet(selection.anchor); const [cell] = $getNodeTriplet(selection.anchor);
return cell.__colSpan > 1 || cell.__rowSpan > 1; return cell.__colSpan > 1 || cell.__rowSpan > 1;
} }
function $cellContainsEmptyParagraph(cell: DEPRECATED_GridCellNode): boolean { function $cellContainsEmptyParagraph(cell: GridCellNode): boolean {
if (cell.getChildrenSize() !== 1) { if (cell.getChildrenSize() !== 1) {
return false; return false;
} }
@ -145,7 +142,7 @@ function currentCellBackgroundColor(editor: LexicalEditor): null | string {
return editor.getEditorState().read(() => { return editor.getEditorState().read(() => {
const selection = $getSelection(); const selection = $getSelection();
if ($isRangeSelection(selection) || $isGridSelection(selection)) { if ($isRangeSelection(selection) || $isGridSelection(selection)) {
const [cell] = DEPRECATED_$getNodeTriplet(selection.anchor); const [cell] = $getNodeTriplet(selection.anchor);
if ($isTableCellNode(cell)) { if ($isTableCellNode(cell)) {
return cell.getBackgroundColor(); return cell.getBackgroundColor();
} }
@ -303,10 +300,10 @@ function TableActionMenu({
if ($isGridSelection(selection)) { if ($isGridSelection(selection)) {
const {columns, rows} = computeSelectionCount(selection); const {columns, rows} = computeSelectionCount(selection);
const nodes = selection.getNodes(); const nodes = selection.getNodes();
let firstCell: null | DEPRECATED_GridCellNode = null; let firstCell: null | GridCellNode = null;
for (let i = 0; i < nodes.length; i++) { for (let i = 0; i < nodes.length; i++) {
const node = nodes[i]; const node = nodes[i];
if (DEPRECATED_$isGridCellNode(node)) { if ($isGridCellNode(node)) {
if (firstCell === null) { if (firstCell === null) {
node.setColSpan(columns).setRowSpan(rows); node.setColSpan(columns).setRowSpan(rows);
firstCell = node; firstCell = node;
@ -318,7 +315,7 @@ function TableActionMenu({
) { ) {
firstChild.remove(); firstChild.remove();
} }
} else if (DEPRECATED_$isGridCellNode(firstCell)) { } else if ($isGridCellNode(firstCell)) {
const isEmpty = $cellContainsEmptyParagraph(node); const isEmpty = $cellContainsEmptyParagraph(node);
if (!isEmpty) { if (!isEmpty) {
firstCell.append(...node.getChildren()); firstCell.append(...node.getChildren());
@ -469,7 +466,7 @@ function TableActionMenu({
editor.update(() => { editor.update(() => {
const selection = $getSelection(); const selection = $getSelection();
if ($isRangeSelection(selection) || $isGridSelection(selection)) { if ($isRangeSelection(selection) || $isGridSelection(selection)) {
const [cell] = DEPRECATED_$getNodeTriplet(selection.anchor); const [cell] = $getNodeTriplet(selection.anchor);
if ($isTableCellNode(cell)) { if ($isTableCellNode(cell)) {
cell.setBackgroundColor(value); cell.setBackgroundColor(value);
} }

View File

@ -7,16 +7,20 @@
*/ */
import type { import type {
GridCellNode,
HTMLTableElementWithWithTableSelectionState, HTMLTableElementWithWithTableSelectionState,
InsertTableCommandPayload, InsertTableCommandPayload,
TableSelection, TableSelection,
} from '@lexical/table'; } from '@lexical/table';
import type {DEPRECATED_GridCellNode, NodeKey} from 'lexical'; import type {NodeKey} from 'lexical';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext'; import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import { import {
$computeGridMap,
$createTableCellNode, $createTableCellNode,
$createTableNodeWithDimensions, $createTableNodeWithDimensions,
$getNodeTriplet,
$isGridRowNode,
$isTableCellNode, $isTableCellNode,
$isTableNode, $isTableNode,
applyTableHandlers, applyTableHandlers,
@ -31,9 +35,6 @@ import {
$isTextNode, $isTextNode,
$nodesOfType, $nodesOfType,
COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_EDITOR,
DEPRECATED_$computeGridMap,
DEPRECATED_$getNodeTriplet,
DEPRECATED_$isGridRowNode,
} from 'lexical'; } from 'lexical';
import {useEffect} from 'react'; import {useEffect} from 'react';
import invariant from 'shared/invariant'; import invariant from 'shared/invariant';
@ -150,14 +151,14 @@ export function TablePlugin({
if (node.getColSpan() > 1 || node.getRowSpan() > 1) { if (node.getColSpan() > 1 || node.getRowSpan() > 1) {
// When we have rowSpan we have to map the entire Table to understand where the new Cells // When we have rowSpan we have to map the entire Table to understand where the new Cells
// fit best; let's analyze all Cells at once to save us from further transform iterations // fit best; let's analyze all Cells at once to save us from further transform iterations
const [, , gridNode] = DEPRECATED_$getNodeTriplet(node); const [, , gridNode] = $getNodeTriplet(node);
const [gridMap] = DEPRECATED_$computeGridMap(gridNode, node, node); const [gridMap] = $computeGridMap(gridNode, node, node);
// TODO this function expects Tables to be normalized. Look into this once it exists // TODO this function expects Tables to be normalized. Look into this once it exists
const rowsCount = gridMap.length; const rowsCount = gridMap.length;
const columnsCount = gridMap[0].length; const columnsCount = gridMap[0].length;
let row = gridNode.getFirstChild(); let row = gridNode.getFirstChild();
invariant( invariant(
DEPRECATED_$isGridRowNode(row), $isGridRowNode(row),
'Expected TableNode first child to be a RowNode', 'Expected TableNode first child to be a RowNode',
); );
const unmerged = []; const unmerged = [];
@ -165,11 +166,11 @@ export function TablePlugin({
if (i !== 0) { if (i !== 0) {
row = row.getNextSibling(); row = row.getNextSibling();
invariant( invariant(
DEPRECATED_$isGridRowNode(row), $isGridRowNode(row),
'Expected TableNode first child to be a RowNode', 'Expected TableNode first child to be a RowNode',
); );
} }
let lastRowCell: null | DEPRECATED_GridCellNode = null; let lastRowCell: null | GridCellNode = null;
for (let j = 0; j < columnsCount; j++) { for (let j = 0; j < columnsCount; j++) {
const cellMap = gridMap[i][j]; const cellMap = gridMap[i][j];
const cell = cellMap.cell; const cell = cellMap.cell;

View File

@ -22,9 +22,6 @@ import type {
import { import {
ElementNode, ElementNode,
deprecated_GridCellNode,
deprecated_GridRowNode,
deprecated_GridNode,
} from 'lexical'; } from 'lexical';
/** /**
@ -40,7 +37,7 @@ export const TableCellHeaderStates = {
export type TableCellHeaderState = $Values<typeof TableCellHeaderStates>; export type TableCellHeaderState = $Values<typeof TableCellHeaderStates>;
declare export class TableCellNode extends deprecated_GridCellNode { declare export class TableCellNode extends GridCellNode {
__headerState: TableCellHeaderState; __headerState: TableCellHeaderState;
__width?: number; __width?: number;
__backgroundColor: null | string; __backgroundColor: null | string;
@ -84,7 +81,7 @@ declare export function $isTableCellNode(
* LexicalTableNode * LexicalTableNode
*/ */
declare export class TableNode extends deprecated_GridNode { declare export class TableNode extends GridNode {
static getType(): string; static getType(): string;
static clone(node: TableNode): TableNode; static clone(node: TableNode): TableNode;
constructor(grid: ?Grid, key?: NodeKey): void; constructor(grid: ?Grid, key?: NodeKey): void;
@ -113,7 +110,7 @@ declare export function $isTableNode(
* LexicalTableRowNode * LexicalTableRowNode
*/ */
declare export class TableRowNode extends deprecated_GridRowNode { declare export class TableRowNode extends GridRowNode {
static getType(): string; static getType(): string;
static clone(node: TableRowNode): TableRowNode; static clone(node: TableRowNode): TableRowNode;
constructor(height?: ?number, key?: NodeKey): void; constructor(height?: ?number, key?: NodeKey): void;
@ -226,13 +223,34 @@ declare export function $deleteTableColumn(
declare export function $insertTableRow__EXPERIMENTAL( declare export function $insertTableRow__EXPERIMENTAL(
insertAfter: boolean, insertAfter: boolean,
): void; ): void;
declare export function $insertTableColumn__EXPERIMENTAL( declare export function $insertTableColumn__EXPERIMENTAL(
insertAfter: boolean, insertAfter: boolean,
): void; ): void;
declare export function $deleteTableRow__EXPERIMENTAL(): void; declare export function $deleteTableRow__EXPERIMENTAL(): void;
declare export function $deleteTableColumn__EXPERIMENTAL(): void; declare export function $deleteTableColumn__EXPERIMENTAL(): void;
declare export function $unmergeCell(): void; declare export function $unmergeCell(): void;
declare export function $computeGridMap(
grid: GridNode,
cellA: GridCellNode,
cellB: GridCellNode,
): [GridMapType, GridMapValueType, GridMapValueType];
declare export function $getNodeTriplet(
source: PointType | LexicalNode | GridCellNode,
): [GridCellNode, GridRowNode, GridNode];
declare export function $getGridCellNodeRect(gridCellNode: GridCellNode): {
rowIndex: number;
columnIndex: number;
rowSpan: number;
colSpan: number;
} | null;
/** /**
* LexicalTableSelection.js * LexicalTableSelection.js
*/ */
@ -303,3 +321,41 @@ declare export function $isGridSelection(
): x is GridSelection; ): x is GridSelection;
declare export function $createGridSelection(): GridSelection; declare export function $createGridSelection(): GridSelection;
/**
* Grid
*/
export type GridMapValueType = {
cell: GridCellNode,
startRow: number,
startColumn: number,
};
export type GridMapType = Array<Array<GridMapValueType>>;
declare export class GridNode extends ElementNode {}
declare export function $isGridNode(
node: ?LexicalNode,
): node is GridNode;
declare export class GridRowNode extends ElementNode {}
declare export function $isGridRowNode(
node: ?LexicalNode,
): node is GridRowNode;
declare export class GridCellNode extends ElementNode {
__colSpan: number;
__rowSpan: number;
constructor(colSpan: number, key?: NodeKey): void;
getColSpan(): number;
setColSpan(colSpan: number): this;
getRowSpan(): number;
setRowSpan(rowSpan: number): this;
}
declare export function $isGridCellNode(
node: ?LexicalNode,
): node is GridCellNode;

View File

@ -13,7 +13,7 @@ import type {
Spread, Spread,
} from 'lexical'; } from 'lexical';
import {ElementNode} from './LexicalElementNode'; import {ElementNode} from 'lexical';
export type SerializedGridCellNode = Spread< export type SerializedGridCellNode = Spread<
{ {
@ -24,7 +24,7 @@ export type SerializedGridCellNode = Spread<
>; >;
/** @noInheritDoc */ /** @noInheritDoc */
export class DEPRECATED_GridCellNode extends ElementNode { export class GridCellNode extends ElementNode {
/** @internal */ /** @internal */
__colSpan: number; __colSpan: number;
__rowSpan: number; __rowSpan: number;
@ -62,8 +62,8 @@ export class DEPRECATED_GridCellNode extends ElementNode {
} }
} }
export function DEPRECATED_$isGridCellNode( export function $isGridCellNode(
node: DEPRECATED_GridCellNode | LexicalNode | null | undefined, node: GridCellNode | LexicalNode | null | undefined,
): node is DEPRECATED_GridCellNode { ): node is GridCellNode {
return node instanceof DEPRECATED_GridCellNode; return node instanceof GridCellNode;
} }

View File

@ -0,0 +1,19 @@
/**
* 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.
*
*/
import type {LexicalNode} from 'lexical';
import {ElementNode} from 'lexical';
export class GridNode extends ElementNode {}
export function $isGridNode(
node: LexicalNode | null | undefined,
): node is GridNode {
return node instanceof GridNode;
}

View File

@ -0,0 +1,19 @@
/**
* 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.
*
*/
import type {LexicalNode} from 'lexical';
import {ElementNode} from 'lexical';
export class GridRowNode extends ElementNode {}
export function $isGridRowNode(
node: LexicalNode | null | undefined,
): node is GridRowNode {
return node instanceof GridRowNode;
}

View File

@ -13,12 +13,6 @@ import {
$isElementNode, $isElementNode,
$normalizeSelection__EXPERIMENTAL, $normalizeSelection__EXPERIMENTAL,
BaseSelection, BaseSelection,
DEPRECATED_$computeGridMap,
DEPRECATED_$getGridCellNodeRect,
DEPRECATED_$isGridCellNode,
DEPRECATED_$isGridNode,
DEPRECATED_$isGridRowNode,
GridMapValueType,
isCurrentlyReadOnlyMode, isCurrentlyReadOnlyMode,
LexicalNode, LexicalNode,
NodeKey, NodeKey,
@ -26,6 +20,12 @@ import {
} from 'lexical'; } from 'lexical';
import invariant from 'shared/invariant'; import invariant from 'shared/invariant';
import {$isGridCellNode} from './LexicalGridCellNode';
import {$isGridNode} from './LexicalGridNode';
import {$isGridRowNode} from './LexicalGridRowNode';
import {GridMapValueType} from './LexicalTableSelection';
import {$computeGridMap, $getGridCellNodeRect} from './LexicalTableUtils';
export type GridSelectionShape = { export type GridSelectionShape = {
fromX: number; fromX: number;
fromY: number; fromY: number;
@ -126,10 +126,10 @@ export class GridSelection implements BaseSelection {
getShape(): GridSelectionShape { getShape(): GridSelectionShape {
const anchorCellNode = $getNodeByKey(this.anchor.key); const anchorCellNode = $getNodeByKey(this.anchor.key);
invariant( invariant(
DEPRECATED_$isGridCellNode(anchorCellNode), $isGridCellNode(anchorCellNode),
'Expected GridSelection anchor to be (or a child of) GridCellNode', 'Expected GridSelection anchor to be (or a child of) GridCellNode',
); );
const anchorCellNodeRect = DEPRECATED_$getGridCellNodeRect(anchorCellNode); const anchorCellNodeRect = $getGridCellNodeRect(anchorCellNode);
invariant( invariant(
anchorCellNodeRect !== null, anchorCellNodeRect !== null,
'getCellRect: expected to find AnchorNode', 'getCellRect: expected to find AnchorNode',
@ -137,10 +137,10 @@ export class GridSelection implements BaseSelection {
const focusCellNode = $getNodeByKey(this.focus.key); const focusCellNode = $getNodeByKey(this.focus.key);
invariant( invariant(
DEPRECATED_$isGridCellNode(focusCellNode), $isGridCellNode(focusCellNode),
'Expected GridSelection focus to be (or a child of) GridCellNode', 'Expected GridSelection focus to be (or a child of) GridCellNode',
); );
const focusCellNodeRect = DEPRECATED_$getGridCellNodeRect(focusCellNode); const focusCellNodeRect = $getGridCellNodeRect(focusCellNode);
invariant( invariant(
focusCellNodeRect !== null, focusCellNodeRect !== null,
'getCellRect: expected to find focusCellNode', 'getCellRect: expected to find focusCellNode',
@ -180,31 +180,25 @@ export class GridSelection implements BaseSelection {
const anchorNode = this.anchor.getNode(); const anchorNode = this.anchor.getNode();
const focusNode = this.focus.getNode(); const focusNode = this.focus.getNode();
const anchorCell = $findMatchingParent( const anchorCell = $findMatchingParent(anchorNode, $isGridCellNode);
anchorNode,
DEPRECATED_$isGridCellNode,
);
// todo replace with triplet // todo replace with triplet
const focusCell = $findMatchingParent( const focusCell = $findMatchingParent(focusNode, $isGridCellNode);
focusNode,
DEPRECATED_$isGridCellNode,
);
invariant( invariant(
DEPRECATED_$isGridCellNode(anchorCell), $isGridCellNode(anchorCell),
'Expected GridSelection anchor to be (or a child of) GridCellNode', 'Expected GridSelection anchor to be (or a child of) GridCellNode',
); );
invariant( invariant(
DEPRECATED_$isGridCellNode(focusCell), $isGridCellNode(focusCell),
'Expected GridSelection focus to be (or a child of) GridCellNode', 'Expected GridSelection focus to be (or a child of) GridCellNode',
); );
const anchorRow = anchorCell.getParent(); const anchorRow = anchorCell.getParent();
invariant( invariant(
DEPRECATED_$isGridRowNode(anchorRow), $isGridRowNode(anchorRow),
'Expected anchorCell to have a parent GridRowNode', 'Expected anchorCell to have a parent GridRowNode',
); );
const gridNode = anchorRow.getParent(); const gridNode = anchorRow.getParent();
invariant( invariant(
DEPRECATED_$isGridNode(gridNode), $isGridNode(gridNode),
'Expected tableNode to have a parent GridNode', 'Expected tableNode to have a parent GridNode',
); );
@ -231,7 +225,7 @@ export class GridSelection implements BaseSelection {
// once (on load) and iterate on it as updates occur. However, to do this we need to have the // once (on load) and iterate on it as updates occur. However, to do this we need to have the
// ability to store a state. Killing GridSelection and moving the logic to the plugin would make // ability to store a state. Killing GridSelection and moving the logic to the plugin would make
// this possible. // this possible.
const [map, cellAMap, cellBMap] = DEPRECATED_$computeGridMap( const [map, cellAMap, cellBMap] = $computeGridMap(
gridNode, gridNode,
anchorCell, anchorCell,
focusCell, focusCell,
@ -313,7 +307,7 @@ export class GridSelection implements BaseSelection {
const {cell} = map[i][j]; const {cell} = map[i][j];
const currentRow = cell.getParent(); const currentRow = cell.getParent();
invariant( invariant(
DEPRECATED_$isGridRowNode(currentRow), $isGridRowNode(currentRow),
'Expected GridCellNode parent to be a GridRowNode', 'Expected GridCellNode parent to be a GridRowNode',
); );
if (currentRow !== lastRow) { if (currentRow !== lastRow) {

View File

@ -14,7 +14,6 @@ import type {
LexicalEditor, LexicalEditor,
LexicalNode, LexicalNode,
NodeKey, NodeKey,
SerializedGridCellNode,
Spread, Spread,
} from 'lexical'; } from 'lexical';
@ -24,10 +23,10 @@ import {
$createParagraphNode, $createParagraphNode,
$isElementNode, $isElementNode,
$isLineBreakNode, $isLineBreakNode,
DEPRECATED_GridCellNode,
} from 'lexical'; } from 'lexical';
import {PIXEL_VALUE_REG_EXP} from './constants'; import {PIXEL_VALUE_REG_EXP} from './constants';
import {GridCellNode, SerializedGridCellNode} from './LexicalGridCellNode';
export const TableCellHeaderStates = { export const TableCellHeaderStates = {
BOTH: 3, BOTH: 3,
@ -49,7 +48,7 @@ export type SerializedTableCellNode = Spread<
>; >;
/** @noInheritDoc */ /** @noInheritDoc */
export class TableCellNode extends DEPRECATED_GridCellNode { export class TableCellNode extends GridCellNode {
/** @internal */ /** @internal */
__headerState: TableCellHeaderState; __headerState: TableCellHeaderState;
/** @internal */ /** @internal */

View File

@ -20,12 +20,9 @@ import type {
} from 'lexical'; } from 'lexical';
import {addClassNamesToElement, isHTMLElement} from '@lexical/utils'; import {addClassNamesToElement, isHTMLElement} from '@lexical/utils';
import { import {$applyNodeReplacement, $getNearestNodeFromDOMNode} from 'lexical';
$applyNodeReplacement,
$getNearestNodeFromDOMNode,
DEPRECATED_GridNode,
} from 'lexical';
import {GridNode} from './LexicalGridNode';
import {$isTableCellNode} from './LexicalTableCellNode'; import {$isTableCellNode} from './LexicalTableCellNode';
import {$isTableRowNode, TableRowNode} from './LexicalTableRowNode'; import {$isTableRowNode, TableRowNode} from './LexicalTableRowNode';
import {getTableGrid} from './LexicalTableSelectionHelpers'; import {getTableGrid} from './LexicalTableSelectionHelpers';
@ -33,7 +30,7 @@ import {getTableGrid} from './LexicalTableSelectionHelpers';
export type SerializedTableNode = SerializedElementNode; export type SerializedTableNode = SerializedElementNode;
/** @noInheritDoc */ /** @noInheritDoc */
export class TableNode extends DEPRECATED_GridNode { export class TableNode extends GridNode {
/** @internal */ /** @internal */
__grid?: Grid; __grid?: Grid;

View File

@ -11,7 +11,6 @@ import type {Spread} from 'lexical';
import {addClassNamesToElement} from '@lexical/utils'; import {addClassNamesToElement} from '@lexical/utils';
import { import {
$applyNodeReplacement, $applyNodeReplacement,
DEPRECATED_GridRowNode,
DOMConversionMap, DOMConversionMap,
DOMConversionOutput, DOMConversionOutput,
EditorConfig, EditorConfig,
@ -21,6 +20,7 @@ import {
} from 'lexical'; } from 'lexical';
import {PIXEL_VALUE_REG_EXP} from './constants'; import {PIXEL_VALUE_REG_EXP} from './constants';
import {GridRowNode} from './LexicalGridRowNode';
export type SerializedTableRowNode = Spread< export type SerializedTableRowNode = Spread<
{ {
@ -30,7 +30,7 @@ export type SerializedTableRowNode = Spread<
>; >;
/** @noInheritDoc */ /** @noInheritDoc */
export class TableRowNode extends DEPRECATED_GridRowNode { export class TableRowNode extends GridRowNode {
/** @internal */ /** @internal */
__height?: number; __height?: number;

View File

@ -27,6 +27,7 @@ import {
import {CAN_USE_DOM} from 'shared/canUseDOM'; import {CAN_USE_DOM} from 'shared/canUseDOM';
import invariant from 'shared/invariant'; import invariant from 'shared/invariant';
import {GridCellNode} from './LexicalGridCellNode';
import { import {
type GridSelection, type GridSelection,
$createGridSelection, $createGridSelection,
@ -39,6 +40,13 @@ import {
getTableGrid, getTableGrid,
} from './LexicalTableSelectionHelpers'; } from './LexicalTableSelectionHelpers';
export type GridMapValueType = {
cell: GridCellNode;
startRow: number;
startColumn: number;
};
export type GridMapType = Array<Array<GridMapValueType>>;
export type Cell = { export type Cell = {
elem: HTMLElement; elem: HTMLElement;
highlighted: boolean; highlighted: boolean;

View File

@ -12,7 +12,6 @@ import type {TableNode} from './LexicalTableNode';
import type {Cell, Cells, Grid} from './LexicalTableSelection'; import type {Cell, Cells, Grid} from './LexicalTableSelection';
import type { import type {
BaseSelection, BaseSelection,
DEPRECATED_GridNode,
LexicalCommand, LexicalCommand,
LexicalEditor, LexicalEditor,
LexicalNode, LexicalNode,
@ -36,9 +35,6 @@ import {
DELETE_CHARACTER_COMMAND, DELETE_CHARACTER_COMMAND,
DELETE_LINE_COMMAND, DELETE_LINE_COMMAND,
DELETE_WORD_COMMAND, DELETE_WORD_COMMAND,
DEPRECATED_$isGridCellNode,
DEPRECATED_$isGridNode,
DEPRECATED_$isGridRowNode,
FOCUS_COMMAND, FOCUS_COMMAND,
FORMAT_TEXT_COMMAND, FORMAT_TEXT_COMMAND,
KEY_ARROW_DOWN_COMMAND, KEY_ARROW_DOWN_COMMAND,
@ -54,6 +50,9 @@ import {
} from 'lexical'; } from 'lexical';
import invariant from 'shared/invariant'; import invariant from 'shared/invariant';
import {$isGridCellNode} from './LexicalGridCellNode';
import {$isGridNode, GridNode} from './LexicalGridNode';
import {$isGridRowNode} from './LexicalGridRowNode';
import {$createGridSelection, $isGridSelection} from './LexicalGridSelection'; import {$createGridSelection, $isGridSelection} from './LexicalGridSelection';
import {$isTableCellNode} from './LexicalTableCellNode'; import {$isTableCellNode} from './LexicalTableCellNode';
import {$isTableNode} from './LexicalTableNode'; import {$isTableNode} from './LexicalTableNode';
@ -473,16 +472,16 @@ export function applyTableHandlers(
const isSelectionInsideOfGrid = const isSelectionInsideOfGrid =
(isRangeSelection && (isRangeSelection &&
$findMatchingParent(selection.anchor.getNode(), (n) => $findMatchingParent(selection.anchor.getNode(), (n) =>
DEPRECATED_$isGridCellNode(n), $isGridCellNode(n),
) !== null && ) !== null &&
$findMatchingParent(selection.focus.getNode(), (n) => $findMatchingParent(selection.focus.getNode(), (n) =>
DEPRECATED_$isGridCellNode(n), $isGridCellNode(n),
) !== null) || ) !== null) ||
isGridSelection; isGridSelection;
if ( if (
nodes.length !== 1 || nodes.length !== 1 ||
!DEPRECATED_$isGridNode(nodes[0]) || !$isGridNode(nodes[0]) ||
!isSelectionInsideOfGrid || !isSelectionInsideOfGrid ||
anchorAndFocus === null anchorAndFocus === null
) { ) {
@ -493,25 +492,23 @@ export function applyTableHandlers(
const newGrid = nodes[0]; const newGrid = nodes[0];
const newGridRows = newGrid.getChildren(); const newGridRows = newGrid.getChildren();
const newColumnCount = newGrid const newColumnCount = newGrid
.getFirstChildOrThrow<DEPRECATED_GridNode>() .getFirstChildOrThrow<GridNode>()
.getChildrenSize(); .getChildrenSize();
const newRowCount = newGrid.getChildrenSize(); const newRowCount = newGrid.getChildrenSize();
const gridCellNode = $findMatchingParent(anchor.getNode(), (n) => const gridCellNode = $findMatchingParent(anchor.getNode(), (n) =>
DEPRECATED_$isGridCellNode(n), $isGridCellNode(n),
); );
const gridRowNode = const gridRowNode =
gridCellNode && gridCellNode &&
$findMatchingParent(gridCellNode, (n) => $findMatchingParent(gridCellNode, (n) => $isGridRowNode(n));
DEPRECATED_$isGridRowNode(n),
);
const gridNode = const gridNode =
gridRowNode && gridRowNode &&
$findMatchingParent(gridRowNode, (n) => DEPRECATED_$isGridNode(n)); $findMatchingParent(gridRowNode, (n) => $isGridNode(n));
if ( if (
!DEPRECATED_$isGridCellNode(gridCellNode) || !$isGridCellNode(gridCellNode) ||
!DEPRECATED_$isGridRowNode(gridRowNode) || !$isGridRowNode(gridRowNode) ||
!DEPRECATED_$isGridNode(gridNode) !$isGridNode(gridNode)
) { ) {
return false; return false;
} }
@ -538,13 +535,13 @@ export function applyTableHandlers(
for (let r = fromY; r <= toY; r++) { for (let r = fromY; r <= toY; r++) {
const currentGridRowNode = gridRowNodes[r]; const currentGridRowNode = gridRowNodes[r];
if (!DEPRECATED_$isGridRowNode(currentGridRowNode)) { if (!$isGridRowNode(currentGridRowNode)) {
return false; return false;
} }
const newGridRowNode = newGridRows[newRowIdx]; const newGridRowNode = newGridRows[newRowIdx];
if (!DEPRECATED_$isGridRowNode(newGridRowNode)) { if (!$isGridRowNode(newGridRowNode)) {
return false; return false;
} }
@ -555,13 +552,13 @@ export function applyTableHandlers(
for (let c = fromX; c <= toX; c++) { for (let c = fromX; c <= toX; c++) {
const currentGridCellNode = gridCellNodes[c]; const currentGridCellNode = gridCellNodes[c];
if (!DEPRECATED_$isGridCellNode(currentGridCellNode)) { if (!$isGridCellNode(currentGridCellNode)) {
return false; return false;
} }
const newGridCellNode = newGridCellNodes[newColumnIdx]; const newGridCellNode = newGridCellNodes[newColumnIdx];
if (!DEPRECATED_$isGridCellNode(newGridCellNode)) { if (!$isGridCellNode(newGridCellNode)) {
return false; return false;
} }

View File

@ -6,8 +6,12 @@
* *
*/ */
import type {Grid} from './LexicalTableSelection'; import type {
import type {DEPRECATED_GridRowNode, ElementNode} from 'lexical'; Grid,
GridMapType,
GridMapValueType,
} from './LexicalTableSelection';
import type {ElementNode, PointType} from 'lexical';
import {$findMatchingParent} from '@lexical/utils'; import {$findMatchingParent} from '@lexical/utils';
import { import {
@ -15,15 +19,14 @@ import {
$createTextNode, $createTextNode,
$getSelection, $getSelection,
$isRangeSelection, $isRangeSelection,
DEPRECATED_$computeGridMap,
DEPRECATED_$getNodeTriplet,
DEPRECATED_$isGridRowNode,
DEPRECATED_GridCellNode,
LexicalNode, LexicalNode,
} from 'lexical'; } from 'lexical';
import invariant from 'shared/invariant'; import invariant from 'shared/invariant';
import {$isGridSelection, InsertTableCommandPayloadHeaders} from '.'; import {$isGridSelection, InsertTableCommandPayloadHeaders} from '.';
import {$isGridCellNode, GridCellNode} from './LexicalGridCellNode';
import {$isGridNode, GridNode} from './LexicalGridNode';
import {$isGridRowNode, GridRowNode} from './LexicalGridRowNode';
import { import {
$createTableCellNode, $createTableCellNode,
$isTableCellNode, $isTableCellNode,
@ -234,12 +237,8 @@ export function $insertTableRow__EXPERIMENTAL(insertAfter = true): void {
'Expected a RangeSelection or GridSelection', 'Expected a RangeSelection or GridSelection',
); );
const focus = selection.focus.getNode(); const focus = selection.focus.getNode();
const [focusCell, , grid] = DEPRECATED_$getNodeTriplet(focus); const [focusCell, , grid] = $getNodeTriplet(focus);
const [gridMap, focusCellMap] = DEPRECATED_$computeGridMap( const [gridMap, focusCellMap] = $computeGridMap(grid, focusCell, focusCell);
grid,
focusCell,
focusCell,
);
const columnCount = gridMap[0].length; const columnCount = gridMap[0].length;
const {startRow: focusStartRow} = focusCellMap; const {startRow: focusStartRow} = focusCellMap;
if (insertAfter) { if (insertAfter) {
@ -260,7 +259,7 @@ export function $insertTableRow__EXPERIMENTAL(insertAfter = true): void {
} }
const focusEndRowNode = grid.getChildAtIndex(focusEndRow); const focusEndRowNode = grid.getChildAtIndex(focusEndRow);
invariant( invariant(
DEPRECATED_$isGridRowNode(focusEndRowNode), $isGridRowNode(focusEndRowNode),
'focusEndRow is not a GridRowNode', 'focusEndRow is not a GridRowNode',
); );
focusEndRowNode.insertAfter(newRow); focusEndRowNode.insertAfter(newRow);
@ -281,7 +280,7 @@ export function $insertTableRow__EXPERIMENTAL(insertAfter = true): void {
} }
const focusStartRowNode = grid.getChildAtIndex(focusStartRow); const focusStartRowNode = grid.getChildAtIndex(focusStartRow);
invariant( invariant(
DEPRECATED_$isGridRowNode(focusStartRowNode), $isGridRowNode(focusStartRowNode),
'focusEndRow is not a GridRowNode', 'focusEndRow is not a GridRowNode',
); );
focusStartRowNode.insertBefore(newRow); focusStartRowNode.insertBefore(newRow);
@ -355,9 +354,9 @@ export function $insertTableColumn__EXPERIMENTAL(insertAfter = true): void {
); );
const anchor = selection.anchor.getNode(); const anchor = selection.anchor.getNode();
const focus = selection.focus.getNode(); const focus = selection.focus.getNode();
const [anchorCell] = DEPRECATED_$getNodeTriplet(anchor); const [anchorCell] = $getNodeTriplet(anchor);
const [focusCell, , grid] = DEPRECATED_$getNodeTriplet(focus); const [focusCell, , grid] = $getNodeTriplet(focus);
const [gridMap, focusCellMap, anchorCellMap] = DEPRECATED_$computeGridMap( const [gridMap, focusCellMap, anchorCellMap] = $computeGridMap(
grid, grid,
focusCell, focusCell,
anchorCell, anchorCell,
@ -371,10 +370,10 @@ export function $insertTableColumn__EXPERIMENTAL(insertAfter = true): void {
: startColumn - 1; : startColumn - 1;
const gridFirstChild = grid.getFirstChild(); const gridFirstChild = grid.getFirstChild();
invariant( invariant(
DEPRECATED_$isGridRowNode(gridFirstChild), $isGridRowNode(gridFirstChild),
'Expected firstTable child to be a row', 'Expected firstTable child to be a row',
); );
let firstInsertedCell: null | DEPRECATED_GridCellNode = null; let firstInsertedCell: null | GridCellNode = null;
function $createTableCellNodeForInsertTableColumn() { function $createTableCellNodeForInsertTableColumn() {
const cell = $createTableCellNode(TableCellHeaderStates.NO_STATUS).append( const cell = $createTableCellNode(TableCellHeaderStates.NO_STATUS).append(
$createParagraphNode(), $createParagraphNode(),
@ -384,12 +383,12 @@ export function $insertTableColumn__EXPERIMENTAL(insertAfter = true): void {
} }
return cell; return cell;
} }
let loopRow: DEPRECATED_GridRowNode = gridFirstChild; let loopRow: GridRowNode = gridFirstChild;
rowLoop: for (let i = 0; i < rowCount; i++) { rowLoop: for (let i = 0; i < rowCount; i++) {
if (i !== 0) { if (i !== 0) {
const currentRow = loopRow.getNextSibling(); const currentRow = loopRow.getNextSibling();
invariant( invariant(
DEPRECATED_$isGridRowNode(currentRow), $isGridRowNode(currentRow),
'Expected row nextSibling to be a row', 'Expected row nextSibling to be a row',
); );
loopRow = currentRow; loopRow = currentRow;
@ -405,7 +404,7 @@ export function $insertTableColumn__EXPERIMENTAL(insertAfter = true): void {
startRow: currentStartRow, startRow: currentStartRow,
} = rowMap[insertAfterColumn]; } = rowMap[insertAfterColumn];
if (currentStartColumn + currentCell.__colSpan - 1 <= insertAfterColumn) { if (currentStartColumn + currentCell.__colSpan - 1 <= insertAfterColumn) {
let insertAfterCell: DEPRECATED_GridCellNode = currentCell; let insertAfterCell: GridCellNode = currentCell;
let insertAfterCellRowStart = currentStartRow; let insertAfterCellRowStart = currentStartRow;
let prevCellIndex = insertAfterColumn; let prevCellIndex = insertAfterColumn;
while (insertAfterCellRowStart !== i && insertAfterCell.__rowSpan > 1) { while (insertAfterCellRowStart !== i && insertAfterCell.__rowSpan > 1) {
@ -460,9 +459,9 @@ export function $deleteTableRow__EXPERIMENTAL(): void {
); );
const anchor = selection.anchor.getNode(); const anchor = selection.anchor.getNode();
const focus = selection.focus.getNode(); const focus = selection.focus.getNode();
const [anchorCell, , grid] = DEPRECATED_$getNodeTriplet(anchor); const [anchorCell, , grid] = $getNodeTriplet(anchor);
const [focusCell] = DEPRECATED_$getNodeTriplet(focus); const [focusCell] = $getNodeTriplet(focus);
const [gridMap, anchorCellMap, focusCellMap] = DEPRECATED_$computeGridMap( const [gridMap, anchorCellMap, focusCellMap] = $computeGridMap(
grid, grid,
anchorCell, anchorCell,
focusCell, focusCell,
@ -477,9 +476,7 @@ export function $deleteTableRow__EXPERIMENTAL(): void {
} }
const columnCount = gridMap[0].length; const columnCount = gridMap[0].length;
const nextRow = gridMap[focusEndRow + 1]; const nextRow = gridMap[focusEndRow + 1];
const nextRowNode: null | DEPRECATED_GridRowNode = grid.getChildAtIndex( const nextRowNode: null | GridRowNode = grid.getChildAtIndex(focusEndRow + 1);
focusEndRow + 1,
);
for (let row = focusEndRow; row >= anchorStartRow; row--) { for (let row = focusEndRow; row >= anchorStartRow; row--) {
for (let column = columnCount - 1; column >= 0; column--) { for (let column = columnCount - 1; column >= 0; column--) {
const { const {
@ -512,7 +509,7 @@ export function $deleteTableRow__EXPERIMENTAL(): void {
} }
const rowNode = grid.getChildAtIndex(row); const rowNode = grid.getChildAtIndex(row);
invariant( invariant(
DEPRECATED_$isGridRowNode(rowNode), $isGridRowNode(rowNode),
'Expected GridNode childAtIndex(%s) to be RowNode', 'Expected GridNode childAtIndex(%s) to be RowNode',
String(row), String(row),
); );
@ -536,9 +533,9 @@ export function $deleteTableColumn__EXPERIMENTAL(): void {
); );
const anchor = selection.anchor.getNode(); const anchor = selection.anchor.getNode();
const focus = selection.focus.getNode(); const focus = selection.focus.getNode();
const [anchorCell, , grid] = DEPRECATED_$getNodeTriplet(anchor); const [anchorCell, , grid] = $getNodeTriplet(anchor);
const [focusCell] = DEPRECATED_$getNodeTriplet(focus); const [focusCell] = $getNodeTriplet(focus);
const [gridMap, anchorCellMap, focusCellMap] = DEPRECATED_$computeGridMap( const [gridMap, anchorCellMap, focusCellMap] = $computeGridMap(
grid, grid,
anchorCell, anchorCell,
focusCell, focusCell,
@ -595,7 +592,7 @@ export function $deleteTableColumn__EXPERIMENTAL(): void {
} }
} }
function $moveSelectionToCell(cell: DEPRECATED_GridCellNode): void { function $moveSelectionToCell(cell: GridCellNode): void {
const firstDescendant = cell.getFirstDescendant(); const firstDescendant = cell.getFirstDescendant();
if (firstDescendant == null) { if (firstDescendant == null) {
cell.selectStart(); cell.selectStart();
@ -620,7 +617,7 @@ export function $unmergeCell(): void {
'Expected a RangeSelection or GridSelection', 'Expected a RangeSelection or GridSelection',
); );
const anchor = selection.anchor.getNode(); const anchor = selection.anchor.getNode();
const [cell, row, grid] = DEPRECATED_$getNodeTriplet(anchor); const [cell, row, grid] = $getNodeTriplet(anchor);
const colSpan = cell.__colSpan; const colSpan = cell.__colSpan;
const rowSpan = cell.__rowSpan; const rowSpan = cell.__rowSpan;
if (colSpan > 1) { if (colSpan > 1) {
@ -630,7 +627,7 @@ export function $unmergeCell(): void {
cell.setColSpan(1); cell.setColSpan(1);
} }
if (rowSpan > 1) { if (rowSpan > 1) {
const [map, cellMap] = DEPRECATED_$computeGridMap(grid, cell, cell); const [map, cellMap] = $computeGridMap(grid, cell, cell);
const {startColumn, startRow} = cellMap; const {startColumn, startRow} = cellMap;
let currentRowNode; let currentRowNode;
for (let i = 1; i < rowSpan; i++) { for (let i = 1; i < rowSpan; i++) {
@ -638,10 +635,10 @@ export function $unmergeCell(): void {
const currentRowMap = map[currentRow]; const currentRowMap = map[currentRow];
currentRowNode = (currentRowNode || row).getNextSibling(); currentRowNode = (currentRowNode || row).getNextSibling();
invariant( invariant(
DEPRECATED_$isGridRowNode(currentRowNode), $isGridRowNode(currentRowNode),
'Expected row next sibling to be a row', 'Expected row next sibling to be a row',
); );
let insertAfterCell: null | DEPRECATED_GridCellNode = null; let insertAfterCell: null | GridCellNode = null;
for (let column = 0; column < startColumn; column++) { for (let column = 0; column < startColumn; column++) {
const currentCellMap = currentRowMap[column]; const currentCellMap = currentRowMap[column];
const currentCell = currentCellMap.cell; const currentCell = currentCellMap.cell;
@ -670,3 +667,148 @@ export function $unmergeCell(): void {
cell.setRowSpan(1); cell.setRowSpan(1);
} }
} }
export function $computeGridMap(
grid: GridNode,
cellA: GridCellNode,
cellB: GridCellNode,
): [GridMapType, GridMapValueType, GridMapValueType] {
const tableMap: GridMapType = [];
let cellAValue: null | GridMapValueType = null;
let cellBValue: null | GridMapValueType = null;
function write(startRow: number, startColumn: number, cell: GridCellNode) {
const value = {
cell,
startColumn,
startRow,
};
const rowSpan = cell.__rowSpan;
const colSpan = cell.__colSpan;
for (let i = 0; i < rowSpan; i++) {
if (tableMap[startRow + i] === undefined) {
tableMap[startRow + i] = [];
}
for (let j = 0; j < colSpan; j++) {
tableMap[startRow + i][startColumn + j] = value;
}
}
if (cellA.is(cell)) {
cellAValue = value;
}
if (cellB.is(cell)) {
cellBValue = value;
}
}
function isEmpty(row: number, column: number) {
return tableMap[row] === undefined || tableMap[row][column] === undefined;
}
const gridChildren = grid.getChildren();
for (let i = 0; i < gridChildren.length; i++) {
const row = gridChildren[i];
invariant(
$isGridRowNode(row),
'Expected GridNode children to be GridRowNode',
);
const rowChildren = row.getChildren();
let j = 0;
for (const cell of rowChildren) {
invariant(
$isGridCellNode(cell),
'Expected GridRowNode children to be GridCellNode',
);
while (!isEmpty(i, j)) {
j++;
}
write(i, j, cell);
j += cell.__colSpan;
}
}
invariant(cellAValue !== null, 'Anchor not found in Grid');
invariant(cellBValue !== null, 'Focus not found in Grid');
return [tableMap, cellAValue, cellBValue];
}
export function $getNodeTriplet(
source: PointType | LexicalNode | GridCellNode,
): [GridCellNode, GridRowNode, GridNode] {
let cell: GridCellNode;
if (source instanceof GridCellNode) {
cell = source;
} else if ('__type' in source) {
const cell_ = $findMatchingParent(source, $isGridCellNode);
invariant($isGridCellNode(cell_), 'Expected to find a parent GridCellNode');
cell = cell_;
} else {
const cell_ = $findMatchingParent(source.getNode(), $isGridCellNode);
invariant($isGridCellNode(cell_), 'Expected to find a parent GridCellNode');
cell = cell_;
}
const row = cell.getParent();
invariant(
$isGridRowNode(row),
'Expected GridCellNode to have a parent GridRowNode',
);
const grid = row.getParent();
invariant(
$isGridNode(grid),
'Expected GridRowNode to have a parent GridNode',
);
return [cell, row, grid];
}
export function $getGridCellNodeRect(gridCellNode: GridCellNode): {
rowIndex: number;
columnIndex: number;
rowSpan: number;
colSpan: number;
} | null {
const [CellNode, , gridNode] = $getNodeTriplet(gridCellNode);
const rows = gridNode.getChildren<GridRowNode>();
const rowCount = rows.length;
const columnCount = rows[0].getChildren().length;
// Create a matrix of the same size as the table to track the position of each cell
const cellMatrix = new Array(rowCount);
for (let i = 0; i < rowCount; i++) {
cellMatrix[i] = new Array(columnCount);
}
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
const row = rows[rowIndex];
const cells = row.getChildren<GridCellNode>();
let columnIndex = 0;
for (let cellIndex = 0; cellIndex < cells.length; cellIndex++) {
// Find the next available position in the matrix, skip the position of merged cells
while (cellMatrix[rowIndex][columnIndex]) {
columnIndex++;
}
const cell = cells[cellIndex];
const rowSpan = cell.__rowSpan || 1;
const colSpan = cell.__colSpan || 1;
// Put the cell into the corresponding position in the matrix
for (let i = 0; i < rowSpan; i++) {
for (let j = 0; j < colSpan; j++) {
cellMatrix[rowIndex + i][columnIndex + j] = cell;
}
}
// Return to the original index, row span and column span of the cell.
if (CellNode === cell) {
return {
colSpan,
columnIndex,
rowIndex,
rowSpan,
};
}
columnIndex += colSpan;
}
}
return null;
}

View File

@ -11,6 +11,9 @@ import type {LexicalCommand} from 'lexical';
import {createCommand} from 'lexical'; import {createCommand} from 'lexical';
export {$isGridCellNode, GridCellNode} from './LexicalGridCellNode';
export {$isGridNode, GridNode} from './LexicalGridNode';
export {$isGridRowNode, GridRowNode} from './LexicalGridRowNode';
export type {GridSelection, GridSelectionShape} from './LexicalGridSelection'; export type {GridSelection, GridSelectionShape} from './LexicalGridSelection';
export {$createGridSelection, $isGridSelection} from './LexicalGridSelection'; export {$createGridSelection, $isGridSelection} from './LexicalGridSelection';
export type {SerializedTableCellNode} from './LexicalTableCellNode'; export type {SerializedTableCellNode} from './LexicalTableCellNode';
@ -42,10 +45,13 @@ export {
getTableSelectionFromTableElement, getTableSelectionFromTableElement,
} from './LexicalTableSelectionHelpers'; } from './LexicalTableSelectionHelpers';
export { export {
$computeGridMap,
$createTableNodeWithDimensions, $createTableNodeWithDimensions,
$deleteTableColumn, $deleteTableColumn,
$deleteTableColumn__EXPERIMENTAL, $deleteTableColumn__EXPERIMENTAL,
$deleteTableRow__EXPERIMENTAL, $deleteTableRow__EXPERIMENTAL,
$getGridCellNodeRect,
$getNodeTriplet,
$getTableCellNodeFromLexicalNode, $getTableCellNodeFromLexicalNode,
$getTableColumnIndexFromTableCellNode, $getTableColumnIndexFromTableCellNode,
$getTableNodeFromLexicalNodeOrThrow, $getTableNodeFromLexicalNodeOrThrow,

View File

@ -535,20 +535,7 @@ declare export function $isRangeSelection(
declare export function $getSelection(): null | BaseSelection; declare export function $getSelection(): null | BaseSelection;
declare export function $getPreviousSelection(): null | BaseSelection; declare export function $getPreviousSelection(): null | BaseSelection;
declare export function $insertNodes(nodes: Array<LexicalNode>): void; declare export function $insertNodes(nodes: Array<LexicalNode>): void;
export type GridMapValueType = {
cell: deprecated_GridCellNode,
startRow: number,
startColumn: number,
};
export type GridMapType = Array<Array<GridMapValueType>>;
declare export function DEPRECATED_$computeGridMap(
grid: deprecated_GridNode,
cellA: deprecated_GridCellNode,
cellB: deprecated_GridCellNode,
): [GridMapType, GridMapValueType, GridMapValueType];
declare export function DEPRECATED_$getNodeTriplet(
source: PointType | LexicalNode | deprecated_GridCellNode,
): [deprecated_GridCellNode, deprecated_GridRowNode, deprecated_GridNode];
/** /**
* LexicalTextNode * LexicalTextNode
@ -806,33 +793,6 @@ declare export function $isParagraphNode(
node: ?LexicalNode, node: ?LexicalNode,
): node is ParagraphNode; ): node is ParagraphNode;
declare export class deprecated_GridNode extends ElementNode {}
declare export function DEPRECATED_$isGridNode(
node: ?LexicalNode,
): node is deprecated_GridNode;
declare export class deprecated_GridRowNode extends ElementNode {}
declare export function DEPRECATED_$isGridRowNode(
node: ?LexicalNode,
): node is deprecated_GridRowNode;
declare export class deprecated_GridCellNode extends ElementNode {
__colSpan: number;
__rowSpan: number;
constructor(colSpan: number, key?: NodeKey): void;
getColSpan(): number;
setColSpan(colSpan: number): this;
getRowSpan(): number;
setRowSpan(rowSpan: number): this;
}
declare export function DEPRECATED_$isGridCellNode(
node: ?LexicalNode,
): node is deprecated_GridCellNode;
/** /**
* LexicalUtils * LexicalUtils
*/ */

View File

@ -24,12 +24,6 @@ import {
$isRootNode, $isRootNode,
$isTextNode, $isTextNode,
$setSelection, $setSelection,
DEPRECATED_$isGridCellNode,
DEPRECATED_$isGridNode,
DEPRECATED_$isGridRowNode,
DEPRECATED_GridCellNode,
DEPRECATED_GridNode,
DEPRECATED_GridRowNode,
SELECTION_CHANGE_COMMAND, SELECTION_CHANGE_COMMAND,
TextNode, TextNode,
} from '.'; } from '.';
@ -46,7 +40,6 @@ import {
isCurrentlyReadOnlyMode, isCurrentlyReadOnlyMode,
} from './LexicalUpdates'; } from './LexicalUpdates';
import { import {
$findMatchingParent,
$getAdjacentNode, $getAdjacentNode,
$getAncestor, $getAncestor,
$getCompositionKey, $getCompositionKey,
@ -95,13 +88,6 @@ export type ElementPointType = {
export type PointType = TextPointType | ElementPointType; export type PointType = TextPointType | ElementPointType;
export type GridMapValueType = {
cell: DEPRECATED_GridCellNode;
startRow: number;
startColumn: number;
};
export type GridMapType = Array<Array<GridMapValueType>>;
export class Point { export class Point {
key: NodeKey; key: NodeKey;
offset: number; offset: number;
@ -408,64 +394,6 @@ export function $isRangeSelection(x: unknown): x is RangeSelection {
return x instanceof RangeSelection; return x instanceof RangeSelection;
} }
export function DEPRECATED_$getGridCellNodeRect(
GridCellNode: DEPRECATED_GridCellNode,
): {
rowIndex: number;
columnIndex: number;
rowSpan: number;
colSpan: number;
} | null {
const [CellNode, , GridNode] = DEPRECATED_$getNodeTriplet(GridCellNode);
const rows = GridNode.getChildren<DEPRECATED_GridRowNode>();
const rowCount = rows.length;
const columnCount = rows[0].getChildren().length;
// Create a matrix of the same size as the table to track the position of each cell
const cellMatrix = new Array(rowCount);
for (let i = 0; i < rowCount; i++) {
cellMatrix[i] = new Array(columnCount);
}
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
const row = rows[rowIndex];
const cells = row.getChildren<DEPRECATED_GridCellNode>();
let columnIndex = 0;
for (let cellIndex = 0; cellIndex < cells.length; cellIndex++) {
// Find the next available position in the matrix, skip the position of merged cells
while (cellMatrix[rowIndex][columnIndex]) {
columnIndex++;
}
const cell = cells[cellIndex];
const rowSpan = cell.__rowSpan || 1;
const colSpan = cell.__colSpan || 1;
// Put the cell into the corresponding position in the matrix
for (let i = 0; i < rowSpan; i++) {
for (let j = 0; j < colSpan; j++) {
cellMatrix[rowIndex + i][columnIndex + j] = cell;
}
}
// Return to the original index, row span and column span of the cell.
if (CellNode === cell) {
return {
colSpan,
columnIndex,
rowIndex,
rowSpan,
};
}
columnIndex += colSpan;
}
}
return null;
}
export class RangeSelection implements BaseSelection { export class RangeSelection implements BaseSelection {
format: number; format: number;
style: string; style: string;
@ -2721,108 +2649,6 @@ export function $getTextContent(): string {
return selection.getTextContent(); return selection.getTextContent();
} }
export function DEPRECATED_$computeGridMap(
grid: DEPRECATED_GridNode,
cellA: DEPRECATED_GridCellNode,
cellB: DEPRECATED_GridCellNode,
): [GridMapType, GridMapValueType, GridMapValueType] {
const tableMap: GridMapType = [];
let cellAValue: null | GridMapValueType = null;
let cellBValue: null | GridMapValueType = null;
function write(
startRow: number,
startColumn: number,
cell: DEPRECATED_GridCellNode,
) {
const value = {
cell,
startColumn,
startRow,
};
const rowSpan = cell.__rowSpan;
const colSpan = cell.__colSpan;
for (let i = 0; i < rowSpan; i++) {
if (tableMap[startRow + i] === undefined) {
tableMap[startRow + i] = [];
}
for (let j = 0; j < colSpan; j++) {
tableMap[startRow + i][startColumn + j] = value;
}
}
if (cellA.is(cell)) {
cellAValue = value;
}
if (cellB.is(cell)) {
cellBValue = value;
}
}
function isEmpty(row: number, column: number) {
return tableMap[row] === undefined || tableMap[row][column] === undefined;
}
const gridChildren = grid.getChildren();
for (let i = 0; i < gridChildren.length; i++) {
const row = gridChildren[i];
invariant(
DEPRECATED_$isGridRowNode(row),
'Expected GridNode children to be GridRowNode',
);
const rowChildren = row.getChildren();
let j = 0;
for (const cell of rowChildren) {
invariant(
DEPRECATED_$isGridCellNode(cell),
'Expected GridRowNode children to be GridCellNode',
);
while (!isEmpty(i, j)) {
j++;
}
write(i, j, cell);
j += cell.__colSpan;
}
}
invariant(cellAValue !== null, 'Anchor not found in Grid');
invariant(cellBValue !== null, 'Focus not found in Grid');
return [tableMap, cellAValue, cellBValue];
}
export function DEPRECATED_$getNodeTriplet(
source: PointType | LexicalNode | DEPRECATED_GridCellNode,
): [DEPRECATED_GridCellNode, DEPRECATED_GridRowNode, DEPRECATED_GridNode] {
let cell: DEPRECATED_GridCellNode;
if (source instanceof DEPRECATED_GridCellNode) {
cell = source;
} else if (source instanceof LexicalNode) {
const cell_ = $findMatchingParent(source, DEPRECATED_$isGridCellNode);
invariant(
DEPRECATED_$isGridCellNode(cell_),
'Expected to find a parent GridCellNode',
);
cell = cell_;
} else {
const cell_ = $findMatchingParent(
source.getNode(),
DEPRECATED_$isGridCellNode,
);
invariant(
DEPRECATED_$isGridCellNode(cell_),
'Expected to find a parent GridCellNode',
);
cell = cell_;
}
const row = cell.getParent();
invariant(
DEPRECATED_$isGridRowNode(row),
'Expected GridCellNode to have a parent GridRowNode',
);
const grid = row.getParent();
invariant(
DEPRECATED_$isGridNode(grid),
'Expected GridRowNode to have a parent GridNode',
);
return [cell, row, grid];
}
function removeTextAndSplitBlock(selection: RangeSelection): number { function removeTextAndSplitBlock(selection: RangeSelection): number {
if (!selection.isCollapsed()) { if (!selection.isCollapsed()) {
selection.removeText(); selection.removeText();

View File

@ -43,8 +43,6 @@ export type {
export type { export type {
BaseSelection, BaseSelection,
ElementPointType as ElementPoint, ElementPointType as ElementPoint,
GridMapType,
GridMapValueType,
NodeSelection, NodeSelection,
Point, Point,
PointType, PointType,
@ -55,7 +53,6 @@ export type {
ElementFormatType, ElementFormatType,
SerializedElementNode, SerializedElementNode,
} from './nodes/LexicalElementNode'; } from './nodes/LexicalElementNode';
export type {SerializedGridCellNode} from './nodes/LexicalGridCellNode';
export type {SerializedRootNode} from './nodes/LexicalRootNode'; export type {SerializedRootNode} from './nodes/LexicalRootNode';
export type { export type {
SerializedTextNode, SerializedTextNode,
@ -134,9 +131,6 @@ export {
$isBlockElementNode, $isBlockElementNode,
$isNodeSelection, $isNodeSelection,
$isRangeSelection, $isRangeSelection,
DEPRECATED_$computeGridMap,
DEPRECATED_$getGridCellNodeRect,
DEPRECATED_$getNodeTriplet,
} from './LexicalSelection'; } from './LexicalSelection';
export {$parseSerializedNode, isCurrentlyReadOnlyMode} from './LexicalUpdates'; export {$parseSerializedNode, isCurrentlyReadOnlyMode} from './LexicalUpdates';
export { export {
@ -166,18 +160,6 @@ export {
} from './LexicalUtils'; } from './LexicalUtils';
export {$isDecoratorNode, DecoratorNode} from './nodes/LexicalDecoratorNode'; export {$isDecoratorNode, DecoratorNode} from './nodes/LexicalDecoratorNode';
export {$isElementNode, ElementNode} from './nodes/LexicalElementNode'; export {$isElementNode, ElementNode} from './nodes/LexicalElementNode';
export {
DEPRECATED_$isGridCellNode,
DEPRECATED_GridCellNode,
} from './nodes/LexicalGridCellNode';
export {
DEPRECATED_$isGridNode,
DEPRECATED_GridNode,
} from './nodes/LexicalGridNode';
export {
DEPRECATED_$isGridRowNode,
DEPRECATED_GridRowNode,
} from './nodes/LexicalGridRowNode';
export type {SerializedLineBreakNode} from './nodes/LexicalLineBreakNode'; export type {SerializedLineBreakNode} from './nodes/LexicalLineBreakNode';
export { export {
$createLineBreakNode, $createLineBreakNode,

View File

@ -1,19 +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.
*
*/
import type {LexicalNode} from '../LexicalNode';
import {ElementNode} from './LexicalElementNode';
export class DEPRECATED_GridNode extends ElementNode {}
export function DEPRECATED_$isGridNode(
node: LexicalNode | null | undefined,
): node is DEPRECATED_GridNode {
return node instanceof DEPRECATED_GridNode;
}

View File

@ -1,19 +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.
*
*/
import type {LexicalNode} from '../LexicalNode';
import {ElementNode} from './LexicalElementNode';
export class DEPRECATED_GridRowNode extends ElementNode {}
export function DEPRECATED_$isGridRowNode(
node: LexicalNode | null | undefined,
): node is DEPRECATED_GridRowNode {
return node instanceof DEPRECATED_GridRowNode;
}