chore: Upgrade all of prosemirror (#5366)
Co-authored-by: Apoorv Mishra <apoorvmishra101092@gmail.com>
This commit is contained in:
57
shared/editor/queries/findChildren.ts
Normal file
57
shared/editor/queries/findChildren.ts
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
44
shared/editor/queries/findParentNode.ts
Normal file
44
shared/editor/queries/findParentNode.ts
Normal 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;
|
||||
};
|
||||
@@ -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];
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
95
shared/editor/queries/table.ts
Normal file
95
shared/editor/queries/table.ts
Normal 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
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user