chore: Upgrade all of prosemirror (#5366)

Co-authored-by: Apoorv Mishra <apoorvmishra101092@gmail.com>
This commit is contained in:
Tom Moor
2023-05-24 22:24:05 -04:00
committed by GitHub
parent e340e568e2
commit d5341a486c
77 changed files with 875 additions and 675 deletions

View File

@@ -0,0 +1,57 @@
import { Node } from "prosemirror-model";
type Predicate = (node: Node) => boolean;
export type NodeWithPos = {
pos: number;
node: Node;
};
export function flatten(node: Node, descend = true): NodeWithPos[] {
if (!node) {
throw new Error('Invalid "node" parameter');
}
const result: NodeWithPos[] = [];
node.descendants((child, pos) => {
result.push({ node: child, pos });
if (!descend) {
return false;
}
return undefined;
});
return result;
}
/**
* Iterates over descendants of a given `node`, returning child nodes predicate
* returns truthy for. It doesn't descend into a node when descend argument is
* `false` (defaults to `true`).
*
* @param node The node to iterate over
* @param predicate Filtering predicate function
* @param descend Whether to descend into a node
* @returns Child nodes
*/
export function findChildren(
node: Node,
predicate: Predicate,
descend = false
) {
if (!node) {
throw new Error('Invalid "node" parameter');
} else if (!predicate) {
throw new Error('Invalid "predicate" parameter');
}
return flatten(node, descend).filter((child) => predicate(child.node));
}
/**
* Iterates over descendants of a given `node`, returning child nodes that
* are blocks.
*
* @param node The node to iterate over
* @returns Child nodes that are blocks
*/
export function findBlockNodes(node: Node): NodeWithPos[] {
return findChildren(node, (child) => child.isBlock);
}

View File

@@ -1,5 +1,5 @@
import { Node } from "prosemirror-model";
import { findBlockNodes, NodeWithPos } from "prosemirror-utils";
import { findBlockNodes, NodeWithPos } from "./findChildren";
export default function findCollapsedNodes(doc: Node): NodeWithPos[] {
const blocks = findBlockNodes(doc);

View File

@@ -1,8 +1,8 @@
import { Node } from "prosemirror-model";
import { findTextNodes, NodeWithPos } from "prosemirror-utils";
import { findChildren, NodeWithPos } from "./findChildren";
export default function findLinkNodes(doc: Node): NodeWithPos[] {
const textNodes = findTextNodes(doc);
const textNodes = findChildren(doc, (child) => child.isText);
const nodes: NodeWithPos[] = [];
for (const nodeWithPos of textNodes) {

View File

@@ -0,0 +1,44 @@
import { Node, ResolvedPos } from "prosemirror-model";
import { Selection } from "prosemirror-state";
type Predicate = (node: Node) => boolean;
type ContentNodeWithPos = {
pos: number;
start: number;
depth: number;
node: Node;
};
export const findParentNode =
(predicate: Predicate) =>
({ $from }: Selection) =>
findParentNodeClosestToPos($from, predicate);
/**
* Iterates over parent nodes starting from the given `$pos`, returning the
* closest node and its start position `predicate` returns truthy for. `start`
* points to the start position of the node, `pos` points directly before the node.
*
* @param $pos position to start from
* @param predicate filtering predicate function
* @returns node and its start position
*/
export const findParentNodeClosestToPos = (
$pos: ResolvedPos,
predicate: Predicate
): ContentNodeWithPos | undefined => {
for (let i = $pos.depth; i > 0; i--) {
const node = $pos.node(i);
if (predicate(node)) {
return {
pos: i > 0 ? $pos.before(i) : 0,
start: $pos.start(i),
depth: i,
node,
};
}
}
return undefined;
};

View File

@@ -1,11 +0,0 @@
import { CellSelection } from "prosemirror-tables";
export default function getColumnIndex(selection: CellSelection) {
const isColSelection = selection.isColSelection && selection.isColSelection();
if (!isColSelection) {
return undefined;
}
const path = (selection.$from as any).path;
return path[path.length - 5];
}

View File

@@ -1,21 +0,0 @@
import { CellSelection } from "prosemirror-tables";
export default function getRowIndex(selection: CellSelection) {
const isRowSelection = selection.isRowSelection && selection.isRowSelection();
if (!isRowSelection) {
return undefined;
}
const path = (selection.$from as any).path;
return path[path.length - 8];
}
export function getRowIndexFromText(selection: CellSelection) {
const isRowSelection = selection.isRowSelection && selection.isRowSelection();
const path = (selection.$from as any).path;
if (isRowSelection) {
return path[path.length - 8];
} else {
return path[path.length - 11];
}
}

View File

@@ -1,6 +1,6 @@
import { NodeType } from "prosemirror-model";
import { EditorState } from "prosemirror-state";
import { findParentNode, findSelectedNodeOfType } from "prosemirror-utils";
import { findParentNode } from "./findParentNode";
const isNodeActive =
(type: NodeType, attrs: Record<string, any> = {}) =>
@@ -9,15 +9,21 @@ const isNodeActive =
return false;
}
const node =
findSelectedNodeOfType(type)(state.selection) ||
findParentNode((node) => node.type === type)(state.selection);
const nodeAfter = state.selection.$from.nodeAfter;
let node = nodeAfter?.type === type ? nodeAfter : undefined;
if (!node) {
const parent = findParentNode((node) => node.type === type)(
state.selection
);
node = parent?.node;
}
if (!Object.keys(attrs).length || !node) {
return !!node;
}
return node.node.hasMarkup(type, { ...node.node.attrs, ...attrs });
return node.hasMarkup(type, { ...node.attrs, ...attrs });
};
export default isNodeActive;

View File

@@ -0,0 +1,95 @@
import { EditorState } from "prosemirror-state";
import { CellSelection, isInTable, selectedRect } from "prosemirror-tables";
export function getColumnIndex(state: EditorState): number | undefined {
if (state.selection instanceof CellSelection) {
if (state.selection.isColSelection()) {
const rect = selectedRect(state);
return rect.left;
}
}
return undefined;
}
export function getRowIndex(state: EditorState): number | undefined {
if (state.selection instanceof CellSelection) {
if (state.selection.isRowSelection()) {
const rect = selectedRect(state);
return rect.top;
}
}
return undefined;
}
export function getCellsInColumn(index: number) {
return (state: EditorState): number[] => {
if (!isInTable(state)) {
return [];
}
const rect = selectedRect(state);
const cells = [];
for (let i = index; i < rect.map.map.length; i += rect.map.width) {
const cell = rect.tableStart + rect.map.map[i];
cells.push(cell);
}
return cells;
};
}
export function getCellsInRow(index: number) {
return (state: EditorState): number[] => {
if (!isInTable(state)) {
return [];
}
const rect = selectedRect(state);
const cells = [];
for (let i = 0; i < rect.map.width; i += 1) {
const cell = rect.tableStart + rect.map.map[index * rect.map.width + i];
cells.push(cell);
}
return cells;
};
}
export function isColumnSelected(index: number) {
return (state: EditorState): boolean => {
if (state.selection instanceof CellSelection) {
if (state.selection.isColSelection()) {
const rect = selectedRect(state);
return rect.left <= index && rect.right > index;
}
}
return false;
};
}
export function isRowSelected(index: number) {
return (state: EditorState): boolean => {
if (state.selection instanceof CellSelection) {
if (state.selection.isRowSelection()) {
const rect = selectedRect(state);
return rect.top <= index && rect.bottom > index;
}
}
return false;
};
}
export function isTableSelected(state: EditorState): boolean {
const rect = selectedRect(state);
return (
rect.top === 0 &&
rect.left === 0 &&
rect.bottom === rect.map.height &&
rect.right === rect.map.width
);
}