chore: Upgrade all of prosemirror (#5366)
Co-authored-by: Apoorv Mishra <apoorvmishra101092@gmail.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { NodeType } from "prosemirror-model";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import { Dispatch } from "../types";
|
||||
import { Command } from "prosemirror-state";
|
||||
|
||||
/**
|
||||
* Converts the current node to a paragraph when pressing backspace at the
|
||||
@@ -9,28 +8,28 @@ import { Dispatch } from "../types";
|
||||
* @param type The node type
|
||||
* @returns A prosemirror command.
|
||||
*/
|
||||
export default function backspaceToParagraph(type: NodeType) {
|
||||
return (state: EditorState, dispatch: Dispatch) => {
|
||||
export default function backspaceToParagraph(type: NodeType): Command {
|
||||
return (state, dispatch) => {
|
||||
const { $from, from, to, empty } = state.selection;
|
||||
|
||||
// if the selection has anything in it then use standard delete behavior
|
||||
if (!empty) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check we're in a matching node
|
||||
if ($from.parent.type !== type) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if we're at the beginning of the heading
|
||||
const $pos = state.doc.resolve(from - 1);
|
||||
if ($pos.parent === $from.parent) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// okay, replace it with a paragraph
|
||||
dispatch(
|
||||
dispatch?.(
|
||||
state.tr
|
||||
.setBlockType(from, to, type.schema.nodes.paragraph)
|
||||
.scrollIntoView()
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import { Command } from "prosemirror-state";
|
||||
import { liftTarget } from "prosemirror-transform";
|
||||
import { Dispatch } from "../types";
|
||||
|
||||
const clearNodes = () => (state: EditorState, dispatch?: Dispatch) => {
|
||||
const clearNodes = (): Command => (state, dispatch) => {
|
||||
const { tr } = state;
|
||||
const { selection } = tr;
|
||||
const { ranges } = selection;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { EditorState, TextSelection } from "prosemirror-state";
|
||||
import { Command, TextSelection } from "prosemirror-state";
|
||||
import isInCode from "../queries/isInCode";
|
||||
import { Dispatch } from "../types";
|
||||
|
||||
/**
|
||||
* Moves the current selection to the previous newline, this is used inside
|
||||
@@ -8,10 +7,7 @@ import { Dispatch } from "../types";
|
||||
*
|
||||
* @returns A prosemirror command.
|
||||
*/
|
||||
export const moveToPreviousNewline = (
|
||||
state: EditorState,
|
||||
dispatch: Dispatch
|
||||
) => {
|
||||
export const moveToPreviousNewline: Command = (state, dispatch) => {
|
||||
if (!isInCode(state)) {
|
||||
return false;
|
||||
}
|
||||
@@ -34,7 +30,7 @@ export const moveToPreviousNewline = (
|
||||
return false;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
dispatch?.(
|
||||
state.tr.setSelection(
|
||||
TextSelection.create(
|
||||
state.doc,
|
||||
@@ -52,7 +48,7 @@ export const moveToPreviousNewline = (
|
||||
*
|
||||
* @returns A prosemirror command.
|
||||
*/
|
||||
export const moveToNextNewline = (state: EditorState, dispatch: Dispatch) => {
|
||||
export const moveToNextNewline: Command = (state, dispatch) => {
|
||||
if (!isInCode(state)) {
|
||||
return false;
|
||||
}
|
||||
@@ -69,7 +65,7 @@ export const moveToNextNewline = (state: EditorState, dispatch: Dispatch) => {
|
||||
return false;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
dispatch?.(
|
||||
state.tr.setSelection(
|
||||
TextSelection.create(state.doc, beginningOfNode + endOfLine)
|
||||
)
|
||||
@@ -85,7 +81,7 @@ export const moveToNextNewline = (state: EditorState, dispatch: Dispatch) => {
|
||||
*
|
||||
* @returns A prosemirror command
|
||||
*/
|
||||
export const newlineInCode = (state: EditorState, dispatch: Dispatch) => {
|
||||
export const newlineInCode: Command = (state, dispatch) => {
|
||||
if (!isInCode(state)) {
|
||||
return false;
|
||||
}
|
||||
@@ -101,7 +97,7 @@ export const newlineInCode = (state: EditorState, dispatch: Dispatch) => {
|
||||
newText += " ".repeat(numOfSpaces);
|
||||
}
|
||||
|
||||
dispatch(tr.insertText(newText, selection.from, selection.to));
|
||||
dispatch?.(tr.insertText(newText, selection.from, selection.to));
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -110,12 +106,12 @@ export const newlineInCode = (state: EditorState, dispatch: Dispatch) => {
|
||||
*
|
||||
* @returns A prosemirror command
|
||||
*/
|
||||
export const insertSpaceTab = (state: EditorState, dispatch: Dispatch) => {
|
||||
export const insertSpaceTab: Command = (state, dispatch) => {
|
||||
if (!isInCode(state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { tr, selection } = state;
|
||||
dispatch(tr.insertText(" ", selection.from, selection.to));
|
||||
dispatch?.(tr.insertText(" ", selection.from, selection.to));
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { EditorState, TextSelection } from "prosemirror-state";
|
||||
import { Dispatch } from "../types";
|
||||
import { Command, TextSelection } from "prosemirror-state";
|
||||
|
||||
const collapseSelection = () => (state: EditorState, dispatch?: Dispatch) => {
|
||||
const collapseSelection = (): Command => (state, dispatch) => {
|
||||
dispatch?.(
|
||||
state.tr.setSelection(
|
||||
TextSelection.create(state.doc, state.tr.selection.from)
|
||||
|
||||
31
shared/editor/commands/deleteEmptyFirstParagraph.ts
Normal file
31
shared/editor/commands/deleteEmptyFirstParagraph.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Command } from "prosemirror-state";
|
||||
import isNodeActive from "../queries/isNodeActive";
|
||||
|
||||
/**
|
||||
* Deletes the first paragraph node if it is empty and the cursor is at the
|
||||
* beginning of the document.
|
||||
*/
|
||||
const deleteEmptyFirstParagraph: Command = (state, dispatch) => {
|
||||
if (!isNodeActive(state.schema.nodes.paragraph)(state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state.selection.from !== 1 || state.selection.to !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parent = state.selection.$from.parent;
|
||||
if (parent.textContent !== "" || parent.childCount > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// delete the empty paragraph node
|
||||
dispatch?.(
|
||||
state.tr
|
||||
.delete(state.selection.from - 1, state.selection.from)
|
||||
.scrollIntoView()
|
||||
);
|
||||
return true;
|
||||
};
|
||||
|
||||
export default deleteEmptyFirstParagraph;
|
||||
@@ -17,9 +17,13 @@ limitations under the License.
|
||||
// This file is based on the implementation found here:
|
||||
// https://bitbucket.org/atlassian/design-system-mirror/src/master/editor/editor-core/src/plugins/text-formatting/commands/text-formatting.ts
|
||||
|
||||
import { Selection, EditorState, TextSelection } from "prosemirror-state";
|
||||
import {
|
||||
Selection,
|
||||
EditorState,
|
||||
TextSelection,
|
||||
Command,
|
||||
} from "prosemirror-state";
|
||||
import isMarkActive from "../queries/isMarkActive";
|
||||
import { Dispatch } from "../types";
|
||||
|
||||
function hasCode(state: EditorState, pos: number) {
|
||||
const { code_inline } = state.schema.marks;
|
||||
@@ -30,8 +34,8 @@ function hasCode(state: EditorState, pos: number) {
|
||||
: false;
|
||||
}
|
||||
|
||||
export default function moveLeft() {
|
||||
return (state: EditorState, dispatch: Dispatch): boolean => {
|
||||
export default function moveLeft(): Command {
|
||||
return (state, dispatch): boolean => {
|
||||
const { code_inline } = state.schema.marks;
|
||||
const { empty, $cursor } = state.selection as TextSelection;
|
||||
if (!empty || !$cursor) {
|
||||
@@ -70,14 +74,14 @@ export default function moveLeft() {
|
||||
Selection.near(state.doc.resolve($cursor.pos - 1))
|
||||
);
|
||||
|
||||
dispatch(tr.removeStoredMark(code_inline));
|
||||
dispatch?.(tr.removeStoredMark(code_inline));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// entering code mark (from right edge): don't move the cursor, just add the mark
|
||||
if (!insideCode && enteringCode) {
|
||||
dispatch(state.tr.addStoredMark(code_inline.create()));
|
||||
dispatch?.(state.tr.addStoredMark(code_inline.create()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -87,7 +91,7 @@ export default function moveLeft() {
|
||||
Selection.near(state.doc.resolve($cursor.pos - 1))
|
||||
);
|
||||
|
||||
dispatch(tr.addStoredMark(code_inline.create()));
|
||||
dispatch?.(tr.addStoredMark(code_inline.create()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -97,7 +101,7 @@ export default function moveLeft() {
|
||||
insideCode &&
|
||||
(exitingCode || (!$cursor.nodeBefore && isFirstChild))
|
||||
) {
|
||||
dispatch(state.tr.removeStoredMark(code_inline));
|
||||
dispatch?.(state.tr.removeStoredMark(code_inline));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,11 @@ limitations under the License.
|
||||
// This file is based on the implementation found here:
|
||||
// https://bitbucket.org/atlassian/design-system-mirror/src/master/editor/editor-core/src/plugins/text-formatting/commands/text-formatting.ts
|
||||
|
||||
import { EditorState, TextSelection } from "prosemirror-state";
|
||||
import { Command, TextSelection } from "prosemirror-state";
|
||||
import isMarkActive from "../queries/isMarkActive";
|
||||
import { Dispatch } from "../types";
|
||||
|
||||
export default function moveRight() {
|
||||
return (state: EditorState, dispatch: Dispatch): boolean => {
|
||||
export default function moveRight(): Command {
|
||||
return (state, dispatch): boolean => {
|
||||
const { code_inline } = state.schema.marks;
|
||||
const { empty, $cursor } = state.selection as TextSelection;
|
||||
if (!empty || !$cursor) {
|
||||
@@ -54,14 +53,14 @@ export default function moveRight() {
|
||||
|
||||
// entering code mark (from the left edge): don't move the cursor, just add the mark
|
||||
if (!insideCode && enteringCode) {
|
||||
dispatch(state.tr.addStoredMark(code_inline.create()));
|
||||
dispatch?.(state.tr.addStoredMark(code_inline.create()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// exiting code mark: don't move the cursor, just remove the mark
|
||||
if (insideCode && exitingCode) {
|
||||
dispatch(state.tr.removeStoredMark(code_inline));
|
||||
dispatch?.(state.tr.removeStoredMark(code_inline));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { NodeType } from "prosemirror-model";
|
||||
import { EditorState, TextSelection } from "prosemirror-state";
|
||||
import { findBlockNodes } from "prosemirror-utils";
|
||||
import { Command, TextSelection } from "prosemirror-state";
|
||||
import { findBlockNodes } from "../queries/findChildren";
|
||||
import findCollapsedNodes from "../queries/findCollapsedNodes";
|
||||
import { Dispatch } from "../types";
|
||||
|
||||
export default function splitHeading(type: NodeType) {
|
||||
return (state: EditorState, dispatch: Dispatch): boolean => {
|
||||
export default function splitHeading(type: NodeType): Command {
|
||||
return (state, dispatch): boolean => {
|
||||
const { $from, from, $to, to } = state.selection;
|
||||
|
||||
// check we're in a matching heading node
|
||||
@@ -33,7 +32,7 @@ export default function splitHeading(type: NodeType) {
|
||||
);
|
||||
|
||||
// Move the selection into the new heading node and make sure it's on screen
|
||||
dispatch(
|
||||
dispatch?.(
|
||||
transaction
|
||||
.setSelection(
|
||||
TextSelection.near(transaction.doc.resolve($from.before()))
|
||||
@@ -75,7 +74,7 @@ export default function splitHeading(type: NodeType) {
|
||||
);
|
||||
|
||||
// Move the selection into the new heading node and make sure it's on screen
|
||||
dispatch(
|
||||
dispatch?.(
|
||||
transaction
|
||||
.setSelection(
|
||||
TextSelection.near(
|
||||
|
||||
152
shared/editor/commands/table.ts
Normal file
152
shared/editor/commands/table.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import { Fragment, Node, NodeType } from "prosemirror-model";
|
||||
import {
|
||||
Command,
|
||||
EditorState,
|
||||
TextSelection,
|
||||
Transaction,
|
||||
} from "prosemirror-state";
|
||||
import {
|
||||
CellSelection,
|
||||
addRow,
|
||||
isInTable,
|
||||
selectedRect,
|
||||
tableNodeTypes,
|
||||
} from "prosemirror-tables";
|
||||
import { getCellsInColumn } from "../queries/table";
|
||||
|
||||
export function createTable(
|
||||
state: EditorState,
|
||||
rowsCount: number,
|
||||
colsCount: number,
|
||||
withHeaderRow = true,
|
||||
cellContent?: Node
|
||||
) {
|
||||
const types = tableNodeTypes(state.schema);
|
||||
const headerCells: Node[] = [];
|
||||
const cells: Node[] = [];
|
||||
const rows: Node[] = [];
|
||||
|
||||
const createCell = (
|
||||
cellType: NodeType,
|
||||
cellContent: Fragment | Node | readonly Node[] | null | undefined
|
||||
) =>
|
||||
cellContent
|
||||
? cellType.createChecked(null, cellContent)
|
||||
: cellType.createAndFill();
|
||||
|
||||
for (let index = 0; index < colsCount; index += 1) {
|
||||
const cell = createCell(types.cell, cellContent);
|
||||
|
||||
if (cell) {
|
||||
cells.push(cell);
|
||||
}
|
||||
|
||||
if (withHeaderRow) {
|
||||
const headerCell = createCell(types.header_cell, cellContent);
|
||||
|
||||
if (headerCell) {
|
||||
headerCells.push(headerCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let index = 0; index < rowsCount; index += 1) {
|
||||
rows.push(
|
||||
types.row.createChecked(
|
||||
null,
|
||||
withHeaderRow && index === 0 ? headerCells : cells
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return types.table.createChecked(null, rows);
|
||||
}
|
||||
|
||||
export function addRowAfterAndMoveSelection({
|
||||
index,
|
||||
}: {
|
||||
index?: number;
|
||||
} = {}): Command {
|
||||
return (state, dispatch) => {
|
||||
if (!isInTable(state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
const rect = selectedRect(state);
|
||||
const indexAfter = index !== undefined ? index + 1 : rect.bottom;
|
||||
const tr = addRow(state.tr, rect, indexAfter);
|
||||
const cells = getCellsInColumn(0)(state);
|
||||
|
||||
// Special case when adding row to the end of the table as the calculated
|
||||
// rect does not include the row that we just added.
|
||||
if (indexAfter !== rect.map.height) {
|
||||
const pos = cells[Math.min(cells.length - 1, indexAfter)];
|
||||
const $pos = tr.doc.resolve(pos);
|
||||
dispatch(tr.setSelection(TextSelection.near($pos)));
|
||||
} else {
|
||||
const $pos = tr.doc.resolve(rect.tableStart + rect.table.nodeSize);
|
||||
dispatch(tr.setSelection(TextSelection.near($pos)));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
export function setColumnAttr({
|
||||
index,
|
||||
alignment,
|
||||
}: {
|
||||
index: number;
|
||||
alignment: string;
|
||||
}): Command {
|
||||
return (state, dispatch) => {
|
||||
if (dispatch) {
|
||||
const cells = getCellsInColumn(index)(state) || [];
|
||||
let transaction = state.tr;
|
||||
cells.forEach((pos) => {
|
||||
transaction = transaction.setNodeMarkup(pos, undefined, {
|
||||
alignment,
|
||||
});
|
||||
});
|
||||
dispatch(transaction);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
export function selectRow(index: number, expand = false) {
|
||||
return (state: EditorState): Transaction => {
|
||||
const rect = selectedRect(state);
|
||||
const pos = rect.map.positionAt(index, 0, rect.table);
|
||||
const $pos = state.doc.resolve(rect.tableStart + pos);
|
||||
const rowSelection =
|
||||
expand && state.selection instanceof CellSelection
|
||||
? CellSelection.rowSelection(state.selection.$anchorCell, $pos)
|
||||
: CellSelection.rowSelection($pos);
|
||||
return state.tr.setSelection(rowSelection);
|
||||
};
|
||||
}
|
||||
|
||||
export function selectColumn(index: number, expand = false) {
|
||||
return (state: EditorState): Transaction => {
|
||||
const rect = selectedRect(state);
|
||||
const pos = rect.map.positionAt(0, index, rect.table);
|
||||
const $pos = state.doc.resolve(rect.tableStart + pos);
|
||||
const colSelection =
|
||||
expand && state.selection instanceof CellSelection
|
||||
? CellSelection.colSelection(state.selection.$anchorCell, $pos)
|
||||
: CellSelection.colSelection($pos);
|
||||
return state.tr.setSelection(colSelection);
|
||||
};
|
||||
}
|
||||
|
||||
export function selectTable(state: EditorState): Transaction {
|
||||
const rect = selectedRect(state);
|
||||
const map = rect.map.map;
|
||||
const $anchor = state.doc.resolve(rect.tableStart + map[0]);
|
||||
const $head = state.doc.resolve(rect.tableStart + map[map.length - 1]);
|
||||
const tableSelection = new CellSelection($anchor, $head);
|
||||
return state.tr.setSelection(tableSelection);
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
import { setBlockType } from "prosemirror-commands";
|
||||
import { NodeType } from "prosemirror-model";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import { Command } from "prosemirror-state";
|
||||
import isNodeActive from "../queries/isNodeActive";
|
||||
import { Dispatch } from "../types";
|
||||
|
||||
export default function toggleBlockType(
|
||||
type: NodeType,
|
||||
toggleType: NodeType,
|
||||
attrs = {}
|
||||
) {
|
||||
return (state: EditorState, dispatch?: Dispatch) => {
|
||||
): Command {
|
||||
return (state, dispatch) => {
|
||||
const isActive = isNodeActive(type, attrs)(state);
|
||||
|
||||
if (isActive) {
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { NodeType } from "prosemirror-model";
|
||||
import { wrapInList, liftListItem } from "prosemirror-schema-list";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import { findParentNode } from "prosemirror-utils";
|
||||
import { Command } from "prosemirror-state";
|
||||
import chainTransactions from "../lib/chainTransactions";
|
||||
import { findParentNode } from "../queries/findParentNode";
|
||||
import isList from "../queries/isList";
|
||||
import { Dispatch } from "../types";
|
||||
import clearNodes from "./clearNodes";
|
||||
|
||||
export default function toggleList(listType: NodeType, itemType: NodeType) {
|
||||
return (state: EditorState, dispatch?: Dispatch) => {
|
||||
export default function toggleList(
|
||||
listType: NodeType,
|
||||
itemType: NodeType
|
||||
): Command {
|
||||
return (state, dispatch) => {
|
||||
const { schema, selection } = state;
|
||||
const { $from, $to } = selection;
|
||||
const range = $from.blockRange($to);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { wrapIn, lift } from "prosemirror-commands";
|
||||
import { NodeType } from "prosemirror-model";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import { Command } from "prosemirror-state";
|
||||
import isNodeActive from "../queries/isNodeActive";
|
||||
import { Dispatch } from "../types";
|
||||
|
||||
export default function toggleWrap(
|
||||
type: NodeType,
|
||||
attrs?: Record<string, any>
|
||||
) {
|
||||
return (state: EditorState, dispatch?: Dispatch) => {
|
||||
): Command {
|
||||
return (state, dispatch) => {
|
||||
const isActive = isNodeActive(type)(state);
|
||||
|
||||
if (isActive) {
|
||||
|
||||
Reference in New Issue
Block a user